src/3rdparty/libjpeg/jcsample.c
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /*
       
     2  * jcsample.c
       
     3  *
       
     4  * Copyright (C) 1991-1996, Thomas G. Lane.
       
     5  * This file is part of the Independent JPEG Group's software.
       
     6  * For conditions of distribution and use, see the accompanying README file.
       
     7  *
       
     8  * This file contains downsampling routines.
       
     9  *
       
    10  * Downsampling input data is counted in "row groups".  A row group
       
    11  * is defined to be max_v_samp_factor pixel rows of each component,
       
    12  * from which the downsampler produces v_samp_factor sample rows.
       
    13  * A single row group is processed in each call to the downsampler module.
       
    14  *
       
    15  * The downsampler is responsible for edge-expansion of its output data
       
    16  * to fill an integral number of DCT blocks horizontally.  The source buffer
       
    17  * may be modified if it is helpful for this purpose (the source buffer is
       
    18  * allocated wide enough to correspond to the desired output width).
       
    19  * The caller (the prep controller) is responsible for vertical padding.
       
    20  *
       
    21  * The downsampler may request "context rows" by setting need_context_rows
       
    22  * during startup.  In this case, the input arrays will contain at least
       
    23  * one row group's worth of pixels above and below the passed-in data;
       
    24  * the caller will create dummy rows at image top and bottom by replicating
       
    25  * the first or last real pixel row.
       
    26  *
       
    27  * An excellent reference for image resampling is
       
    28  *   Digital Image Warping, George Wolberg, 1990.
       
    29  *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
       
    30  *
       
    31  * The downsampling algorithm used here is a simple average of the source
       
    32  * pixels covered by the output pixel.  The hi-falutin sampling literature
       
    33  * refers to this as a "box filter".  In general the characteristics of a box
       
    34  * filter are not very good, but for the specific cases we normally use (1:1
       
    35  * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
       
    36  * nearly so bad.  If you intend to use other sampling ratios, you'd be well
       
    37  * advised to improve this code.
       
    38  *
       
    39  * A simple input-smoothing capability is provided.  This is mainly intended
       
    40  * for cleaning up color-dithered GIF input files (if you find it inadequate,
       
    41  * we suggest using an external filtering program such as pnmconvol).  When
       
    42  * enabled, each input pixel P is replaced by a weighted sum of itself and its
       
    43  * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
       
    44  * where SF = (smoothing_factor / 1024).
       
    45  * Currently, smoothing is only supported for 2h2v sampling factors.
       
    46  */
       
    47 
       
    48 #define JPEG_INTERNALS
       
    49 #include "jinclude.h"
       
    50 #include "jpeglib.h"
       
    51 
       
    52 
       
    53 /* Pointer to routine to downsample a single component */
       
    54 typedef JMETHOD(void, downsample1_ptr,
       
    55 		(j_compress_ptr cinfo, jpeg_component_info * compptr,
       
    56 		 JSAMPARRAY input_data, JSAMPARRAY output_data));
       
    57 
       
    58 /* Private subobject */
       
    59 
       
    60 typedef struct {
       
    61   struct jpeg_downsampler pub;	/* public fields */
       
    62 
       
    63   /* Downsampling method pointers, one per component */
       
    64   downsample1_ptr methods[MAX_COMPONENTS];
       
    65 } my_downsampler;
       
    66 
       
    67 typedef my_downsampler * my_downsample_ptr;
       
    68 
       
    69 
       
    70 /*
       
    71  * Initialize for a downsampling pass.
       
    72  */
       
    73 
       
    74 METHODDEF(void)
       
    75 start_pass_downsample (j_compress_ptr cinfo)
       
    76 {
       
    77   /* no work for now */
       
    78 }
       
    79 
       
    80 
       
    81 /*
       
    82  * Expand a component horizontally from width input_cols to width output_cols,
       
    83  * by duplicating the rightmost samples.
       
    84  */
       
    85 
       
    86 LOCAL(void)
       
    87 expand_right_edge (JSAMPARRAY image_data, int num_rows,
       
    88 		   JDIMENSION input_cols, JDIMENSION output_cols)
       
    89 {
       
    90   register JSAMPROW ptr;
       
    91   register JSAMPLE pixval;
       
    92   register int count;
       
    93   int row;
       
    94   int numcols = (int) (output_cols - input_cols);
       
    95 
       
    96   if (numcols > 0) {
       
    97     for (row = 0; row < num_rows; row++) {
       
    98       ptr = image_data[row] + input_cols;
       
    99       pixval = ptr[-1];		/* don't need GETJSAMPLE() here */
       
   100       for (count = numcols; count > 0; count--)
       
   101 	*ptr++ = pixval;
       
   102     }
       
   103   }
       
   104 }
       
   105 
       
   106 
       
   107 /*
       
   108  * Do downsampling for a whole row group (all components).
       
   109  *
       
   110  * In this version we simply downsample each component independently.
       
   111  */
       
   112 
       
   113 METHODDEF(void)
       
   114 sep_downsample (j_compress_ptr cinfo,
       
   115 		JSAMPIMAGE input_buf, JDIMENSION in_row_index,
       
   116 		JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
       
   117 {
       
   118   my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
       
   119   int ci;
       
   120   jpeg_component_info * compptr;
       
   121   JSAMPARRAY in_ptr, out_ptr;
       
   122 
       
   123   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       
   124        ci++, compptr++) {
       
   125     in_ptr = input_buf[ci] + in_row_index;
       
   126     out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
       
   127     (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
       
   128   }
       
   129 }
       
   130 
       
   131 
       
   132 /*
       
   133  * Downsample pixel values of a single component.
       
   134  * One row group is processed per call.
       
   135  * This version handles arbitrary integral sampling ratios, without smoothing.
       
   136  * Note that this version is not actually used for customary sampling ratios.
       
   137  */
       
   138 
       
   139 METHODDEF(void)
       
   140 int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
       
   141 		JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   142 {
       
   143   int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
       
   144   JDIMENSION outcol, outcol_h;	/* outcol_h == outcol*h_expand */
       
   145   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
       
   146   JSAMPROW inptr, outptr;
       
   147   INT32 outvalue;
       
   148 
       
   149   h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
       
   150   v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
       
   151   numpix = h_expand * v_expand;
       
   152   numpix2 = numpix/2;
       
   153 
       
   154   /* Expand input data enough to let all the output samples be generated
       
   155    * by the standard loop.  Special-casing padded output would be more
       
   156    * efficient.
       
   157    */
       
   158   expand_right_edge(input_data, cinfo->max_v_samp_factor,
       
   159 		    cinfo->image_width, output_cols * h_expand);
       
   160 
       
   161   inrow = 0;
       
   162   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
       
   163     outptr = output_data[outrow];
       
   164     for (outcol = 0, outcol_h = 0; outcol < output_cols;
       
   165 	 outcol++, outcol_h += h_expand) {
       
   166       outvalue = 0;
       
   167       for (v = 0; v < v_expand; v++) {
       
   168 	inptr = input_data[inrow+v] + outcol_h;
       
   169 	for (h = 0; h < h_expand; h++) {
       
   170 	  outvalue += (INT32) GETJSAMPLE(*inptr++);
       
   171 	}
       
   172       }
       
   173       *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
       
   174     }
       
   175     inrow += v_expand;
       
   176   }
       
   177 }
       
   178 
       
   179 
       
   180 /*
       
   181  * Downsample pixel values of a single component.
       
   182  * This version handles the special case of a full-size component,
       
   183  * without smoothing.
       
   184  */
       
   185 
       
   186 METHODDEF(void)
       
   187 fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
       
   188 		     JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   189 {
       
   190   /* Copy the data */
       
   191   jcopy_sample_rows(input_data, 0, output_data, 0,
       
   192 		    cinfo->max_v_samp_factor, cinfo->image_width);
       
   193   /* Edge-expand */
       
   194   expand_right_edge(output_data, cinfo->max_v_samp_factor,
       
   195 		    cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
       
   196 }
       
   197 
       
   198 
       
   199 /*
       
   200  * Downsample pixel values of a single component.
       
   201  * This version handles the common case of 2:1 horizontal and 1:1 vertical,
       
   202  * without smoothing.
       
   203  *
       
   204  * A note about the "bias" calculations: when rounding fractional values to
       
   205  * integer, we do not want to always round 0.5 up to the next integer.
       
   206  * If we did that, we'd introduce a noticeable bias towards larger values.
       
   207  * Instead, this code is arranged so that 0.5 will be rounded up or down at
       
   208  * alternate pixel locations (a simple ordered dither pattern).
       
   209  */
       
   210 
       
   211 METHODDEF(void)
       
   212 h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
       
   213 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   214 {
       
   215   int outrow;
       
   216   JDIMENSION outcol;
       
   217   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
       
   218   register JSAMPROW inptr, outptr;
       
   219   register int bias;
       
   220 
       
   221   /* Expand input data enough to let all the output samples be generated
       
   222    * by the standard loop.  Special-casing padded output would be more
       
   223    * efficient.
       
   224    */
       
   225   expand_right_edge(input_data, cinfo->max_v_samp_factor,
       
   226 		    cinfo->image_width, output_cols * 2);
       
   227 
       
   228   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
       
   229     outptr = output_data[outrow];
       
   230     inptr = input_data[outrow];
       
   231     bias = 0;			/* bias = 0,1,0,1,... for successive samples */
       
   232     for (outcol = 0; outcol < output_cols; outcol++) {
       
   233       *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
       
   234 			      + bias) >> 1);
       
   235       bias ^= 1;		/* 0=>1, 1=>0 */
       
   236       inptr += 2;
       
   237     }
       
   238   }
       
   239 }
       
   240 
       
   241 
       
   242 /*
       
   243  * Downsample pixel values of a single component.
       
   244  * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
       
   245  * without smoothing.
       
   246  */
       
   247 
       
   248 METHODDEF(void)
       
   249 h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
       
   250 		 JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   251 {
       
   252   int inrow, outrow;
       
   253   JDIMENSION outcol;
       
   254   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
       
   255   register JSAMPROW inptr0, inptr1, outptr;
       
   256   register int bias;
       
   257 
       
   258   /* Expand input data enough to let all the output samples be generated
       
   259    * by the standard loop.  Special-casing padded output would be more
       
   260    * efficient.
       
   261    */
       
   262   expand_right_edge(input_data, cinfo->max_v_samp_factor,
       
   263 		    cinfo->image_width, output_cols * 2);
       
   264 
       
   265   inrow = 0;
       
   266   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
       
   267     outptr = output_data[outrow];
       
   268     inptr0 = input_data[inrow];
       
   269     inptr1 = input_data[inrow+1];
       
   270     bias = 1;			/* bias = 1,2,1,2,... for successive samples */
       
   271     for (outcol = 0; outcol < output_cols; outcol++) {
       
   272       *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
       
   273 			      GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
       
   274 			      + bias) >> 2);
       
   275       bias ^= 3;		/* 1=>2, 2=>1 */
       
   276       inptr0 += 2; inptr1 += 2;
       
   277     }
       
   278     inrow += 2;
       
   279   }
       
   280 }
       
   281 
       
   282 
       
   283 #ifdef INPUT_SMOOTHING_SUPPORTED
       
   284 
       
   285 /*
       
   286  * Downsample pixel values of a single component.
       
   287  * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
       
   288  * with smoothing.  One row of context is required.
       
   289  */
       
   290 
       
   291 METHODDEF(void)
       
   292 h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
       
   293 			JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   294 {
       
   295   int inrow, outrow;
       
   296   JDIMENSION colctr;
       
   297   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
       
   298   register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
       
   299   INT32 membersum, neighsum, memberscale, neighscale;
       
   300 
       
   301   /* Expand input data enough to let all the output samples be generated
       
   302    * by the standard loop.  Special-casing padded output would be more
       
   303    * efficient.
       
   304    */
       
   305   expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
       
   306 		    cinfo->image_width, output_cols * 2);
       
   307 
       
   308   /* We don't bother to form the individual "smoothed" input pixel values;
       
   309    * we can directly compute the output which is the average of the four
       
   310    * smoothed values.  Each of the four member pixels contributes a fraction
       
   311    * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
       
   312    * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
       
   313    * output.  The four corner-adjacent neighbor pixels contribute a fraction
       
   314    * SF to just one smoothed pixel, or SF/4 to the final output; while the
       
   315    * eight edge-adjacent neighbors contribute SF to each of two smoothed
       
   316    * pixels, or SF/2 overall.  In order to use integer arithmetic, these
       
   317    * factors are scaled by 2^16 = 65536.
       
   318    * Also recall that SF = smoothing_factor / 1024.
       
   319    */
       
   320 
       
   321   memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
       
   322   neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
       
   323 
       
   324   inrow = 0;
       
   325   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
       
   326     outptr = output_data[outrow];
       
   327     inptr0 = input_data[inrow];
       
   328     inptr1 = input_data[inrow+1];
       
   329     above_ptr = input_data[inrow-1];
       
   330     below_ptr = input_data[inrow+2];
       
   331 
       
   332     /* Special case for first column: pretend column -1 is same as column 0 */
       
   333     membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
       
   334 		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
       
   335     neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
       
   336 	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
       
   337 	       GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
       
   338 	       GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
       
   339     neighsum += neighsum;
       
   340     neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
       
   341 		GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
       
   342     membersum = membersum * memberscale + neighsum * neighscale;
       
   343     *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
       
   344     inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
       
   345 
       
   346     for (colctr = output_cols - 2; colctr > 0; colctr--) {
       
   347       /* sum of pixels directly mapped to this output element */
       
   348       membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
       
   349 		  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
       
   350       /* sum of edge-neighbor pixels */
       
   351       neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
       
   352 		 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
       
   353 		 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
       
   354 		 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
       
   355       /* The edge-neighbors count twice as much as corner-neighbors */
       
   356       neighsum += neighsum;
       
   357       /* Add in the corner-neighbors */
       
   358       neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
       
   359 		  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
       
   360       /* form final output scaled up by 2^16 */
       
   361       membersum = membersum * memberscale + neighsum * neighscale;
       
   362       /* round, descale and output it */
       
   363       *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
       
   364       inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
       
   365     }
       
   366 
       
   367     /* Special case for last column */
       
   368     membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
       
   369 		GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
       
   370     neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
       
   371 	       GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
       
   372 	       GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
       
   373 	       GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
       
   374     neighsum += neighsum;
       
   375     neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
       
   376 		GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
       
   377     membersum = membersum * memberscale + neighsum * neighscale;
       
   378     *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
       
   379 
       
   380     inrow += 2;
       
   381   }
       
   382 }
       
   383 
       
   384 
       
   385 /*
       
   386  * Downsample pixel values of a single component.
       
   387  * This version handles the special case of a full-size component,
       
   388  * with smoothing.  One row of context is required.
       
   389  */
       
   390 
       
   391 METHODDEF(void)
       
   392 fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
       
   393 			    JSAMPARRAY input_data, JSAMPARRAY output_data)
       
   394 {
       
   395   int outrow;
       
   396   JDIMENSION colctr;
       
   397   JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
       
   398   register JSAMPROW inptr, above_ptr, below_ptr, outptr;
       
   399   INT32 membersum, neighsum, memberscale, neighscale;
       
   400   int colsum, lastcolsum, nextcolsum;
       
   401 
       
   402   /* Expand input data enough to let all the output samples be generated
       
   403    * by the standard loop.  Special-casing padded output would be more
       
   404    * efficient.
       
   405    */
       
   406   expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
       
   407 		    cinfo->image_width, output_cols);
       
   408 
       
   409   /* Each of the eight neighbor pixels contributes a fraction SF to the
       
   410    * smoothed pixel, while the main pixel contributes (1-8*SF).  In order
       
   411    * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
       
   412    * Also recall that SF = smoothing_factor / 1024.
       
   413    */
       
   414 
       
   415   memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
       
   416   neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
       
   417 
       
   418   for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
       
   419     outptr = output_data[outrow];
       
   420     inptr = input_data[outrow];
       
   421     above_ptr = input_data[outrow-1];
       
   422     below_ptr = input_data[outrow+1];
       
   423 
       
   424     /* Special case for first column */
       
   425     colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
       
   426 	     GETJSAMPLE(*inptr);
       
   427     membersum = GETJSAMPLE(*inptr++);
       
   428     nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
       
   429 		 GETJSAMPLE(*inptr);
       
   430     neighsum = colsum + (colsum - membersum) + nextcolsum;
       
   431     membersum = membersum * memberscale + neighsum * neighscale;
       
   432     *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
       
   433     lastcolsum = colsum; colsum = nextcolsum;
       
   434 
       
   435     for (colctr = output_cols - 2; colctr > 0; colctr--) {
       
   436       membersum = GETJSAMPLE(*inptr++);
       
   437       above_ptr++; below_ptr++;
       
   438       nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
       
   439 		   GETJSAMPLE(*inptr);
       
   440       neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
       
   441       membersum = membersum * memberscale + neighsum * neighscale;
       
   442       *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
       
   443       lastcolsum = colsum; colsum = nextcolsum;
       
   444     }
       
   445 
       
   446     /* Special case for last column */
       
   447     membersum = GETJSAMPLE(*inptr);
       
   448     neighsum = lastcolsum + (colsum - membersum) + colsum;
       
   449     membersum = membersum * memberscale + neighsum * neighscale;
       
   450     *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
       
   451 
       
   452   }
       
   453 }
       
   454 
       
   455 #endif /* INPUT_SMOOTHING_SUPPORTED */
       
   456 
       
   457 
       
   458 /*
       
   459  * Module initialization routine for downsampling.
       
   460  * Note that we must select a routine for each component.
       
   461  */
       
   462 
       
   463 GLOBAL(void)
       
   464 jinit_downsampler (j_compress_ptr cinfo)
       
   465 {
       
   466   my_downsample_ptr downsample;
       
   467   int ci;
       
   468   jpeg_component_info * compptr;
       
   469   boolean smoothok = TRUE;
       
   470 
       
   471   downsample = (my_downsample_ptr)
       
   472     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
       
   473 				SIZEOF(my_downsampler));
       
   474   cinfo->downsample = (struct jpeg_downsampler *) downsample;
       
   475   downsample->pub.start_pass = start_pass_downsample;
       
   476   downsample->pub.downsample = sep_downsample;
       
   477   downsample->pub.need_context_rows = FALSE;
       
   478 
       
   479   if (cinfo->CCIR601_sampling)
       
   480     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
       
   481 
       
   482   /* Verify we can handle the sampling factors, and set up method pointers */
       
   483   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
       
   484        ci++, compptr++) {
       
   485     if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
       
   486 	compptr->v_samp_factor == cinfo->max_v_samp_factor) {
       
   487 #ifdef INPUT_SMOOTHING_SUPPORTED
       
   488       if (cinfo->smoothing_factor) {
       
   489 	downsample->methods[ci] = fullsize_smooth_downsample;
       
   490 	downsample->pub.need_context_rows = TRUE;
       
   491       } else
       
   492 #endif
       
   493 	downsample->methods[ci] = fullsize_downsample;
       
   494     } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
       
   495 	       compptr->v_samp_factor == cinfo->max_v_samp_factor) {
       
   496       smoothok = FALSE;
       
   497       downsample->methods[ci] = h2v1_downsample;
       
   498     } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
       
   499 	       compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
       
   500 #ifdef INPUT_SMOOTHING_SUPPORTED
       
   501       if (cinfo->smoothing_factor) {
       
   502 	downsample->methods[ci] = h2v2_smooth_downsample;
       
   503 	downsample->pub.need_context_rows = TRUE;
       
   504       } else
       
   505 #endif
       
   506 	downsample->methods[ci] = h2v2_downsample;
       
   507     } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
       
   508 	       (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
       
   509       smoothok = FALSE;
       
   510       downsample->methods[ci] = int_downsample;
       
   511     } else
       
   512       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
       
   513   }
       
   514 
       
   515 #ifdef INPUT_SMOOTHING_SUPPORTED
       
   516   if (cinfo->smoothing_factor && !smoothok)
       
   517     TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
       
   518 #endif
       
   519 }