/*
 * jdmerge.c
 *
 * This file was part of the Independent JPEG Group's software:
 * Copyright (C) 1994-1996, Thomas G. Lane.
 * libjpeg-turbo Modifications:
 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 * Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
 * Copyright (C) 2013, Linaro Limited.
 * For conditions of distribution and use, see the accompanying README.ijg
 * file.
 *
 * This file contains code for merged upsampling/color conversion.
 *
 * This file combines functions from jdsample.c and jdcolor.c;
 * read those files first to understand what's going on.
 *
 * When the chroma components are to be upsampled by simple replication
 * (ie, box filtering), we can save some work in color conversion by
 * calculating all the output pixels corresponding to a pair of chroma
 * samples at one time.  In the conversion equations
 *      R = Y           + K1 * Cr
 *      G = Y + K2 * Cb + K3 * Cr
 *      B = Y + K4 * Cb
 * only the Y term varies among the group of pixels corresponding to a pair
 * of chroma samples, so the rest of the terms can be calculated just once.
 * At typical sampling ratios, this eliminates half or three-quarters of the
 * multiplications needed for color conversion.
 *
 * This file currently provides implementations for the following cases:
 *      YCbCr => RGB color conversion only.
 *      Sampling ratios of 2h1v or 2h2v.
 *      No scaling needed at upsample time.
 *      Corner-aligned (non-CCIR601) sampling alignment.
 * Other special cases could be added, but in most applications these are
 * the only common cases.  (For uncommon cases we fall back on the more
 * general code in jdsample.c and jdcolor.c.)
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jsimd.h"
#include "jconfigint.h"

#ifdef UPSAMPLE_MERGING_SUPPORTED


/* Private subobject */

typedef struct {
  struct jpeg_upsampler pub;    /* public fields */

  /* Pointer to routine to do actual upsampling/conversion of one row group */
  void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                    JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);

  /* Private state for YCC->RGB conversion */
  int *Cr_r_tab;                /* => table for Cr to R conversion */
  int *Cb_b_tab;                /* => table for Cb to B conversion */
  JLONG *Cr_g_tab;              /* => table for Cr to G conversion */
  JLONG *Cb_g_tab;              /* => table for Cb to G conversion */

  /* For 2:1 vertical sampling, we produce two output rows at a time.
   * We need a "spare" row buffer to hold the second output row if the
   * application provides just a one-row buffer; we also use the spare
   * to discard the dummy last row if the image height is odd.
   */
  JSAMPROW spare_row;
  boolean spare_full;           /* T if spare buffer is occupied */

  JDIMENSION out_row_width;     /* samples per output row */
  JDIMENSION rows_to_go;        /* counts rows remaining in image */
} my_upsampler;

typedef my_upsampler *my_upsample_ptr;

#define SCALEBITS       16      /* speediest right-shift on some machines */
#define ONE_HALF        ((JLONG)1 << (SCALEBITS - 1))
#define FIX(x)          ((JLONG)((x) * (1L << SCALEBITS) + 0.5))


/* Include inline routines for colorspace extensions */

#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_PIXELSIZE

#define RGB_RED EXT_RGB_RED
#define RGB_GREEN EXT_RGB_GREEN
#define RGB_BLUE EXT_RGB_BLUE
#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
#define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal

#define RGB_RED EXT_RGBX_RED
#define RGB_GREEN EXT_RGBX_GREEN
#define RGB_BLUE EXT_RGBX_BLUE
#define RGB_ALPHA 3
#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
#define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_ALPHA
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal

#define RGB_RED EXT_BGR_RED
#define RGB_GREEN EXT_BGR_GREEN
#define RGB_BLUE EXT_BGR_BLUE
#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
#define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal

#define RGB_RED EXT_BGRX_RED
#define RGB_GREEN EXT_BGRX_GREEN
#define RGB_BLUE EXT_BGRX_BLUE
#define RGB_ALPHA 3
#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
#define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_ALPHA
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal

