jdsample.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jdsample.c (16381B)
       ---
            1 /*
            2  * jdsample.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 upsampling routines.
            9  *
           10  * Upsampling input data is counted in "row groups".  A row group
           11  * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
           12  * sample rows of each component.  Upsampling will normally produce
           13  * max_v_samp_factor pixel rows from each row group (but this could vary
           14  * if the upsampler is applying a scale factor of its own).
           15  *
           16  * An excellent reference for image resampling is
           17  *   Digital Image Warping, George Wolberg, 1990.
           18  *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
           19  */
           20 
           21 #define JPEG_INTERNALS
           22 #include "jinclude.h"
           23 #include "jpeglib.h"
           24 
           25 
           26 /* Pointer to routine to upsample a single component */
           27 typedef JMETHOD(void, upsample1_ptr,
           28                 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
           29                  JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
           30 
           31 /* Private subobject */
           32 
           33 typedef struct {
           34   struct jpeg_upsampler pub;        /* public fields */
           35 
           36   /* Color conversion buffer.  When using separate upsampling and color
           37    * conversion steps, this buffer holds one upsampled row group until it
           38    * has been color converted and output.
           39    * Note: we do not allocate any storage for component(s) which are full-size,
           40    * ie do not need rescaling.  The corresponding entry of color_buf[] is
           41    * simply set to point to the input data array, thereby avoiding copying.
           42    */
           43   JSAMPARRAY color_buf[MAX_COMPONENTS];
           44 
           45   /* Per-component upsampling method pointers */
           46   upsample1_ptr methods[MAX_COMPONENTS];
           47 
           48   int next_row_out;                /* counts rows emitted from color_buf */
           49   JDIMENSION rows_to_go;        /* counts rows remaining in image */
           50 
           51   /* Height of an input row group for each component. */
           52   int rowgroup_height[MAX_COMPONENTS];
           53 
           54   /* These arrays save pixel expansion factors so that int_expand need not
           55    * recompute them each time.  They are unused for other upsampling methods.
           56    */
           57   UINT8 h_expand[MAX_COMPONENTS];
           58   UINT8 v_expand[MAX_COMPONENTS];
           59 } my_upsampler;
           60 
           61 typedef my_upsampler * my_upsample_ptr;
           62 
           63 
           64 /*
           65  * Initialize for an upsampling pass.
           66  */
           67 
           68 METHODDEF(void)
           69 start_pass_upsample (j_decompress_ptr cinfo)
           70 {
           71   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
           72 
           73   /* Mark the conversion buffer empty */
           74   upsample->next_row_out = cinfo->max_v_samp_factor;
           75   /* Initialize total-height counter for detecting bottom of image */
           76   upsample->rows_to_go = cinfo->output_height;
           77 }
           78 
           79 
           80 /*
           81  * Control routine to do upsampling (and color conversion).
           82  *
           83  * In this version we upsample each component independently.
           84  * We upsample one row group into the conversion buffer, then apply
           85  * color conversion a row at a time.
           86  */
           87 
           88 METHODDEF(void)
           89 sep_upsample (j_decompress_ptr cinfo,
           90               JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
           91               JDIMENSION in_row_groups_avail,
           92               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
           93               JDIMENSION out_rows_avail)
           94 {
           95   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
           96   int ci;
           97   jpeg_component_info * compptr;
           98   JDIMENSION num_rows;
           99 
          100   /* Fill the conversion buffer, if it's empty */
          101   if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
          102     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
          103          ci++, compptr++) {
          104       /* Invoke per-component upsample method.  Notice we pass a POINTER
          105        * to color_buf[ci], so that fullsize_upsample can change it.
          106        */
          107       (*upsample->methods[ci]) (cinfo, compptr,
          108         input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
          109         upsample->color_buf + ci);
          110     }
          111     upsample->next_row_out = 0;
          112   }
          113 
          114   /* Color-convert and emit rows */
          115 
          116   /* How many we have in the buffer: */
          117   num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
          118   /* Not more than the distance to the end of the image.  Need this test
          119    * in case the image height is not a multiple of max_v_samp_factor:
          120    */
          121   if (num_rows > upsample->rows_to_go) 
          122     num_rows = upsample->rows_to_go;
          123   /* And not more than what the client can accept: */
          124   out_rows_avail -= *out_row_ctr;
          125   if (num_rows > out_rows_avail)
          126     num_rows = out_rows_avail;
          127 
          128   (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
          129                                      (JDIMENSION) upsample->next_row_out,
          130                                      output_buf + *out_row_ctr,
          131                                      (int) num_rows);
          132 
          133   /* Adjust counts */
          134   *out_row_ctr += num_rows;
          135   upsample->rows_to_go -= num_rows;
          136   upsample->next_row_out += num_rows;
          137   /* When the buffer is emptied, declare this input row group consumed */
          138   if (upsample->next_row_out >= cinfo->max_v_samp_factor)
          139     (*in_row_group_ctr)++;
          140 }
          141 
          142 
          143 /*
          144  * These are the routines invoked by sep_upsample to upsample pixel values
          145  * of a single component.  One row group is processed per call.
          146  */
          147 
          148 
          149 /*
          150  * For full-size components, we just make color_buf[ci] point at the
          151  * input buffer, and thus avoid copying any data.  Note that this is
          152  * safe only because sep_upsample doesn't declare the input row group
          153  * "consumed" until we are done color converting and emitting it.
          154  */
          155 
          156 METHODDEF(void)
          157 fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          158                    JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          159 {
          160   *output_data_ptr = input_data;
          161 }
          162 
          163 
          164 /*
          165  * This is a no-op version used for "uninteresting" components.
          166  * These components will not be referenced by color conversion.
          167  */
          168 
          169 METHODDEF(void)
          170 noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          171                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          172 {
          173   *output_data_ptr = NULL;        /* safety check */
          174 }
          175 
          176 
          177 /*
          178  * This version handles any integral sampling ratios.
          179  * This is not used for typical JPEG files, so it need not be fast.
          180  * Nor, for that matter, is it particularly accurate: the algorithm is
          181  * simple replication of the input pixel onto the corresponding output
          182  * pixels.  The hi-falutin sampling literature refers to this as a
          183  * "box filter".  A box filter tends to introduce visible artifacts,
          184  * so if you are actually going to use 3:1 or 4:1 sampling ratios
          185  * you would be well advised to improve this code.
          186  */
          187 
          188 METHODDEF(void)
          189 int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          190               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          191 {
          192   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          193   JSAMPARRAY output_data = *output_data_ptr;
          194   register JSAMPROW inptr, outptr;
          195   register JSAMPLE invalue;
          196   register int h;
          197   JSAMPROW outend;
          198   int h_expand, v_expand;
          199   int inrow, outrow;
          200 
          201   h_expand = upsample->h_expand[compptr->component_index];
          202   v_expand = upsample->v_expand[compptr->component_index];
          203 
          204   inrow = outrow = 0;
          205   while (outrow < cinfo->max_v_samp_factor) {
          206     /* Generate one output row with proper horizontal expansion */
          207     inptr = input_data[inrow];
          208     outptr = output_data[outrow];
          209     outend = outptr + cinfo->output_width;
          210     while (outptr < outend) {
          211       invalue = *inptr++;        /* don't need GETJSAMPLE() here */
          212       for (h = h_expand; h > 0; h--) {
          213         *outptr++ = invalue;
          214       }
          215     }
          216     /* Generate any additional output rows by duplicating the first one */
          217     if (v_expand > 1) {
          218       jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
          219                         v_expand-1, cinfo->output_width);
          220     }
          221     inrow++;
          222     outrow += v_expand;
          223   }
          224 }
          225 
          226 
          227 /*
          228  * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
          229  * It's still a box filter.
          230  */
          231 
          232 METHODDEF(void)
          233 h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          234                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          235 {
          236   JSAMPARRAY output_data = *output_data_ptr;
          237   register JSAMPROW inptr, outptr;
          238   register JSAMPLE invalue;
          239   JSAMPROW outend;
          240   int inrow;
          241 
          242   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
          243     inptr = input_data[inrow];
          244     outptr = output_data[inrow];
          245     outend = outptr + cinfo->output_width;
          246     while (outptr < outend) {
          247       invalue = *inptr++;        /* don't need GETJSAMPLE() here */
          248       *outptr++ = invalue;
          249       *outptr++ = invalue;
          250     }
          251   }
          252 }
          253 
          254 
          255 /*
          256  * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
          257  * It's still a box filter.
          258  */
          259 
          260 METHODDEF(void)
          261 h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          262                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          263 {
          264   JSAMPARRAY output_data = *output_data_ptr;
          265   register JSAMPROW inptr, outptr;
          266   register JSAMPLE invalue;
          267   JSAMPROW outend;
          268   int inrow, outrow;
          269 
          270   inrow = outrow = 0;
          271   while (outrow < cinfo->max_v_samp_factor) {
          272     inptr = input_data[inrow];
          273     outptr = output_data[outrow];
          274     outend = outptr + cinfo->output_width;
          275     while (outptr < outend) {
          276       invalue = *inptr++;        /* don't need GETJSAMPLE() here */
          277       *outptr++ = invalue;
          278       *outptr++ = invalue;
          279     }
          280     jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
          281                       1, cinfo->output_width);
          282     inrow++;
          283     outrow += 2;
          284   }
          285 }
          286 
          287 
          288 /*
          289  * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
          290  *
          291  * The upsampling algorithm is linear interpolation between pixel centers,
          292  * also known as a "triangle filter".  This is a good compromise between
          293  * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
          294  * of the way between input pixel centers.
          295  *
          296  * A note about the "bias" calculations: when rounding fractional values to
          297  * integer, we do not want to always round 0.5 up to the next integer.
          298  * If we did that, we'd introduce a noticeable bias towards larger values.
          299  * Instead, this code is arranged so that 0.5 will be rounded up or down at
          300  * alternate pixel locations (a simple ordered dither pattern).
          301  */
          302 
          303 METHODDEF(void)
          304 h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          305                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          306 {
          307   JSAMPARRAY output_data = *output_data_ptr;
          308   register JSAMPROW inptr, outptr;
          309   register int invalue;
          310   register JDIMENSION colctr;
          311   int inrow;
          312 
          313   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
          314     inptr = input_data[inrow];
          315     outptr = output_data[inrow];
          316     /* Special case for first column */
          317     invalue = GETJSAMPLE(*inptr++);
          318     *outptr++ = (JSAMPLE) invalue;
          319     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
          320 
          321     for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
          322       /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
          323       invalue = GETJSAMPLE(*inptr++) * 3;
          324       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
          325       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
          326     }
          327 
          328     /* Special case for last column */
          329     invalue = GETJSAMPLE(*inptr);
          330     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
          331     *outptr++ = (JSAMPLE) invalue;
          332   }
          333 }
          334 
          335 
          336 /*
          337  * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
          338  * Again a triangle filter; see comments for h2v1 case, above.
          339  *
          340  * It is OK for us to reference the adjacent input rows because we demanded
          341  * context from the main buffer controller (see initialization code).
          342  */
          343 
          344 METHODDEF(void)
          345 h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
          346                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
          347 {
          348   JSAMPARRAY output_data = *output_data_ptr;
          349   register JSAMPROW inptr0, inptr1, outptr;
          350 #if BITS_IN_JSAMPLE == 8
          351   register int thiscolsum, lastcolsum, nextcolsum;
          352 #else
          353   register INT32 thiscolsum, lastcolsum, nextcolsum;
          354 #endif
          355   register JDIMENSION colctr;
          356   int inrow, outrow, v;
          357 
          358   inrow = outrow = 0;
          359   while (outrow < cinfo->max_v_samp_factor) {
          360     for (v = 0; v < 2; v++) {
          361       /* inptr0 points to nearest input row, inptr1 points to next nearest */
          362       inptr0 = input_data[inrow];
          363       if (v == 0)                /* next nearest is row above */
          364         inptr1 = input_data[inrow-1];
          365       else                        /* next nearest is row below */
          366         inptr1 = input_data[inrow+1];
          367       outptr = output_data[outrow++];
          368 
          369       /* Special case for first column */
          370       thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
          371       nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
          372       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
          373       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
          374       lastcolsum = thiscolsum; thiscolsum = nextcolsum;
          375 
          376       for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
          377         /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
          378         /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
          379         nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
          380         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
          381         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
          382         lastcolsum = thiscolsum; thiscolsum = nextcolsum;
          383       }
          384 
          385       /* Special case for last column */
          386       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
          387       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
          388     }
          389     inrow++;
          390   }
          391 }
          392 
          393 
          394 /*
          395  * Module initialization routine for upsampling.
          396  */
          397 
          398 GLOBAL(void)
          399 jinit_upsampler (j_decompress_ptr cinfo)
          400 {
          401   my_upsample_ptr upsample;
          402   int ci;
          403   jpeg_component_info * compptr;
          404   boolean need_buffer, do_fancy;
          405   int h_in_group, v_in_group, h_out_group, v_out_group;
          406 
          407   upsample = (my_upsample_ptr)
          408     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
          409                                 SIZEOF(my_upsampler));
          410   cinfo->upsample = (struct jpeg_upsampler *) upsample;
          411   upsample->pub.start_pass = start_pass_upsample;
          412   upsample->pub.upsample = sep_upsample;
          413   upsample->pub.need_context_rows = FALSE; /* until we find out differently */
          414 
          415   if (cinfo->CCIR601_sampling)        /* this isn't supported */
          416     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
          417 
          418   /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
          419    * so don't ask for it.
          420    */
          421   do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
          422 
          423   /* Verify we can handle the sampling factors, select per-component methods,
          424    * and create storage as needed.
          425    */
          426   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
          427        ci++, compptr++) {
          428     /* Compute size of an "input group" after IDCT scaling.  This many samples
          429      * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
          430      */
          431     h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
          432                  cinfo->min_DCT_scaled_size;
          433     v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
          434                  cinfo->min_DCT_scaled_size;
          435     h_out_group = cinfo->max_h_samp_factor;
          436     v_out_group = cinfo->max_v_samp_factor;
          437     upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
          438     need_buffer = TRUE;
          439     if (! compptr->component_needed) {
          440       /* Don't bother to upsample an uninteresting component. */
          441       upsample->methods[ci] = noop_upsample;
          442       need_buffer = FALSE;
          443     } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
          444       /* Fullsize components can be processed without any work. */
          445       upsample->methods[ci] = fullsize_upsample;
          446       need_buffer = FALSE;
          447     } else if (h_in_group * 2 == h_out_group &&
          448                v_in_group == v_out_group) {
          449       /* Special cases for 2h1v upsampling */
          450       if (do_fancy && compptr->downsampled_width > 2)
          451         upsample->methods[ci] = h2v1_fancy_upsample;
          452       else
          453         upsample->methods[ci] = h2v1_upsample;
          454     } else if (h_in_group * 2 == h_out_group &&
          455                v_in_group * 2 == v_out_group) {
          456       /* Special cases for 2h2v upsampling */
          457       if (do_fancy && compptr->downsampled_width > 2) {
          458         upsample->methods[ci] = h2v2_fancy_upsample;
          459         upsample->pub.need_context_rows = TRUE;
          460       } else
          461         upsample->methods[ci] = h2v2_upsample;
          462     } else if ((h_out_group % h_in_group) == 0 &&
          463                (v_out_group % v_in_group) == 0) {
          464       /* Generic integral-factors upsampling method */
          465       upsample->methods[ci] = int_upsample;
          466       upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
          467       upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
          468     } else
          469       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
          470     if (need_buffer) {
          471       upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
          472         ((j_common_ptr) cinfo, JPOOL_IMAGE,
          473          (JDIMENSION) jround_up((long) cinfo->output_width,
          474                                 (long) cinfo->max_h_samp_factor),
          475          (JDIMENSION) cinfo->max_v_samp_factor);
          476     }
          477   }
          478 }