1  /********************************************************************** <BR>


2  This file is part of Crack dot Com's free source code release of


3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for


4  information about compiling & licensing issues visit this URL</a>


5  <PRE> If that doesn't help, contact Jonathan Clark at


6  golgotha_source@usa.net (Subject should have "GOLG" in it)


7  ***********************************************************************/


8 


9  /*


10  * jcsample.c


11  *


12  * Copyright (C) 19911996, Thomas G. Lane.


13  * This file is part of the Independent JPEG Group's software.


14  * For conditions of distribution and use, see the accompanying README file.


15  *


16  * This file contains downsampling routines.


17  *


18  * Downsampling input data is counted in "row groups". A row group


19  * is defined to be max_v_samp_factor pixel rows of each component,


20  * from which the downsampler produces v_samp_factor sample rows.


21  * A single row group is processed in each call to the downsampler module.


22  *


23  * The downsampler is responsible for edgeexpansion of its output data


24  * to fill an integral number of DCT blocks horizontally. The source buffer


25  * may be modified if it is helpful for this purpose (the source buffer is


26  * allocated wide enough to correspond to the desired output width).


27  * The caller (the prep controller) is responsible for vertical padding.


28  *


29  * The downsampler may request "context rows" by setting need_context_rows


30  * during startup. In this case, the input arrays will contain at least


31  * one row group's worth of pixels above and below the passedin data;


32  * the caller will create dummy rows at image top and bottom by replicating


33  * the first or last real pixel row.


34  *


35  * An excellent reference for image resampling is


36  * Digital Image Warping, George Wolberg, 1990.


37  * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0818689447.


38  *


39  * The downsampling algorithm used here is a simple average of the source


40  * pixels covered by the output pixel. The hifalutin sampling literature


41  * refers to this as a "box filter". In general the characteristics of a box


42  * filter are not very good, but for the specific cases we normally use (1:1


43  * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not


44  * nearly so bad. If you intend to use other sampling ratios, you'd be well


45  * advised to improve this code.


46  *


47  * A simple inputsmoothing capability is provided. This is mainly intended


48  * for cleaning up colordithered GIF input files (if you find it inadequate,


49  * we suggest using an external filtering program such as pnmconvol). When


50  * enabled, each input pixel P is replaced by a weighted sum of itself and its


51  * eight neighbors. P's weight is 18*SF and each neighbor's weight is SF,


52  * where SF = (smoothing_factor / 1024).


53  * Currently, smoothing is only supported for 2h2v sampling factors.


54  */


55 


56  #define JPEG_INTERNALS


57  #include "loaders/jpg/jinclude.h"


58  #include "loaders/jpg/jpeglib.h"


59 


60 


61  /* Pointer to routine to downsample a single component */


62  typedef JMETHOD(void, downsample1_ptr,


63  (j_compress_ptr cinfo, jpeg_component_info * compptr,


64  JSAMPARRAY input_data, JSAMPARRAY output_data));


65 


66  /* Private subobject */


67 


68  typedef struct {


69  struct jpeg_downsampler pub; /* public fields */


70 


71  /* Downsampling method pointers, one per component */


72  downsample1_ptr methods[MAX_COMPONENTS];


73  } my_downsampler;


74 


75  typedef my_downsampler * my_downsample_ptr;


76 


77 


78  /*


79  * Initialize for a downsampling pass.


80  */


81 


82  METHODDEF(void)


83  start_pass_downsample (j_compress_ptr cinfo)


84  {


85  /* no work for now */


86  }


87 


88 


89  /*


90  * Expand a component horizontally from width input_cols to width output_cols,


91  * by duplicating the rightmost samples.


92  */


93 


94  LOCAL(void)


95  expand_right_edge (JSAMPARRAY image_data, int num_rows,


96  JDIMENSION input_cols, JDIMENSION output_cols)


97  {


98  register JSAMPROW ptr;


99  register JSAMPLE pixval;


100  register int count;


101  int row;


102  int numcols = (int) (output_cols  input_cols);


103 


104  if (numcols > 0) {


105  for (row = 0; row < num_rows; row++) {


106  ptr = image_data[row] + input_cols;


107  pixval = ptr[1]; /* don't need GETJSAMPLE() here */


108  for (count = numcols; count > 0; count)


109  *ptr++ = pixval;


110  }


111  }


112  }


