17ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian/*
27ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
37ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *
47ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
57ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
67ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
77ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  in the file PATENTS.  All contributing project authors may
87ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
97ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian */
107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#ifndef VPX_DSP_INV_TXFM_H_
127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#define VPX_DSP_INV_TXFM_H_
137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include <assert.h>
157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "./vpx_config.h"
177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vpx_dsp/txfm_common.h"
187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vpx_ports/mem.h"
197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#ifdef __cplusplus
217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianextern "C" {
227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
2468e1c830ade592be74773e249bf94e2bbfb50de7Johannstatic INLINE tran_high_t check_range(tran_high_t input) {
257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_COEFFICIENT_RANGE_CHECKING
267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // For valid VP9 input streams, intermediate stage coefficients should always
277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // stay within the range of a signed 16 bit integer. Coefficients can go out
287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // of this range for invalid/corrupt VP9 streams. However, strictly checking
297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // this range for every intermediate coefficient can burdensome for a decoder,
307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // therefore the following assertion is only enabled when configured with
317ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // --enable-coefficient-range-checking.
327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  assert(INT16_MIN <= input);
337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  assert(input <= INT16_MAX);
347ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_COEFFICIENT_RANGE_CHECKING
3568e1c830ade592be74773e249bf94e2bbfb50de7Johann  return input;
367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
377ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
3868e1c830ade592be74773e249bf94e2bbfb50de7Johannstatic INLINE tran_high_t dct_const_round_shift(tran_high_t input) {
397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
4068e1c830ade592be74773e249bf94e2bbfb50de7Johann  return (tran_high_t)rv;
417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
447bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic INLINE tran_high_t highbd_check_range(tran_high_t input, int bd) {
457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_COEFFICIENT_RANGE_CHECKING
467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // For valid highbitdepth VP9 streams, intermediate stage coefficients will
477ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // stay within the ranges:
487ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // - 8 bit: signed 16 bit integer
497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // - 10 bit: signed 18 bit integer
507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  // - 12 bit: signed 20 bit integer
517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int32_t int_max = (1 << (7 + bd)) - 1;
527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  const int32_t int_min = -int_max - 1;
537ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  assert(int_min <= input);
547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian  assert(input <= int_max);
557bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)int_min;
567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_COEFFICIENT_RANGE_CHECKING
577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)bd;
5868e1c830ade592be74773e249bf94e2bbfb50de7Johann  return input;
597ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_VP9_HIGHBITDEPTH
617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
627ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_EMULATE_HARDWARE
637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// When CONFIG_EMULATE_HARDWARE is 1 the transform performs a
647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// non-normative method to handle overflows. A stream that causes
657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// overflows  in the inverse transform is considered invalid in VP9,
667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// and a hardware implementer is free to choose any reasonable
677ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// method to handle overflows. However to aid in hardware
687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// verification they can use a specific implementation of the
697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// WRAPLOW() macro below that is identical to their intended
707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// hardware implementation (and also use configure options to trigger
717ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// the C-implementation of the transform).
727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian//
737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// The particular WRAPLOW implementation below performs strict
747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// overflow wrapping to match common hardware implementations.
757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// bd of 8 uses trans_low with 16bits, need to remove 16bits
767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// bd of 10 uses trans_low with 18bits, need to remove 14bits
777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// bd of 12 uses trans_low with 20bits, need to remove 12bits
787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian// bd of x uses trans_low with 8+x bits, need to remove 24-x bits
7968e1c830ade592be74773e249bf94e2bbfb50de7Johann
8068e1c830ade592be74773e249bf94e2bbfb50de7Johann#define WRAPLOW(x) ((((int32_t)check_range(x)) << 16) >> 16)
8168e1c830ade592be74773e249bf94e2bbfb50de7Johann#if CONFIG_VP9_HIGHBITDEPTH
8268e1c830ade592be74773e249bf94e2bbfb50de7Johann#define HIGHBD_WRAPLOW(x, bd) \
837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ((((int32_t)highbd_check_range((x), bd)) << (24 - bd)) >> (24 - bd))
8468e1c830ade592be74773e249bf94e2bbfb50de7Johann#endif  // CONFIG_VP9_HIGHBITDEPTH
8568e1c830ade592be74773e249bf94e2bbfb50de7Johann
867bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else  // CONFIG_EMULATE_HARDWARE
8768e1c830ade592be74773e249bf94e2bbfb50de7Johann
8868e1c830ade592be74773e249bf94e2bbfb50de7Johann#define WRAPLOW(x) ((int32_t)check_range(x))
8968e1c830ade592be74773e249bf94e2bbfb50de7Johann#if CONFIG_VP9_HIGHBITDEPTH
907bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define HIGHBD_WRAPLOW(x, bd) ((int32_t)highbd_check_range((x), bd))
9168e1c830ade592be74773e249bf94e2bbfb50de7Johann#endif  // CONFIG_VP9_HIGHBITDEPTH
927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // CONFIG_EMULATE_HARDWARE
937ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
947ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid idct4_c(const tran_low_t *input, tran_low_t *output);
957ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid idct8_c(const tran_low_t *input, tran_low_t *output);
967ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid idct16_c(const tran_low_t *input, tran_low_t *output);
977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid idct32_c(const tran_low_t *input, tran_low_t *output);
987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid iadst4_c(const tran_low_t *input, tran_low_t *output);
997ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid iadst8_c(const tran_low_t *input, tran_low_t *output);
1007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid iadst16_c(const tran_low_t *input, tran_low_t *output);
1017ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH
1037ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_idct4_c(const tran_low_t *input, tran_low_t *output, int bd);
1047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_idct8_c(const tran_low_t *input, tran_low_t *output, int bd);
1057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_idct16_c(const tran_low_t *input, tran_low_t *output, int bd);
1067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_iadst4_c(const tran_low_t *input, tran_low_t *output, int bd);
1087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_iadst8_c(const tran_low_t *input, tran_low_t *output, int bd);
1097ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vpx_highbd_iadst16_c(const tran_low_t *input, tran_low_t *output, int bd);
1107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE uint16_t highbd_clip_pixel_add(uint16_t dest, tran_high_t trans,
1127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian                                             int bd) {
11368e1c830ade592be74773e249bf94e2bbfb50de7Johann  trans = HIGHBD_WRAPLOW(trans, bd);
11468e1c830ade592be74773e249bf94e2bbfb50de7Johann  return clip_pixel_highbd(dest + (int)trans, bd);
1157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
1167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
1177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianstatic INLINE uint8_t clip_pixel_add(uint8_t dest, tran_high_t trans) {
11968e1c830ade592be74773e249bf94e2bbfb50de7Johann  trans = WRAPLOW(trans);
12068e1c830ade592be74773e249bf94e2bbfb50de7Johann  return clip_pixel(dest + (int)trans);
1217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}
1227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#ifdef __cplusplus
1237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian}  // extern "C"
1247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif
1257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian
1267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif  // VPX_DSP_INV_TXFM_H_
127