12cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane/*
22cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane * jdsample.c
32cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane *
4a73e870ad02de20c2b34cb3a5382c2846c2afbe3DRC * This file was part of the Independent JPEG Group's software:
5489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane * Copyright (C) 1991-1996, Thomas G. Lane.
6a6ef282a49f2d7d1b4d19cc89f63e81fd66b35b7DRC * libjpeg-turbo Modifications:
759a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
836a6eec93250e390d1028b3372078810b4428eafDRC * Copyright (C) 2010, D. R. Commander.
95ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC * Copyright (C) 2014, MIPS Technologies, Inc., California
100ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * Copyright (C) 2015, Google, Inc.
110ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * For conditions of distribution and use, see the accompanying README.ijg
120ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * file.
132cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane *
1488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * This file contains upsampling routines.
1536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
1636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Upsampling input data is counted in "row groups".  A row group
1736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
1836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * sample rows of each component.  Upsampling will normally produce
1936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * max_v_samp_factor pixel rows from each row group (but this could vary
2036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * if the upsampler is applying a scale factor of its own).
2188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *
2288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * An excellent reference for image resampling is
2388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *   Digital Image Warping, George Wolberg, 1990.
2488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
252cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane */
262cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
27ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC#include "jdsample.h"
2859a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman#include "jsimd.h"
2936a6eec93250e390d1028b3372078810b4428eafDRC#include "jpegcomp.h"
3036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
322cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
332cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane/*
3436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize for an upsampling pass.
352cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane */
362cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
37489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
3836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanestart_pass_upsample (j_decompress_ptr cinfo)
392cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane{
4036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
4136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Mark the conversion buffer empty */
4336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  upsample->next_row_out = cinfo->max_v_samp_factor;
4436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Initialize total-height counter for detecting bottom of image */
4536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  upsample->rows_to_go = cinfo->output_height;
462cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane}
472cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
482cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
492cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane/*
5036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Control routine to do upsampling (and color conversion).
5188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *
5236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * In this version we upsample each component independently.
5336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * We upsample one row group into the conversion buffer, then apply
5436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * color conversion a row at a time.
5536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
5636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
57489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
5836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanesep_upsample (j_decompress_ptr cinfo,
59e5eaf37440b8e337ab150c017df7c03faf846c51DRC              JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
60e5eaf37440b8e337ab150c017df7c03faf846c51DRC              JDIMENSION in_row_groups_avail,
61e5eaf37440b8e337ab150c017df7c03faf846c51DRC              JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
62e5eaf37440b8e337ab150c017df7c03faf846c51DRC              JDIMENSION out_rows_avail)
6336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
6436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
6536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int ci;
6636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  jpeg_component_info * compptr;
6736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JDIMENSION num_rows;
6836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
6936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Fill the conversion buffer, if it's empty */
7036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
7136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
72e5eaf37440b8e337ab150c017df7c03faf846c51DRC         ci++, compptr++) {
7336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Invoke per-component upsample method.  Notice we pass a POINTER
7436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       * to color_buf[ci], so that fullsize_upsample can change it.
7536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       */
7636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      (*upsample->methods[ci]) (cinfo, compptr,
77e5eaf37440b8e337ab150c017df7c03faf846c51DRC        input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
78e5eaf37440b8e337ab150c017df7c03faf846c51DRC        upsample->color_buf + ci);
7936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
8036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    upsample->next_row_out = 0;
8136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
8236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
8336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Color-convert and emit rows */
8436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
8536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* How many we have in the buffer: */
8636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
8736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Not more than the distance to the end of the image.  Need this test
8836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * in case the image height is not a multiple of max_v_samp_factor:
8936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   */
90e5eaf37440b8e337ab150c017df7c03faf846c51DRC  if (num_rows > upsample->rows_to_go)
9136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    num_rows = upsample->rows_to_go;
9236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* And not more than what the client can accept: */
9336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  out_rows_avail -= *out_row_ctr;
9436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (num_rows > out_rows_avail)
9536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    num_rows = out_rows_avail;
9636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
9736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
98e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                     (JDIMENSION) upsample->next_row_out,
99e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                     output_buf + *out_row_ctr,
100e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                     (int) num_rows);
10136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
10236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Adjust counts */
10336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  *out_row_ctr += num_rows;
10436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  upsample->rows_to_go -= num_rows;
10536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  upsample->next_row_out += num_rows;
10636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* When the buffer is emptied, declare this input row group consumed */
10736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (upsample->next_row_out >= cinfo->max_v_samp_factor)
10836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    (*in_row_group_ctr)++;
10936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
11036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
11136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
11236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
11336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * These are the routines invoked by sep_upsample to upsample pixel values
11436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * of a single component.  One row group is processed per call.
11536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
11636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
11736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
11836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
11936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For full-size components, we just make color_buf[ci] point at the
12036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * input buffer, and thus avoid copying any data.  Note that this is
12136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * safe only because sep_upsample doesn't declare the input row group
12236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * "consumed" until we are done color converting and emitting it.
12336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
12436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
125489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
12636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanefullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
127e5eaf37440b8e337ab150c017df7c03faf846c51DRC                   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
12836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
12936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  *output_data_ptr = input_data;
13036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
13136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
13236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
13336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
13436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This is a no-op version used for "uninteresting" components.
13536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * These components will not be referenced by color conversion.
13636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
13736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
138489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
13936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanenoop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
140e5eaf37440b8e337ab150c017df7c03faf846c51DRC               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
14136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
142e5eaf37440b8e337ab150c017df7c03faf846c51DRC  *output_data_ptr = NULL;      /* safety check */
14336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
14436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
14536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
14636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
14736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This version handles any integral sampling ratios.
1484a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane * This is not used for typical JPEG files, so it need not be fast.
14988aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * Nor, for that matter, is it particularly accurate: the algorithm is
15088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * simple replication of the input pixel onto the corresponding output
15188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * pixels.  The hi-falutin sampling literature refers to this as a
15288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * "box filter".  A box filter tends to introduce visible artifacts,
15388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * so if you are actually going to use 3:1 or 4:1 sampling ratios
15488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * you would be well advised to improve this code.
1552cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane */
1562cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
157489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
15836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneint_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
159e5eaf37440b8e337ab150c017df7c03faf846c51DRC              JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
1602cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane{
16136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
16236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY output_data = *output_data_ptr;
1634a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane  register JSAMPROW inptr, outptr;
1644a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane  register JSAMPLE invalue;
16536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register int h;
16636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPROW outend;
16736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int h_expand, v_expand;
1682cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane  int inrow, outrow;
1692cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
17036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  h_expand = upsample->h_expand[compptr->component_index];
17136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  v_expand = upsample->v_expand[compptr->component_index];
1722cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
17336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  inrow = outrow = 0;
17436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  while (outrow < cinfo->max_v_samp_factor) {
17536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Generate one output row with proper horizontal expansion */
17636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inptr = input_data[inrow];
17736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outptr = output_data[outrow];
17836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outend = outptr + cinfo->output_width;
17936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    while (outptr < outend) {
180e5eaf37440b8e337ab150c017df7c03faf846c51DRC      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
18136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      for (h = h_expand; h > 0; h--) {
182e5eaf37440b8e337ab150c017df7c03faf846c51DRC        *outptr++ = invalue;
1832cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane      }
1842cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane    }
18536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Generate any additional output rows by duplicating the first one */
18636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (v_expand > 1) {
18736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
188e5eaf37440b8e337ab150c017df7c03faf846c51DRC                        v_expand-1, cinfo->output_width);
18936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
19036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inrow++;
19136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outrow += v_expand;
1922cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane  }
1932cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane}
1942cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
1952cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
1962cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane/*
19736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
19836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * It's still a box filter.
19936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
20036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
201489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
20236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneh2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
203e5eaf37440b8e337ab150c017df7c03faf846c51DRC               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
20436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
20536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY output_data = *output_data_ptr;
20636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JSAMPROW inptr, outptr;
20736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JSAMPLE invalue;
20836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPROW outend;
20936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int inrow;
21036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
21136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
21236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inptr = input_data[inrow];
21336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outptr = output_data[inrow];
21436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outend = outptr + cinfo->output_width;
21536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    while (outptr < outend) {
216e5eaf37440b8e337ab150c017df7c03faf846c51DRC      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
21736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = invalue;
21836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = invalue;
21936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
22036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
22136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
22236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
22336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
22436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
22536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
22636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * It's still a box filter.
22736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
22836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
229489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
23036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneh2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
231e5eaf37440b8e337ab150c017df7c03faf846c51DRC               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
23236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
23336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY output_data = *output_data_ptr;
23436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JSAMPROW inptr, outptr;
23536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JSAMPLE invalue;
23636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPROW outend;
23736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int inrow, outrow;
23836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
23936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  inrow = outrow = 0;
24036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  while (outrow < cinfo->max_v_samp_factor) {
24136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inptr = input_data[inrow];
24236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outptr = output_data[outrow];
24336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outend = outptr + cinfo->output_width;
24436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    while (outptr < outend) {
245e5eaf37440b8e337ab150c017df7c03faf846c51DRC      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
24636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = invalue;
24736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = invalue;
24836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
24936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
250e5eaf37440b8e337ab150c017df7c03faf846c51DRC                      1, cinfo->output_width);
25136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inrow++;
25236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    outrow += 2;
25336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
25436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
25536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
25636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
25736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
25836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
25988aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *
26088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * The upsampling algorithm is linear interpolation between pixel centers,
26188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * also known as a "triangle filter".  This is a good compromise between
26288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
26388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane * of the way between input pixel centers.
26436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
26536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * A note about the "bias" calculations: when rounding fractional values to
26636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * integer, we do not want to always round 0.5 up to the next integer.
26736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * If we did that, we'd introduce a noticeable bias towards larger values.
26836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Instead, this code is arranged so that 0.5 will be rounded up or down at
26936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * alternate pixel locations (a simple ordered dither pattern).
2704a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane */
2714a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
272489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
27336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneh2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
274e5eaf37440b8e337ab150c017df7c03faf846c51DRC                     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
2754a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane{
27636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY output_data = *output_data_ptr;
2774a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane  register JSAMPROW inptr, outptr;
27888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  register int invalue;
27936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JDIMENSION colctr;
28088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  int inrow;
2814a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
28236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
28388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    inptr = input_data[inrow];
28488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    outptr = output_data[inrow];
28588aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    /* Special case for first column */
28688aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    invalue = GETJSAMPLE(*inptr++);
28788aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    *outptr++ = (JSAMPLE) invalue;
28888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
28988aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
29036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
29188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
29288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      invalue = GETJSAMPLE(*inptr++) * 3;
29336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
29488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
29588aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    }
2964a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
29788aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    /* Special case for last column */
29888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    invalue = GETJSAMPLE(*inptr);
29936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
30088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    *outptr++ = (JSAMPLE) invalue;
30188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  }
30288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane}
30388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
30488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
30588aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane/*
30636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
30736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Again a triangle filter; see comments for h2v1 case, above.
30888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane *
30936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * It is OK for us to reference the adjacent input rows because we demanded
31036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * context from the main buffer controller (see initialization code).
3114a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane */
3124a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
313489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
31436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneh2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
315e5eaf37440b8e337ab150c017df7c03faf846c51DRC                     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
31688aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane{
31736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY output_data = *output_data_ptr;
31888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  register JSAMPROW inptr0, inptr1, outptr;
31936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#if BITS_IN_JSAMPLE == 8
32088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  register int thiscolsum, lastcolsum, nextcolsum;
32188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane#else
32288aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  register INT32 thiscolsum, lastcolsum, nextcolsum;
32388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane#endif
32436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  register JDIMENSION colctr;
32588aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane  int inrow, outrow, v;
32688aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
32736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  inrow = outrow = 0;
32836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  while (outrow < cinfo->max_v_samp_factor) {
32988aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane    for (v = 0; v < 2; v++) {
33088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      /* inptr0 points to nearest input row, inptr1 points to next nearest */
33188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      inptr0 = input_data[inrow];
332e5eaf37440b8e337ab150c017df7c03faf846c51DRC      if (v == 0)               /* next nearest is row above */
333e5eaf37440b8e337ab150c017df7c03faf846c51DRC        inptr1 = input_data[inrow-1];
334e5eaf37440b8e337ab150c017df7c03faf846c51DRC      else                      /* next nearest is row below */
335e5eaf37440b8e337ab150c017df7c03faf846c51DRC        inptr1 = input_data[inrow+1];
33688aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      outptr = output_data[outrow++];
33788aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
33888aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      /* Special case for first column */
33988aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
34088aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
34188aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
34236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
34388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      lastcolsum = thiscolsum; thiscolsum = nextcolsum;
34488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
34536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
346e5eaf37440b8e337ab150c017df7c03faf846c51DRC        /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
347e5eaf37440b8e337ab150c017df7c03faf846c51DRC        /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
348e5eaf37440b8e337ab150c017df7c03faf846c51DRC        nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
349e5eaf37440b8e337ab150c017df7c03faf846c51DRC        *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
350e5eaf37440b8e337ab150c017df7c03faf846c51DRC        *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
351e5eaf37440b8e337ab150c017df7c03faf846c51DRC        lastcolsum = thiscolsum; thiscolsum = nextcolsum;
3524a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane      }
35388aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane
35488aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      /* Special case for last column */
35588aeed428fd820659e3ae00292cb84ecfc05dd23Thomas G. Lane      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
35636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
3574a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane    }
35836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    inrow++;
3594a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane  }
3604a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane}
3614a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
3624a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane
3634a6b7303643714d495b9d26742d8a156fd120936Thomas G. Lane/*
36436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Module initialization routine for upsampling.
3652cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane */
3662cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane
367489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(void)
36836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanejinit_upsampler (j_decompress_ptr cinfo)
3692cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane{
37036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  my_upsample_ptr upsample;
37136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int ci;
3722cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane  jpeg_component_info * compptr;
37336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  boolean need_buffer, do_fancy;
37436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int h_in_group, v_in_group, h_out_group, v_out_group;
37536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3760ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC  if (!cinfo->master->jinit_upsampler_no_alloc) {
3770ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    upsample = (my_upsample_ptr)
3780ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
3790ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC                                  sizeof(my_upsampler));
3800ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    cinfo->upsample = (struct jpeg_upsampler *) upsample;
3810ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    upsample->pub.start_pass = start_pass_upsample;
3820ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    upsample->pub.upsample = sep_upsample;
3830ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    upsample->pub.need_context_rows = FALSE; /* until we find out differently */
3840ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC  } else
3850ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    upsample = (my_upsample_ptr) cinfo->upsample;
38636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
387e5eaf37440b8e337ab150c017df7c03faf846c51DRC  if (cinfo->CCIR601_sampling)  /* this isn't supported */
38836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
38936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
39036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
39136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * so don't ask for it.
39236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   */
39349967cdb30edd0479a1719eedc1dace5ba078d3fDRC  do_fancy = cinfo->do_fancy_upsampling && cinfo->_min_DCT_scaled_size > 1;
39436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
39536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Verify we can handle the sampling factors, select per-component methods,
39636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * and create storage as needed.
39736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   */
39836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
39936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       ci++, compptr++) {
40036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Compute size of an "input group" after IDCT scaling.  This many samples
40136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
40236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
40349967cdb30edd0479a1719eedc1dace5ba078d3fDRC    h_in_group = (compptr->h_samp_factor * compptr->_DCT_scaled_size) /
404e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 cinfo->_min_DCT_scaled_size;
40549967cdb30edd0479a1719eedc1dace5ba078d3fDRC    v_in_group = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
406e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 cinfo->_min_DCT_scaled_size;
40736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    h_out_group = cinfo->max_h_samp_factor;
40836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    v_out_group = cinfo->max_v_samp_factor;
40936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
41036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    need_buffer = TRUE;
41136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (! compptr->component_needed) {
41236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Don't bother to upsample an uninteresting component. */
41336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      upsample->methods[ci] = noop_upsample;
41436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      need_buffer = FALSE;
41536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
41636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Fullsize components can be processed without any work. */
41736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      upsample->methods[ci] = fullsize_upsample;
41836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      need_buffer = FALSE;
41936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } else if (h_in_group * 2 == h_out_group &&
420e5eaf37440b8e337ab150c017df7c03faf846c51DRC               v_in_group == v_out_group) {
42136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Special cases for 2h1v upsampling */
42259a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman      if (do_fancy && compptr->downsampled_width > 2) {
423e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (jsimd_can_h2v1_fancy_upsample())
424e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
425e5eaf37440b8e337ab150c017df7c03faf846c51DRC        else
426e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = h2v1_fancy_upsample;
42759a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman      } else {
428e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (jsimd_can_h2v1_upsample())
429e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = jsimd_h2v1_upsample;
430e5eaf37440b8e337ab150c017df7c03faf846c51DRC        else
431e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = h2v1_upsample;
43259a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman      }
43336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } else if (h_in_group * 2 == h_out_group &&
434e5eaf37440b8e337ab150c017df7c03faf846c51DRC               v_in_group * 2 == v_out_group) {
43536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Special cases for 2h2v upsampling */
43636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (do_fancy && compptr->downsampled_width > 2) {
437e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (jsimd_can_h2v2_fancy_upsample())
438e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
439e5eaf37440b8e337ab150c017df7c03faf846c51DRC        else
440e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = h2v2_fancy_upsample;
441e5eaf37440b8e337ab150c017df7c03faf846c51DRC        upsample->pub.need_context_rows = TRUE;
44259a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman      } else {
443e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (jsimd_can_h2v2_upsample())
444e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = jsimd_h2v2_upsample;
445e5eaf37440b8e337ab150c017df7c03faf846c51DRC        else
446e5eaf37440b8e337ab150c017df7c03faf846c51DRC          upsample->methods[ci] = h2v2_upsample;
44759a3938b2e3f6c49730a57935f389078219a8fabPierre Ossman      }
44836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } else if ((h_out_group % h_in_group) == 0 &&
449e5eaf37440b8e337ab150c017df7c03faf846c51DRC               (v_out_group % v_in_group) == 0) {
45036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Generic integral-factors upsampling method */
4515ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC#if defined(__mips__)
4525ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC      if (jsimd_can_int_upsample())
4535ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC        upsample->methods[ci] = jsimd_int_upsample;
4545ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC      else
4555ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC#endif
4565ef463056ae22f24c3915ba7ab03eefd5bb6fde7DRC        upsample->methods[ci] = int_upsample;
45736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
45836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
45936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } else
46036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
4610ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC    if (need_buffer && !cinfo->master->jinit_upsampler_no_alloc) {
46236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
463e5eaf37440b8e337ab150c017df7c03faf846c51DRC        ((j_common_ptr) cinfo, JPOOL_IMAGE,
464e5eaf37440b8e337ab150c017df7c03faf846c51DRC         (JDIMENSION) jround_up((long) cinfo->output_width,
465e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                (long) cinfo->max_h_samp_factor),
466e5eaf37440b8e337ab150c017df7c03faf846c51DRC         (JDIMENSION) cinfo->max_v_samp_factor);
46736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
4682cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane  }
4692cbeb8abd92d5ad8a1bd415b51b3816213b15f3Thomas G. Lane}
470