113 


114 


115  /*


116  * Do downsampling for a whole row group (all components).


117  *


118  * In this version we simply downsample each component independently.


119  */


120 


121  METHODDEF(void)


122  sep_downsample (j_compress_ptr cinfo,


123  JSAMPIMAGE input_buf, JDIMENSION in_row_index,


124  JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)


125  {


126  my_downsample_ptr downsample = (my_downsample_ptr) cinfo>downsample;


127  int ci;


128  jpeg_component_info * compptr;


129  JSAMPARRAY in_ptr, out_ptr;


130 


131  for (ci = 0, compptr = cinfo>comp_info; ci < cinfo>num_components;


132  ci++, compptr++) {


133  in_ptr = input_buf[ci] + in_row_index;


134  out_ptr = output_buf[ci] + (out_row_group_index * compptr>v_samp_factor);


135  (*downsample>methods[ci]) (cinfo, compptr, in_ptr, out_ptr);


136  }


137  }


138 


139 


140  /*


141  * Downsample pixel values of a single component.


142  * One row group is processed per call.


143  * This version handles arbitrary integral sampling ratios, without smoothing.


144  * Note that this version is not actually used for customary sampling ratios.


145  */


146 


147  METHODDEF(void)


148  int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,


149  JSAMPARRAY input_data, JSAMPARRAY output_data)


150  {


151  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;


152  JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */


153  JDIMENSION output_cols = compptr>width_in_blocks * DCTSIZE;


154  JSAMPROW inptr, outptr;


155  INT32 outvalue;


156 


157  h_expand = cinfo>max_h_samp_factor / compptr>h_samp_factor;


158  v_expand = cinfo>max_v_samp_factor / compptr>v_samp_factor;


159  numpix = h_expand * v_expand;


160  numpix2 = numpix/2;


161 


162  /* Expand input data enough to let all the output samples be generated


163  * by the standard loop. Specialcasing padded output would be more


164  * efficient.


165  */


166  expand_right_edge(input_data, cinfo>max_v_samp_factor,


167  cinfo>image_width, output_cols * h_expand);


168 


169  inrow = 0;


170  for (outrow = 0; outrow < compptr>v_samp_factor; outrow++) {


171  outptr = output_data[outrow];


172  for (outcol = 0, outcol_h = 0; outcol < output_cols;


173  outcol++, outcol_h += h_expand) {


174  outvalue = 0;


175  for (v = 0; v < v_expand; v++) {


176  inptr = input_data[inrow+v] + outcol_h;


177  for (h = 0; h < h_expand; h++) {


178  outvalue += (INT32) GETJSAMPLE(*inptr++);


179  }


180  }


181  *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);


182  }


183  inrow += v_expand;


184  }


185  }


186 


187 


188  /*


189  * Downsample pixel values of a single component.


190  * This version handles the special case of a fullsize component,


191  * without smoothing.


192  */


193 


194  METHODDEF(void)


195  fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,


196  JSAMPARRAY input_data, JSAMPARRAY output_data)


197  {


198  /* Copy the data */


199  jcopy_sample_rows(input_data, 0, output_data, 0,


200  cinfo>max_v_samp_factor, cinfo>image_width);


201  /* Edgeexpand */


202  expand_right_edge(output_data, cinfo>max_v_samp_factor,


203  cinfo>image_width, compptr>width_in_blocks * DCTSIZE);


204  }


205 


206 


207  /*


208  * Downsample pixel values of a single component.


209  * This version handles the common case of 2:1 horizontal and 1:1 vertical,


210  * without smoothing.


211  *


212  * A note about the "bias" calculations: when rounding fractional values to


213  * integer, we do not want to always round 0.5 up to the next integer.


214  * If we did that, we'd introduce a noticeable bias towards larger values.


215  * Instead, this code is arranged so that 0.5 will be rounded up or down at


216  * alternate pixel locations (a simple ordered dither pattern).


217  */


218 


219  METHODDEF(void)


220  h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,


221  JSAMPARRAY input_data, JSAMPARRAY output_data)


