📄 jpg_enc.c
字号:
static void jpg_finish_input(j_compress_ptr cinfo, struct jpg_src_s *sinfo){ /* Avoid compiler warnings about unused parameters. */ cinfo = 0; sinfo = 0;}/******************************************************************************\* Code for save operation.\******************************************************************************//* Save an image to a stream in the the JPG format. */int jpg_encode(jas_image_t *image, jas_stream_t *out, char *optstr){ JDIMENSION numscanlines; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; jas_image_coord_t width; jas_image_coord_t height; jpg_src_t src_mgr_buf; jpg_src_t *src_mgr = &src_mgr_buf; FILE *output_file; int cmptno; jpg_enc_t encbuf; jpg_enc_t *enc = &encbuf; jpg_encopts_t encopts; output_file = 0; if (jpg_parseencopts(optstr, &encopts)) goto error; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_clrspc(image) != JAS_CLRSPC_SRGB) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_clrspc(image) != JAS_CLRSPC_SYCBCR) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_clrspc(image) != JAS_CLRSPC_SGRAY) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 1; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; default: jas_eprintf("error: JPG format does not support color space\n"); goto error; break; } width = jas_image_width(image); height = jas_image_height(image); for (cmptno = 0; cmptno < enc->numcmpts; ++cmptno) { if (jas_image_cmptwidth(image, enc->cmpts[cmptno]) != width || jas_image_cmptheight(image, enc->cmpts[cmptno]) != height || jas_image_cmpttlx(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpttly(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpthstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptvstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptprec(image, enc->cmpts[cmptno]) != 8 || jas_image_cmptsgnd(image, enc->cmpts[cmptno]) != false) { jas_eprintf("error: The JPG encoder cannot handle an image with this geometry.\n"); goto error; } } if (!(output_file = tmpfile())) { goto error; } /* Create a JPEG compression object. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* Specify data destination for compression */ jpeg_stdio_dest(&cinfo, output_file); cinfo.in_color_space = tojpgcs(jas_image_clrspc(image)); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = enc->numcmpts; jpeg_set_defaults(&cinfo); src_mgr->error = 0; src_mgr->image = image; src_mgr->data = jas_matrix_create(1, width); src_mgr->buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, (JDIMENSION) width * cinfo.input_components, (JDIMENSION) 1); src_mgr->buffer_height = 1; src_mgr->enc = enc; /* Read the input file header to obtain file size & colorspace. */ jpg_start_input(&cinfo, src_mgr); if (encopts.qual >= 0) { jpeg_set_quality(&cinfo, encopts.qual, TRUE); } /* Now that we know input colorspace, fix colorspace-dependent defaults */ jpeg_default_colorspace(&cinfo); /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { if ((numscanlines = jpg_get_pixel_rows(&cinfo, src_mgr)) <= 0) { break; } jpeg_write_scanlines(&cinfo, src_mgr->buffer, numscanlines); } /* Finish compression and release memory */ jpg_finish_input(&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); rewind(output_file); jpg_copyfiletostream(out, output_file); fclose(output_file); output_file = 0; return 0;error: if (output_file) { fclose(output_file); } return -1;}static int tojpgcs(int colorspace){ switch (jas_clrspc_fam(colorspace)) { case JAS_CLRSPC_FAM_RGB: return JCS_RGB; break; case JAS_CLRSPC_FAM_YCBCR: return JCS_YCbCr; break; case JAS_CLRSPC_FAM_GRAY: return JCS_GRAYSCALE; break; default: abort(); break; }}/* Parse the encoder options string. */static int jpg_parseencopts(char *optstr, jpg_encopts_t *encopts){ jas_tvparser_t *tvp; char *qual_str; int ret; tvp = 0; /* Initialize default values for encoder options. */ encopts->qual = -1; /* Create the tag-value parser. */ if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) { goto error; } /* Get tag-value pairs, and process as necessary. */ while (!(ret = jas_tvparser_next(tvp))) { switch (jas_taginfo_nonull(jas_taginfos_lookup(jpg_opttab, jas_tvparser_gettag(tvp)))->id) { case OPT_QUAL: qual_str = jas_tvparser_getval(tvp); if (sscanf(qual_str, "%d", &encopts->qual) != 1) { fprintf(stderr, "ignoring bad quality specifier %s\n", jas_tvparser_getval(tvp)); encopts->qual = -1; } break; default: fprintf(stderr, "warning: ignoring invalid option %s\n", jas_tvparser_gettag(tvp)); break; } } if (ret < 0) { goto error; } /* Destroy the tag-value parser. */ jas_tvparser_destroy(tvp); return 0;error: if (tvp) { jas_tvparser_destroy(tvp); } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -