Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jdinput.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 #define JPEG_INTERNALS
00015 #include "jinclude.h"
00016 #include "jpeglib.h"
00017 
00018 
00019 
00020 
00021 typedef struct {
00022   struct jpeg_input_controller pub; 
00023 
00024   boolean inheaders;            
00025 } my_input_controller;
00026 
00027 typedef my_input_controller * my_inputctl_ptr;
00028 
00029 
00030 
00031 METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
00032 
00033 
00034 
00035 
00036 
00037 
00038 LOCAL(void)
00039 initial_setup (j_decompress_ptr cinfo)
00040 
00041 {
00042   int ci;
00043   jpeg_component_info *compptr;
00044 
00045   
00046   if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
00047       (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
00048     ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
00049 
00050   
00051   if (cinfo->data_precision != BITS_IN_JSAMPLE)
00052     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
00053 
00054   
00055   if (cinfo->num_components > MAX_COMPONENTS)
00056     ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
00057              MAX_COMPONENTS);
00058 
00059   
00060   cinfo->max_h_samp_factor = 1;
00061   cinfo->max_v_samp_factor = 1;
00062   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00063        ci++, compptr++) {
00064     if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
00065         compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
00066       ERREXIT(cinfo, JERR_BAD_SAMPLING);
00067     cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
00068                                    compptr->h_samp_factor);
00069     cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
00070                                    compptr->v_samp_factor);
00071   }
00072 
00073   
00074 
00075 
00076 
00077   cinfo->min_DCT_scaled_size = DCTSIZE;
00078 
00079   
00080   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00081        ci++, compptr++) {
00082     compptr->DCT_scaled_size = DCTSIZE;
00083     
00084     compptr->width_in_blocks = (JDIMENSION)
00085       jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
00086                     (long) (cinfo->max_h_samp_factor * DCTSIZE));
00087     compptr->height_in_blocks = (JDIMENSION)
00088       jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
00089                     (long) (cinfo->max_v_samp_factor * DCTSIZE));
00090     
00091 
00092 
00093 
00094     
00095     compptr->downsampled_width = (JDIMENSION)
00096       jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
00097                     (long) cinfo->max_h_samp_factor);
00098     compptr->downsampled_height = (JDIMENSION)
00099       jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
00100                     (long) cinfo->max_v_samp_factor);
00101     
00102     compptr->component_needed = TRUE;
00103     
00104     compptr->quant_table = NULL;
00105   }
00106 
00107   
00108   cinfo->total_iMCU_rows = (JDIMENSION)
00109     jdiv_round_up((long) cinfo->image_height,
00110                   (long) (cinfo->max_v_samp_factor*DCTSIZE));
00111 
00112   
00113   if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
00114     cinfo->inputctl->has_multiple_scans = TRUE;
00115   else
00116     cinfo->inputctl->has_multiple_scans = FALSE;
00117 }
00118 
00119 
00120 LOCAL(void)
00121 per_scan_setup (j_decompress_ptr cinfo)
00122 
00123 
00124 {
00125   int ci, mcublks, tmp;
00126   jpeg_component_info *compptr;
00127   
00128   if (cinfo->comps_in_scan == 1) {
00129     
00130     
00131     compptr = cinfo->cur_comp_info[0];
00132     
00133     
00134     cinfo->MCUs_per_row = compptr->width_in_blocks;
00135     cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
00136     
00137     
00138     compptr->MCU_width = 1;
00139     compptr->MCU_height = 1;
00140     compptr->MCU_blocks = 1;
00141     compptr->MCU_sample_width = compptr->DCT_scaled_size;
00142     compptr->last_col_width = 1;
00143     
00144 
00145 
00146     tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
00147     if (tmp == 0) tmp = compptr->v_samp_factor;
00148     compptr->last_row_height = tmp;
00149     
00150     
00151     cinfo->blocks_in_MCU = 1;
00152     cinfo->MCU_membership[0] = 0;
00153     
00154   } else {
00155     
00156     
00157     if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
00158       ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
00159                MAX_COMPS_IN_SCAN);
00160     
00161     
00162     cinfo->MCUs_per_row = (JDIMENSION)
00163       jdiv_round_up((long) cinfo->image_width,
00164                     (long) (cinfo->max_h_samp_factor*DCTSIZE));
00165     cinfo->MCU_rows_in_scan = (JDIMENSION)
00166       jdiv_round_up((long) cinfo->image_height,
00167                     (long) (cinfo->max_v_samp_factor*DCTSIZE));
00168     
00169     cinfo->blocks_in_MCU = 0;
00170     
00171     for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00172       compptr = cinfo->cur_comp_info[ci];
00173       
00174       compptr->MCU_width = compptr->h_samp_factor;
00175       compptr->MCU_height = compptr->v_samp_factor;
00176       compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
00177       compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
00178       
00179       tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
00180       if (tmp == 0) tmp = compptr->MCU_width;
00181       compptr->last_col_width = tmp;
00182       tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
00183       if (tmp == 0) tmp = compptr->MCU_height;
00184       compptr->last_row_height = tmp;
00185       
00186       mcublks = compptr->MCU_blocks;
00187       if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
00188         ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
00189       while (mcublks-- > 0) {
00190         cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
00191       }
00192     }
00193     
00194   }
00195 }
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 LOCAL(void)
00220 latch_quant_tables (j_decompress_ptr cinfo)
00221 {
00222   int ci, qtblno;
00223   jpeg_component_info *compptr;
00224   JQUANT_TBL * qtbl;
00225 
00226   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00227     compptr = cinfo->cur_comp_info[ci];
00228     
00229     if (compptr->quant_table != NULL)
00230       continue;
00231     
00232     qtblno = compptr->quant_tbl_no;
00233     if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
00234         cinfo->quant_tbl_ptrs[qtblno] == NULL)
00235       ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
00236     
00237     qtbl = (JQUANT_TBL *)
00238       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00239                                   SIZEOF(JQUANT_TBL));
00240     MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
00241     compptr->quant_table = qtbl;
00242   }
00243 }
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 METHODDEF(void)
00254 start_input_pass (j_decompress_ptr cinfo)
00255 {
00256   per_scan_setup(cinfo);
00257   latch_quant_tables(cinfo);
00258   (*cinfo->entropy->start_pass) (cinfo);
00259   (*cinfo->coef->start_input_pass) (cinfo);
00260   cinfo->inputctl->consume_input = cinfo->coef->consume_data;
00261 }
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 METHODDEF(void)
00271 finish_input_pass (j_decompress_ptr cinfo)
00272 {
00273   cinfo->inputctl->consume_input = consume_markers;
00274 }
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 METHODDEF(int)
00288 consume_markers (j_decompress_ptr cinfo)
00289 {
00290   my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
00291   int val;
00292 
00293   if (inputctl->pub.eoi_reached) 
00294     return JPEG_REACHED_EOI;
00295 
00296   val = (*cinfo->marker->read_markers) (cinfo);
00297 
00298   switch (val) {
00299   case JPEG_REACHED_SOS:        
00300     if (inputctl->inheaders) {  
00301       initial_setup(cinfo);
00302       inputctl->inheaders = FALSE;
00303       
00304 
00305 
00306 
00307     } else {                    
00308       if (! inputctl->pub.has_multiple_scans)
00309         ERREXIT(cinfo, JERR_EOI_EXPECTED); 
00310       start_input_pass(cinfo);
00311     }
00312     break;
00313   case JPEG_REACHED_EOI:        
00314     inputctl->pub.eoi_reached = TRUE;
00315     if (inputctl->inheaders) {  
00316       if (cinfo->marker->saw_SOF)
00317         ERREXIT(cinfo, JERR_SOF_NO_SOS);
00318     } else {
00319       
00320 
00321 
00322       if (cinfo->output_scan_number > cinfo->input_scan_number)
00323         cinfo->output_scan_number = cinfo->input_scan_number;
00324     }
00325     break;
00326   case JPEG_SUSPENDED:
00327     break;
00328   }
00329 
00330   return val;
00331 }
00332 
00333 
00334 
00335 
00336 
00337 
00338 METHODDEF(void)
00339 reset_input_controller (j_decompress_ptr cinfo)
00340 {
00341   my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
00342 
00343   inputctl->pub.consume_input = consume_markers;
00344   inputctl->pub.has_multiple_scans = FALSE; 
00345   inputctl->pub.eoi_reached = FALSE;
00346   inputctl->inheaders = TRUE;
00347   
00348   (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
00349   (*cinfo->marker->reset_marker_reader) (cinfo);
00350   
00351   cinfo->coef_bits = NULL;
00352 }
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 GLOBAL(void)
00361 jinit_input_controller (j_decompress_ptr cinfo)
00362 {
00363   my_inputctl_ptr inputctl;
00364 
00365   
00366   inputctl = (my_inputctl_ptr)
00367     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00368                                 SIZEOF(my_input_controller));
00369   cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
00370   
00371   inputctl->pub.consume_input = consume_markers;
00372   inputctl->pub.reset_input_controller = reset_input_controller;
00373   inputctl->pub.start_input_pass = start_input_pass;
00374   inputctl->pub.finish_input_pass = finish_input_pass;
00375   
00376 
00377 
00378   inputctl->pub.has_multiple_scans = FALSE; 
00379   inputctl->pub.eoi_reached = FALSE;
00380   inputctl->inheaders = TRUE;
00381 }