222  {


223  int outrow;


224  JDIMENSION outcol;


225  JDIMENSION output_cols = compptr>width_in_blocks * DCTSIZE;


226  register JSAMPROW inptr, outptr;


227  register int bias;


228 


229  /* Expand input data enough to let all the output samples be generated


230  * by the standard loop. Specialcasing padded output would be more


231  * efficient.


232  */


233  expand_right_edge(input_data, cinfo>max_v_samp_factor,


234  cinfo>image_width, output_cols * 2);


235 


236  for (outrow = 0; outrow < compptr>v_samp_factor; outrow++) {


237  outptr = output_data[outrow];


238  inptr = input_data[outrow];


239  bias = 0; /* bias = 0,1,0,1,... for successive samples */


240  for (outcol = 0; outcol < output_cols; outcol++) {


241  *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])


242  + bias) >> 1);


243  bias ^= 1; /* 0=>1, 1=>0 */


244  inptr += 2;


245  }


246  }


247  }


248 


249 


250  /*


251  * Downsample pixel values of a single component.


252  * This version handles the standard case of 2:1 horizontal and 2:1 vertical,


253  * without smoothing.


254  */


255 


256  METHODDEF(void)


257  h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,


258  JSAMPARRAY input_data, JSAMPARRAY output_data)


259  {


260  int inrow, outrow;


261  JDIMENSION outcol;


262  JDIMENSION output_cols = compptr>width_in_blocks * DCTSIZE;


263  register JSAMPROW inptr0, inptr1, outptr;


264  register int bias;


265 


266  /* Expand input data enough to let all the output samples be generated


267  * by the standard loop. Specialcasing padded output would be more


268  * efficient.


269  */


270  expand_right_edge(input_data, cinfo>max_v_samp_factor,


271  cinfo>image_width, output_cols * 2);


272 


273  inrow = 0;


274  for (outrow = 0; outrow < compptr>v_samp_factor; outrow++) {


275  outptr = output_data[outrow];


276  inptr0 = input_data[inrow];


277  inptr1 = input_data[inrow+1];


278  bias = 1; /* bias = 1,2,1,2,... for successive samples */


279  for (outcol = 0; outcol < output_cols; outcol++) {


280  *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +


281  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])


282  + bias) >> 2);


283  bias ^= 3; /* 1=>2, 2=>1 */


284  inptr0 += 2; inptr1 += 2;


285  }


286  inrow += 2;


287  }


288  }


289 


290 


291  #ifdef INPUT_SMOOTHING_SUPPORTED


292 


293  /*


294  * Downsample pixel values of a single component.


295  * This version handles the standard case of 2:1 horizontal and 2:1 vertical,


296  * with smoothing. One row of context is required.


297  */


298 


299  METHODDEF(void)


300  h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,


301  JSAMPARRAY input_data, JSAMPARRAY output_data)


302  {


303  int inrow, outrow;


304  JDIMENSION colctr;


305  JDIMENSION output_cols = compptr>width_in_blocks * DCTSIZE;


306  register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;


307  INT32 membersum, neighsum, memberscale, neighscale;


308 


309  /* Expand input data enough to let all the output samples be generated


310  * by the standard loop. Specialcasing padded output would be more


311  * efficient.


312  */


313  expand_right_edge(input_data  1, cinfo>max_v_samp_factor + 2,


314  cinfo>image_width, output_cols * 2);


315 


316  /* We don't bother to form the individual "smoothed" input pixel values;


317  * we can directly compute the output which is the average of the four


318  * smoothed values. Each of the four member pixels contributes a fraction


319  * (18*SF) to its own smoothed image and a fraction SF to each of the three


320  * other smoothed pixels, therefore a total fraction (15*SF)/4 to the final


321  * output. The four corneradjacent neighbor pixels contribute a fraction


322  * SF to just one smoothed pixel, or SF/4 to the final output; while the


323  * eight edgeadjacent neighbors contribute SF to each of two smoothed


324  * pixels, or SF/2 overall. In order to use integer arithmetic, these


325  * factors are scaled by 2^16 = 65536.


326  * Also recall that SF = smoothing_factor / 1024.


327  */


328 


329  memberscale = 16384  cinfo>smoothing_factor * 80; /* scaled (15*SF)/4 */


330  neighscale = cinfo>smoothing_factor * 16; /* scaled SF/4 */


331 


332  inrow = 0;


333  for (outrow = 0; outrow < compptr>v_samp_factor; outrow++) {


334  outptr = output_data[outrow];


335  inptr0 = input_data[inrow];


336  inptr1 = input_data[inrow+1];


337  above_ptr = input_data[inrow1];


338  below_ptr = input_data[inrow+2];


339 


340  /* Special case for first column: pretend column 1 is same as column 0 */


341  membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +


342  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);


343  neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +


344  GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +


345  GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +


346  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);


