LCOV - code coverage report
Current view: top level - media/libjpeg - jdsample.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 197 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13