/*
 * jccolext-neon.c - colorspace conversion (32-bit Arm Neon)
 *
 * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

/* This file is included by jccolor-neon.c */


/* RGB -> YCbCr conversion is defined by the following equations:
 *    Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
 *    Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128
 *    Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + 128
 *
 * Avoid floating point arithmetic by using shifted integer constants:
 *    0.29899597 = 19595 * 2^-16
 *    0.58700561 = 38470 * 2^-16
 *    0.11399841 =  7471 * 2^-16
 *    0.16874695 = 11059 * 2^-16
 *    0.33125305 = 21709 * 2^-16
 *    0.50000000 = 32768 * 2^-16
 *    0.41868592 = 27439 * 2^-16
 *    0.08131409 =  5329 * 2^-16
 * These constants are defined in jccolor-neon.c
 *
 * We add the fixed-point equivalent of 0.5 to Cb and Cr, which effectively
 * rounds up or down the result via integer truncation.
 */

void jsimd_rgb_ycc_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
                                JSAMPIMAGE output_buf, JDIMENSION output_row,
                                int num_rows)
{
  /* Pointer to RGB(X/A) input data */
  JSAMPROW inptr;
  /* Pointers to Y, Cb, and Cr output data */
  JSAMPROW outptr0, outptr1, outptr2;

  /* Set up conversion constants. */
#if defined(__clang__)
  const uint16x4x2_t consts = vld1_u16_x2(jsimd_rgb_ycc_neon_consts);
#else
  /* GCC does not currently support the intrinsic vld1_<type>_x2(). */
  const uint16x4_t consts1 = vld1_u16(jsimd_rgb_ycc_neon_consts);
  const uint16x4_t consts2 = vld1_u16(jsimd_rgb_ycc_neon_consts + 4);
  const uint16x4x2_t consts = { { consts1, consts2 } };
#endif
  const uint32x4_t scaled_128_5 = vdupq_n_u32((128 << 16) + 32767);

  while (--num_rows >= 0) {
    inptr = *input_buf++;
    outptr0 = output_buf[0][output_row];
    outptr1 = output_buf[1][output_row];
    outptr2 = output_buf[2][output_row];
    output_row++;

    int cols_remaining = image_width;
    for (; cols_remaining > 0; cols_remaining -= 8) {

      /* To prevent buffer overread by the vector load instructions, the last
       * (image_width % 8) columns of data are first memcopied to a temporary
       * buffer large enough to accommodate the vector load.
       */
      if (cols_remaining < 8) {
        ALIGN(16) uint8_t tmp_buf[8 * RGB_PIXELSIZE];
        memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
        inptr = tmp_buf;
      }

#if RGB_PIXELSIZE == 4
      uint8x8x4_t input_pixels = vld4_u8(inptr);
#else
      uint8x8x3_t input_pixels = vld3_u8(inptr);
#endif
      uint16x8_t r = vmovl_u8(input_pixels.val[RGB_RED]);
      uint16x8_t g = vmovl_u8(input_pixels.val[RGB_GREEN]);
      uint16x8_t b = vmovl_u8(input_pixels.val[RGB_BLUE]);

      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
      uint32x4_t y_low = vmull_lane_u16(vget_low_u16(r), consts.val[0], 0);
      y_low = vmlal_lane_u16(y_low, vget_low_u16(g), consts.val[0], 1);
      y_low = vmlal_lane_u16(y_low, vget_low_u16(b), consts.val[0], 2);
      uint32x4_t y_high = vmull_lane_u16(vget_high_u16(r), consts.val[0], 0);
      y_high = vmlal_lane_u16(y_high, vget_high_u16(g), consts.val[0], 1);
      y_high = vmlal_lane_u16(y_high, vget_high_u16(b), consts.val[0], 2);

      /* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128 */
      uint32x4_t cb_low = scaled_128_5;
      cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(r), consts.val[0], 3);
      cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(g), consts.val[1], 0);
      cb_low = vmlal_lane_u16(cb_low, vget_low_u16(b), consts.val[1], 1);
      uint32x4_t cb_high = scaled_128_5;
      cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(r), consts.val[0], 3);
      cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(g), consts.val[1], 0);
      cb_high = vmlal_lane_u16(cb_high, vget_high_u16(b), consts.val[1], 1);

      /* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128 */
      uint32x4_t cr_low = scaled_128_5;
      cr_low = vmlal_lane_u16(cr_low, vget_low_u16(r), consts.val[1], 1);
      cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(g), consts.val[1], 2);
      cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(b), consts.val[1], 3);
      uint32x4_t cr_high = scaled_128_5;
      cr_high = vmlal_lane_u16(cr_high, vget_high_u16(r), consts.val[1], 1);
      cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(g), consts.val[1], 2);
      cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(b), consts.val[1], 3);

      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
      uint16x8_t y_u16 = vcombine_u16(vrshrn_n_u32(y_low, 16),
                                      vrshrn_n_u32(y_high, 16));
      /* Descale Cb values (right shift) and narrow to 16-bit. */
      uint16x8_t cb_u16 = vcombine_u16(vshrn_n_u32(cb_low, 16),
                                       vshrn_n_u32(cb_high, 16));
      /* Descale Cr values (right shift) and narrow to 16-bit. */
      uint16x8_t cr_u16 = vcombine_u16(vshrn_n_u32(cr_low, 16),
                                       vshrn_n_u32(cr_high, 16));
      /* Narrow Y, Cb, and Cr values to 8-bit and store to memory.  Buffer
       * overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
       */
      vst1_u8(outptr0, vmovn_u16(y_u16));
      vst1_u8(outptr1, vmovn_u16(cb_u16));
      vst1_u8(outptr2, vmovn_u16(cr_u16));

      /* Increment pointers. */
      inptr += (8 * RGB_PIXELSIZE);
      outptr0 += 8;
      outptr1 += 8;
      outptr2 += 8;
    }
  }
}