#define RGB_RED EXT_XBGR_RED
#define RGB_GREEN EXT_XBGR_GREEN
#define RGB_BLUE EXT_XBGR_BLUE
#define RGB_ALPHA 0
#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
#define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_ALPHA
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal

#define RGB_RED EXT_XRGB_RED
#define RGB_GREEN EXT_XRGB_GREEN
#define RGB_BLUE EXT_XRGB_BLUE
#define RGB_ALPHA 0
#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
#define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
#define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
#include "jdmrgext.c"
#undef RGB_RED
#undef RGB_GREEN
#undef RGB_BLUE
#undef RGB_ALPHA
#undef RGB_PIXELSIZE
#undef h2v1_merged_upsample_internal
#undef h2v2_merged_upsample_internal


/*
 * Initialize tables for YCC->RGB colorspace conversion.
 * This is taken directly from jdcolor.c; see that file for more info.
 */

LOCAL(void)
build_ycc_rgb_table(j_decompress_ptr cinfo)
{
  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
  int i;
  JLONG x;
  SHIFT_TEMPS

  upsample->Cr_r_tab = (int *)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                (MAXJSAMPLE + 1) * sizeof(int));
  upsample->Cb_b_tab = (int *)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                (MAXJSAMPLE + 1) * sizeof(int));
  upsample->Cr_g_tab = (JLONG *)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                (MAXJSAMPLE + 1) * sizeof(JLONG));
  upsample->Cb_g_tab = (JLONG *)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                (MAXJSAMPLE + 1) * sizeof(JLONG));

  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    /* Cr=>R value is nearest int to 1.40200 * x */
    upsample->Cr_r_tab[i] = (int)
                    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    /* Cb=>B value is nearest int to 1.77200 * x */
    upsample->Cb_b_tab[i] = (int)
                    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
    /* Cr=>G value is scaled-up -0.71414 * x */
    upsample->Cr_g_tab[i] = (-FIX(0.71414)) * x;
    /* Cb=>G value is scaled-up -0.34414 * x */
    /* We also add in ONE_HALF so that need not do it in inner loop */
    upsample->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
  }
}


/*
 * Initialize for an upsampling pass.
 */

METHODDEF(void)
start_pass_merged_upsample(j_decompress_ptr cinfo)
{
  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;

  /* Mark the spare buffer empty */
  upsample->spare_full = FALSE;
  /* Initialize total-height counter for detecting bottom of image */
  upsample->rows_to_go = cinfo->output_height;
}


/*
 * Control routine to do upsampling (and color conversion).
 *
 * The control routine just handles the row buffering considerations.
 */

METHODDEF(void)
merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                   JDIMENSION *in_row_group_ctr,
                   JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
                   JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
/* 2:1 vertical sampling case: may need a spare row. */
{
  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
  JSAMPROW work_ptrs[2];
  JDIMENSION num_rows;          /* number of rows returned to caller */

  if (upsample->spare_full) {
    /* If we have a spare row saved from a previous cycle, just return it. */
    JDIMENSION size = upsample->out_row_width;
    if (cinfo->out_color_space == JCS_RGB565)
      size = cinfo->output_width * 2;
    jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0, 1,
                      size);
    num_rows = 1;
    upsample->spare_full = FALSE;
  } else {
    /* Figure number of rows to return to caller. */
    num_rows = 2;
    /* Not more than the distance to the end of the image. */
    if (num_rows > upsample->rows_to_go)
      num_rows = upsample->rows_to_go;
    /* And not more than what the client can accept: */
    out_rows_avail -= *out_row_ctr;
    if (num_rows > out_rows_avail)
      num_rows = out_rows_avail;
    /* Create output pointer array for upsampler. */
    work_ptrs[0] = output_buf[*out_row_ctr];
    if (num_rows > 1) {
      work_ptrs[1] = output_buf[*out_row_ctr + 1];
    } else {
      work_ptrs[1] = upsample->spare_row;
      upsample->spare_full = TRUE;
    }
    /* Now do the upsampling. */
    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  }

  /* Adjust counts */
  *out_row_ctr += num_rows;
  upsample->rows_to_go -= num_rows;
  /* When the buffer is emptied, declare this input row group consumed */
  if (!upsample->spare_full)
    (*in_row_group_ctr)++;
}


