sl@0: /* sl@0: * LIBOIL - Library of Optimized Inner Loops sl@0: * Copyright (c) 2003,2004 David A. Schleef sl@0: * All rights reserved. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the above copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR sl@0: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED sl@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, sl@0: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES sl@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR sl@0: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, sl@0: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING sl@0: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE sl@0: * POSSIBILITY OF SUCH DAMAGE. sl@0: */ sl@0: sl@0: /******************************************************************** sl@0: * * sl@0: * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * sl@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * sl@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * sl@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * sl@0: * * sl@0: * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003 * sl@0: * by the Xiph.Org Foundation http://www.xiph.org/ * sl@0: * * sl@0: ******************************************************************** sl@0: sl@0: function: sl@0: last mod: $Id: fdct8x8theora.c,v 1.3 2005-12-16 17:30:40 ds Exp $ sl@0: sl@0: ********************************************************************/ sl@0: //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: sl@0: #ifdef HAVE_CONFIG_H sl@0: #include "config.h" sl@0: #endif sl@0: sl@0: #include sl@0: #include sl@0: #include "liboil/dct/dct.h" sl@0: #include sl@0: sl@0: static int32_t xC1S7 = 64277; sl@0: static int32_t xC2S6 = 60547; sl@0: static int32_t xC3S5 = 54491; sl@0: static int32_t xC4S4 = 46341; sl@0: static int32_t xC5S3 = 36410; sl@0: static int32_t xC6S2 = 25080; sl@0: static int32_t xC7S1 = 12785; sl@0: sl@0: #define SIGNBITDUPPED(X) ((signed )(((X) & 0x80000000)) >> 31) sl@0: #define DOROUND(X) ( (SIGNBITDUPPED(X) & (0xffff)) + (X) ) sl@0: sl@0: /** sl@0: * oil_fdct8x8theora: sl@0: * @s_8x8: sl@0: * @d_8x8: sl@0: * sl@0: * Calculates the FDCT transformation of @s_8x8 according to the Theora sl@0: * specification and places the result in @d_8x8. sl@0: * sl@0: * Note that the source and destination arrays are reversed compared sl@0: * to normal Liboil order. sl@0: */ sl@0: OIL_DEFINE_CLASS(fdct8x8theora, "int16_t *s_8x8, int16_t *d_8x8"); sl@0: sl@0: static void sl@0: fdct8x8theora_ref(const int16_t *src, int16_t *dest) sl@0: { sl@0: int loop; sl@0: sl@0: int32_t is07, is12, is34, is56; sl@0: int32_t is0734, is1256; sl@0: int32_t id07, id12, id34, id56; sl@0: sl@0: int32_t irot_input_x, irot_input_y; sl@0: int32_t icommon_product1; /* Re-used product (c4s4 * (s12 - s56)). */ sl@0: int32_t icommon_product2; /* Re-used product (c4s4 * (d12 + d56)). */ sl@0: sl@0: int32_t temp1, temp2; /* intermediate variable for computation */ sl@0: sl@0: int32_t InterData[64]; sl@0: int32_t *ip = InterData; sl@0: int16_t * op = dest; sl@0: for (loop = 0; loop < 8; loop++){ sl@0: /* Pre calculate some common sums and differences. */ sl@0: is07 = src[0] + src[7]; sl@0: is12 = src[1] + src[2]; sl@0: is34 = src[3] + src[4]; sl@0: is56 = src[5] + src[6]; sl@0: sl@0: id07 = src[0] - src[7]; sl@0: id12 = src[1] - src[2]; sl@0: id34 = src[3] - src[4]; sl@0: id56 = src[5] - src[6]; sl@0: sl@0: is0734 = is07 + is34; sl@0: is1256 = is12 + is56; sl@0: sl@0: /* Pre-Calculate some common product terms. */ sl@0: icommon_product1 = xC4S4*(is12 - is56); sl@0: icommon_product1 = DOROUND(icommon_product1); sl@0: icommon_product1>>=16; sl@0: sl@0: icommon_product2 = xC4S4*(id12 + id56); sl@0: icommon_product2 = DOROUND(icommon_product2); sl@0: icommon_product2>>=16; sl@0: sl@0: sl@0: ip[0] = (xC4S4*(is0734 + is1256)); sl@0: ip[0] = DOROUND(ip[0]); sl@0: ip[0] >>= 16; sl@0: sl@0: ip[4] = (xC4S4*(is0734 - is1256)); sl@0: ip[4] = DOROUND(ip[4]); sl@0: ip[4] >>= 16; sl@0: sl@0: /* Define inputs to rotation for outputs 2 and 6 */ sl@0: irot_input_x = id12 - id56; sl@0: irot_input_y = is07 - is34; sl@0: sl@0: /* Apply rotation for outputs 2 and 6. */ sl@0: temp1=xC6S2*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC2S6*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[2] = temp1 + temp2; sl@0: sl@0: temp1=xC6S2*irot_input_y; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC2S6*irot_input_x ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[6] = temp1 -temp2 ; sl@0: sl@0: /* Define inputs to rotation for outputs 1 and 7 */ sl@0: irot_input_x = icommon_product1 + id07; sl@0: irot_input_y = -( id34 + icommon_product2 ); sl@0: sl@0: /* Apply rotation for outputs 1 and 7. */ sl@0: sl@0: temp1=xC1S7*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC7S1*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[1] = temp1 - temp2; sl@0: sl@0: temp1=xC7S1*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC1S7*irot_input_y ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[7] = temp1 + temp2 ; sl@0: sl@0: /* Define inputs to rotation for outputs 3 and 5 */ sl@0: irot_input_x = id07 - icommon_product1; sl@0: irot_input_y = id34 - icommon_product2; sl@0: sl@0: /* Apply rotation for outputs 3 and 5. */ sl@0: temp1=xC3S5*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC5S3*irot_input_y ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[3] = temp1 - temp2 ; sl@0: sl@0: temp1=xC5S3*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC3S5*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: ip[5] = temp1 + temp2; sl@0: sl@0: /* Increment data pointer for next row. */ sl@0: src += 8 ; sl@0: ip += 8; /* advance pointer to next row */ sl@0: sl@0: } sl@0: sl@0: sl@0: /* Performed DCT on rows, now transform the columns */ sl@0: ip = InterData; sl@0: for (loop = 0; loop < 8; loop++){ sl@0: /* Pre calculate some common sums and differences. */ sl@0: is07 = ip[0 * 8] + ip[7 * 8]; sl@0: is12 = ip[1 * 8] + ip[2 * 8]; sl@0: is34 = ip[3 * 8] + ip[4 * 8]; sl@0: is56 = ip[5 * 8] + ip[6 * 8]; sl@0: sl@0: id07 = ip[0 * 8] - ip[7 * 8]; sl@0: id12 = ip[1 * 8] - ip[2 * 8]; sl@0: id34 = ip[3 * 8] - ip[4 * 8]; sl@0: id56 = ip[5 * 8] - ip[6 * 8]; sl@0: sl@0: is0734 = is07 + is34; sl@0: is1256 = is12 + is56; sl@0: sl@0: /* Pre-Calculate some common product terms. */ sl@0: icommon_product1 = xC4S4*(is12 - is56) ; sl@0: icommon_product2 = xC4S4*(id12 + id56) ; sl@0: icommon_product1 = DOROUND(icommon_product1); sl@0: icommon_product2 = DOROUND(icommon_product2); sl@0: icommon_product1>>=16; sl@0: icommon_product2>>=16; sl@0: sl@0: sl@0: temp1 = xC4S4*(is0734 + is1256) ; sl@0: temp2 = xC4S4*(is0734 - is1256) ; sl@0: temp1 = DOROUND(temp1); sl@0: temp2 = DOROUND(temp2); sl@0: temp1>>=16; sl@0: temp2>>=16; sl@0: op[0*8] = (int16_t) temp1; sl@0: op[4*8] = (int16_t) temp2; sl@0: sl@0: /* Define inputs to rotation for outputs 2 and 6 */ sl@0: irot_input_x = id12 - id56; sl@0: irot_input_y = is07 - is34; sl@0: sl@0: /* Apply rotation for outputs 2 and 6. */ sl@0: temp1=xC6S2*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC2S6*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[2*8] = (int16_t) (temp1 + temp2); sl@0: sl@0: temp1=xC6S2*irot_input_y; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC2S6*irot_input_x ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[6*8] = (int16_t) (temp1 -temp2) ; sl@0: sl@0: /* Define inputs to rotation for outputs 1 and 7 */ sl@0: irot_input_x = icommon_product1 + id07; sl@0: irot_input_y = -( id34 + icommon_product2 ); sl@0: sl@0: /* Apply rotation for outputs 1 and 7. */ sl@0: temp1=xC1S7*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC7S1*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[1*8] = (int16_t) (temp1 - temp2); sl@0: sl@0: temp1=xC7S1*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC1S7*irot_input_y ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[7*8] = (int16_t) (temp1 + temp2); sl@0: sl@0: /* Define inputs to rotation for outputs 3 and 5 */ sl@0: irot_input_x = id07 - icommon_product1; sl@0: irot_input_y = id34 - icommon_product2; sl@0: sl@0: /* Apply rotation for outputs 3 and 5. */ sl@0: temp1=xC3S5*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC5S3*irot_input_y ; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[3*8] = (int16_t) (temp1 - temp2) ; sl@0: sl@0: temp1=xC5S3*irot_input_x; sl@0: temp1=DOROUND(temp1); sl@0: temp1>>=16; sl@0: temp2=xC3S5*irot_input_y; sl@0: temp2=DOROUND(temp2); sl@0: temp2>>=16; sl@0: op[5*8] = (int16_t) (temp1 + temp2); sl@0: sl@0: /* Increment data pointer for next column. */ sl@0: ip ++; sl@0: op ++; sl@0: } sl@0: } sl@0: sl@0: OIL_DEFINE_IMPL_REF (fdct8x8theora_ref, fdct8x8theora); sl@0: sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: OilFunctionClass* __oil_function_class_fdct8x8theora() { sl@0: return &_oil_function_class_fdct8x8theora; sl@0: } sl@0: #endif sl@0: sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: OilFunctionImpl* __oil_function_impl_fdct8x8theora_ref() { sl@0: return &_oil_function_impl_fdct8x8theora_ref; sl@0: } sl@0: #endif sl@0: sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: sl@0: EXPORT_C void** _oil_function_class_ptr_fdct8x8theora () { sl@0: oil_function_class_ptr_fdct8x8theora = __oil_function_class_fdct8x8theora(); sl@0: return &oil_function_class_ptr_fdct8x8theora->func; sl@0: } sl@0: #endif sl@0: