LCOV - code coverage report
Current view: directory - media/libjpeg - jdmerge.c (source / functions) Found Hit Coverage
Test: app.info Lines: 94 0 0.0 %
Date: 2012-06-02 Functions: 7 0 0.0 %

       1                 : /*
       2                 :  * jdmerge.c
       3                 :  *
       4                 :  * Copyright (C) 1994-1996, Thomas G. Lane.
       5                 :  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
       6                 :  * Copyright (C) 2009, 2011, D. R. Commander.
       7                 :  * This file is part of the Independent JPEG Group's software.
       8                 :  * For conditions of distribution and use, see the accompanying README file.
       9                 :  *
      10                 :  * This file contains code for merged upsampling/color conversion.
      11                 :  *
      12                 :  * This file combines functions from jdsample.c and jdcolor.c;
      13                 :  * read those files first to understand what's going on.
      14                 :  *
      15                 :  * When the chroma components are to be upsampled by simple replication
      16                 :  * (ie, box filtering), we can save some work in color conversion by
      17                 :  * calculating all the output pixels corresponding to a pair of chroma
      18                 :  * samples at one time.  In the conversion equations
      19                 :  *      R = Y           + K1 * Cr
      20                 :  *      G = Y + K2 * Cb + K3 * Cr
      21                 :  *      B = Y + K4 * Cb
      22                 :  * only the Y term varies among the group of pixels corresponding to a pair
      23                 :  * of chroma samples, so the rest of the terms can be calculated just once.
      24                 :  * At typical sampling ratios, this eliminates half or three-quarters of the
      25                 :  * multiplications needed for color conversion.
      26                 :  *
      27                 :  * This file currently provides implementations for the following cases:
      28                 :  *      YCbCr => RGB color conversion only.
      29                 :  *      Sampling ratios of 2h1v or 2h2v.
      30                 :  *      No scaling needed at upsample time.
      31                 :  *      Corner-aligned (non-CCIR601) sampling alignment.
      32                 :  * Other special cases could be added, but in most applications these are
      33                 :  * the only common cases.  (For uncommon cases we fall back on the more
      34                 :  * general code in jdsample.c and jdcolor.c.)
      35                 :  */
      36                 : 
      37                 : #define JPEG_INTERNALS
      38                 : #include "jinclude.h"
      39                 : #include "jpeglib.h"
      40                 : #include "jsimd.h"
      41                 : #include "config.h"
      42                 : 
      43                 : #ifdef UPSAMPLE_MERGING_SUPPORTED
      44                 : 
      45                 : 
      46                 : /* Private subobject */
      47                 : 
      48                 : typedef struct {
      49                 :   struct jpeg_upsampler pub;    /* public fields */
      50                 : 
      51                 :   /* Pointer to routine to do actual upsampling/conversion of one row group */
      52                 :   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
      53                 :                            JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
      54                 :                            JSAMPARRAY output_buf));
      55                 : 
      56                 :   /* Private state for YCC->RGB conversion */
      57                 :   int * Cr_r_tab;               /* => table for Cr to R conversion */
      58                 :   int * Cb_b_tab;               /* => table for Cb to B conversion */
      59                 :   INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
      60                 :   INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
      61                 : 
      62                 :   /* For 2:1 vertical sampling, we produce two output rows at a time.
      63                 :    * We need a "spare" row buffer to hold the second output row if the
      64                 :    * application provides just a one-row buffer; we also use the spare
      65                 :    * to discard the dummy last row if the image height is odd.
      66                 :    */
      67                 :   JSAMPROW spare_row;
      68                 :   boolean spare_full;           /* T if spare buffer is occupied */
      69                 : 
      70                 :   JDIMENSION out_row_width;     /* samples per output row */
      71                 :   JDIMENSION rows_to_go;        /* counts rows remaining in image */
      72                 : } my_upsampler;
      73                 : 
      74                 : typedef my_upsampler * my_upsample_ptr;
      75                 : 
      76                 : #define SCALEBITS       16      /* speediest right-shift on some machines */
      77                 : #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
      78                 : #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
      79                 : 
      80                 : 
      81                 : /* Include inline routines for colorspace extensions */
      82                 : 
      83                 : #include "jdmrgext.c"
      84                 : #undef RGB_RED
      85                 : #undef RGB_GREEN
      86                 : #undef RGB_BLUE
      87                 : #undef RGB_PIXELSIZE
      88                 : 
      89                 : #define RGB_RED EXT_RGB_RED
      90                 : #define RGB_GREEN EXT_RGB_GREEN
      91                 : #define RGB_BLUE EXT_RGB_BLUE
      92                 : #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
      93                 : #define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
      94                 : #define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
      95                 : #include "jdmrgext.c"
      96                 : #undef RGB_RED
      97                 : #undef RGB_GREEN
      98                 : #undef RGB_BLUE
      99                 : #undef RGB_PIXELSIZE
     100                 : #undef h2v1_merged_upsample_internal
     101                 : #undef h2v2_merged_upsample_internal
     102                 : 
     103                 : #define RGB_RED EXT_RGBX_RED
     104                 : #define RGB_GREEN EXT_RGBX_GREEN
     105                 : #define RGB_BLUE EXT_RGBX_BLUE
     106                 : #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
     107                 : #define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
     108                 : #define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
     109                 : #include "jdmrgext.c"
     110                 : #undef RGB_RED
     111                 : #undef RGB_GREEN
     112                 : #undef RGB_BLUE
     113                 : #undef RGB_PIXELSIZE
     114                 : #undef h2v1_merged_upsample_internal
     115                 : #undef h2v2_merged_upsample_internal
     116                 : 
     117                 : #define RGB_RED EXT_BGR_RED
     118                 : #define RGB_GREEN EXT_BGR_GREEN
     119                 : #define RGB_BLUE EXT_BGR_BLUE
     120                 : #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
     121                 : #define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
     122                 : #define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
     123                 : #include "jdmrgext.c"
     124                 : #undef RGB_RED
     125                 : #undef RGB_GREEN
     126                 : #undef RGB_BLUE
     127                 : #undef RGB_PIXELSIZE
     128                 : #undef h2v1_merged_upsample_internal
     129                 : #undef h2v2_merged_upsample_internal
     130                 : 
     131                 : #define RGB_RED EXT_BGRX_RED
     132                 : #define RGB_GREEN EXT_BGRX_GREEN
     133                 : #define RGB_BLUE EXT_BGRX_BLUE
     134                 : #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
     135                 : #define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
     136                 : #define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
     137                 : #include "jdmrgext.c"
     138                 : #undef RGB_RED
     139                 : #undef RGB_GREEN
     140                 : #undef RGB_BLUE
     141                 : #undef RGB_PIXELSIZE
     142                 : #undef h2v1_merged_upsample_internal
     143                 : #undef h2v2_merged_upsample_internal
     144                 : 
     145                 : #define RGB_RED EXT_XBGR_RED
     146                 : #define RGB_GREEN EXT_XBGR_GREEN
     147                 : #define RGB_BLUE EXT_XBGR_BLUE
     148                 : #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
     149                 : #define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
     150                 : #define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
     151                 : #include "jdmrgext.c"
     152                 : #undef RGB_RED
     153                 : #undef RGB_GREEN
     154                 : #undef RGB_BLUE
     155                 : #undef RGB_PIXELSIZE
     156                 : #undef h2v1_merged_upsample_internal
     157                 : #undef h2v2_merged_upsample_internal
     158                 : 
     159                 : #define RGB_RED EXT_XRGB_RED
     160                 : #define RGB_GREEN EXT_XRGB_GREEN
     161                 : #define RGB_BLUE EXT_XRGB_BLUE
     162                 : #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
     163                 : #define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
     164                 : #define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
     165                 : #include "jdmrgext.c"
     166                 : #undef RGB_RED
     167                 : #undef RGB_GREEN
     168                 : #undef RGB_BLUE
     169                 : #undef RGB_PIXELSIZE
     170                 : #undef h2v1_merged_upsample_internal
     171                 : #undef h2v2_merged_upsample_internal
     172                 : 
     173                 : 
     174                 : /*
     175                 :  * Initialize tables for YCC->RGB colorspace conversion.
     176                 :  * This is taken directly from jdcolor.c; see that file for more info.
     177                 :  */
     178                 : 
     179                 : LOCAL(void)
     180               0 : build_ycc_rgb_table (j_decompress_ptr cinfo)
     181                 : {
     182               0 :   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     183                 :   int i;
     184                 :   INT32 x;
     185                 :   SHIFT_TEMPS
     186                 : 
     187               0 :   upsample->Cr_r_tab = (int *)
     188               0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     189                 :                                 (MAXJSAMPLE+1) * SIZEOF(int));
     190               0 :   upsample->Cb_b_tab = (int *)
     191               0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     192                 :                                 (MAXJSAMPLE+1) * SIZEOF(int));
     193               0 :   upsample->Cr_g_tab = (INT32 *)
     194               0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     195                 :                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
     196               0 :   upsample->Cb_g_tab = (INT32 *)
     197               0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     198                 :                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
     199                 : 
     200               0 :   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
     201                 :     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
     202                 :     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
     203                 :     /* Cr=>R value is nearest int to 1.40200 * x */
     204               0 :     upsample->Cr_r_tab[i] = (int)
     205               0 :                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
     206                 :     /* Cb=>B value is nearest int to 1.77200 * x */
     207               0 :     upsample->Cb_b_tab[i] = (int)
     208               0 :                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
     209                 :     /* Cr=>G value is scaled-up -0.71414 * x */
     210               0 :     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
     211                 :     /* Cb=>G value is scaled-up -0.34414 * x */
     212                 :     /* We also add in ONE_HALF so that need not do it in inner loop */
     213               0 :     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
     214                 :   }
     215               0 : }
     216                 : 
     217                 : 
     218                 : /*
     219                 :  * Initialize for an upsampling pass.
     220                 :  */
     221                 : 
     222                 : METHODDEF(void)
     223               0 : start_pass_merged_upsample (j_decompress_ptr cinfo)
     224                 : {
     225               0 :   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     226                 : 
     227                 :   /* Mark the spare buffer empty */
     228               0 :   upsample->spare_full = FALSE;
     229                 :   /* Initialize total-height counter for detecting bottom of image */
     230               0 :   upsample->rows_to_go = cinfo->output_height;
     231               0 : }
     232                 : 
     233                 : 
     234                 : /*
     235                 :  * Control routine to do upsampling (and color conversion).
     236                 :  *
     237                 :  * The control routine just handles the row buffering considerations.
     238                 :  */
     239                 : 
     240                 : METHODDEF(void)
     241               0 : merged_2v_upsample (j_decompress_ptr cinfo,
     242                 :                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
     243                 :                     JDIMENSION in_row_groups_avail,
     244                 :                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
     245                 :                     JDIMENSION out_rows_avail)
     246                 : /* 2:1 vertical sampling case: may need a spare row. */
     247                 : {
     248               0 :   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     249                 :   JSAMPROW work_ptrs[2];
     250                 :   JDIMENSION num_rows;          /* number of rows returned to caller */
     251                 : 
     252               0 :   if (upsample->spare_full) {
     253                 :     /* If we have a spare row saved from a previous cycle, just return it. */
     254               0 :     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
     255                 :                       1, upsample->out_row_width);
     256               0 :     num_rows = 1;
     257               0 :     upsample->spare_full = FALSE;
     258                 :   } else {
     259                 :     /* Figure number of rows to return to caller. */
     260               0 :     num_rows = 2;
     261                 :     /* Not more than the distance to the end of the image. */
     262               0 :     if (num_rows > upsample->rows_to_go)
     263               0 :       num_rows = upsample->rows_to_go;
     264                 :     /* And not more than what the client can accept: */
     265               0 :     out_rows_avail -= *out_row_ctr;
     266               0 :     if (num_rows > out_rows_avail)
     267               0 :       num_rows = out_rows_avail;
     268                 :     /* Create output pointer array for upsampler. */
     269               0 :     work_ptrs[0] = output_buf[*out_row_ctr];
     270               0 :     if (num_rows > 1) {
     271               0 :       work_ptrs[1] = output_buf[*out_row_ctr + 1];
     272                 :     } else {
     273               0 :       work_ptrs[1] = upsample->spare_row;
     274               0 :       upsample->spare_full = TRUE;
     275                 :     }
     276                 :     /* Now do the upsampling. */
     277               0 :     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
     278                 :   }
     279                 : 
     280                 :   /* Adjust counts */
     281               0 :   *out_row_ctr += num_rows;
     282               0 :   upsample->rows_to_go -= num_rows;
     283                 :   /* When the buffer is emptied, declare this input row group consumed */
     284               0 :   if (! upsample->spare_full)
     285               0 :     (*in_row_group_ctr)++;
     286               0 : }
     287                 : 
     288                 : 
     289                 : METHODDEF(void)
     290               0 : merged_1v_upsample (j_decompress_ptr cinfo,
     291                 :                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
     292                 :                     JDIMENSION in_row_groups_avail,
     293                 :                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
     294                 :                     JDIMENSION out_rows_avail)
     295                 : /* 1:1 vertical sampling case: much easier, never need a spare row. */
     296                 : {
     297               0 :   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     298                 : 
     299                 :   /* Just do the upsampling. */
     300               0 :   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
     301               0 :                          output_buf + *out_row_ctr);
     302                 :   /* Adjust counts */
     303               0 :   (*out_row_ctr)++;
     304               0 :   (*in_row_group_ctr)++;
     305               0 : }
     306                 : 
     307                 : 
     308                 : /*
     309                 :  * These are the routines invoked by the control routines to do
     310                 :  * the actual upsampling/conversion.  One row group is processed per call.
     311                 :  *
     312                 :  * Note: since we may be writing directly into application-supplied buffers,
     313                 :  * we have to be honest about the output width; we can't assume the buffer
     314                 :  * has been rounded up to an even width.
     315                 :  */
     316                 : 
     317                 : 
     318                 : /*
     319                 :  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
     320                 :  */
     321                 : 
     322                 : METHODDEF(void)
     323               0 : h2v1_merged_upsample (j_decompress_ptr cinfo,
     324                 :                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
     325                 :                       JSAMPARRAY output_buf)
     326                 : {
     327               0 :   switch (cinfo->out_color_space) {
     328                 :     case JCS_EXT_RGB:
     329                 :       extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     330                 :                                            output_buf);
     331               0 :       break;
     332                 :     case JCS_EXT_RGBX:
     333                 :     case JCS_EXT_RGBA:
     334                 :       extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     335                 :                                             output_buf);
     336               0 :       break;
     337                 :     case JCS_EXT_BGR:
     338                 :       extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     339                 :                                            output_buf);
     340               0 :       break;
     341                 :     case JCS_EXT_BGRX:
     342                 :     case JCS_EXT_BGRA:
     343                 :       extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     344                 :                                             output_buf);
     345               0 :       break;
     346                 :     case JCS_EXT_XBGR:
     347                 :     case JCS_EXT_ABGR:
     348                 :       extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     349                 :                                             output_buf);
     350               0 :       break;
     351                 :     case JCS_EXT_XRGB:
     352                 :     case JCS_EXT_ARGB:
     353                 :       extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     354                 :                                             output_buf);
     355               0 :       break;
     356                 :     default:
     357                 :       h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     358                 :                                     output_buf);
     359               0 :       break;
     360                 :   }
     361               0 : }
     362                 : 
     363                 : 
     364                 : /*
     365                 :  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
     366                 :  */
     367                 : 
     368                 : METHODDEF(void)
     369               0 : h2v2_merged_upsample (j_decompress_ptr cinfo,
     370                 :                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
     371                 :                       JSAMPARRAY output_buf)
     372                 : {
     373               0 :   switch (cinfo->out_color_space) {
     374                 :     case JCS_EXT_RGB:
     375                 :       extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     376                 :                                            output_buf);
     377               0 :       break;
     378                 :     case JCS_EXT_RGBX:
     379                 :     case JCS_EXT_RGBA:
     380                 :       extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     381                 :                                             output_buf);
     382               0 :       break;
     383                 :     case JCS_EXT_BGR:
     384                 :       extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     385                 :                                            output_buf);
     386               0 :       break;
     387                 :     case JCS_EXT_BGRX:
     388                 :     case JCS_EXT_BGRA:
     389                 :       extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     390                 :                                             output_buf);
     391               0 :       break;
     392                 :     case JCS_EXT_XBGR:
     393                 :     case JCS_EXT_ABGR:
     394                 :       extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     395                 :                                             output_buf);
     396               0 :       break;
     397                 :     case JCS_EXT_XRGB:
     398                 :     case JCS_EXT_ARGB:
     399                 :       extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     400                 :                                             output_buf);
     401               0 :       break;
     402                 :     default:
     403                 :       h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
     404                 :                                     output_buf);
     405               0 :       break;
     406                 :   }
     407               0 : }
     408                 : 
     409                 : 
     410                 : /*
     411                 :  * Module initialization routine for merged upsampling/color conversion.
     412                 :  *
     413                 :  * NB: this is called under the conditions determined by use_merged_upsample()
     414                 :  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
     415                 :  * of this module; no safety checks are made here.
     416                 :  */
     417                 : 
     418                 : GLOBAL(void)
     419               0 : jinit_merged_upsampler (j_decompress_ptr cinfo)
     420                 : {
     421                 :   my_upsample_ptr upsample;
     422                 : 
     423               0 :   upsample = (my_upsample_ptr)
     424               0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     425                 :                                 SIZEOF(my_upsampler));
     426               0 :   cinfo->upsample = (struct jpeg_upsampler *) upsample;
     427               0 :   upsample->pub.start_pass = start_pass_merged_upsample;
     428               0 :   upsample->pub.need_context_rows = FALSE;
     429                 : 
     430               0 :   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
     431                 : 
     432               0 :   if (cinfo->max_v_samp_factor == 2) {
     433               0 :     upsample->pub.upsample = merged_2v_upsample;
     434               0 :     if (jsimd_can_h2v2_merged_upsample())
     435               0 :       upsample->upmethod = jsimd_h2v2_merged_upsample;
     436                 :     else
     437               0 :       upsample->upmethod = h2v2_merged_upsample;
     438                 :     /* Allocate a spare row buffer */
     439               0 :     upsample->spare_row = (JSAMPROW)
     440               0 :       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     441                 :                 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
     442                 :   } else {
     443               0 :     upsample->pub.upsample = merged_1v_upsample;
     444               0 :     if (jsimd_can_h2v1_merged_upsample())
     445               0 :       upsample->upmethod = jsimd_h2v1_merged_upsample;
     446                 :     else
     447               0 :       upsample->upmethod = h2v1_merged_upsample;
     448                 :     /* No spare row needed */
     449               0 :     upsample->spare_row = NULL;
     450                 :   }
     451                 : 
     452               0 :   build_ycc_rgb_table(cinfo);
     453               0 : }
     454                 : 
     455                 : #endif /* UPSAMPLE_MERGING_SUPPORTED */

Generated by: LCOV version 1.7