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. 
   8  * This file contains downsampling routines. 
  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. 
  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. 
  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. 
  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. 
  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. 
  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. 
  48 #define JPEG_INTERNALS 
  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
)); 
  58 /* Private subobject */ 
  61   struct jpeg_downsampler pub
;  /* public fields */ 
  63   /* Downsampling method pointers, one per component */ 
  64   downsample1_ptr methods
[MAX_COMPONENTS
]; 
  67 typedef my_downsampler 
* my_downsample_ptr
; 
  71  * Initialize for a downsampling pass. 
  75 start_pass_downsample (j_compress_ptr cinfo
) 
  82  * Expand a component horizontally from width input_cols to width output_cols, 
  83  * by duplicating the rightmost samples. 
  87 expand_right_edge (JSAMPARRAY image_data
, int num_rows
, 
  88                    JDIMENSION input_cols
, JDIMENSION output_cols
) 
  90   register JSAMPROW ptr
; 
  91   register JSAMPLE pixval
; 
  94   int numcols 
= (int) (output_cols 
- input_cols
); 
  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
--) 
 108  * Do downsampling for a whole row group (all components). 
 110  * In this version we simply downsample each component independently. 
 114 sep_downsample (j_compress_ptr cinfo
, 
 115                 JSAMPIMAGE input_buf
, JDIMENSION in_row_index
, 
 116                 JSAMPIMAGE output_buf
, JDIMENSION out_row_group_index
) 
 118   my_downsample_ptr downsample 
= (my_downsample_ptr
) cinfo
->downsample
; 
 120   jpeg_component_info 
* compptr
; 
 121   JSAMPARRAY in_ptr
, out_ptr
; 
 123   for (ci 
= 0, compptr 
= cinfo
->comp_info
; ci 
< cinfo
->num_components
; 
 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
); 
 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. 
 140 int_downsample (j_compress_ptr cinfo
, jpeg_component_info 
* compptr
, 
 141                 JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 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
; 
 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
; 
 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 
 158   expand_right_edge(input_data
, cinfo
->max_v_samp_factor
, 
 159                     cinfo
->image_width
, output_cols 
* h_expand
); 
 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
) { 
 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 
+= (JPEG_INT32
) GETJSAMPLE(*inptr
++); 
 173       *outptr
++ = (JSAMPLE
) ((outvalue 
+ numpix2
) / numpix
); 
 181  * Downsample pixel values of a single component. 
 182  * This version handles the special case of a full-size component, 
 187 fullsize_downsample (j_compress_ptr cinfo
, jpeg_component_info 
* compptr
, 
 188                      JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 191   jcopy_sample_rows(input_data
, 0, output_data
, 0, 
 192                     cinfo
->max_v_samp_factor
, cinfo
->image_width
); 
 194   expand_right_edge(output_data
, cinfo
->max_v_samp_factor
, 
 195                     cinfo
->image_width
, compptr
->width_in_blocks 
* DCTSIZE
); 
 200  * Downsample pixel values of a single component. 
 201  * This version handles the common case of 2:1 horizontal and 1:1 vertical, 
 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). 
 212 h2v1_downsample (j_compress_ptr cinfo
, jpeg_component_info 
* compptr
, 
 213                  JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 217   JDIMENSION output_cols 
= compptr
->width_in_blocks 
* DCTSIZE
; 
 218   register JSAMPROW inptr
, outptr
; 
 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 
 225   expand_right_edge(input_data
, cinfo
->max_v_samp_factor
, 
 226                     cinfo
->image_width
, output_cols 
* 2); 
 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]) 
 235       bias 
^= 1;                /* 0=>1, 1=>0 */ 
 243  * Downsample pixel values of a single component. 
 244  * This version handles the standard case of 2:1 horizontal and 2:1 vertical, 
 249 h2v2_downsample (j_compress_ptr cinfo
, jpeg_component_info 
* compptr
, 
 250                  JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 254   JDIMENSION output_cols 
= compptr
->width_in_blocks 
* DCTSIZE
; 
 255   register JSAMPROW inptr0
, inptr1
, outptr
; 
 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 
 262   expand_right_edge(input_data
, cinfo
->max_v_samp_factor
, 
 263                     cinfo
->image_width
, output_cols 
* 2); 
 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]) 
 275       bias 
^= 3;                /* 1=>2, 2=>1 */ 
 276       inptr0 
+= 2; inptr1 
+= 2; 
 283 #ifdef INPUT_SMOOTHING_SUPPORTED 
 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. 
 292 h2v2_smooth_downsample (j_compress_ptr cinfo
, jpeg_component_info 
* compptr
, 
 293                         JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 297   JDIMENSION output_cols 
= compptr
->width_in_blocks 
* DCTSIZE
; 
 298   register JSAMPROW inptr0
, inptr1
, above_ptr
, below_ptr
, outptr
; 
 299   JPEG_INT32 membersum
, neighsum
, memberscale
, neighscale
; 
 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 
 305   expand_right_edge(input_data 
- 1, cinfo
->max_v_samp_factor 
+ 2, 
 306                     cinfo
->image_width
, output_cols 
* 2); 
 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. 
 321   memberscale 
= 16384 - cinfo
->smoothing_factor 
* 80; /* scaled (1-5*SF)/4 */ 
 322   neighscale 
= cinfo
->smoothing_factor 
* 16; /* scaled SF/4 */ 
 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]; 
 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; 
 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; 
 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); 
 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. 
 392 fullsize_smooth_downsample (j_compress_ptr cinfo
, jpeg_component_info 
*compptr
, 
 393                             JSAMPARRAY input_data
, JSAMPARRAY output_data
) 
 397   JDIMENSION output_cols 
= compptr
->width_in_blocks 
* DCTSIZE
; 
 398   register JSAMPROW inptr
, above_ptr
, below_ptr
, outptr
; 
 399   JPEG_INT32 membersum
, neighsum
, memberscale
, neighscale
; 
 400   int colsum
, lastcolsum
, nextcolsum
; 
 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 
 406   expand_right_edge(input_data 
- 1, cinfo
->max_v_samp_factor 
+ 2, 
 407                     cinfo
->image_width
, output_cols
); 
 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. 
 415   memberscale 
= 65536L - cinfo
->smoothing_factor 
* 512L; /* scaled 1-8*SF */ 
 416   neighscale 
= cinfo
->smoothing_factor 
* 64; /* scaled SF */ 
 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]; 
 424     /* Special case for first column */ 
 425     colsum 
= GETJSAMPLE(*above_ptr
++) + GETJSAMPLE(*below_ptr
++) + 
 427     membersum 
= GETJSAMPLE(*inptr
++); 
 428     nextcolsum 
= GETJSAMPLE(*above_ptr
) + GETJSAMPLE(*below_ptr
) + 
 430     neighsum 
= colsum 
+ (colsum 
- membersum
) + nextcolsum
; 
 431     membersum 
= membersum 
* memberscale 
+ neighsum 
* neighscale
; 
 432     *outptr
++ = (JSAMPLE
) ((membersum 
+ 32768) >> 16); 
 433     lastcolsum 
= colsum
; colsum 
= nextcolsum
; 
 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
) + 
 440       neighsum 
= lastcolsum 
+ (colsum 
- membersum
) + nextcolsum
; 
 441       membersum 
= membersum 
* memberscale 
+ neighsum 
* neighscale
; 
 442       *outptr
++ = (JSAMPLE
) ((membersum 
+ 32768) >> 16); 
 443       lastcolsum 
= colsum
; colsum 
= nextcolsum
; 
 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); 
 455 #endif /* INPUT_SMOOTHING_SUPPORTED */ 
 459  * Module initialization routine for downsampling. 
 460  * Note that we must select a routine for each component. 
 464 jinit_downsampler (j_compress_ptr cinfo
) 
 466   my_downsample_ptr downsample
; 
 468   jpeg_component_info 
* compptr
; 
 469   boolean smoothok 
= TRUE
; 
 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
; 
 479   if (cinfo
->CCIR601_sampling
) 
 480     ERREXIT(cinfo
, JERR_CCIR601_NOTIMPL
); 
 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
; 
 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
; 
 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
) { 
 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
; 
 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) { 
 510       downsample
->methods
[ci
] = int_downsample
; 
 512       ERREXIT(cinfo
, JERR_FRACT_SAMPLE_NOTIMPL
); 
 515 #ifdef INPUT_SMOOTHING_SUPPORTED 
 516   if (cinfo
->smoothing_factor 
&& !smoothok
) 
 517     TRACEMS(cinfo
, 0, JTRC_SMOOTH_NOTIMPL
);