Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jccoefct.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #define JPEG_INTERNALS
00014 #include "jinclude.h"
00015 #include "jpeglib.h"
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #ifdef ENTROPY_OPT_SUPPORTED
00024 #define FULL_COEF_BUFFER_SUPPORTED
00025 #else
00026 #ifdef C_MULTISCAN_FILES_SUPPORTED
00027 #define FULL_COEF_BUFFER_SUPPORTED
00028 #endif
00029 #endif
00030 
00031 
00032 
00033 
00034 typedef struct {
00035   struct jpeg_c_coef_controller pub; 
00036 
00037   JDIMENSION iMCU_row_num;      
00038   JDIMENSION mcu_ctr;           
00039   int MCU_vert_offset;          
00040   int MCU_rows_per_iMCU_row;    
00041 
00042   
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051   JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
00052 
00053   
00054   jvirt_barray_ptr whole_image[MAX_COMPONENTS];
00055 } my_coef_controller;
00056 
00057 typedef my_coef_controller * my_coef_ptr;
00058 
00059 
00060 
00061 METHODDEF(boolean) compress_data
00062     JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
00063 #ifdef FULL_COEF_BUFFER_SUPPORTED
00064 METHODDEF(boolean) compress_first_pass
00065     JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
00066 METHODDEF(boolean) compress_output
00067     JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
00068 #endif
00069 
00070 
00071 LOCAL(void)
00072 start_iMCU_row (j_compress_ptr cinfo)
00073 
00074 {
00075   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00076 
00077   
00078 
00079 
00080 
00081   if (cinfo->comps_in_scan > 1) {
00082     coef->MCU_rows_per_iMCU_row = 1;
00083   } else {
00084     if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
00085       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
00086     else
00087       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
00088   }
00089 
00090   coef->mcu_ctr = 0;
00091   coef->MCU_vert_offset = 0;
00092 }
00093 
00094 
00095 
00096 
00097 
00098 
00099 METHODDEF(void)
00100 start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
00101 {
00102   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00103 
00104   coef->iMCU_row_num = 0;
00105   start_iMCU_row(cinfo);
00106 
00107   switch (pass_mode) {
00108   case JBUF_PASS_THRU:
00109     if (coef->whole_image[0] != NULL)
00110       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00111     coef->pub.compress_data = compress_data;
00112     break;
00113 #ifdef FULL_COEF_BUFFER_SUPPORTED
00114   case JBUF_SAVE_AND_PASS:
00115     if (coef->whole_image[0] == NULL)
00116       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00117     coef->pub.compress_data = compress_first_pass;
00118     break;
00119   case JBUF_CRANK_DEST:
00120     if (coef->whole_image[0] == NULL)
00121       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00122     coef->pub.compress_data = compress_output;
00123     break;
00124 #endif
00125   default:
00126     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00127     break;
00128   }
00129 }
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 METHODDEF(boolean)
00143 compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
00144 {
00145   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00146   JDIMENSION MCU_col_num;       
00147   JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
00148   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
00149   int blkn, bi, ci, yindex, yoffset, blockcnt;
00150   JDIMENSION ypos, xpos;
00151   jpeg_component_info *compptr;
00152 
00153   
00154   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
00155        yoffset++) {
00156     for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
00157          MCU_col_num++) {
00158       
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167       blkn = 0;
00168       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00169         compptr = cinfo->cur_comp_info[ci];
00170         blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
00171                                                 : compptr->last_col_width;
00172         xpos = MCU_col_num * compptr->MCU_sample_width;
00173         ypos = yoffset * DCTSIZE; 
00174         for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
00175           if (coef->iMCU_row_num < last_iMCU_row ||
00176               yoffset+yindex < compptr->last_row_height) {
00177             (*cinfo->fdct->forward_DCT) (cinfo, compptr,
00178                                          input_buf[compptr->component_index],
00179                                          coef->MCU_buffer[blkn],
00180                                          ypos, xpos, (JDIMENSION) blockcnt);
00181             if (blockcnt < compptr->MCU_width) {
00182               
00183               jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
00184                         (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
00185               for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
00186                 coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
00187               }
00188             }
00189           } else {
00190             
00191             jzero_far((void FAR *) coef->MCU_buffer[blkn],
00192                       compptr->MCU_width * SIZEOF(JBLOCK));
00193             for (bi = 0; bi < compptr->MCU_width; bi++) {
00194               coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
00195             }
00196           }
00197           blkn += compptr->MCU_width;
00198           ypos += DCTSIZE;
00199         }
00200       }
00201       
00202 
00203 
00204       if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
00205         
00206         coef->MCU_vert_offset = yoffset;
00207         coef->mcu_ctr = MCU_col_num;
00208         return FALSE;
00209       }
00210     }
00211     
00212     coef->mcu_ctr = 0;
00213   }
00214   
00215   coef->iMCU_row_num++;
00216   start_iMCU_row(cinfo);
00217   return TRUE;
00218 }
00219 
00220 
00221 #ifdef FULL_COEF_BUFFER_SUPPORTED
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 METHODDEF(boolean)
00245 compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
00246 {
00247   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00248   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
00249   JDIMENSION blocks_across, MCUs_across, MCUindex;
00250   int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
00251   JCOEF lastDC;
00252   jpeg_component_info *compptr;
00253   JBLOCKARRAY buffer;
00254   JBLOCKROW thisblockrow, lastblockrow;
00255 
00256   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00257        ci++, compptr++) {
00258     
00259     buffer = (*cinfo->mem->access_virt_barray)
00260       ((j_common_ptr) cinfo, coef->whole_image[ci],
00261        coef->iMCU_row_num * compptr->v_samp_factor,
00262        (JDIMENSION) compptr->v_samp_factor, TRUE);
00263     
00264     if (coef->iMCU_row_num < last_iMCU_row)
00265       block_rows = compptr->v_samp_factor;
00266     else {
00267       
00268       block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
00269       if (block_rows == 0) block_rows = compptr->v_samp_factor;
00270     }
00271     blocks_across = compptr->width_in_blocks;
00272     h_samp_factor = compptr->h_samp_factor;
00273     
00274     ndummy = (int) (blocks_across % h_samp_factor);
00275     if (ndummy > 0)
00276       ndummy = h_samp_factor - ndummy;
00277     
00278 
00279 
00280     for (block_row = 0; block_row < block_rows; block_row++) {
00281       thisblockrow = buffer[block_row];
00282       (*cinfo->fdct->forward_DCT) (cinfo, compptr,
00283                                    input_buf[ci], thisblockrow,
00284                                    (JDIMENSION) (block_row * DCTSIZE),
00285                                    (JDIMENSION) 0, blocks_across);
00286       if (ndummy > 0) {
00287         
00288         thisblockrow += blocks_across; 
00289         jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
00290         lastDC = thisblockrow[-1][0];
00291         for (bi = 0; bi < ndummy; bi++) {
00292           thisblockrow[bi][0] = lastDC;
00293         }
00294       }
00295     }
00296     
00297 
00298 
00299 
00300 
00301     if (coef->iMCU_row_num == last_iMCU_row) {
00302       blocks_across += ndummy;  
00303       MCUs_across = blocks_across / h_samp_factor;
00304       for (block_row = block_rows; block_row < compptr->v_samp_factor;
00305            block_row++) {
00306         thisblockrow = buffer[block_row];
00307         lastblockrow = buffer[block_row-1];
00308         jzero_far((void FAR *) thisblockrow,
00309                   (size_t) (blocks_across * SIZEOF(JBLOCK)));
00310         for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
00311           lastDC = lastblockrow[h_samp_factor-1][0];
00312           for (bi = 0; bi < h_samp_factor; bi++) {
00313             thisblockrow[bi][0] = lastDC;
00314           }
00315           thisblockrow += h_samp_factor; 
00316           lastblockrow += h_samp_factor;
00317         }
00318       }
00319     }
00320   }
00321   
00322 
00323 
00324 
00325   
00326   return compress_output(cinfo, input_buf);
00327 }
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 METHODDEF(boolean)
00341 compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
00342 {
00343   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00344   JDIMENSION MCU_col_num;       
00345   int blkn, ci, xindex, yindex, yoffset;
00346   JDIMENSION start_col;
00347   JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
00348   JBLOCKROW buffer_ptr;
00349   jpeg_component_info *compptr;
00350 
00351   
00352 
00353 
00354 
00355   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00356     compptr = cinfo->cur_comp_info[ci];
00357     buffer[ci] = (*cinfo->mem->access_virt_barray)
00358       ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
00359        coef->iMCU_row_num * compptr->v_samp_factor,
00360        (JDIMENSION) compptr->v_samp_factor, FALSE);
00361   }
00362 
00363   
00364   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
00365        yoffset++) {
00366     for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
00367          MCU_col_num++) {
00368       
00369       blkn = 0;                 
00370       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00371         compptr = cinfo->cur_comp_info[ci];
00372         start_col = MCU_col_num * compptr->MCU_width;
00373         for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
00374           buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
00375           for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
00376             coef->MCU_buffer[blkn++] = buffer_ptr++;
00377           }
00378         }
00379       }
00380       
00381       if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
00382         
00383         coef->MCU_vert_offset = yoffset;
00384         coef->mcu_ctr = MCU_col_num;
00385         return FALSE;
00386       }
00387     }
00388     
00389     coef->mcu_ctr = 0;
00390   }
00391   
00392   coef->iMCU_row_num++;
00393   start_iMCU_row(cinfo);
00394   return TRUE;
00395 }
00396 
00397 #endif 
00398 
00399 
00400 
00401 
00402 
00403 
00404 GLOBAL(void)
00405 jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
00406 {
00407   my_coef_ptr coef;
00408 
00409   coef = (my_coef_ptr)
00410     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00411                                 SIZEOF(my_coef_controller));
00412   cinfo->coef = (struct jpeg_c_coef_controller *) coef;
00413   coef->pub.start_pass = start_pass_coef;
00414 
00415   
00416   if (need_full_buffer) {
00417 #ifdef FULL_COEF_BUFFER_SUPPORTED
00418     
00419     
00420     int ci;
00421     jpeg_component_info *compptr;
00422 
00423     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00424          ci++, compptr++) {
00425       coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
00426         ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
00427          (JDIMENSION) jround_up((long) compptr->width_in_blocks,
00428                                 (long) compptr->h_samp_factor),
00429          (JDIMENSION) jround_up((long) compptr->height_in_blocks,
00430                                 (long) compptr->v_samp_factor),
00431          (JDIMENSION) compptr->v_samp_factor);
00432     }
00433 #else
00434     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00435 #endif
00436   } else {
00437     
00438     JBLOCKROW buffer;
00439     int i;
00440 
00441     buffer = (JBLOCKROW)
00442       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00443                                   C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
00444     for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
00445       coef->MCU_buffer[i] = buffer + i;
00446     }
00447     coef->whole_image[0] = NULL; 
00448   }
00449 }