METHODDEF(void)
merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                   JDIMENSION *in_row_group_ctr,
                   JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
                   JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
/* 1:1 vertical sampling case: much easier, never need a spare row. */
{
  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;

  /* Just do the upsampling. */
  (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
                         output_buf + *out_row_ctr);
  /* Adjust counts */
  (*out_row_ctr)++;
  (*in_row_group_ctr)++;
}


/*
 * These are the routines invoked by the control routines to do
 * the actual upsampling/conversion.  One row group is processed per call.
 *
 * Note: since we may be writing directly into application-supplied buffers,
 * we have to be honest about the output width; we can't assume the buffer
 * has been rounded up to an even width.
 */


/*
 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
 */

METHODDEF(void)
h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                     JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  switch (cinfo->out_color_space) {
  case JCS_EXT_RGB:
    extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                         output_buf);
    break;
  case JCS_EXT_RGBX:
  case JCS_EXT_RGBA:
    extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_BGR:
    extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                         output_buf);
    break;
  case JCS_EXT_BGRX:
  case JCS_EXT_BGRA:
    extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_XBGR:
  case JCS_EXT_ABGR:
    extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_XRGB:
  case JCS_EXT_ARGB:
    extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  default:
    h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                  output_buf);
    break;
  }
}


/*
 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
 */

METHODDEF(void)
h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                     JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  switch (cinfo->out_color_space) {
  case JCS_EXT_RGB:
    extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                         output_buf);
    break;
  case JCS_EXT_RGBX:
  case JCS_EXT_RGBA:
    extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_BGR:
    extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                         output_buf);
    break;
  case JCS_EXT_BGRX:
  case JCS_EXT_BGRA:
    extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_XBGR:
  case JCS_EXT_ABGR:
    extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  case JCS_EXT_XRGB:
  case JCS_EXT_ARGB:
    extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                          output_buf);
    break;
  default:
    h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
                                  output_buf);
    break;
  }
}


/*
 * RGB565 conversion
 */

#define PACK_SHORT_565_LE(r, g, b)  ((((r) << 8) & 0xF800) | \
                                     (((g) << 3) & 0x7E0) | ((b) >> 3))
#define PACK_SHORT_565_BE(r, g, b)  (((r) & 0xF8) | ((g) >> 5) | \
                                     (((g) << 11) & 0xE000) | \
                                     (((b) << 5) & 0x1F00))

#define PACK_TWO_PIXELS_LE(l, r)    ((r << 16) | l)
#define PACK_TWO_PIXELS_BE(l, r)    ((l << 16) | r)

#define PACK_NEED_ALIGNMENT(ptr)    (((size_t)(ptr)) & 3)

#define WRITE_TWO_PIXELS_LE(addr, pixels) { \
  ((INT16 *)(addr))[0] = (INT16)(pixels); \
  ((INT16 *)(addr))[1] = (INT16)((pixels) >> 16); \
}
#define WRITE_TWO_PIXELS_BE(addr, pixels) { \
  ((INT16 *)(addr))[1] = (INT16)(pixels); \
  ((INT16 *)(addr))[0] = (INT16)((pixels) >> 16); \
}

#define DITHER_565_R(r, dither)  ((r) + ((dither) & 0xFF))
#define DITHER_565_G(g, dither)  ((g) + (((dither) & 0xFF) >> 1))
#define DITHER_565_B(b, dither)  ((b) + ((dither) & 0xFF))


/* Declarations for ordered dithering
 *
 * We use a 4x4 ordered dither array packed into 32 bits.  This array is
 * sufficent for dithering RGB888 to RGB565.
 */

#define DITHER_MASK       0x3
#define DITHER_ROTATE(x)  ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))
static const JLONG dither_matrix[4] = {
  0x0008020A,
  0x0C040E06,
  0x030B0109,
  0x0F070D05
};


/* Include inline routines for RGB565 conversion */

