/* -*-C-*- ************************************************************************* * * File: win_dct.c * RCS: $Header: /ImageMagick/delegates/fpx/jpeg/win_dct.c,v 1.2 2000/12/23 22:37:48 bfriesen Exp $ * Description: Forward DCT based on Winograd's algorithm * Author: Gregory S. Yovanof * Created: Fri Dec 4 11:04:22 1992 * Initial Source Release: Wed Jan 17 1996 * Language: C * Package: Hewlett-Packard JPEG Encoder/Decoder * * Copyright (c) 1999 Digital Imaging Group, Inc. * For conditions of distribution and use, see copyright notice * in Flashpix.h * ****************************************************************************** */ #include #include #include #include "jpegconf.h" #include "dct.h" #include "win_dct.h" /* DCT-Scale Factors -- This table has been zigzagged */ static double Float2DDctNorm[] = { 0.125000, 0.090120, 0.090120, 0.095671, 0.064973, 0.095671, 0.106304, 0.068975, 0.068975, 0.106304, 0.125000, 0.076641, 0.073223, 0.076641, 0.125000, 0.159095, 0.090120, 0.081361, 0.081361, 0.090120, 0.159095, 0.230970, 0.114701, 0.095671, 0.090404, 0.095671, 0.114701, 0.230970, 0.453064, 0.166520, 0.121766, 0.106304, 0.106304, 0.121766, 0.166520, 0.453064, 0.326641, 0.176777, 0.135299, 0.125000, 0.135299, 0.176777, 0.326641, 0.346760, 0.196424, 0.159095, 0.159095, 0.196424, 0.346760, 0.385299, 0.230970, 0.202489, 0.230970, 0.385299, 0.453064, 0.293969, 0.293969, 0.453064, 0.576641, 0.426777, 0.576641, 0.837153, 0.837153, 1.642134 }; void Fill_Winograd_Quant_Table(const int *in, /* regular quantization table */ int *out) /* winograd quantization table */ { double *fptr; int i, q; #ifdef DEBUG if (((-1L) >> 15) >= 0) { debug("Fill_Winograd_Quant_Table: This compiler does not shift signed bit"); } #endif fptr = Float2DDctNorm; for (i = 0; i < 63; i++) { *out++ = q = FIX((*fptr++) / ((float) *in++)); } /* * Note that in order for FIX(fptr[i]/in[i]) to fit inside 16-bit signed * int, (fptr[i]/in[i] < 1) => (in[i] > fptr[i]) (1). Since in[i] >= 1, * and (fptr[i] < 1) for i = 0 to 62, (1) is true for i = 0 to 62. For * i = 63, (1) is true only when in[63] >= 2 */ *out++ = q = FIX((*fptr++) / (*in < 2 ? 2.0 : (float)*in)); } /* Associate dummy variables with registers */ #define in0 r0 #define in1 r0 #define in2 r0 #define in3 r0 #define in4 r2 #define in5 r4 #define in6 r1 #define in7 r1 #define stg0 r1 #define stg1 r1 #define stg2 r0 #define stg3 r0 #define stg4 tmp #define stg5 r7 #define stg6 r6 #define stg7 r5 #define stg10 r3 #define stg11 r0 #define stg12 r4 #define stg13 r2 #define stg14 r0 #define stg15 r2 #define stg16 r1 #define stg23 r0 #define stg32 r0 #define stg34 r0 #define stg35 r2 #define stg36 r1 #define stg45 r3 #define stg47 r2 #define hold1 r0 #define hold2 r1 #define hold3 r3 void Dct(int *x) { register int *jptr, r0,r1,r2,r3,r4,r5,r6,r7, tmp, i; /* Do Rows */ for (jptr = x, i = 8; i > 0; i--, jptr += 8) { in0 = jptr[0]; in7 = jptr[7]; stg7 = in0 - in7; stg0 = in0 + in7; in3 = jptr[3]; in4 = jptr[4]; stg4 = in3 - in4; stg3 = in3 + in4; stg10 = stg0 + stg3; stg13 = stg0 - stg3; in1 = jptr[1]; in6 = jptr[6]; stg6 = in1 - in6; stg1 = in1 + in6; in2 = jptr[2]; in5 = jptr[5]; stg5 = in2 - in5; stg2 = in2 + in5; stg12 = stg1 - stg2; stg11 = stg1 + stg2; jptr[0] = stg10 + stg11; jptr[4] = stg10 - stg11; stg23 = stg12 + stg13; stg32 = SCALEM(a1*stg23); jptr[2] = stg32 + stg13; jptr[6] = stg13 - stg32; stg14 = - stg4 - stg5; stg15 = stg5 + stg6; stg35 = SCALEM(a3*stg15); stg16 = stg6 + stg7; hold3 = SCALEM(a4*stg16); hold2 = SCALEM(a5*(stg14+stg16)); hold1 = SCALEM(a2*stg14); stg34 = -hold1 - hold2; stg36 = hold3 - hold2; stg45 = stg35 + stg7; stg47 = stg7 - stg35; jptr[5] = stg47 + stg34; jptr[1] = stg45 + stg36; jptr[7] = stg45 - stg36; jptr[3] = -stg34 + stg47; } /** Do Columns **/ for (jptr = x, i = 8; i > 0; i--, jptr++) { in0 = jptr[0]; in7 = jptr[56]; stg7 = in0 - in7; stg0 = in0 + in7; in3 = jptr[24]; in4 = jptr[32]; stg4 = in3 - in4; stg3 = in3 + in4; stg10 = stg0 + stg3; stg13 = stg0 - stg3; in1 = jptr[8]; in6 = jptr[48]; stg6 = in1 - in6; stg1 = in1 + in6; in2 = jptr[16]; in5 = jptr[40]; stg5 = in2 - in5; stg2 = in2 + in5; stg12 = stg1 - stg2; stg11 = stg1 + stg2; jptr[0] = stg10 + stg11; jptr[32] = stg10 - stg11; stg23 = stg12 + stg13; stg32 = SCALEM(a1*stg23); jptr[16] = stg32 + stg13; jptr[48] = stg13 - stg32; stg14 = - stg4 - stg5; stg15 = stg5 + stg6; stg35 = SCALEM(a3*stg15); stg16 = stg6 + stg7; hold3 = SCALEM(a4*stg16); hold2 = SCALEM(a5*(stg14+stg16)); hold1 = SCALEM(a2*stg14); stg34 = -hold1 - hold2; stg36 = hold3 - hold2; stg45 = stg35 + stg7; stg47 = stg7 - stg35; jptr[40] = stg47 + stg34; jptr[8] = stg45 + stg36; jptr[56] = stg45 - stg36; jptr[24] = -stg34 + stg47; } }