📄 img_fdct_8x8_c.c
字号:
/* ======================================================================== */
/* TEXAS INSTRUMENTS, INC. */
/* */
/* IMGLIB DSP Image/Video Processing Library */
/* */
/* This library contains proprietary intellectual property of Texas */
/* Instruments, Inc. The library and its source code are protected by */
/* various copyrights, and portions may also be protected by patents or */
/* other legal protections. */
/* */
/* This software is licensed for use with Texas Instruments TMS320 */
/* family DSPs. This license was provided to you prior to installing */
/* the software. You may review this license by consulting the file */
/* TI_license.PDF which accompanies the files in this library. */
/* ------------------------------------------------------------------------ */
/* Copyright (C) 2002 Texas Instruments, Incorporated. */
/* All Rights Reserved. */
/* ======================================================================== */
/* ======================================================================== */
/* NAME */
/* IMG_fdct_8x8 -- 8x8 Block FDCT With Rounding, Endian Neutral. */
/* */
/* REVISION DATE */
/* 19-Oct-2000 */
/* */
/* USAGE */
/* This routine has the following C prototype: */
/* */
/* void IMG_fdct_8x8(short fdct_data[], unsigned num_fdcts) */
/* */
/* The fdct routine accepts a list of 8x8 pixel blocks and performs */
/* FDCTs on each. The array should be laid out identically to */
/* "fdct_data[num_fdcts][8][8]". All operations in this array are */
/* performed entirely in-place. */
/* */
/* DESCRIPTION */
/* The IMG_fdct_8x8 function implements a Chen FDCT. Output values are */
/* rounded, providing improved accuracy. Input terms are expected */
/* to be signed 12Q0 values, producing signed 16Q0 results. (A */
/* smaller dynamic range may be used on the input, producing a */
/* correspondingly smaller output range. Typical applications */
/* include processing signed 9Q0 and unsigned 8Q0 pixel data, */
/* producing signed 13Q0 or 12Q0 outputs, respectively.) */
/* */
/* Note: This code guarantees correct operation, even in the case */
/* that 'num_fdcts == 0'. In this case, the function performs an */
/* early exit without storing any results or intermediate values. */
/* */
/* TECHNIQUES */
/* I've applied a sqrt(2) scaling to each pass, which results in a */
/* fractional Q point at various points of the algorithm. A chief */
/* benefit of this technique is that the F0 and F4 terms see no */
/* multiplies. To perform this scaling, the C2 and C6 cosine terms */
/* are scaled up by sqrt(2), and the intermediate values in stage 2 */
/* (s0, q0, s1, and q1) are also multiplied by sqrt(2). The */
/* effect in stage 2 is to cancel the multiply by C4 on s0 and q0, */
/* and to introduce a multiply by 2*C4 on s1 and q1. */
/* */
/* The horizontal pass does not explicitly jump from block-to-block, */
/* since all horizontal rows are adjacent in memory. (eg. Moving */
/* between rows within a block is identical to moving between the */
/* last row of one block and the first row of the next block.) */
/* */
/* ASSUMPTIONS */
/* n/a */
/* */
/* NOTES */
/* n/a */
/* */
/* SOURCE */
/* Chen FDCT. */
/* ------------------------------------------------------------------------ */
/* Copyright (c) 2002 Texas Instruments, Incorporated. */
/* All Rights Reserved. */
/* ======================================================================== */
void IMG_fdct_8x8_c(short *dct_data, unsigned num_fdcts)
{
/* -------------------------------------------------------------------- */
/* Set up the cosine coefficients. */
/* -------------------------------------------------------------------- */
const unsigned short c1 = 0x1F62, c3 = 0x1A9B; /* Q13 coeffs */
const unsigned short c5 = 0x11C7, c7 = 0x063E; /* Q13 coeffs */
const unsigned short c2 = 0x29CF, c6 = 0x1151; /* Q13.5 coeffs */
const unsigned short C1 = 0xFB15, C3 = 0xD4DB; /* Q16 coeffs */
const unsigned short C5 = 0x8E3A, C7 = 0x31F1; /* Q16 coeffs */
const unsigned short C2 = 0xA73D, C6 = 0x4546; /* Q15.5 coeffs */
const unsigned short C4 = 0xB505; /* Q16 coeff */
/* -------------------------------------------------------------------- */
/* Intermediate calculations. */
/* -------------------------------------------------------------------- */
short f0, f1, f2, f3, f4, f5, f6, f7; /* Spatial domain samples. */
short g0, g1, h0, h1, p0, p1; /* Even-half intermediate. */
short r0, r1, r0_,r1_; /* Even-half intermediate. */
short P0, P1, R0, R1; /* Even-half intermediate. */
short g2, g3, h2, h3; /* Odd-half intermediate. */
short q1a,s1a,q0, q1, s0, s1; /* Odd-half intermediate. */
short Q0, Q1, S0, S1; /* Odd-half intermediate. */
short F0, F1, F2, F3, F4, F5, F6, F7; /* Freq. domain results. */
/* -------------------------------------------------------------------- */
/* Input and output pointers, loop control. */
/* -------------------------------------------------------------------- */
unsigned i, j;
short (*dct)[8][8] = (short (*)[8][8])dct_data;
if (!num_fdcts) return;
/* -------------------------------------------------------------------- */
/* Outer vertical loop -- Process each 8x8 block. */
/* -------------------------------------------------------------------- */
for (i = 0; i < num_fdcts; i++)
{
/* ---------------------------------------------------------------- */
/* Perform Vertical 1-D FDCT on columns within each block. */
/* ---------------------------------------------------------------- */
for (j = 0; j < 8; j++)
{
/* ------------------------------------------------------------ */
/* Load the spatial-domain samples. */
/* The incoming terms start at Q0 precision. */
/* ------------------------------------------------------------ */
f0 = dct[i][0][j];
f1 = dct[i][1][j];
f2 = dct[i][2][j];
f3 = dct[i][3][j];
f4 = dct[i][4][j];
f5 = dct[i][5][j];
f6 = dct[i][6][j];
f7 = dct[i][7][j];
/* ------------------------------------------------------------ */
/* Stage 1: Separate into even and odd halves. */
/* */
/* The results of this stage are implicitly in Q1, since we */
/* do not explicitly multiply by 0.5. */
/* ------------------------------------------------------------ */
g0 = f0 + f7; g1 = f1 + f6; /* Results in Q1 */
h1 = f2 + f5; h0 = f3 + f4; /* Results in Q1 */
g3 = f2 - f5; g2 = f3 - f4; /* Results in Q1 */
h2 = f0 - f7; h3 = f1 - f6; /* Results in Q1 */
/* ------------------------------------------------------------ */
/* Stage 2 */
/* */
/* Note, on the odd-half, the results are in Q1.5 since those */
/* values are scaled upwards by sqrt(2) at this point. */
/* ------------------------------------------------------------ */
p0 = g0 + h0; r0 = g0 - h0; /* Results in Q1 */
p1 = g1 + h1; r1 = g1 - h1; /* Results in Q1 */
q1a = g2 + g2; /* q1a is now Q2 */
s1a = h2 + h2; /* s1a is now Q2 */
q1 = (q1a * C4 + 0x8000) >> 16; /* Results in Q1.5 */
s1 = (s1a * C4 + 0x8000) >> 16; /* Results in Q1.5 */
s0 = h3 + g3; /* Results in Q1.5 */
q0 = h3 - g3; /* Results in Q1.5 */
/* ------------------------------------------------------------ */
/* Stage 3 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -