Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jdmainct.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #define JPEG_INTERNALS
00017 #include "jinclude.h"
00018 #include "jpeglib.h"
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 typedef struct {
00115   struct jpeg_d_main_controller pub; 
00116 
00117   
00118   JSAMPARRAY buffer[MAX_COMPONENTS];
00119 
00120   boolean buffer_full;          
00121   JDIMENSION rowgroup_ctr;      
00122 
00123   
00124 
00125   
00126   JSAMPIMAGE xbuffer[2];        
00127 
00128   int whichptr;                 
00129   int context_state;            
00130   JDIMENSION rowgroups_avail;   
00131   JDIMENSION iMCU_row_ctr;      
00132 } my_main_controller;
00133 
00134 typedef my_main_controller * my_main_ptr;
00135 
00136 
00137 #define CTX_PREPARE_FOR_IMCU    0       
00138 #define CTX_PROCESS_IMCU        1       
00139 #define CTX_POSTPONED_ROW       2       
00140 
00141 
00142 
00143 METHODDEF(void) process_data_simple_main
00144         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
00145              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
00146 METHODDEF(void) process_data_context_main
00147         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
00148              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
00149 #ifdef QUANT_2PASS_SUPPORTED
00150 METHODDEF(void) process_data_crank_post
00151         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
00152              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
00153 #endif
00154 
00155 
00156 LOCAL(void)
00157 alloc_funny_pointers (j_decompress_ptr cinfo)
00158 
00159 
00160 
00161 {
00162   my_main_ptr main = (my_main_ptr) cinfo->main;
00163   int ci, rgroup;
00164   int M = cinfo->min_DCT_scaled_size;
00165   jpeg_component_info *compptr;
00166   JSAMPARRAY xbuf;
00167 
00168   
00169 
00170 
00171   main->xbuffer[0] = (JSAMPIMAGE)
00172     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00173                                 cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
00174   main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components;
00175 
00176   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00177        ci++, compptr++) {
00178     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00179       cinfo->min_DCT_scaled_size; 
00180     
00181 
00182 
00183     xbuf = (JSAMPARRAY)
00184       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00185                                   2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
00186     xbuf += rgroup;             
00187     main->xbuffer[0][ci] = xbuf;
00188     xbuf += rgroup * (M + 4);
00189     main->xbuffer[1][ci] = xbuf;
00190   }
00191 }
00192 
00193 
00194 LOCAL(void)
00195 make_funny_pointers (j_decompress_ptr cinfo)
00196 
00197 
00198 
00199 
00200 
00201 
00202 {
00203   my_main_ptr main = (my_main_ptr) cinfo->main;
00204   int ci, i, rgroup;
00205   int M = cinfo->min_DCT_scaled_size;
00206   jpeg_component_info *compptr;
00207   JSAMPARRAY buf, xbuf0, xbuf1;
00208 
00209   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00210        ci++, compptr++) {
00211     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00212       cinfo->min_DCT_scaled_size; 
00213     xbuf0 = main->xbuffer[0][ci];
00214     xbuf1 = main->xbuffer[1][ci];
00215     
00216     buf = main->buffer[ci];
00217     for (i = 0; i < rgroup * (M + 2); i++) {
00218       xbuf0[i] = xbuf1[i] = buf[i];
00219     }
00220     
00221     for (i = 0; i < rgroup * 2; i++) {
00222       xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
00223       xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
00224     }
00225     
00226 
00227 
00228 
00229 
00230     for (i = 0; i < rgroup; i++) {
00231       xbuf0[i - rgroup] = xbuf0[0];
00232     }
00233   }
00234 }
00235 
00236 
00237 LOCAL(void)
00238 set_wraparound_pointers (j_decompress_ptr cinfo)
00239 
00240 
00241 
00242 {
00243   my_main_ptr main = (my_main_ptr) cinfo->main;
00244   int ci, i, rgroup;
00245   int M = cinfo->min_DCT_scaled_size;
00246   jpeg_component_info *compptr;
00247   JSAMPARRAY xbuf0, xbuf1;
00248 
00249   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00250        ci++, compptr++) {
00251     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00252       cinfo->min_DCT_scaled_size; 
00253     xbuf0 = main->xbuffer[0][ci];
00254     xbuf1 = main->xbuffer[1][ci];
00255     for (i = 0; i < rgroup; i++) {
00256       xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
00257       xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
00258       xbuf0[rgroup*(M+2) + i] = xbuf0[i];
00259       xbuf1[rgroup*(M+2) + i] = xbuf1[i];
00260     }
00261   }
00262 }
00263 
00264 
00265 LOCAL(void)
00266 set_bottom_pointers (j_decompress_ptr cinfo)
00267 
00268 
00269 
00270 
00271 {
00272   my_main_ptr main = (my_main_ptr) cinfo->main;
00273   int ci, i, rgroup, iMCUheight, rows_left;
00274   jpeg_component_info *compptr;
00275   JSAMPARRAY xbuf;
00276 
00277   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00278        ci++, compptr++) {
00279     
00280     iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
00281     rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
00282     
00283     rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
00284     if (rows_left == 0) rows_left = iMCUheight;
00285     
00286 
00287 
00288     if (ci == 0) {
00289       main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
00290     }
00291     
00292 
00293 
00294     xbuf = main->xbuffer[main->whichptr][ci];
00295     for (i = 0; i < rgroup * 2; i++) {
00296       xbuf[rows_left + i] = xbuf[rows_left-1];
00297     }
00298   }
00299 }
00300 
00301 
00302 
00303 
00304 
00305 
00306 METHODDEF(void)
00307 start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
00308 {
00309   my_main_ptr main = (my_main_ptr) cinfo->main;
00310 
00311   switch (pass_mode) {
00312   case JBUF_PASS_THRU:
00313     if (cinfo->upsample->need_context_rows) {
00314       main->pub.process_data = process_data_context_main;
00315       make_funny_pointers(cinfo); 
00316       main->whichptr = 0;       
00317       main->context_state = CTX_PREPARE_FOR_IMCU;
00318       main->iMCU_row_ctr = 0;
00319     } else {
00320       
00321       main->pub.process_data = process_data_simple_main;
00322     }
00323     main->buffer_full = FALSE;  
00324     main->rowgroup_ctr = 0;
00325     break;
00326 #ifdef QUANT_2PASS_SUPPORTED
00327   case JBUF_CRANK_DEST:
00328     
00329     main->pub.process_data = process_data_crank_post;
00330     break;
00331 #endif
00332   default:
00333     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00334     break;
00335   }
00336 }
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 METHODDEF(void)
00345 process_data_simple_main (j_decompress_ptr cinfo,
00346                           JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00347                           JDIMENSION out_rows_avail)
00348 {
00349   my_main_ptr main = (my_main_ptr) cinfo->main;
00350   JDIMENSION rowgroups_avail;
00351 
00352   
00353   if (! main->buffer_full) {
00354     if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer))
00355       return;                   
00356     main->buffer_full = TRUE;   
00357   }
00358 
00359   
00360   rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
00361   
00362 
00363 
00364 
00365 
00366   
00367   (*cinfo->post->post_process_data) (cinfo, main->buffer,
00368                                      &main->rowgroup_ctr, rowgroups_avail,
00369                                      output_buf, out_row_ctr, out_rows_avail);
00370 
00371   
00372   if (main->rowgroup_ctr >= rowgroups_avail) {
00373     main->buffer_full = FALSE;
00374     main->rowgroup_ctr = 0;
00375   }
00376 }
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 METHODDEF(void)
00385 process_data_context_main (j_decompress_ptr cinfo,
00386                            JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00387                            JDIMENSION out_rows_avail)
00388 {
00389   my_main_ptr main = (my_main_ptr) cinfo->main;
00390 
00391   
00392   if (! main->buffer_full) {
00393     if (! (*cinfo->coef->decompress_data) (cinfo,
00394                                            main->xbuffer[main->whichptr]))
00395       return;                   
00396     main->buffer_full = TRUE;   
00397     main->iMCU_row_ctr++;       
00398   }
00399 
00400   
00401 
00402 
00403 
00404 
00405   switch (main->context_state) {
00406   case CTX_POSTPONED_ROW:
00407     
00408     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
00409                         &main->rowgroup_ctr, main->rowgroups_avail,
00410                         output_buf, out_row_ctr, out_rows_avail);
00411     if (main->rowgroup_ctr < main->rowgroups_avail)
00412       return;                   
00413     main->context_state = CTX_PREPARE_FOR_IMCU;
00414     if (*out_row_ctr >= out_rows_avail)
00415       return;                   
00416     
00417   case CTX_PREPARE_FOR_IMCU:
00418     
00419     main->rowgroup_ctr = 0;
00420     main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
00421     
00422 
00423 
00424     if (main->iMCU_row_ctr == cinfo->total_iMCU_rows)
00425       set_bottom_pointers(cinfo);
00426     main->context_state = CTX_PROCESS_IMCU;
00427     
00428   case CTX_PROCESS_IMCU:
00429     
00430     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
00431                         &main->rowgroup_ctr, main->rowgroups_avail,
00432                         output_buf, out_row_ctr, out_rows_avail);
00433     if (main->rowgroup_ctr < main->rowgroups_avail)
00434       return;                   
00435     
00436     if (main->iMCU_row_ctr == 1)
00437       set_wraparound_pointers(cinfo);
00438     
00439     main->whichptr ^= 1;        
00440     main->buffer_full = FALSE;
00441     
00442     
00443     main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
00444     main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
00445     main->context_state = CTX_POSTPONED_ROW;
00446   }
00447 }
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 #ifdef QUANT_2PASS_SUPPORTED
00457 
00458 METHODDEF(void)
00459 process_data_crank_post (j_decompress_ptr cinfo,
00460                          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00461                          JDIMENSION out_rows_avail)
00462 {
00463   (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
00464                                      (JDIMENSION *) NULL, (JDIMENSION) 0,
00465                                      output_buf, out_row_ctr, out_rows_avail);
00466 }
00467 
00468 #endif 
00469 
00470 
00471 
00472 
00473 
00474 
00475 GLOBAL(void)
00476 jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
00477 {
00478   my_main_ptr main;
00479   int ci, rgroup, ngroups;
00480   jpeg_component_info *compptr;
00481 
00482   main = (my_main_ptr)
00483     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00484                                 SIZEOF(my_main_controller));
00485   cinfo->main = (struct jpeg_d_main_controller *) main;
00486   main->pub.start_pass = start_pass_main;
00487 
00488   if (need_full_buffer)         
00489     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00490 
00491   
00492 
00493 
00494   if (cinfo->upsample->need_context_rows) {
00495     if (cinfo->min_DCT_scaled_size < 2) 
00496       ERREXIT(cinfo, JERR_NOTIMPL);
00497     alloc_funny_pointers(cinfo); 
00498     ngroups = cinfo->min_DCT_scaled_size + 2;
00499   } else {
00500     ngroups = cinfo->min_DCT_scaled_size;
00501   }
00502 
00503   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00504        ci++, compptr++) {
00505     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00506       cinfo->min_DCT_scaled_size; 
00507     main->buffer[ci] = (*cinfo->mem->alloc_sarray)
00508                         ((j_common_ptr) cinfo, JPOOL_IMAGE,
00509                          compptr->width_in_blocks * compptr->DCT_scaled_size,
00510                          (JDIMENSION) (rgroup * ngroups));
00511   }
00512 }