jdmerge.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jdmerge.c (13916B)
       ---
            1 /*
            2  * jdmerge.c
            3  *
            4  * Copyright (C) 1994-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 code for merged upsampling/color conversion.
            9  *
           10  * This file combines functions from jdsample.c and jdcolor.c;
           11  * read those files first to understand what's going on.
           12  *
           13  * When the chroma components are to be upsampled by simple replication
           14  * (ie, box filtering), we can save some work in color conversion by
           15  * calculating all the output pixels corresponding to a pair of chroma
           16  * samples at one time.  In the conversion equations
           17  *        R = Y           + K1 * Cr
           18  *        G = Y + K2 * Cb + K3 * Cr
           19  *        B = Y + K4 * Cb
           20  * only the Y term varies among the group of pixels corresponding to a pair
           21  * of chroma samples, so the rest of the terms can be calculated just once.
           22  * At typical sampling ratios, this eliminates half or three-quarters of the
           23  * multiplications needed for color conversion.
           24  *
           25  * This file currently provides implementations for the following cases:
           26  *        YCbCr => RGB color conversion only.
           27  *        Sampling ratios of 2h1v or 2h2v.
           28  *        No scaling needed at upsample time.
           29  *        Corner-aligned (non-CCIR601) sampling alignment.
           30  * Other special cases could be added, but in most applications these are
           31  * the only common cases.  (For uncommon cases we fall back on the more
           32  * general code in jdsample.c and jdcolor.c.)
           33  */
           34 
           35 #define JPEG_INTERNALS
           36 #include "jinclude.h"
           37 #include "jpeglib.h"
           38 
           39 #ifdef UPSAMPLE_MERGING_SUPPORTED
           40 
           41 
           42 /* Private subobject */
           43 
           44 typedef struct {
           45   struct jpeg_upsampler pub;        /* public fields */
           46 
           47   /* Pointer to routine to do actual upsampling/conversion of one row group */
           48   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
           49                            JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
           50                            JSAMPARRAY output_buf));
           51 
           52   /* Private state for YCC->RGB conversion */
           53   int * Cr_r_tab;                /* => table for Cr to R conversion */
           54   int * Cb_b_tab;                /* => table for Cb to B conversion */
           55   INT32 * Cr_g_tab;                /* => table for Cr to G conversion */
           56   INT32 * Cb_g_tab;                /* => table for Cb to G conversion */
           57 
           58   /* For 2:1 vertical sampling, we produce two output rows at a time.
           59    * We need a "spare" row buffer to hold the second output row if the
           60    * application provides just a one-row buffer; we also use the spare
           61    * to discard the dummy last row if the image height is odd.
           62    */
           63   JSAMPROW spare_row;
           64   boolean spare_full;                /* T if spare buffer is occupied */
           65 
           66   JDIMENSION out_row_width;        /* samples per output row */
           67   JDIMENSION rows_to_go;        /* counts rows remaining in image */
           68 } my_upsampler;
           69 
           70 typedef my_upsampler * my_upsample_ptr;
           71 
           72 #define SCALEBITS        16        /* speediest right-shift on some machines */
           73 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
           74 #define FIX(x)                ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
           75 
           76 
           77 /*
           78  * Initialize tables for YCC->RGB colorspace conversion.
           79  * This is taken directly from jdcolor.c; see that file for more info.
           80  */
           81 
           82 LOCAL(void)
           83 build_ycc_rgb_table (j_decompress_ptr cinfo)
           84 {
           85   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
           86   int i;
           87   INT32 x;
           88   SHIFT_TEMPS
           89 
           90   upsample->Cr_r_tab = (int *)
           91     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
           92                                 (MAXJSAMPLE+1) * SIZEOF(int));
           93   upsample->Cb_b_tab = (int *)
           94     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
           95                                 (MAXJSAMPLE+1) * SIZEOF(int));
           96   upsample->Cr_g_tab = (INT32 *)
           97     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
           98                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
           99   upsample->Cb_g_tab = (INT32 *)
          100     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
          101                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
          102 
          103   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
          104     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
          105     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
          106     /* Cr=>R value is nearest int to 1.40200 * x */
          107     upsample->Cr_r_tab[i] = (int)
          108                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
          109     /* Cb=>B value is nearest int to 1.77200 * x */
          110     upsample->Cb_b_tab[i] = (int)
          111                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
          112     /* Cr=>G value is scaled-up -0.71414 * x */
          113     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
          114     /* Cb=>G value is scaled-up -0.34414 * x */
          115     /* We also add in ONE_HALF so that need not do it in inner loop */
          116     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
          117   }
          118 }
          119 
          120 
          121 /*
          122  * Initialize for an upsampling pass.
          123  */
          124 
          125 METHODDEF(void)
          126 start_pass_merged_upsample (j_decompress_ptr cinfo)
          127 {
          128   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          129 
          130   /* Mark the spare buffer empty */
          131   upsample->spare_full = FALSE;
          132   /* Initialize total-height counter for detecting bottom of image */
          133   upsample->rows_to_go = cinfo->output_height;
          134 }
          135 
          136 
          137 /*
          138  * Control routine to do upsampling (and color conversion).
          139  *
          140  * The control routine just handles the row buffering considerations.
          141  */
          142 
          143 METHODDEF(void)
          144 merged_2v_upsample (j_decompress_ptr cinfo,
          145                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
          146                     JDIMENSION in_row_groups_avail,
          147                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
          148                     JDIMENSION out_rows_avail)
          149 /* 2:1 vertical sampling case: may need a spare row. */
          150 {
          151   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          152   JSAMPROW work_ptrs[2];
          153   JDIMENSION num_rows;                /* number of rows returned to caller */
          154 
          155   if (upsample->spare_full) {
          156     /* If we have a spare row saved from a previous cycle, just return it. */
          157     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
          158                       1, upsample->out_row_width);
          159     num_rows = 1;
          160     upsample->spare_full = FALSE;
          161   } else {
          162     /* Figure number of rows to return to caller. */
          163     num_rows = 2;
          164     /* Not more than the distance to the end of the image. */
          165     if (num_rows > upsample->rows_to_go)
          166       num_rows = upsample->rows_to_go;
          167     /* And not more than what the client can accept: */
          168     out_rows_avail -= *out_row_ctr;
          169     if (num_rows > out_rows_avail)
          170       num_rows = out_rows_avail;
          171     /* Create output pointer array for upsampler. */
          172     work_ptrs[0] = output_buf[*out_row_ctr];
          173     if (num_rows > 1) {
          174       work_ptrs[1] = output_buf[*out_row_ctr + 1];
          175     } else {
          176       work_ptrs[1] = upsample->spare_row;
          177       upsample->spare_full = TRUE;
          178     }
          179     /* Now do the upsampling. */
          180     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
          181   }
          182 
          183   /* Adjust counts */
          184   *out_row_ctr += num_rows;
          185   upsample->rows_to_go -= num_rows;
          186   /* When the buffer is emptied, declare this input row group consumed */
          187   if (! upsample->spare_full)
          188     (*in_row_group_ctr)++;
          189 }
          190 
          191 
          192 METHODDEF(void)
          193 merged_1v_upsample (j_decompress_ptr cinfo,
          194                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
          195                     JDIMENSION in_row_groups_avail,
          196                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
          197                     JDIMENSION out_rows_avail)
          198 /* 1:1 vertical sampling case: much easier, never need a spare row. */
          199 {
          200   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          201 
          202   /* Just do the upsampling. */
          203   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
          204                          output_buf + *out_row_ctr);
          205   /* Adjust counts */
          206   (*out_row_ctr)++;
          207   (*in_row_group_ctr)++;
          208 }
          209 
          210 
          211 /*
          212  * These are the routines invoked by the control routines to do
          213  * the actual upsampling/conversion.  One row group is processed per call.
          214  *
          215  * Note: since we may be writing directly into application-supplied buffers,
          216  * we have to be honest about the output width; we can't assume the buffer
          217  * has been rounded up to an even width.
          218  */
          219 
          220 
          221 /*
          222  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
          223  */
          224 
          225 METHODDEF(void)
          226 h2v1_merged_upsample (j_decompress_ptr cinfo,
          227                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
          228                       JSAMPARRAY output_buf)
          229 {
          230   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          231   register int y, cred, cgreen, cblue;
          232   int cb, cr;
          233   register JSAMPROW outptr;
          234   JSAMPROW inptr0, inptr1, inptr2;
          235   JDIMENSION col;
          236   /* copy these pointers into registers if possible */
          237   register JSAMPLE * range_limit = cinfo->sample_range_limit;
          238   int * Crrtab = upsample->Cr_r_tab;
          239   int * Cbbtab = upsample->Cb_b_tab;
          240   INT32 * Crgtab = upsample->Cr_g_tab;
          241   INT32 * Cbgtab = upsample->Cb_g_tab;
          242   SHIFT_TEMPS
          243 
          244   inptr0 = input_buf[0][in_row_group_ctr];
          245   inptr1 = input_buf[1][in_row_group_ctr];
          246   inptr2 = input_buf[2][in_row_group_ctr];
          247   outptr = output_buf[0];
          248   /* Loop for each pair of output pixels */
          249   for (col = cinfo->output_width >> 1; col > 0; col--) {
          250     /* Do the chroma part of the calculation */
          251     cb = GETJSAMPLE(*inptr1++);
          252     cr = GETJSAMPLE(*inptr2++);
          253     cred = Crrtab[cr];
          254     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
          255     cblue = Cbbtab[cb];
          256     /* Fetch 2 Y values and emit 2 pixels */
          257     y  = GETJSAMPLE(*inptr0++);
          258     outptr[RGB_RED] =   range_limit[y + cred];
          259     outptr[RGB_GREEN] = range_limit[y + cgreen];
          260     outptr[RGB_BLUE] =  range_limit[y + cblue];
          261     outptr += RGB_PIXELSIZE;
          262     y  = GETJSAMPLE(*inptr0++);
          263     outptr[RGB_RED] =   range_limit[y + cred];
          264     outptr[RGB_GREEN] = range_limit[y + cgreen];
          265     outptr[RGB_BLUE] =  range_limit[y + cblue];
          266     outptr += RGB_PIXELSIZE;
          267   }
          268   /* If image width is odd, do the last output column separately */
          269   if (cinfo->output_width & 1) {
          270     cb = GETJSAMPLE(*inptr1);
          271     cr = GETJSAMPLE(*inptr2);
          272     cred = Crrtab[cr];
          273     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
          274     cblue = Cbbtab[cb];
          275     y  = GETJSAMPLE(*inptr0);
          276     outptr[RGB_RED] =   range_limit[y + cred];
          277     outptr[RGB_GREEN] = range_limit[y + cgreen];
          278     outptr[RGB_BLUE] =  range_limit[y + cblue];
          279   }
          280 }
          281 
          282 
          283 /*
          284  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
          285  */
          286 
          287 METHODDEF(void)
          288 h2v2_merged_upsample (j_decompress_ptr cinfo,
          289                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
          290                       JSAMPARRAY output_buf)
          291 {
          292   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
          293   register int y, cred, cgreen, cblue;
          294   int cb, cr;
          295   register JSAMPROW outptr0, outptr1;
          296   JSAMPROW inptr00, inptr01, inptr1, inptr2;
          297   JDIMENSION col;
          298   /* copy these pointers into registers if possible */
          299   register JSAMPLE * range_limit = cinfo->sample_range_limit;
          300   int * Crrtab = upsample->Cr_r_tab;
          301   int * Cbbtab = upsample->Cb_b_tab;
          302   INT32 * Crgtab = upsample->Cr_g_tab;
          303   INT32 * Cbgtab = upsample->Cb_g_tab;
          304   SHIFT_TEMPS
          305 
          306   inptr00 = input_buf[0][in_row_group_ctr*2];
          307   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
          308   inptr1 = input_buf[1][in_row_group_ctr];
          309   inptr2 = input_buf[2][in_row_group_ctr];
          310   outptr0 = output_buf[0];
          311   outptr1 = output_buf[1];
          312   /* Loop for each group of output pixels */
          313   for (col = cinfo->output_width >> 1; col > 0; col--) {
          314     /* Do the chroma part of the calculation */
          315     cb = GETJSAMPLE(*inptr1++);
          316     cr = GETJSAMPLE(*inptr2++);
          317     cred = Crrtab[cr];
          318     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
          319     cblue = Cbbtab[cb];
          320     /* Fetch 4 Y values and emit 4 pixels */
          321     y  = GETJSAMPLE(*inptr00++);
          322     outptr0[RGB_RED] =   range_limit[y + cred];
          323     outptr0[RGB_GREEN] = range_limit[y + cgreen];
          324     outptr0[RGB_BLUE] =  range_limit[y + cblue];
          325     outptr0 += RGB_PIXELSIZE;
          326     y  = GETJSAMPLE(*inptr00++);
          327     outptr0[RGB_RED] =   range_limit[y + cred];
          328     outptr0[RGB_GREEN] = range_limit[y + cgreen];
          329     outptr0[RGB_BLUE] =  range_limit[y + cblue];
          330     outptr0 += RGB_PIXELSIZE;
          331     y  = GETJSAMPLE(*inptr01++);
          332     outptr1[RGB_RED] =   range_limit[y + cred];
          333     outptr1[RGB_GREEN] = range_limit[y + cgreen];
          334     outptr1[RGB_BLUE] =  range_limit[y + cblue];
          335     outptr1 += RGB_PIXELSIZE;
          336     y  = GETJSAMPLE(*inptr01++);
          337     outptr1[RGB_RED] =   range_limit[y + cred];
          338     outptr1[RGB_GREEN] = range_limit[y + cgreen];
          339     outptr1[RGB_BLUE] =  range_limit[y + cblue];
          340     outptr1 += RGB_PIXELSIZE;
          341   }
          342   /* If image width is odd, do the last output column separately */
          343   if (cinfo->output_width & 1) {
          344     cb = GETJSAMPLE(*inptr1);
          345     cr = GETJSAMPLE(*inptr2);
          346     cred = Crrtab[cr];
          347     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
          348     cblue = Cbbtab[cb];
          349     y  = GETJSAMPLE(*inptr00);
          350     outptr0[RGB_RED] =   range_limit[y + cred];
          351     outptr0[RGB_GREEN] = range_limit[y + cgreen];
          352     outptr0[RGB_BLUE] =  range_limit[y + cblue];
          353     y  = GETJSAMPLE(*inptr01);
          354     outptr1[RGB_RED] =   range_limit[y + cred];
          355     outptr1[RGB_GREEN] = range_limit[y + cgreen];
          356     outptr1[RGB_BLUE] =  range_limit[y + cblue];
          357   }
          358 }
          359 
          360 
          361 /*
          362  * Module initialization routine for merged upsampling/color conversion.
          363  *
          364  * NB: this is called under the conditions determined by use_merged_upsample()
          365  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
          366  * of this module; no safety checks are made here.
          367  */
          368 
          369 GLOBAL(void)
          370 jinit_merged_upsampler (j_decompress_ptr cinfo)
          371 {
          372   my_upsample_ptr upsample;
          373 
          374   upsample = (my_upsample_ptr)
          375     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
          376                                 SIZEOF(my_upsampler));
          377   cinfo->upsample = (struct jpeg_upsampler *) upsample;
          378   upsample->pub.start_pass = start_pass_merged_upsample;
          379   upsample->pub.need_context_rows = FALSE;
          380 
          381   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
          382 
          383   if (cinfo->max_v_samp_factor == 2) {
          384     upsample->pub.upsample = merged_2v_upsample;
          385     upsample->upmethod = h2v2_merged_upsample;
          386     /* Allocate a spare row buffer */
          387     upsample->spare_row = (JSAMPROW)
          388       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
          389                 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
          390   } else {
          391     upsample->pub.upsample = merged_1v_upsample;
          392     upsample->upmethod = h2v1_merged_upsample;
          393     /* No spare row needed */
          394     upsample->spare_row = NULL;
          395   }
          396 
          397   build_ycc_rgb_table(cinfo);
          398 }
          399 
          400 #endif /* UPSAMPLE_MERGING_SUPPORTED */