📄 dct.c
字号:
/************************************************************************ * * dct.c, part of tmn (TMN encoder) * * Copyright (C) 1997 University of BC, Canada * * Contacts: * Michael Gallant <mikeg@ee.ubc.ca> * Guy Cote <guyc@ee.ubc.ca> * Berna Erol <bernae@ee.ubc.ca> * * UBC Image Processing Laboratory http://www.ee.ubc.ca/image * 2356 Main Mall tel.: +1 604 822 4051 * Vancouver BC Canada V6T1Z4 fax.: +1 604 822 5949 * * Copyright (C) 1995, 1996 Telenor R&D, Norway * * Contacts: * Robert Danielsen <Robert.Danielsen@nta.no> * * Telenor Research and Development http://www.nta.no/brukere/DVC/ * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * ************************************************************************//* Disclaimer of Warranty * * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose. In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. * * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. * * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. * * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders. Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. * *//***************************************************************** * * These routines are translated from Gisle Bj鴑tegaards's FORTRAN * routines by Robert.Danielsen@nta.no * * 970715 Modified by Guy Cote <guyc@ee.ubc.ca> to include new * scanning for (advanced intra coding mode of H.263+ * *****************************************************************/#include "macros.h"#include "sim.h"#include <math.h>#ifndef PI# ifdef M_PI# define PI M_PI# else# define PI 3.14159265358979323846# endif#endif#define USE_ACCURATE_ROUNDING#define RIGHT_SHIFT(x, shft) ((x) >> (shft))#ifdef USE_ACCURATE_ROUNDING#define ONE ((int) 1)#define DESCALE(x, n) RIGHT_SHIFT((x) + (ONE << ((n) - 1)), n)#else#define DESCALE(x, n) RIGHT_SHIFT(x, n)#endif/*modified by zyy,浮点转定点,乘上2 exp(CONST_BITS),即8192*/#define CONST_BITS 13 /*!< 8192*/#define PASS1_BITS 2#define FIX_0_298631336 ((int) 2446) /*!< FIX(0.298631336) */#define FIX_0_390180644 ((int) 3196) /*!< FIX(0.390180644) */#define FIX_0_541196100 ((int) 4433) /*!< FIX(0.541196100) */#define FIX_0_765366865 ((int) 6270) /*!< FIX(0.765366865)*/#define FIX_0_899976223 ((int) 7373) /*!< FIX(0.899976223) */#define FIX_1_175875602 ((int) 9633) /*!< FIX(1.175875602) */#define FIX_1_501321110 ((int) 12299) /*!< FIX(1.501321110) */#define FIX_1_847759065 ((int) 15137) /*!< FIX(1.847759065) */#define FIX_1_961570560 ((int) 16069) /*!< FIX(1.961570560)*/#define FIX_2_053119869 ((int) 16819) /*!< FIX(2.053119869) */#define FIX_2_562915447 ((int) 20995) /*!< FIX(2.562915447) */#define FIX_3_072711026 ((int) 25172) /*!< FIX(3.072711026)*/#define W1 2841 /*!< 2048*sqrt(2)*cos(1*pi/16) */#define W2 2676 /*!< 2048*sqrt(2)*cos(2*pi/16) */#define W3 2408 /*!< 2048*sqrt(2)*cos(3*pi/16) */#define W5 1609 /*!< 2048*sqrt(2)*cos(5*pi/16) */#define W6 1108 /*!< 2048*sqrt(2)*cos(6*pi/16) */#define W7 565 /*!< 2048*sqrt(2)*cos(7*pi/16) *//* private data */ int iclip[1024]; /*!< clipping table */ int *iclp;int zigzag[8][8] = { {0, 1, 5, 6, 14, 15, 27, 28}, {2, 4, 7, 13, 16, 26, 29, 42}, {3, 8, 12, 17, 25, 30, 41, 43}, {9, 11, 18, 24, 31, 40, 44, 53}, {10, 19, 23, 32, 39, 45, 52, 54}, {20, 22, 33, 38, 46, 51, 55, 60}, {21, 34, 37, 47, 50, 56, 59, 61}, {35, 36, 48, 49, 57, 58, 62, 63},};int alternate_horizontal[8][8] = { {0, 1, 2, 3, 10, 11, 12, 13}, {4, 5, 8, 9, 17, 16, 15, 14}, {6, 7, 19, 18, 26, 27, 28, 29}, {20, 21, 24, 25, 30, 31, 32, 33}, {22, 23, 34, 35, 42, 43, 44, 45}, {36, 37, 40, 41, 46, 47, 48, 49}, {38, 39, 50, 51, 56, 57, 58, 59}, {52, 53, 54, 55, 60, 61, 62, 63},};int alternate_vertical[8][8] = { {0, 4, 6, 20, 22, 36, 38, 52}, {1, 5, 7, 21, 23, 37, 39, 53}, {2, 8, 19, 24, 34, 40, 50, 54}, {3, 9, 18, 25, 35, 41, 51, 55}, {10, 17, 26, 30, 42, 46, 56, 60}, {11, 16, 27, 31, 43, 47, 57, 61}, {12, 15, 28, 32, 44, 48, 58, 62}, {13, 14, 29, 33, 45, 49, 59, 63},};/********************************************************************** * * Name: Dct * Description: Does dct on an 8x8 block * * Input: 64 pixels in a 1D array * Returns: 64 coefficients in a 1D array * Side effects: * * Date: 930128 Author: Robert.Danielsen@nta.no * **********************************************************************/extern FILE *pfile1, *pfile2;int Dct (int *block, int *coeff){#if 1 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; int z1, z2, z3, z4, z5; int *blkptr; int *dataptr; int data[64]; int i; /* Pass 1: process rows. */ /* Note results are scaled up by sqrt(8) compared to a true DCT; */ /* furthermore, we scale the results by 2**PASS1_BITS. */ /**modified by zyy,根据DCT变换公式,按LL&M公式1 的计算结果, 还应除以sqrt(N),但是这里没有除,所以经过行变换和 列变换后,实际得到的DCT系数值要比真实的系数值大 N 倍。因此,最后还有右移3 位。**/ dataptr = data; blkptr = block; for (i = 0; i < 8; i++) { tmp0 = blkptr[0] + blkptr[7]; tmp7 = blkptr[0] - blkptr[7]; tmp1 = blkptr[1] + blkptr[6]; tmp6 = blkptr[1] - blkptr[6]; tmp2 = blkptr[2] + blkptr[5]; tmp5 = blkptr[2] - blkptr[5]; tmp3 = blkptr[3] + blkptr[4]; tmp4 = blkptr[3] - blkptr[4]; /* Even part per LL&M figure 1 --- note that published figure is faulty; * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". */ tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = (tmp10 + tmp11) << PASS1_BITS; dataptr[4] = (tmp10 - tmp11) << PASS1_BITS; z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[2] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS - PASS1_BITS); dataptr[6] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS - PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). * i0..i3 in the paper are tmp4..tmp7 here. */ z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[7] = DESCALE(tmp4 + z1 + z3, CONST_BITS - PASS1_BITS); dataptr[5] = DESCALE(tmp5 + z2 + z4, CONST_BITS - PASS1_BITS); dataptr[3] = DESCALE(tmp6 + z2 + z3, CONST_BITS - PASS1_BITS); dataptr[1] = DESCALE(tmp7 + z1 + z4, CONST_BITS - PASS1_BITS); dataptr += 8; /* advance pointer to next row */ blkptr += 8; } /**modified by zyy,行变换后得到的值比真实值大sqrt(N)*2**PASS1_BITS。**/ /* Pass 2: process columns. * We remove the PASS1_BITS scaling, but leave the results scaled up * by an overall factor of 8. */ dataptr = data; for (i = 0; i < 8; i++) { tmp0 = dataptr[0] + dataptr[56]; tmp7 = dataptr[0] - dataptr[56]; tmp1 = dataptr[8] + dataptr[48]; tmp6 = dataptr[8] - dataptr[48]; tmp2 = dataptr[16] + dataptr[40]; tmp5 = dataptr[16] - dataptr[40]; tmp3 = dataptr[24] + dataptr[32]; tmp4 = dataptr[24] - dataptr[32]; /* Even part per LL&M figure 1 --- note that published figure is faulty; * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". */ tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = DESCALE(tmp10 + tmp11, PASS1_BITS); dataptr[32] = DESCALE(tmp10 - tmp11, PASS1_BITS); z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[16] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS + PASS1_BITS); dataptr[48] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS + PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). * i0..i3 in the paper are tmp4..tmp7 here. */ z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[56] = DESCALE(tmp4 + z1 + z3, CONST_BITS + PASS1_BITS); dataptr[40] = DESCALE(tmp5 + z2 + z4, CONST_BITS + PASS1_BITS); dataptr[24] = DESCALE(tmp6 + z2 + z3, CONST_BITS + PASS1_BITS); dataptr[8] = DESCALE(tmp7 + z1 + z4, CONST_BITS + PASS1_BITS); dataptr++; /* advance pointer to next column */ } /* descale */ /**modified by zyy,右移3位(除sqrt(N)*sqrt(N)),恢复到真实值**/ for (i = 0; i < 64; i++) coeff[i] = DESCALE(data[i], 3); return 0;#else int j1, i, j, k; float b[8]; float b1[8]; float d[8][8]; float f0 = (float) .7071068; float f1 = (float) .4903926; float f2 = (float) .4619398; float f3 = (float) .4157348; float f4 = (float) .3535534; float f5 = (float) .2777851; float f6 = (float) .1913417; float f7 = (float) .0975452; for (i = 0, k = 0; i < 8; i++, k += 8) { for (j = 0; j < 8; j++) { b[j] = (float) block[k + j]; } /* Horizontal transform */ for (j = 0; j < 4; j++) { j1 = 7 - j; b1[j] = b[j] + b[j1]; b1[j1] = b[j] - b[j1]; } b[0] = b1[0] + b1[3]; b[1] = b1[1] + b1[2]; b[2] = b1[1] - b1[2]; b[3] = b1[0] - b1[3]; b[4] = b1[4]; b[5] = (b1[6] - b1[5]) * f0; b[6] = (b1[6] + b1[5]) * f0; b[7] = b1[7]; d[i][0] = (b[0] + b[1]) * f4; d[i][4] = (b[0] - b[1]) * f4; d[i][2] = b[2] * f6 + b[3] * f2; d[i][6] = b[3] * f6 - b[2] * f2; b1[4] = b[4] + b[5]; b1[7] = b[7] + b[6]; b1[5] = b[4] - b[5]; b1[6] = b[7] - b[6]; d[i][1] = b1[4] * f7 + b1[7] * f1; d[i][5] = b1[5] * f3 + b1[6] * f5; d[i][7] = b1[7] * f7 - b1[4] * f1; d[i][3] = b1[6] * f3 - b1[5] * f5; } /* Vertical transform */ for (i = 0; i < 8; i++) { for (j = 0; j < 4; j++) { j1 = 7 - j; b1[j] = d[j][i] + d[j1][i]; b1[j1] = d[j][i] - d[j1][i]; } b[0] = b1[0] + b1[3]; b[1] = b1[1] + b1[2]; b[2] = b1[1] - b1[2]; b[3] = b1[0] - b1[3]; b[4] = b1[4]; b[5] = (b1[6] - b1[5]) * f0; b[6] = (b1[6] + b1[5]) * f0; b[7] = b1[7]; d[0][i] = (b[0] + b[1]) * f4; d[4][i] = (b[0] - b[1]) * f4; d[2][i] = b[2] * f6 + b[3] * f2; d[6][i] = b[3] * f6 - b[2] * f2; b1[4] = b[4] + b[5]; b1[7] = b[7] + b[6]; b1[5] = b[4] - b[5]; b1[6] = b[7] - b[6]; d[1][i] = b1[4] * f7 + b1[7] * f1; d[5][i] = b1[5] * f3 + b1[6] * f5; d[7][i] = b1[7] * f7 - b1[4] * f1; d[3][i] = b1[6] * f3 - b1[5] * f5; } for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { *(coeff + j + i * 8) = (int) (d[i][j]); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -