836 lines
28 KiB
C
836 lines
28 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: iljpgdedct.c /main/3 1995/10/23 15:55:19 rswiston $ */
|
|
/**---------------------------------------------------------------------
|
|
***
|
|
*** (c)Copyright 1992 Hewlett-Packard Co.
|
|
***
|
|
*** RESTRICTED RIGHTS LEGEND
|
|
*** Use, duplication, or disclosure by the U.S. Government is subject to
|
|
*** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
|
|
*** Technical Data and Computer Software clause in DFARS 252.227-7013.
|
|
*** Hewlett-Packard Company
|
|
*** 3000 Hanover Street
|
|
*** Palo Alto, CA 94304 U.S.A.
|
|
*** Rights for non-DOD U.S. Government Departments and Agencies are as set
|
|
*** forth in FAR 52.227-19(c)(1,2).
|
|
***
|
|
***-------------------------------------------------------------------*/
|
|
|
|
#include "iljpgdecodeint.h"
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Macros to check if "clipValue" (an int) is outside range 0..255, and
|
|
to branch to point named by second macro if so, which clips and returns.
|
|
This is done to avoid taking a branch on the common case of value
|
|
not out of range - significant speedup on RISC machine.
|
|
*/
|
|
#define ILJPG_CLIP_256(_gotoLabel, _returnLabel) \
|
|
if ((clipValue) >> 8) goto _gotoLabel; \
|
|
_returnLabel:
|
|
|
|
#define ILJPG_CLIP_256_LABEL(_gotoLabel, _returnLabel) \
|
|
_gotoLabel: \
|
|
if ((clipValue) > 255) clipValue = 255; else clipValue = 0; \
|
|
goto _returnLabel;
|
|
|
|
|
|
/* compute 2-D DCT descaling matrix */
|
|
static void _il_fwft_rev_scale (
|
|
iljpgPtr q, /* pointer to quantization matrix */
|
|
float *s /* pointer to pointer to descaling matrix */
|
|
)
|
|
{
|
|
int i, j, prevValue, value, QIndex;
|
|
double a, c0, b[8], pi;
|
|
iljpgPtr qptr;
|
|
float *sptr;
|
|
|
|
pi = 4.0 * atan(1.0);
|
|
c0 = 1.0 / (2.0 * 0.707106718);
|
|
a = 1.0 / (2 * c0);
|
|
b[0] = a / 2.0;
|
|
for (i = 1; i < 8; i++) {
|
|
a = cos (i * pi / 16.0) / 2.0;
|
|
b[i] = a;
|
|
}
|
|
|
|
/* descaling matrix including dequantization effects */
|
|
/* Note: given Q table is zigzag'd, as in JIF stream. De-zigzag *qptr.
|
|
Also: if an entry in the Q table is zero, then: if it is the first entry,
|
|
store 16 (?) in the Q table, otherwise store the previous Q table value.
|
|
*/
|
|
|
|
sptr = s;
|
|
qptr = q;
|
|
prevValue = 16; /* in case 1st Q table value is 0 */
|
|
QIndex = 0;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
for (j = 0; j < 8; j++) {
|
|
value = qptr[_iljpgZigzagTable[QIndex++]];
|
|
if (value == 0)
|
|
value = prevValue;
|
|
*sptr++ = b[i] * b[j] * value;
|
|
prevValue = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------- _iljpgDeDCTInit -------------------------- */
|
|
/* Called by iljpgDecode() to init for DCT decoding.
|
|
*/
|
|
ILJPG_PRIVATE_EXTERN
|
|
iljpgError _iljpgDeDCTInit (
|
|
iljpgDecodePrivPtr pPriv
|
|
)
|
|
{
|
|
iljpgDataPtr pData;
|
|
int i;
|
|
|
|
pData = pPriv->pData;
|
|
|
|
/* Build a "rev scale" table for each QTable; store into private */
|
|
for (i = 0; i < 4; i++)
|
|
pPriv->DCTRevScaleTables[i] = (float *)NULL;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (pData->QTables[i]) {
|
|
if (!(pPriv->DCTRevScaleTables[i] = (float *)ILJPG_MALLOC(sizeof(float) * 64)))
|
|
return ILJPG_ERROR_DECODE_MALLOC;
|
|
_il_fwft_rev_scale (pData->QTables[i], pPriv->DCTRevScaleTables[i]);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* -------------------- _iljpgDeDCTCleanup -------------------------- */
|
|
/* Called by iljpgDecode() to cleanup after DCT decoding.
|
|
*/
|
|
ILJPG_PRIVATE_EXTERN
|
|
iljpgError _iljpgDeDCTCleanup (
|
|
iljpgDecodePrivPtr pPriv
|
|
)
|
|
{
|
|
int i;
|
|
|
|
/* Free any "rev scale" tables that were allocated in iljpgDeDCTInit() */
|
|
for (i = 0; i < 4; i++) {
|
|
if (pPriv->DCTRevScaleTables[i])
|
|
ILJPG_FREE (pPriv->DCTRevScaleTables[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
NAME
|
|
float implementation of inverse quantize and inverse dct.
|
|
input and output in integer format.
|
|
Output is clamped to the range 0-255.
|
|
PURPOSE
|
|
perform inverse quantization and inverse DCT of a 8x8 array. During
|
|
inverse quantization, the input array is processed in dezigzag order.
|
|
|
|
NOTES
|
|
includes the +128 shift in inverse DCT as per JPEG spec. This shift is
|
|
accomplished by shifting the DC value by 128 prior to performing the
|
|
inverse DCT.
|
|
|
|
The constants b1,..,b5 used by the fast DCT method are declared as
|
|
register variables; this allows the 'c89' compiler to perform the
|
|
multplies as floating point 32 bit multiplies rather than promoting
|
|
to double followed by a double to float conversion.
|
|
(4/29/92, V. Bhaskaran)
|
|
|
|
METHOD
|
|
8x8 INVERSE DCT
|
|
|
|
This implementation is based on computation of a 8 point inverse DCT
|
|
using a 16 point Winograd Fourier Transform.
|
|
The winograd fourier transform method requires 5 multiplies and 29
|
|
additions for a 8 point inverse dct.
|
|
|
|
Let T[] be a 8x8 input DCT array for which we need to perform the
|
|
inverse DCT.
|
|
|
|
| t00 t01 t02 t03 t04 t05 t06 t07 |
|
|
| t10 t11 t12 t13 t14 t15 t16 t17 |
|
|
| t20 t21 t22 t23 t24 t25 t26 t27 |
|
|
T[] = | t30 t31 t32 t33 t34 t35 t36 t37 |
|
|
| t40 t41 t42 t43 t44 t45 t46 t47 |
|
|
| t50 t51 t52 t53 t54 t55 t56 t57 |
|
|
| t60 t61 t62 t63 t64 t65 t66 t67 |
|
|
| t70 t71 t72 t73 t74 t75 t76 t77 |
|
|
|
|
1. The T[] matrix values are descaled by the inverse DCT denormalization
|
|
values and the quantization matrix values.
|
|
If we denote T[] = {t(i,j)}, S[] = {s(i,j)}, and X[] = {y(i,j)},
|
|
then,
|
|
X(i,j) = s(i,j) * t(i,j)
|
|
Here, S[] is the descaling matrix and includes quantization matrix.
|
|
|
|
Define a[n] as
|
|
a[n] = cos (n pi / 16) / 2 C[n], pi = 3.1415....
|
|
and,
|
|
C[0] = 1 / sqrt(2), C[1] = C[2] = ... = C[7] = 1,
|
|
Define b[n] as
|
|
b0 = a[0]
|
|
bi = 2 a[i], i = 1,2,...,7
|
|
|
|
Then, descaling matrix S[] has the following structure
|
|
| b0b0q00 b1b0q01 b2b0q02 b3b0q03 b4b0q04 b5b0q05 b6b0q06 b7b0q07 |
|
|
| b0b1q10 b1b1q11 b2b1q12 b3b1q13 b4b1q14 b5b1q15 b6b1q16 b7b1q17 |
|
|
| b0b2q20 b1b2q21 b2b2q22 b3b2q23 b4b2q24 b5b2q25 b6b2q26 b7b2q27 |
|
|
| b0b3q30 b1b3q31 b2b3q32 b3b3q33 b4b3q34 b5b3q35 b6b3q36 b7b3q37 |
|
|
| b0b4q40 b1b4q41 b2b4q42 b3b4q43 b4b4q44 b5b4q45 b6b4q46 b7b4q47 |
|
|
| b0b5q50 b1b5q51 b2b5q52 b3b5q53 b4b5q54 b5b5q55 b6b5q56 b7b5q57 |
|
|
| b0b6q60 b1b6q61 b2b6q62 b3b6q63 b4b6q64 b5b6q65 b6b6q66 b7b6q67 |
|
|
| b0b7q70 b1b7q71 b2b7q72 b3b7q73 b4b7q74 b5b7q75 b6b7q76 b7b7q77 |
|
|
|
|
Note that q00,q01,...,q60,..,q77 is the quantization matrix specified
|
|
during the compression stage.
|
|
Note that in the above descaling matrix description,
|
|
bibj = bjbi, and bibjqji implies multiplying bi,bj and qji.
|
|
The descaling matrix can be precomputed at the start of the component
|
|
scan (JPEG terminology).
|
|
|
|
2. After T[] has been descaled, for each column of the descaled matrix,
|
|
X[], perform a 8 point inverse dct and write results back to X[] in
|
|
column order.
|
|
Note that input to 8 point inverse dct is out of order, i.e. x0, x4,
|
|
x2, x6, x5, x1, x7, x3, but output is in order.
|
|
y0, y1, y2, y3, y4, y5, y6, y7
|
|
3. After all eight column inverse dcts have been computed, perform
|
|
8 point inverse dct on each row of X[] and write results to Y[]
|
|
in row order.
|
|
4. The Y[] matrix values must be rounded to meet the specifications of
|
|
the input data that was compressed. Typically, for image data, this
|
|
implies restricting Y[] to take on values only in the range 0 - 255.
|
|
|
|
NOTES
|
|
Author: V. Bhaskaran, HPL, PaloAlto. Telnet: 7-7153.
|
|
bhaskara@hplvab.hpl.hp.com
|
|
Version: 0 (5-29-92).
|
|
*/
|
|
|
|
|
|
/* -------------------- _iljpgDeDCTFull -------------------------- */
|
|
/* Do a full 8x8 inverse DCT, from *pSrc to *pDst, where each "scan line"
|
|
in the 8x8 block pointed to by pDst is "nBytesPerRow" bytes away.
|
|
pRevScale is from DCTRevScaleTables[i], where i is the Q table index
|
|
for this component.
|
|
*/
|
|
ILJPG_PRIVATE_EXTERN
|
|
void _iljpgDeDCTFull (
|
|
int *pSrc,
|
|
long nBytesPerRow,
|
|
iljpgPtr ix, /* RETURNED */
|
|
float *pRevScale
|
|
)
|
|
{
|
|
int i;
|
|
int *zptr;
|
|
float ox[64];
|
|
float in0, in1, in2, in3, in4, in5, in6, in7;
|
|
float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
|
float tmp;
|
|
int clipValue;
|
|
iljpgPtr ixaddr;
|
|
float *oxaddr;
|
|
/* Constants needed by the 16 point Winograd Fourier Transform for inv. DCT */
|
|
float b1 = 1.41421356;
|
|
float b2 = -2.61312587;
|
|
float b3 = 1.41421356;
|
|
float b4 = 1.08239220;
|
|
float b5 = 0.76536686;
|
|
|
|
|
|
oxaddr = ox;
|
|
zptr = &_iljpgZigzagTable[0]; /* zigzag scanning order */
|
|
tmp = 128.0; /* JPEG +128 shift in spatial domain for DCT output */
|
|
|
|
/* do 1-D inverse DCT along columns. setup input data, which is out of order */
|
|
for (i = 0; i < 8; i++, oxaddr++, zptr++, pRevScale++, tmp = 0.0) {
|
|
|
|
in0 = *(pSrc + zptr[0]) * pRevScale[0] + tmp; /* Add 128.0 to first DCT only */
|
|
in1 = *(pSrc + zptr[32]) * pRevScale[32];
|
|
in2 = *(pSrc + zptr[16]) * pRevScale[16];
|
|
in3 = *(pSrc + zptr[48]) * pRevScale[48];
|
|
in4 = *(pSrc + zptr[40]) * pRevScale[40];
|
|
in5 = *(pSrc + zptr[8]) * pRevScale[8];
|
|
in6 = *(pSrc + zptr[56]) * pRevScale[56];
|
|
in7 = *(pSrc + zptr[24]) * pRevScale[24];
|
|
|
|
/* Stage 0 */
|
|
tmp4 = in4 - in7;
|
|
tmp5 = in5 + in6;
|
|
tmp6 = in5 - in6;
|
|
tmp7 = in4 + in7;
|
|
|
|
/* Stage 1 */
|
|
tmp2 = in2 - in3;
|
|
tmp3 = in2 + in3;
|
|
in5 = tmp5 - tmp7;
|
|
in7 = tmp5 + tmp7;
|
|
|
|
/* Stage 1.1 */
|
|
tmp = tmp4 - tmp6;
|
|
tmp = b5 * tmp;
|
|
|
|
/* Stage 2 */
|
|
in2 = b1 * tmp2;
|
|
in4 = b2 * tmp4;
|
|
tmp5 = b3 * in5;
|
|
in6 = b4 * tmp6;
|
|
tmp0 = in0 + in1;
|
|
tmp1 = in0 - in1;
|
|
in2 -= tmp3;
|
|
in4 += tmp;
|
|
in6 -= tmp;
|
|
|
|
/* Stage 3 */
|
|
in6 -= in7;
|
|
tmp5 -= in6;
|
|
|
|
/* Stage 4 */
|
|
in0 = tmp0 + tmp3;
|
|
in1 = tmp1 + in2;
|
|
tmp2 = tmp1 - in2;
|
|
in3 = tmp0 - tmp3;
|
|
tmp4 = in4 + tmp5;
|
|
|
|
/* Stage 5 */
|
|
*oxaddr = in0 + in7; /* y0 */
|
|
*(oxaddr+8) = in1 + in6; /* y1 */
|
|
*(oxaddr+16) = tmp2 + tmp5; /* y2 */
|
|
*(oxaddr+24) = in3 - tmp4; /* y3 */
|
|
*(oxaddr+32) = in3 + tmp4; /* y4 */
|
|
*(oxaddr+40) = tmp2 - tmp5; /* y5 */
|
|
*(oxaddr+48) = in1 - in6; /* y6 */
|
|
*(oxaddr+56) = in0 - in7; /* y7 */
|
|
}
|
|
|
|
ixaddr = ix;
|
|
oxaddr = ox;
|
|
for (i = 0; i < 8; i++) { /* do 1-D inverse DCT along rows */
|
|
|
|
/* setup input data - input data is out of order */
|
|
in0 = *oxaddr;
|
|
in1 = *(oxaddr+4);
|
|
in2 = *(oxaddr+2);
|
|
in3 = *(oxaddr+6);
|
|
in4 = *(oxaddr+5);
|
|
in5 = *(oxaddr+1);
|
|
in6 = *(oxaddr+7);
|
|
in7 = *(oxaddr+3);
|
|
|
|
/* Stage 0 */
|
|
tmp4 = in4 - in7;
|
|
tmp5 = in5 + in6;
|
|
tmp6 = in5 - in6;
|
|
tmp7 = in4 + in7;
|
|
|
|
/* Stage 1 */
|
|
tmp2 = in2 - in3;
|
|
tmp3 = in2 + in3;
|
|
in5 = tmp5 - tmp7;
|
|
in7 = tmp5 + tmp7;
|
|
|
|
/* Stage 1.1 */
|
|
tmp = tmp4 - tmp6;
|
|
tmp = b5 * tmp;
|
|
|
|
/* Stage 2 */
|
|
tmp0 = in0 + in1;
|
|
tmp1 = in0 - in1;
|
|
in2 = b1 * tmp2;
|
|
in4 = b2 * tmp4 + tmp;
|
|
tmp5 = b3 * in5;
|
|
in6 = b4 * tmp6 - tmp;
|
|
in2 -= tmp3;
|
|
|
|
/* Stage 2.1 */
|
|
in6 -= in7;
|
|
tmp5 -= in6;
|
|
|
|
/* Stage 3 */
|
|
in0 = tmp0 + tmp3;
|
|
in1 = tmp1 + in2;
|
|
tmp2 = tmp1 - in2;
|
|
in3 = tmp0 - tmp3;
|
|
tmp4 = in4 + tmp5;
|
|
|
|
/* Stage 4: clip values to 0..255 and store */
|
|
clipValue = (int)(in0 + in7); /* y0 */
|
|
ILJPG_CLIP_256 (fClipG0, fClipR0)
|
|
*ixaddr = clipValue;
|
|
clipValue = (int)(in1 + in6); /* y1 */
|
|
ILJPG_CLIP_256 (fClipG1, fClipR1)
|
|
*(ixaddr+1) = clipValue;
|
|
clipValue = (int)(tmp2 + tmp5); /* y2 */
|
|
ILJPG_CLIP_256 (fClipG2, fClipR2)
|
|
*(ixaddr+2) = clipValue;
|
|
clipValue = (int)(in3 - tmp4); /* y3 */
|
|
ILJPG_CLIP_256 (fClipG3, fClipR3)
|
|
*(ixaddr+3) = clipValue;
|
|
clipValue = (int)(in3 + tmp4); /* y4 */
|
|
ILJPG_CLIP_256 (fClipG4, fClipR4)
|
|
*(ixaddr+4) = clipValue;
|
|
clipValue = (int)(tmp2 - tmp5); /* y5 */
|
|
ILJPG_CLIP_256 (fClipG5, fClipR5)
|
|
*(ixaddr+5) = clipValue;
|
|
clipValue = (int)(in1 - in6); /* y6 */
|
|
ILJPG_CLIP_256 (fClipG6, fClipR6)
|
|
*(ixaddr+6) = clipValue;
|
|
clipValue = (int)(in0 - in7); /* y7 */
|
|
ILJPG_CLIP_256 (fClipG7, fClipR7)
|
|
*(ixaddr+7) = clipValue;
|
|
|
|
oxaddr += 8;
|
|
ixaddr += nBytesPerRow;
|
|
}
|
|
|
|
/* Goto points for above clip macros */
|
|
return;
|
|
|
|
ILJPG_CLIP_256_LABEL (fClipG0, fClipR0)
|
|
ILJPG_CLIP_256_LABEL (fClipG1, fClipR1)
|
|
ILJPG_CLIP_256_LABEL (fClipG2, fClipR2)
|
|
ILJPG_CLIP_256_LABEL (fClipG3, fClipR3)
|
|
ILJPG_CLIP_256_LABEL (fClipG4, fClipR4)
|
|
ILJPG_CLIP_256_LABEL (fClipG5, fClipR5)
|
|
ILJPG_CLIP_256_LABEL (fClipG6, fClipR6)
|
|
ILJPG_CLIP_256_LABEL (fClipG7, fClipR7)
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
float implementation of inverse quantize and inverse dct.
|
|
Assumes that only the first 4x4 submatrix of DCT
|
|
coefficients is non-zero.
|
|
Input and output in integer format.
|
|
|
|
This reduces the fast inverse DCT multiply and add count
|
|
from 80 multiplies, 464 additions to 60 multiplies,
|
|
252 additions.
|
|
PURPOSE
|
|
perform inverse quantization and inverse DCT of a 8x8 array.
|
|
Data is dezigzagged during the inverse quantization process.
|
|
|
|
NOTES
|
|
includes the +128 shift in inverse DCT as per JPEG spec. This shift is
|
|
accomplished by shifting the DC value by 128 prior to performing the
|
|
inverse DCT.
|
|
METHOD
|
|
8x8 INVERSE DCT
|
|
|
|
This implementation is based on computation of a 8 point inverse DCT
|
|
using a 16 point Winograd Fourier Transform.
|
|
The winograd fourier transform method requires 5 multiplies and 29
|
|
additions for a 8 point inverse dct.
|
|
|
|
Let T[] be a 8x8 input DCT array for which we need to perform the
|
|
inverse DCT.
|
|
Note that the matrix shown below suggests that the DCT matrix has
|
|
only 16 non-zero coefficients and the coefficient locations are
|
|
as indicated in the matrix shown below.
|
|
|
|
| t00 t01 t02 t03 --- --- --- --- |
|
|
| t10 t11 t12 t13 --- --- --- --- |
|
|
| t20 t21 t22 t23 --- --- --- --- |
|
|
T[] = | t30 t31 t32 t33 --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
|
|
1. The T[] matrix values are descaled by the inverse DCT denormalization
|
|
values and the quantization matrix values.
|
|
If we denote T[] = {t(i,j)}, S[] = {s(i,j)}, and X[] = {y(i,j)},
|
|
then,
|
|
X(i,j) = s(i,j) * t(i,j)
|
|
Here, S[] is the descaling matrix and includes quantization matrix.
|
|
Since only 1/4th of the T[] matrix is non-zero we need to descale
|
|
only these components. The rest are simply accounted for by setting
|
|
the corresponding locations in X[] to zero.
|
|
|
|
Define a[n] as
|
|
a[n] = cos (n pi / 16) / 2 C[n], pi = 3.1415....
|
|
and,
|
|
C[0] = 1 / sqrt(2), C[1] = C[2] = ... = C[7] = 1,
|
|
Define b[n] as
|
|
b0 = a[0]
|
|
bi = 2 a[i], i = 1,2,...,7
|
|
|
|
Then, descaling matrix S[] has the following structure
|
|
| b0b0q00 b1b0q01 b2b0q02 b3b0q03 b4b0q04 b5b0q05 b6b0q06 b7b0q07 |
|
|
| b0b1q10 b1b1q11 b2b1q12 b3b1q13 b4b1q14 b5b1q15 b6b1q16 b7b1q17 |
|
|
| b0b2q20 b1b2q21 b2b2q22 b3b2q23 b4b2q24 b5b2q25 b6b2q26 b7b2q27 |
|
|
| b0b3q30 b1b3q31 b2b3q32 b3b3q33 b4b3q34 b5b3q35 b6b3q36 b7b3q37 |
|
|
| b0b4q40 b1b4q41 b2b4q42 b3b4q43 b4b4q44 b5b4q45 b6b4q46 b7b4q47 |
|
|
| b0b5q50 b1b5q51 b2b5q52 b3b5q53 b4b5q54 b5b5q55 b6b5q56 b7b5q57 |
|
|
| b0b6q60 b1b6q61 b2b6q62 b3b6q63 b4b6q64 b5b6q65 b6b6q66 b7b6q67 |
|
|
| b0b7q70 b1b7q71 b2b7q72 b3b7q73 b4b7q74 b5b7q75 b6b7q76 b7b7q77 |
|
|
|
|
Note that q00,q01,...,q60,..,q77 is the quantization matrix specified
|
|
during the compression stage.
|
|
Note that in the above descaling matrix description,
|
|
bibj = bjbi, and bibjqji implies multiplying bi,bj and qji.
|
|
The descaling matrix can be precomputed at the start of the component
|
|
scan (JPEG terminology).
|
|
|
|
2. After T[] has been descaled, for each column of the descaled matrix,
|
|
X[], perform a 8 point inverse dct and write results back to X[] in
|
|
column order. A pruned dct which uses 4 input points and generates
|
|
8 output points is used.
|
|
Note that input to 8 point inverse dct is out of order, i.e. x0, x4,
|
|
x2, x6, x5, x1, x7, x3, but output is in order.
|
|
y0, y1, y2, y3, y4, y5, y6, y7
|
|
Since we know that only the first four components of each column is
|
|
nonzero, we exploit this in pruning our fast DCT computation, thus,
|
|
reducing the multiplies/adds by a factor of two.
|
|
|
|
3. After the first four column inverse dcts have been computed, perform
|
|
8 point inverse dct on each row of X[] and write results to Y[]
|
|
in row order.
|
|
Since we know that the first four components along each row could
|
|
be non-zero (the remaining have to be zero as per the structure of
|
|
the X[] matrix), we can exploit this in pruning the fast DCT
|
|
computation, and thereby, reducing the multiplies/adds by a factor
|
|
of two.
|
|
4. The Y[] matrix values must be rounded to meet the specifications of
|
|
the input data that was compressed. Typically, for image data, this
|
|
implies restricting Y[] to take on values only in the range 0 - 255.
|
|
|
|
NOTES
|
|
Author: V. Bhaskaran, HPL, PaloAlto. Telnet: 7-7153.
|
|
Version: 0 (5-29-92).
|
|
*/
|
|
|
|
/* -------------------- _iljpgDeDCT4x4 -------------------------- */
|
|
/* Do an inverse DCT, from *pSrc to *pDst, each a ptr to 64 ints.
|
|
Assumes that only the top-left 4x4 DCT coefficients are non-zero.
|
|
pRevScale is from DCTRevScaleTables[i], where i is the Q table index
|
|
for this component.
|
|
*/
|
|
ILJPG_PRIVATE_EXTERN
|
|
void _iljpgDeDCT4x4 (
|
|
int *pSrc,
|
|
long nBytesPerRow,
|
|
iljpgPtr ix, /* RETURNED */
|
|
float *pRevScale
|
|
)
|
|
{
|
|
int i;
|
|
int *zptr;
|
|
float ox[64];
|
|
float in0, in2, in3, in4, in5, in7;
|
|
float tmp0, tmp1, tmp2, tmp5, tmp6, tmp7;
|
|
float tmp;
|
|
float *oxaddr;
|
|
int clipValue;
|
|
iljpgPtr ixaddr;
|
|
/* Constants needed by the 16 point Winograd Fourier Transform for inv. DCT */
|
|
float b1 = 1.41421356;
|
|
float b2 = -2.61312587;
|
|
float b3 = 1.41421356;
|
|
float b4 = 1.08239220;
|
|
float b5 = 0.76536686;
|
|
|
|
#ifdef NOTDEF
|
|
orxptr = ox;
|
|
rsptr = pRevScale;
|
|
rzptr = &_iljpgZigzagTable[0];
|
|
/* descale-dequantize dct coefficients - need to do this for 4x4 submatrix */
|
|
for (i = 0; i < 4; i++, orxptr += 8, rsptr += 8, rzptr += 8) {
|
|
for (j = 0, ocxptr = orxptr, csptr = rsptr, czptr = rzptr;
|
|
j < 4; j++, ocxptr++, czptr++) {
|
|
k = *(pSrc + *czptr);
|
|
*ocxptr = (k * *csptr++);
|
|
}
|
|
}
|
|
|
|
*ox += 128.0; /* JPEG +128 shift in spatial domain for DCT output */
|
|
#endif
|
|
|
|
oxaddr = ox;
|
|
zptr = &_iljpgZigzagTable[0]; /* zigzag scanning order */
|
|
tmp = 128.0; /* JPEG +128 shift in spatial domain for DCT output */
|
|
|
|
/* do 1-D inverse DCT along columns. setup input data, which is out of order */
|
|
for (i = 0; i < 4; i++, oxaddr++, zptr++, pRevScale++, tmp = 0.0) {
|
|
|
|
in0 = *(pSrc + zptr[0]) * pRevScale[0] + tmp; /* Add 128.0 to first DCT only */
|
|
in2 = *(pSrc + zptr[16]) * pRevScale[16];
|
|
in5 = *(pSrc + zptr[8]) * pRevScale[8];
|
|
in7 = *(pSrc + zptr[24]) * pRevScale[24];
|
|
|
|
#ifdef NOTDEF
|
|
in0 = *oxaddr;
|
|
in2 = *(oxaddr+16);
|
|
in5 = *(oxaddr+8);
|
|
in7 = *(oxaddr+24);
|
|
#endif
|
|
|
|
/* Stage 1 */
|
|
tmp5 = in5 - in7;
|
|
tmp7 = in5 + in7;
|
|
|
|
/* Stage 2 */
|
|
tmp = -in7 -in5;
|
|
tmp = b5 * tmp;
|
|
|
|
tmp2 = b1 * in2;
|
|
tmp6 = b4 * in5;
|
|
in4 = b2 * -in7;
|
|
in5 = b3 * tmp5;
|
|
in4 += tmp;
|
|
tmp6 -= tmp;
|
|
tmp2 -= in2;
|
|
|
|
/* Stage 3 */
|
|
tmp6 -= tmp7;
|
|
in5 -= tmp6;
|
|
|
|
/* Stage 4 */
|
|
tmp0 = in0 + in2;
|
|
tmp1 = in0 + tmp2;
|
|
in3 = in0 - in2;
|
|
in4 += in5;
|
|
tmp2 = in0 - tmp2;
|
|
|
|
/* Stage 5 */
|
|
*oxaddr = tmp0 + tmp7; /* y0 */
|
|
*(oxaddr+8) = tmp1 + tmp6; /* y1 */
|
|
*(oxaddr+16) = tmp2 + in5; /* y2 */
|
|
*(oxaddr+24) = in3 - in4; /* y3 */
|
|
*(oxaddr+32) = in3 + in4; /* y4 */
|
|
*(oxaddr+40) = tmp2 - in5; /* y5 */
|
|
*(oxaddr+48) = tmp1 - tmp6; /* y6 */
|
|
*(oxaddr+56) = tmp0 - tmp7; /* y7 */
|
|
}
|
|
|
|
ixaddr = ix;
|
|
oxaddr = ox;
|
|
for (i = 0; i < 8; i++) { /* do 1-D inverse DCT along rows */
|
|
|
|
/* setup input data - input data is out of order */
|
|
in0 = *oxaddr;
|
|
in2 = *(oxaddr+2);
|
|
in5 = *(oxaddr+1);
|
|
in7 = *(oxaddr+3);
|
|
|
|
/* Stage 1 */
|
|
tmp5 = in5 - in7;
|
|
tmp7 = in5 + in7;
|
|
|
|
/* Stage 2 */
|
|
tmp = -in7 -in5;
|
|
tmp = b5 * tmp;
|
|
|
|
tmp2 = b1 * in2;
|
|
tmp6 = b4 * in5;
|
|
in4 = b2 * -in7;
|
|
in5 = b3 * tmp5;
|
|
in4 += tmp;
|
|
tmp6 -= tmp;
|
|
|
|
/* Stage 3 */
|
|
tmp2 -= in2;
|
|
|
|
/* Stage 3.1 */
|
|
tmp6 -= tmp7;
|
|
in5 -= tmp6;
|
|
|
|
/* Stage 4 */
|
|
tmp0 = in0 + in2;
|
|
tmp1 = in0 + tmp2;
|
|
in3 = in0 - in2;
|
|
in4 += in5;
|
|
tmp2 = in0 - tmp2;
|
|
|
|
/* Stage 5 */
|
|
|
|
clipValue = (int)(tmp0 + tmp7); /* y0 */
|
|
ILJPG_CLIP_256 (pClipG0, pClipR0)
|
|
*ixaddr = clipValue;
|
|
clipValue = (int)(tmp1 + tmp6); /* y1 */
|
|
ILJPG_CLIP_256 (pClipG1, pClipR1)
|
|
*(ixaddr+1) = clipValue;
|
|
clipValue = (int)(tmp2 + in5); /* y2 */
|
|
ILJPG_CLIP_256 (pClipG2, pClipR2)
|
|
*(ixaddr+2) = clipValue;
|
|
clipValue = (int)(in3 - in4); /* y3 */
|
|
ILJPG_CLIP_256 (pClipG3, pClipR3)
|
|
*(ixaddr+3) = clipValue;
|
|
clipValue = (int)(in3 + in4); /* y4 */
|
|
ILJPG_CLIP_256 (pClipG4, pClipR4)
|
|
*(ixaddr+4) = clipValue;
|
|
clipValue = (int)(tmp2 - in5); /* y5 */
|
|
ILJPG_CLIP_256 (pClipG5, pClipR5)
|
|
*(ixaddr+5) = clipValue;
|
|
clipValue = (int)(tmp1 - tmp6); /* y6 */
|
|
ILJPG_CLIP_256 (pClipG6, pClipR6)
|
|
*(ixaddr+6) = clipValue;
|
|
clipValue = (int)(tmp0 - tmp7); /* y7 */
|
|
ILJPG_CLIP_256 (pClipG7, pClipR7)
|
|
*(ixaddr+7) = clipValue;
|
|
|
|
ixaddr += nBytesPerRow;
|
|
oxaddr += 8;
|
|
|
|
}
|
|
|
|
/* Goto points for above clip macros */
|
|
return;
|
|
|
|
ILJPG_CLIP_256_LABEL (pClipG0, pClipR0)
|
|
ILJPG_CLIP_256_LABEL (pClipG1, pClipR1)
|
|
ILJPG_CLIP_256_LABEL (pClipG2, pClipR2)
|
|
ILJPG_CLIP_256_LABEL (pClipG3, pClipR3)
|
|
ILJPG_CLIP_256_LABEL (pClipG4, pClipR4)
|
|
ILJPG_CLIP_256_LABEL (pClipG5, pClipR5)
|
|
ILJPG_CLIP_256_LABEL (pClipG6, pClipR6)
|
|
ILJPG_CLIP_256_LABEL (pClipG7, pClipR7)
|
|
}
|
|
|
|
/*
|
|
float implementation of inverse quantize and inverse dct.
|
|
PURPOSE
|
|
perform inverse quantization and inverse DCT of a 8x8 array.
|
|
Assumes that all coefficients of 8x8 DCT matrix except DC coefficient
|
|
are zero.
|
|
Input and output in integer format.
|
|
NOTES
|
|
includes the +128 shift in inverse DCT as per JPEG spec. This shift is
|
|
accomplished by shifting the DC value by 128 prior to performing the
|
|
inverse DCT.
|
|
METHOD
|
|
8x8 INVERSE DCT
|
|
|
|
Let T[] be a 8x8 input DCT array for which we need to perform the
|
|
inverse DCT.
|
|
Note that the matrix shown below suggests that the DCT matrix has
|
|
only 16 non-zero coefficients and the coefficient locations are
|
|
as indicated in the matrix shown below.
|
|
|
|
| t00 --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
T[] = | --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
| --- --- --- --- --- --- --- --- |
|
|
|
|
1. The T[] matrix values are descaled by the inverse DCT denormalization
|
|
values and the quantization matrix values.
|
|
If we denote T[] = {t(i,j)}, S[] = {s(i,j)}, and X[] = {y(i,j)},
|
|
then,
|
|
X(i,j) = s(i,j) * t(i,j)
|
|
Here, S[] is the descaling matrix and includes quantization matrix.
|
|
Since only 1/4th of the T[] matrix is non-zero we need to descale
|
|
only these components. The rest are simply accounted for by setting
|
|
the corresponding locations in X[] to zero.
|
|
|
|
Define a[n] as
|
|
a[n] = cos (n pi / 16) / 2 C[n], pi = 3.1415....
|
|
and,
|
|
C[0] = 1 / sqrt(2), C[1] = C[2] = ... = C[7] = 1,
|
|
Define b[n] as
|
|
b0 = a[0]
|
|
bi = 2 a[i], i = 1,2,...,7
|
|
|
|
Then, descaling matrix S[] has the following structure
|
|
| b0b0q00 b1b0q01 b2b0q02 b3b0q03 b4b0q04 b5b0q05 b6b0q06 b7b0q07 |
|
|
| b0b1q10 b1b1q11 b2b1q12 b3b1q13 b4b1q14 b5b1q15 b6b1q16 b7b1q17 |
|
|
| b0b2q20 b1b2q21 b2b2q22 b3b2q23 b4b2q24 b5b2q25 b6b2q26 b7b2q27 |
|
|
| b0b3q30 b1b3q31 b2b3q32 b3b3q33 b4b3q34 b5b3q35 b6b3q36 b7b3q37 |
|
|
| b0b4q40 b1b4q41 b2b4q42 b3b4q43 b4b4q44 b5b4q45 b6b4q46 b7b4q47 |
|
|
| b0b5q50 b1b5q51 b2b5q52 b3b5q53 b4b5q54 b5b5q55 b6b5q56 b7b5q57 |
|
|
| b0b6q60 b1b6q61 b2b6q62 b3b6q63 b4b6q64 b5b6q65 b6b6q66 b7b6q67 |
|
|
| b0b7q70 b1b7q71 b2b7q72 b3b7q73 b4b7q74 b5b7q75 b6b7q76 b7b7q77 |
|
|
|
|
Note that q00,q01,...,q60,..,q77 is the quantization matrix specified
|
|
during the compression stage.
|
|
Note that in the above descaling matrix description,
|
|
bibj = bjbi, and bibjqji implies multiplying bi,bj and qji.
|
|
The descaling matrix can be precomputed at the start of the component
|
|
scan (JPEG terminology).
|
|
|
|
2. After T[] has been descaled, compute y(0,0) = t(0,0) * s(0,0) + 128.
|
|
set y(i,j) = y(0,0), for all i = 0,7, j = 0,7.
|
|
4. The Y[] matrix values must be rounded to meet the specifications of
|
|
the input data that was compressed. Typically, for image data, this
|
|
implies restricting Y[] to take on values only in the range 0 - 255.
|
|
NOTES
|
|
Author: V. Bhaskaran, HPL, PaloAlto. Telnet: 7-7153.
|
|
Version: 0 (5-29-92).
|
|
*/
|
|
|
|
/* -------------------- _iljpgDeDCTDCOnly -------------------------- */
|
|
/* Do an inverse DCT, from *pSrc to *pDst, each a ptr to 64 ints.
|
|
Assumes that only the top-left coefficient (the DC) is non-zero.
|
|
pRevScale is from DCTRevScaleTables[i], where i is the Q table index
|
|
for this component.
|
|
*/
|
|
ILJPG_PRIVATE_EXTERN
|
|
void _iljpgDeDCTDCOnly (
|
|
int *pSrc,
|
|
long nBytesPerRow,
|
|
iljpgPtr pDst, /* RETURNED */
|
|
float *pRevScale
|
|
)
|
|
{
|
|
int i, dc;
|
|
int j;
|
|
|
|
j = *pSrc;
|
|
j = (j < -2047) ? -2047 : ((j > 2047) ? 2047 : j);
|
|
dc = (int)(j * *pRevScale + 128.0);
|
|
if (dc < 0) dc = 0; else if (dc > 255) dc = 255;
|
|
|
|
/*
|
|
since only DC value is nonzero, inverse DCT is simply a copy of the
|
|
descaled and dequantized DC value copied to rest of 8x8 array.
|
|
*/
|
|
for (i = 0; i < 8; i++, pDst += nBytesPerRow) {
|
|
pDst[0] = dc;
|
|
pDst[1] = dc;
|
|
pDst[2] = dc;
|
|
pDst[3] = dc;
|
|
pDst[4] = dc;
|
|
pDst[5] = dc;
|
|
pDst[6] = dc;
|
|
pDst[7] = dc;
|
|
}
|
|
}
|
|
|
|
|