#define PACK_SHORT_565 PACK_SHORT_565_LE
#define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE
#define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_LE
#define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_le
#define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_le
#define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_le
#define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_le
#include "jdmrg565.c"
#undef PACK_SHORT_565
#undef PACK_TWO_PIXELS
#undef WRITE_TWO_PIXELS
#undef h2v1_merged_upsample_565_internal
#undef h2v1_merged_upsample_565D_internal
#undef h2v2_merged_upsample_565_internal
#undef h2v2_merged_upsample_565D_internal

#define PACK_SHORT_565 PACK_SHORT_565_BE
#define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE
#define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_BE
#define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_be
#define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_be
#define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_be
#define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_be
#include "jdmrg565.c"
#undef PACK_SHORT_565
#undef PACK_TWO_PIXELS
#undef WRITE_TWO_PIXELS
#undef h2v1_merged_upsample_565_internal
#undef h2v1_merged_upsample_565D_internal
#undef h2v2_merged_upsample_565_internal
#undef h2v2_merged_upsample_565D_internal


static INLINE boolean is_big_endian(void)
{
  int test_value = 1;
  if (*(char *)&test_value != 1)
    return TRUE;
  return FALSE;
}


METHODDEF(void)
h2v1_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                         JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  if (is_big_endian())
    h2v1_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
                                output_buf);
  else
    h2v1_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr,
                                output_buf);
}


METHODDEF(void)
h2v1_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                          JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  if (is_big_endian())
    h2v1_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
                                 output_buf);
  else
    h2v1_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr,
                                 output_buf);
}


METHODDEF(void)
h2v2_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                         JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  if (is_big_endian())
    h2v2_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
                                output_buf);
  else
    h2v2_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr,
                                output_buf);
}


METHODDEF(void)
h2v2_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                          JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
{
  if (is_big_endian())
    h2v2_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
                                 output_buf);
  else
    h2v2_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr,
                                 output_buf);
}


/*
 * Module initialization routine for merged upsampling/color conversion.
 *
 * NB: this is called under the conditions determined by use_merged_upsample()
 * in jdmaster.c.  That routine MUST correspond to the actual capabilities
 * of this module; no safety checks are made here.
 */

GLOBAL(void)
jinit_merged_upsampler(j_decompress_ptr cinfo)
{
  my_upsample_ptr upsample;

  upsample = (my_upsample_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                sizeof(my_upsampler));
  cinfo->upsample = (struct jpeg_upsampler *)upsample;
  upsample->pub.start_pass = start_pass_merged_upsample;
  upsample->pub.need_context_rows = FALSE;

  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;

  if (cinfo->max_v_samp_factor == 2) {
    upsample->pub.upsample = merged_2v_upsample;
    if (jsimd_can_h2v2_merged_upsample())
      upsample->upmethod = jsimd_h2v2_merged_upsample;
    else
      upsample->upmethod = h2v2_merged_upsample;
    if (cinfo->out_color_space == JCS_RGB565) {
      if (cinfo->dither_mode != JDITHER_NONE) {
        upsample->upmethod = h2v2_merged_upsample_565D;
      } else {
        upsample->upmethod = h2v2_merged_upsample_565;
      }
    }
    /* Allocate a spare row buffer */
    upsample->spare_row = (JSAMPROW)
      (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                (size_t)(upsample->out_row_width * sizeof(JSAMPLE)));
  } else {
    upsample->pub.upsample = merged_1v_upsample;
    if (jsimd_can_h2v1_merged_upsample())
      upsample->upmethod = jsimd_h2v1_merged_upsample;
    else
      upsample->upmethod = h2v1_merged_upsample;
    if (cinfo->out_color_space == JCS_RGB565) {
      if (cinfo->dither_mode != JDITHER_NONE) {
        upsample->upmethod = h2v1_merged_upsample_565D;
      } else {
        upsample->upmethod = h2v1_merged_upsample_565;
      }
    }
    /* No spare row needed */
    upsample->spare_row = NULL;
  }

  build_ycc_rgb_table(cinfo);
}

#endif /* UPSAMPLE_MERGING_SUPPORTED */
