Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jdsample.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #define JPEG_INTERNALS
00022 #include "jinclude.h"
00023 #include "jpeglib.h"
00024 
00025 
00026 
00027 typedef JMETHOD(void, upsample1_ptr,
00028                 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00029                  JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
00030 
00031 
00032 
00033 typedef struct {
00034   struct jpeg_upsampler pub;    
00035 
00036   
00037 
00038 
00039 
00040 
00041 
00042 
00043   JSAMPARRAY color_buf[MAX_COMPONENTS];
00044 
00045   
00046   upsample1_ptr methods[MAX_COMPONENTS];
00047 
00048   int next_row_out;             
00049   JDIMENSION rows_to_go;        
00050 
00051   
00052   int rowgroup_height[MAX_COMPONENTS];
00053 
00054   
00055 
00056 
00057   UINT8 h_expand[MAX_COMPONENTS];
00058   UINT8 v_expand[MAX_COMPONENTS];
00059 } my_upsampler;
00060 
00061 typedef my_upsampler * my_upsample_ptr;
00062 
00063 
00064 
00065 
00066 
00067 
00068 METHODDEF(void)
00069 start_pass_upsample (j_decompress_ptr cinfo)
00070 {
00071   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00072 
00073   
00074   upsample->next_row_out = cinfo->max_v_samp_factor;
00075   
00076   upsample->rows_to_go = cinfo->output_height;
00077 }
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 METHODDEF(void)
00089 sep_upsample (j_decompress_ptr cinfo,
00090               JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00091               JDIMENSION in_row_groups_avail,
00092               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00093               JDIMENSION out_rows_avail)
00094 {
00095   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00096   int ci;
00097   jpeg_component_info * compptr;
00098   JDIMENSION num_rows;
00099 
00100   
00101   if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
00102     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00103          ci++, compptr++) {
00104       
00105 
00106 
00107       (*upsample->methods[ci]) (cinfo, compptr,
00108         input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
00109         upsample->color_buf + ci);
00110     }
00111     upsample->next_row_out = 0;
00112   }
00113 
00114   
00115 
00116   
00117   num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
00118   
00119 
00120 
00121   if (num_rows > upsample->rows_to_go) 
00122     num_rows = upsample->rows_to_go;
00123   
00124   out_rows_avail -= *out_row_ctr;
00125   if (num_rows > out_rows_avail)
00126     num_rows = out_rows_avail;
00127 
00128   (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
00129                                      (JDIMENSION) upsample->next_row_out,
00130                                      output_buf + *out_row_ctr,
00131                                      (int) num_rows);
00132 
00133   
00134   *out_row_ctr += num_rows;
00135   upsample->rows_to_go -= num_rows;
00136   upsample->next_row_out += num_rows;
00137   
00138   if (upsample->next_row_out >= cinfo->max_v_samp_factor)
00139     (*in_row_group_ctr)++;
00140 }
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 METHODDEF(void)
00157 fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00158                    JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00159 {
00160   *output_data_ptr = input_data;
00161 }
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 METHODDEF(void)
00170 noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00171                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00172 {
00173   *output_data_ptr = NULL;      
00174 }
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 METHODDEF(void)
00189 int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00190               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00191 {
00192   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00193   JSAMPARRAY output_data = *output_data_ptr;
00194   register JSAMPROW inptr, outptr;
00195   register JSAMPLE invalue;
00196   register int h;
00197   JSAMPROW outend;
00198   int h_expand, v_expand;
00199   int inrow, outrow;
00200 
00201   h_expand = upsample->h_expand[compptr->component_index];
00202   v_expand = upsample->v_expand[compptr->component_index];
00203 
00204   inrow = outrow = 0;
00205   while (outrow < cinfo->max_v_samp_factor) {
00206     
00207     inptr = input_data[inrow];
00208     outptr = output_data[outrow];
00209     outend = outptr + cinfo->output_width;
00210     while (outptr < outend) {
00211       invalue = *inptr++;       
00212       for (h = h_expand; h > 0; h--) {
00213         *outptr++ = invalue;
00214       }
00215     }
00216     
00217     if (v_expand > 1) {
00218       jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00219                         v_expand-1, cinfo->output_width);
00220     }
00221     inrow++;
00222     outrow += v_expand;
00223   }
00224 }
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 METHODDEF(void)
00233 h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00234                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00235 {
00236   JSAMPARRAY output_data = *output_data_ptr;
00237   register JSAMPROW inptr, outptr;
00238   register JSAMPLE invalue;
00239   JSAMPROW outend;
00240   int inrow;
00241 
00242   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
00243     inptr = input_data[inrow];
00244     outptr = output_data[inrow];
00245     outend = outptr + cinfo->output_width;
00246     while (outptr < outend) {
00247       invalue = *inptr++;       
00248       *outptr++ = invalue;
00249       *outptr++ = invalue;
00250     }
00251   }
00252 }
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 METHODDEF(void)
00261 h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00262                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00263 {
00264   JSAMPARRAY output_data = *output_data_ptr;
00265   register JSAMPROW inptr, outptr;
00266   register JSAMPLE invalue;
00267   JSAMPROW outend;
00268   int inrow, outrow;
00269 
00270   inrow = outrow = 0;
00271   while (outrow < cinfo->max_v_samp_factor) {
00272     inptr = input_data[inrow];
00273     outptr = output_data[outrow];
00274     outend = outptr + cinfo->output_width;
00275     while (outptr < outend) {
00276       invalue = *inptr++;       
00277       *outptr++ = invalue;
00278       *outptr++ = invalue;
00279     }
00280     jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00281                       1, cinfo->output_width);
00282     inrow++;
00283     outrow += 2;
00284   }
00285 }
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 METHODDEF(void)
00304 h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00305                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00306 {
00307   JSAMPARRAY output_data = *output_data_ptr;
00308   register JSAMPROW inptr, outptr;
00309   register int invalue;
00310   register JDIMENSION colctr;
00311   int inrow;
00312 
00313   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
00314     inptr = input_data[inrow];
00315     outptr = output_data[inrow];
00316     
00317     invalue = GETJSAMPLE(*inptr++);
00318     *outptr++ = (JSAMPLE) invalue;
00319     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
00320 
00321     for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
00322       
00323       invalue = GETJSAMPLE(*inptr++) * 3;
00324       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
00325       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
00326     }
00327 
00328     
00329     invalue = GETJSAMPLE(*inptr);
00330     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
00331     *outptr++ = (JSAMPLE) invalue;
00332   }
00333 }
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 METHODDEF(void)
00345 h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00346                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00347 {
00348   JSAMPARRAY output_data = *output_data_ptr;
00349   register JSAMPROW inptr0, inptr1, outptr;
00350 #if BITS_IN_JSAMPLE == 8
00351   register int thiscolsum, lastcolsum, nextcolsum;
00352 #else
00353   register INT32 thiscolsum, lastcolsum, nextcolsum;
00354 #endif
00355   register JDIMENSION colctr;
00356   int inrow, outrow, v;
00357 
00358   inrow = outrow = 0;
00359   while (outrow < cinfo->max_v_samp_factor) {
00360     for (v = 0; v < 2; v++) {
00361       
00362       inptr0 = input_data[inrow];
00363       if (v == 0)               
00364         inptr1 = input_data[inrow-1];
00365       else                      
00366         inptr1 = input_data[inrow+1];
00367       outptr = output_data[outrow++];
00368 
00369       
00370       thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00371       nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00372       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
00373       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
00374       lastcolsum = thiscolsum; thiscolsum = nextcolsum;
00375 
00376       for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
00377         
00378         
00379         nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
00380         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
00381         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
00382         lastcolsum = thiscolsum; thiscolsum = nextcolsum;
00383       }
00384 
00385       
00386       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
00387       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
00388     }
00389     inrow++;
00390   }
00391 }
00392 
00393 
00394 
00395 
00396 
00397 
00398 GLOBAL(void)
00399 jinit_upsampler (j_decompress_ptr cinfo)
00400 {
00401   my_upsample_ptr upsample;
00402   int ci;
00403   jpeg_component_info * compptr;
00404   boolean need_buffer, do_fancy;
00405   int h_in_group, v_in_group, h_out_group, v_out_group;
00406 
00407   upsample = (my_upsample_ptr)
00408     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00409                                 SIZEOF(my_upsampler));
00410   cinfo->upsample = (struct jpeg_upsampler *) upsample;
00411   upsample->pub.start_pass = start_pass_upsample;
00412   upsample->pub.upsample = sep_upsample;
00413   upsample->pub.need_context_rows = FALSE; 
00414 
00415   if (cinfo->CCIR601_sampling)  
00416     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
00417 
00418   
00419 
00420 
00421   do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
00422 
00423   
00424 
00425 
00426   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00427        ci++, compptr++) {
00428     
00429 
00430 
00431     h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
00432                  cinfo->min_DCT_scaled_size;
00433     v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
00434                  cinfo->min_DCT_scaled_size;
00435     h_out_group = cinfo->max_h_samp_factor;
00436     v_out_group = cinfo->max_v_samp_factor;
00437     upsample->rowgroup_height[ci] = v_in_group; 
00438     need_buffer = TRUE;
00439     if (! compptr->component_needed) {
00440       
00441       upsample->methods[ci] = noop_upsample;
00442       need_buffer = FALSE;
00443     } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
00444       
00445       upsample->methods[ci] = fullsize_upsample;
00446       need_buffer = FALSE;
00447     } else if (h_in_group * 2 == h_out_group &&
00448                v_in_group == v_out_group) {
00449       
00450       if (do_fancy && compptr->downsampled_width > 2)
00451         upsample->methods[ci] = h2v1_fancy_upsample;
00452       else
00453         upsample->methods[ci] = h2v1_upsample;
00454     } else if (h_in_group * 2 == h_out_group &&
00455                v_in_group * 2 == v_out_group) {
00456       
00457       if (do_fancy && compptr->downsampled_width > 2) {
00458         upsample->methods[ci] = h2v2_fancy_upsample;
00459         upsample->pub.need_context_rows = TRUE;
00460       } else
00461         upsample->methods[ci] = h2v2_upsample;
00462     } else if ((h_out_group % h_in_group) == 0 &&
00463                (v_out_group % v_in_group) == 0) {
00464       
00465       upsample->methods[ci] = int_upsample;
00466       upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
00467       upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
00468     } else
00469       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
00470     if (need_buffer) {
00471       upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
00472         ((j_common_ptr) cinfo, JPOOL_IMAGE,
00473          (JDIMENSION) jround_up((long) cinfo->output_width,
00474                                 (long) cinfo->max_h_samp_factor),
00475          (JDIMENSION) cinfo->max_v_samp_factor);
00476     }
00477   }
00478 }