int RGB_To_JPEG_encode(struct jpeg_compress_struct *cinfo, char *inData, char *outData, int flipped, int quality, int decimation) { struct jmf_error_mgr *jerr = (struct jmf_error_mgr *) cinfo->err; JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ jmf_destination_mgr *jmf_dest = (jmf_destination_mgr *) cinfo->dest; jmf_dest_data *clientData = (jmf_dest_data *) cinfo->client_data; int direction = 1; int start = 0; clientData->data = (char *) outData; clientData->length = 0; /* Establish the setjmp return context for jmf_error_exit to use. */ if (setjmp(jerr->setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ return 0; } jmf_dest->buffer = (JOCTET *) clientData->tmp_data; if (quality >= 0) { jm_jpeg_set_quality(cinfo, quality, TRUE); } /* Default decimation is YUV 4:2:0. If we need 422 or 444, we modify the h_samp_factor and v_samp_factor for U and V components. */ if (decimation >= 1) { int hs, vs; switch (decimation) { case 1: hs = 2; vs = 2; break; case 2: hs = 2; vs = 1; break; case 4: hs = 1; vs = 1; break; } (cinfo->comp_info[0]).v_samp_factor = vs; (cinfo->comp_info[0]).h_samp_factor = hs; (cinfo->comp_info[1]).v_samp_factor = 1; (cinfo->comp_info[2]).v_samp_factor = 1; (cinfo->comp_info[1]).h_samp_factor = 1; (cinfo->comp_info[2]).h_samp_factor = 1; } jm_jpeg_start_compress(cinfo, TRUE); row_stride = cinfo->image_width * 3; /* JSAMPLEs per row in image_buffer */ if (flipped) { direction = -1; start = (cinfo->image_height - 1) * row_stride; } while (cinfo->next_scanline < cinfo->image_height) { row_pointer[0] = (unsigned char *) &inData[start + direction * cinfo->next_scanline * row_stride]; (void) jm_jpeg_write_scanlines(cinfo, row_pointer, 1); } jm_jpeg_finish_compress(cinfo); return clientData->length; }
struct jpeg_compress_struct * RGB_To_JPEG_init(int width, int height, int quality, int decimation) { struct jmf_error_mgr *jerr; struct jpeg_compress_struct *cinfo; jmf_destination_mgr *jmf_dest; jmf_dest_data *clientData; clientData = (jmf_dest_data*) malloc(sizeof(jmf_dest_data)); /* Alloc 1 */ clientData->tmp_data = (char *) malloc(JMF_OUTPUT_BUF_SIZE); /* Alloc 2 */ //clientData->data = (char *) outData; //clientData->length = 0; /* Step 1: allocate and initialize JPEG compression object */ cinfo = (struct jpeg_compress_struct *) malloc(sizeof(struct jpeg_compress_struct));/* Alloc 3 */ /* Initialize error parameters */ jerr = (struct jmf_error_mgr *) malloc(sizeof(struct jmf_error_mgr)); /* Alloc 4 */ clientData->jerr = (void *) jerr; cinfo->err = jm_jpeg_std_error(&(jerr->pub)); (jerr->pub).error_exit = jmf_error_exit; /* Establish the setjmp return context for jmf_error_exit to use. */ if (setjmp(jerr->setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jm_jpeg_destroy_compress(cinfo); free(jerr); free(clientData->tmp_data); free(clientData); free(cinfo); printf("JPEG encoding error!\n"); return 0; } /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(cinfo); /* Set up my own destination manager. */ jmf_dest = (jmf_destination_mgr *) malloc(sizeof(jmf_destination_mgr));/* Alloc 5 */ jmf_dest->pub.init_destination = jmf_init_destination; jmf_dest->pub.empty_output_buffer = jmf_empty_output_buffer; jmf_dest->pub.term_destination = jmf_term_destination; cinfo->dest = (struct jpeg_destination_mgr *) jmf_dest; /* Set up client data */ cinfo->client_data = clientData; /* Step 3: set parameters for compression */ /* First we supply a description of the input image. * Four fields of the cinfo struct must be filled in: */ cinfo->image_width = width; /* image width and height, in pixels */ cinfo->image_height = height; cinfo->input_components = 3; /* # of color components per pixel */ cinfo->in_color_space = JCS_RGB; /* colorspace of input image */ /* Tell the library to set default parameters */ jm_jpeg_set_defaults(cinfo); /* Default decimation is YUV 4:2:0. If we need 422 or 444, we modify the h_samp_factor and v_samp_factor for U and V components. */ if (decimation >= 1) { int hs, vs; switch (decimation) { case 1: hs = 2; vs = 2; break; case 2: hs = 2; vs = 1; break; case 4: hs = 1; vs = 1; break; } (cinfo->comp_info[0]).v_samp_factor = vs; (cinfo->comp_info[0]).h_samp_factor = hs; (cinfo->comp_info[1]).v_samp_factor = 1; (cinfo->comp_info[2]).v_samp_factor = 1; (cinfo->comp_info[1]).h_samp_factor = 1; (cinfo->comp_info[2]).h_samp_factor = 1; } /* Now you can set any non-default parameters you wish to. * Here we just illustrate the use of quality (quantization table) scaling: */ jm_jpeg_set_quality(cinfo, quality, TRUE /* limit to baseline-JPEG values */ ); return cinfo; }
jm_jpeg_set_defaults (j_compress_ptr cinfo) { int i; /* Safety check to ensure start_compress not called yet. */ if (cinfo->global_state != CSTATE_START) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); /* Allocate comp_info array large enough for maximum component count. * Array is made permanent in case application wants to compress * multiple images at same param settings. */ if (cinfo->comp_info == NULL) cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, MAX_COMPONENTS * SIZEOF(jpeg_component_info)); /* Initialize everything not dependent on the color space */ cinfo->data_precision = BITS_IN_JSAMPLE; /* Set up two quantization tables using default quality of 75 */ jm_jpeg_set_quality(cinfo, 75, TRUE); /* Set up two Huffman tables */ std_huff_tables(cinfo); /* Initialize default arithmetic coding conditioning */ for (i = 0; i < NUM_ARITH_TBLS; i++) { cinfo->arith_dc_L[i] = 0; cinfo->arith_dc_U[i] = 1; cinfo->arith_ac_K[i] = 5; } /* Default is no multiple-scan output */ cinfo->scan_info = NULL; cinfo->num_scans = 0; /* Expect normal source image, not raw downsampled data */ cinfo->raw_data_in = FALSE; /* Use Huffman coding, not arithmetic coding, by default */ cinfo->arith_code = FALSE; /* By default, don't do extra passes to optimize entropy coding */ cinfo->optimize_coding = FALSE; /* The standard Huffman tables are only valid for 8-bit data precision. * If the precision is higher, force optimization on so that usable * tables will be computed. This test can be removed if default tables * are supplied that are valid for the desired precision. */ if (cinfo->data_precision > 8) cinfo->optimize_coding = TRUE; /* By default, use the simpler non-cosited sampling alignment */ cinfo->CCIR601_sampling = FALSE; /* No input smoothing */ cinfo->smoothing_factor = 0; /* DCT algorithm preference */ cinfo->dct_method = JDCT_DEFAULT; /* No restart markers */ cinfo->restart_interval = 0; cinfo->restart_in_rows = 0; /* Fill in default JFIF marker parameters. Note that whether the marker * will actually be written is determined by jm_jpeg_set_colorspace. * * By default, the library emits JFIF version code 1.01. * An application that wants to emit JFIF 1.02 extension markers should set * JFIF_minor_version to 2. We could probably get away with just defaulting * to 1.02, but there may still be some decoders in use that will complain * about that; saying 1.01 should minimize compatibility problems. */ cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ cinfo->JFIF_minor_version = 1; cinfo->density_unit = 0; /* Pixel size is unknown by default */ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->Y_density = 1; /* Choose JPEG colorspace based on input space, set defaults accordingly */ jm_jpeg_default_colorspace(cinfo); }