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