Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed
jcprepct.c
00001 /* 00002 * jcprepct.c 00003 * 00004 * Copyright (C) 1994-1996, Thomas G. Lane. 00005 * This file is part of the Independent JPEG Group's software. 00006 * For conditions of distribution and use, see the accompanying README file. 00007 * 00008 * This file contains the compression preprocessing controller. 00009 * This controller manages the color conversion, downsampling, 00010 * and edge expansion steps. 00011 * 00012 * Most of the complexity here is associated with buffering input rows 00013 * as required by the downsampler. See the comments at the head of 00014 * jcsample.c for the downsampler's needs. 00015 */ 00016 00017 #define JPEG_INTERNALS 00018 #include "jinclude.h" 00019 #include "jpeglib.h" 00020 00021 00022 /* At present, jcsample.c can request context rows only for smoothing. 00023 * In the future, we might also need context rows for CCIR601 sampling 00024 * or other more-complex downsampling procedures. The code to support 00025 * context rows should be compiled only if needed. 00026 */ 00027 #ifdef INPUT_SMOOTHING_SUPPORTED 00028 #define CONTEXT_ROWS_SUPPORTED 00029 #endif 00030 00031 00032 /* 00033 * For the simple (no-context-row) case, we just need to buffer one 00034 * row group's worth of pixels for the downsampling step. At the bottom of 00035 * the image, we pad to a full row group by replicating the last pixel row. 00036 * The downsampler's last output row is then replicated if needed to pad 00037 * out to a full iMCU row. 00038 * 00039 * When providing context rows, we must buffer three row groups' worth of 00040 * pixels. Three row groups are physically allocated, but the row pointer 00041 * arrays are made five row groups high, with the extra pointers above and 00042 * below "wrapping around" to point to the last and first real row groups. 00043 * This allows the downsampler to access the proper context rows. 00044 * At the top and bottom of the image, we create dummy context rows by 00045 * copying the first or last real pixel row. This copying could be avoided 00046 * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the 00047 * trouble on the compression side. 00048 */ 00049 00050 00051 /* Private buffer controller object */ 00052 00053 typedef struct { 00054 struct jpeg_c_prep_controller pub; /* public fields */ 00055 00056 /* Downsampling input buffer. This buffer holds color-converted data 00057 * until we have enough to do a downsample step. 00058 */ 00059 JSAMPARRAY color_buf[MAX_COMPONENTS]; 00060 00061 JDIMENSION rows_to_go; /* counts rows remaining in source image */ 00062 int next_buf_row; /* index of next row to store in color_buf */ 00063 00064 #ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ 00065 int this_row_group; /* starting row index of group to process */ 00066 int next_buf_stop; /* downsample when we reach this index */ 00067 #endif 00068 } my_prep_controller; 00069 00070 typedef my_prep_controller * my_prep_ptr; 00071 00072 00073 /* 00074 * Initialize for a processing pass. 00075 */ 00076 00077 METHODDEF(void) 00078 start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 00079 { 00080 my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 00081 00082 if (pass_mode != JBUF_PASS_THRU) 00083 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00084 00085 /* Initialize total-height counter for detecting bottom of image */ 00086 prep->rows_to_go = cinfo->image_height; 00087 /* Mark the conversion buffer empty */ 00088 prep->next_buf_row = 0; 00089 #ifdef CONTEXT_ROWS_SUPPORTED 00090 /* Preset additional state variables for context mode. 00091 * These aren't used in non-context mode, so we needn't test which mode. 00092 */ 00093 prep->this_row_group = 0; 00094 /* Set next_buf_stop to stop after two row groups have been read in. */ 00095 prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; 00096 #endif 00097 } 00098 00099 00100 /* 00101 * Expand an image vertically from height input_rows to height output_rows, 00102 * by duplicating the bottom row. 00103 */ 00104 00105 LOCAL(void) 00106 expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, 00107 int input_rows, int output_rows) 00108 { 00109 register int row; 00110 00111 for (row = input_rows; row < output_rows; row++) { 00112 jcopy_sample_rows(image_data, input_rows-1, image_data, row, 00113 1, num_cols); 00114 } 00115 } 00116 00117 00118 /* 00119 * Process some data in the simple no-context case. 00120 * 00121 * Preprocessor output data is counted in "row groups". A row group 00122 * is defined to be v_samp_factor sample rows of each component. 00123 * Downsampling will produce this much data from each max_v_samp_factor 00124 * input rows. 00125 */ 00126 00127 METHODDEF(void) 00128 pre_process_data (j_compress_ptr cinfo, 00129 JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 00130 JDIMENSION in_rows_avail, 00131 JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 00132 JDIMENSION out_row_groups_avail) 00133 { 00134 my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 00135 int numrows, ci; 00136 JDIMENSION inrows; 00137 jpeg_component_info * compptr; 00138 00139 while (*in_row_ctr < in_rows_avail && 00140 *out_row_group_ctr < out_row_groups_avail) { 00141 /* Do color conversion to fill the conversion buffer. */ 00142 inrows = in_rows_avail - *in_row_ctr; 00143 numrows = cinfo->max_v_samp_factor - prep->next_buf_row; 00144 numrows = (int) MIN((JDIMENSION) numrows, inrows); 00145 (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 00146 prep->color_buf, 00147 (JDIMENSION) prep->next_buf_row, 00148 numrows); 00149 *in_row_ctr += numrows; 00150 prep->next_buf_row += numrows; 00151 prep->rows_to_go -= numrows; 00152 /* If at bottom of image, pad to fill the conversion buffer. */ 00153 if (prep->rows_to_go == 0 && 00154 prep->next_buf_row < cinfo->max_v_samp_factor) { 00155 for (ci = 0; ci < cinfo->num_components; ci++) { 00156 expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 00157 prep->next_buf_row, cinfo->max_v_samp_factor); 00158 } 00159 prep->next_buf_row = cinfo->max_v_samp_factor; 00160 } 00161 /* If we've filled the conversion buffer, empty it. */ 00162 if (prep->next_buf_row == cinfo->max_v_samp_factor) { 00163 (*cinfo->downsample->downsample) (cinfo, 00164 prep->color_buf, (JDIMENSION) 0, 00165 output_buf, *out_row_group_ctr); 00166 prep->next_buf_row = 0; 00167 (*out_row_group_ctr)++; 00168 } 00169 /* If at bottom of image, pad the output to a full iMCU height. 00170 * Note we assume the caller is providing a one-iMCU-height output buffer! 00171 */ 00172 if (prep->rows_to_go == 0 && 00173 *out_row_group_ctr < out_row_groups_avail) { 00174 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00175 ci++, compptr++) { 00176 numrows = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / 00177 cinfo->min_DCT_v_scaled_size; 00178 expand_bottom_edge(output_buf[ci], 00179 compptr->width_in_blocks * compptr->DCT_h_scaled_size, 00180 (int) (*out_row_group_ctr * numrows), 00181 (int) (out_row_groups_avail * numrows)); 00182 } 00183 *out_row_group_ctr = out_row_groups_avail; 00184 break; /* can exit outer loop without test */ 00185 } 00186 } 00187 } 00188 00189 00190 #ifdef CONTEXT_ROWS_SUPPORTED 00191 00192 /* 00193 * Process some data in the context case. 00194 */ 00195 00196 METHODDEF(void) 00197 pre_process_context (j_compress_ptr cinfo, 00198 JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 00199 JDIMENSION in_rows_avail, 00200 JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 00201 JDIMENSION out_row_groups_avail) 00202 { 00203 my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 00204 int numrows, ci; 00205 int buf_height = cinfo->max_v_samp_factor * 3; 00206 JDIMENSION inrows; 00207 00208 while (*out_row_group_ctr < out_row_groups_avail) { 00209 if (*in_row_ctr < in_rows_avail) { 00210 /* Do color conversion to fill the conversion buffer. */ 00211 inrows = in_rows_avail - *in_row_ctr; 00212 numrows = prep->next_buf_stop - prep->next_buf_row; 00213 numrows = (int) MIN((JDIMENSION) numrows, inrows); 00214 (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 00215 prep->color_buf, 00216 (JDIMENSION) prep->next_buf_row, 00217 numrows); 00218 /* Pad at top of image, if first time through */ 00219 if (prep->rows_to_go == cinfo->image_height) { 00220 for (ci = 0; ci < cinfo->num_components; ci++) { 00221 int row; 00222 for (row = 1; row <= cinfo->max_v_samp_factor; row++) { 00223 jcopy_sample_rows(prep->color_buf[ci], 0, 00224 prep->color_buf[ci], -row, 00225 1, cinfo->image_width); 00226 } 00227 } 00228 } 00229 *in_row_ctr += numrows; 00230 prep->next_buf_row += numrows; 00231 prep->rows_to_go -= numrows; 00232 } else { 00233 /* Return for more data, unless we are at the bottom of the image. */ 00234 if (prep->rows_to_go != 0) 00235 break; 00236 /* When at bottom of image, pad to fill the conversion buffer. */ 00237 if (prep->next_buf_row < prep->next_buf_stop) { 00238 for (ci = 0; ci < cinfo->num_components; ci++) { 00239 expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 00240 prep->next_buf_row, prep->next_buf_stop); 00241 } 00242 prep->next_buf_row = prep->next_buf_stop; 00243 } 00244 } 00245 /* If we've gotten enough data, downsample a row group. */ 00246 if (prep->next_buf_row == prep->next_buf_stop) { 00247 (*cinfo->downsample->downsample) (cinfo, 00248 prep->color_buf, 00249 (JDIMENSION) prep->this_row_group, 00250 output_buf, *out_row_group_ctr); 00251 (*out_row_group_ctr)++; 00252 /* Advance pointers with wraparound as necessary. */ 00253 prep->this_row_group += cinfo->max_v_samp_factor; 00254 if (prep->this_row_group >= buf_height) 00255 prep->this_row_group = 0; 00256 if (prep->next_buf_row >= buf_height) 00257 prep->next_buf_row = 0; 00258 prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; 00259 } 00260 } 00261 } 00262 00263 00264 /* 00265 * Create the wrapped-around downsampling input buffer needed for context mode. 00266 */ 00267 00268 LOCAL(void) 00269 create_context_buffer (j_compress_ptr cinfo) 00270 { 00271 my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 00272 int rgroup_height = cinfo->max_v_samp_factor; 00273 int ci, i; 00274 jpeg_component_info * compptr; 00275 JSAMPARRAY true_buffer, fake_buffer; 00276 00277 /* Grab enough space for fake row pointers for all the components; 00278 * we need five row groups' worth of pointers for each component. 00279 */ 00280 fake_buffer = (JSAMPARRAY) 00281 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 00282 (cinfo->num_components * 5 * rgroup_height) * 00283 SIZEOF(JSAMPROW)); 00284 00285 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00286 ci++, compptr++) { 00287 /* Allocate the actual buffer space (3 row groups) for this component. 00288 * We make the buffer wide enough to allow the downsampler to edge-expand 00289 * horizontally within the buffer, if it so chooses. 00290 */ 00291 true_buffer = (*cinfo->mem->alloc_sarray) 00292 ((j_common_ptr) cinfo, JPOOL_IMAGE, 00293 (JDIMENSION) (((long) compptr->width_in_blocks * 00294 cinfo->min_DCT_h_scaled_size * 00295 cinfo->max_h_samp_factor) / compptr->h_samp_factor), 00296 (JDIMENSION) (3 * rgroup_height)); 00297 /* Copy true buffer row pointers into the middle of the fake row array */ 00298 MEMCOPY(fake_buffer + rgroup_height, true_buffer, 00299 3 * rgroup_height * SIZEOF(JSAMPROW)); 00300 /* Fill in the above and below wraparound pointers */ 00301 for (i = 0; i < rgroup_height; i++) { 00302 fake_buffer[i] = true_buffer[2 * rgroup_height + i]; 00303 fake_buffer[4 * rgroup_height + i] = true_buffer[i]; 00304 } 00305 prep->color_buf[ci] = fake_buffer + rgroup_height; 00306 fake_buffer += 5 * rgroup_height; /* point to space for next component */ 00307 } 00308 } 00309 00310 #endif /* CONTEXT_ROWS_SUPPORTED */ 00311 00312 00313 /* 00314 * Initialize preprocessing controller. 00315 */ 00316 00317 GLOBAL(void) 00318 jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) 00319 { 00320 my_prep_ptr prep; 00321 int ci; 00322 jpeg_component_info * compptr; 00323 00324 if (need_full_buffer) /* safety check */ 00325 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00326 00327 prep = (my_prep_ptr) 00328 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 00329 SIZEOF(my_prep_controller)); 00330 cinfo->prep = (struct jpeg_c_prep_controller *) prep; 00331 prep->pub.start_pass = start_pass_prep; 00332 00333 /* Allocate the color conversion buffer. 00334 * We make the buffer wide enough to allow the downsampler to edge-expand 00335 * horizontally within the buffer, if it so chooses. 00336 */ 00337 if (cinfo->downsample->need_context_rows) { 00338 /* Set up to provide context rows */ 00339 #ifdef CONTEXT_ROWS_SUPPORTED 00340 prep->pub.pre_process_data = pre_process_context; 00341 create_context_buffer(cinfo); 00342 #else 00343 ERREXIT(cinfo, JERR_NOT_COMPILED); 00344 #endif 00345 } else { 00346 /* No context, just make it tall enough for one row group */ 00347 prep->pub.pre_process_data = pre_process_data; 00348 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00349 ci++, compptr++) { 00350 prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) 00351 ((j_common_ptr) cinfo, JPOOL_IMAGE, 00352 (JDIMENSION) (((long) compptr->width_in_blocks * 00353 cinfo->min_DCT_h_scaled_size * 00354 cinfo->max_h_samp_factor) / compptr->h_samp_factor), 00355 (JDIMENSION) cinfo->max_v_samp_factor); 00356 } 00357 } 00358 }
Generated on Wed Jul 13 2022 18:56:09 by