347  neighsum += neighsum;


348  neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +


349  GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);


350  membersum = membersum * memberscale + neighsum * neighscale;


351  *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);


352  inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;


353 


354  for (colctr = output_cols  2; colctr > 0; colctr) {


355  /* sum of pixels directly mapped to this output element */


356  membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +


357  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);


358  /* sum of edgeneighbor pixels */


359  neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +


360  GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +


361  GETJSAMPLE(inptr0[1]) + GETJSAMPLE(inptr0[2]) +


362  GETJSAMPLE(inptr1[1]) + GETJSAMPLE(inptr1[2]);


363  /* The edgeneighbors count twice as much as cornerneighbors */


364  neighsum += neighsum;


365  /* Add in the cornerneighbors */


366  neighsum += GETJSAMPLE(above_ptr[1]) + GETJSAMPLE(above_ptr[2]) +


367  GETJSAMPLE(below_ptr[1]) + GETJSAMPLE(below_ptr[2]);


368  /* form final output scaled up by 2^16 */


369  membersum = membersum * memberscale + neighsum * neighscale;


370  /* round, descale and output it */


371  *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);


372  inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;


373  }


374 


375  /* Special case for last column */


376  membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +


377  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);


378  neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +


379  GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +


380  GETJSAMPLE(inptr0[1]) + GETJSAMPLE(inptr0[1]) +


381  GETJSAMPLE(inptr1[1]) + GETJSAMPLE(inptr1[1]);


382  neighsum += neighsum;


383  neighsum += GETJSAMPLE(above_ptr[1]) + GETJSAMPLE(above_ptr[1]) +


384  GETJSAMPLE(below_ptr[1]) + GETJSAMPLE(below_ptr[1]);


385  membersum = membersum * memberscale + neighsum * neighscale;


386  *outptr = (JSAMPLE) ((membersum + 32768) >> 16);


387 


388  inrow += 2;


389  }


390  }


391 


392 


393  /*


394  * Downsample pixel values of a single component.


395  * This version handles the special case of a fullsize component,


396  * with smoothing. One row of context is required.


397  */


398 


399  METHODDEF(void)


400  fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,


401  JSAMPARRAY input_data, JSAMPARRAY output_data)


402  {


403  int outrow;


404  JDIMENSION colctr;


405  JDIMENSION output_cols = compptr>width_in_blocks * DCTSIZE;


406  register JSAMPROW inptr, above_ptr, below_ptr, outptr;


407  INT32 membersum, neighsum, memberscale, neighscale;


408  int colsum, lastcolsum, nextcolsum;


409 


410  /* Expand input data enough to let all the output samples be generated


411  * by the standard loop. Specialcasing padded output would be more


412  * efficient.


413  */


414  expand_right_edge(input_data  1, cinfo>max_v_samp_factor + 2,


415  cinfo>image_width, output_cols);


416 


417  /* Each of the eight neighbor pixels contributes a fraction SF to the


418  * smoothed pixel, while the main pixel contributes (18*SF). In order


419  * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.


420  * Also recall that SF = smoothing_factor / 1024.


421  */


422 


423  memberscale = 65536L  cinfo>smoothing_factor * 512L; /* scaled 18*SF */


424  neighscale = cinfo>smoothing_factor * 64; /* scaled SF */


425 


426  for (outrow = 0; outrow < compptr>v_samp_factor; outrow++) {


427  outptr = output_data[outrow];


428  inptr = input_data[outrow];


429  above_ptr = input_data[outrow1];


430  below_ptr = input_data[outrow+1];


431 


432  /* Special case for first column */


433  colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +


434  GETJSAMPLE(*inptr);


435  membersum = GETJSAMPLE(*inptr++);


436  nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +


437  GETJSAMPLE(*inptr);


438  neighsum = colsum + (colsum  membersum) + nextcolsum;


439  membersum = membersum * memberscale + neighsum * neighscale;


440  *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);


441  lastcolsum = colsum; colsum = nextcolsum;


442 


443  for (colctr = output_cols  2; colctr > 0; colctr) {


444  membersum = GETJSAMPLE(*inptr++);


445  above_ptr++; below_ptr++;


446  nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +


447  GETJSAMPLE(*inptr);


448  neighsum = lastcolsum + (colsum  membersum) + nextcolsum;


449  membersum = membersum * memberscale + neighsum * neighscale;


450  *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);


451  lastcolsum = colsum; colsum = nextcolsum;


452  }


453 


454  /* Special case for last column */


455  membersum = GETJSAMPLE(*inptr);


456  neighsum = lastcolsum + (colsum  membersum) + colsum;


457  membersum = membersum * memberscale + neighsum * neighscale;


458  *outptr = (JSAMPLE) ((membersum + 32768) >> 16);


459 


460  }


461  }


462 


463  #endif /* INPUT_SMOOTHING_SUPPORTED */


464 


465 


466  /*


467  * Module initialization routine for downsampling.


468  * Note that we must select a routine for each component.


469  */


470 


471  GLOBAL(void)


472  jinit_downsampler (j_compress_ptr cinfo)


473  {


474  my_downsample_ptr downsample;


475  int ci;


476  jpeg_component_info * compptr;


477  boolean smoothok = TRUE;


478 


479  downsample = (my_downsample_ptr)


480  (*cinfo>mem>alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,


481  SIZEOF(my_downsampler));


482  cinfo>downsample = (struct jpeg_downsampler *) downsample;


483  downsample>pub.start_pass = start_pass_downsample;


484  downsample>pub.downsample = sep_downsample;


485  downsample>pub.need_context_rows = FALSE;


486 


487  if (cinfo>CCIR601_sampling)


488  ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);


489 


490  /* Verify we can handle the sampling factors, and set up method pointers */


491  for (ci = 0, compptr = cinfo>comp_info; ci < cinfo>num_components;


492  ci++, compptr++) {


493  if (compptr>h_samp_factor == cinfo>max_h_samp_factor &&


494  compptr>v_samp_factor == cinfo>max_v_samp_factor) {


495  #ifdef INPUT_SMOOTHING_SUPPORTED


496  if (cinfo>smoothing_factor) {


497  downsample>methods[ci] = fullsize_smooth_downsample;


498  downsample>pub.need_context_rows = TRUE;


499  } else


500  #endif


501  downsample>methods[ci] = fullsize_downsample;


502  } else if (compptr>h_samp_factor * 2 == cinfo>max_h_samp_factor &&


503  compptr>v_samp_factor == cinfo>max_v_samp_factor) {


504  smoothok = FALSE;


505  downsample>methods[ci] = h2v1_downsample;


506  } else if (compptr>h_samp_factor * 2 == cinfo>max_h_samp_factor &&


507  compptr>v_samp_factor * 2 == cinfo>max_v_samp_factor) {


508  #ifdef INPUT_SMOOTHING_SUPPORTED


509  if (cinfo>smoothing_factor) {


510  downsample>methods[ci] = h2v2_smooth_downsample;


511  downsample>pub.need_context_rows = TRUE;


512  } else


513  #endif


514  downsample>methods[ci] = h2v2_downsample;


515  } else if ((cinfo>max_h_samp_factor % compptr>h_samp_factor) == 0 &&


516  (cinfo>max_v_samp_factor % compptr>v_samp_factor) == 0) {


517  smoothok = FALSE;


518  downsample>methods[ci] = int_downsample;


519  } else


520  ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);


521  }


522 


523  #ifdef INPUT_SMOOTHING_SUPPORTED


524  if (cinfo>smoothing_factor && !smoothok)


525  TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);


526  #endif


527  }

