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