annotate faanidct.c @ 10311:943b63f364ca libavcodec

Make sure all the bits are written to output in fax data decoder. This fixes decoding TIFF images with fax compression and width being not multiple of eight (and issue 1429).
author kostya
date Tue, 29 Sep 2009 05:55:14 +0000
parents b72f6c4cee12
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
1 /*
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
2 * Floating point AAN IDCT
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
3 * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
4 *
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
5 * This file is part of FFmpeg.
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
6 *
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
11 *
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
15 * Lesser General Public License for more details.
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
16 *
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
20 */
6421
53308ac1a5cc better include
michael
parents: 6418
diff changeset
21 #include "faanidct.h"
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
22
6418
eb740c8e9212 Add explanatory comment to '#define FLOAT float'.
diego
parents: 6415
diff changeset
23 /* To allow switching to double. */
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
24 #define FLOAT float
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
25
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
26 #define B0 1.0000000000000000000000
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
27 #define B1 1.3870398453221474618216 // cos(pi*1/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
28 #define B2 1.3065629648763765278566 // cos(pi*2/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
29 #define B3 1.1758756024193587169745 // cos(pi*3/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
30 #define B4 1.0000000000000000000000 // cos(pi*4/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
31 #define B5 0.7856949583871021812779 // cos(pi*5/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
32 #define B6 0.5411961001461969843997 // cos(pi*6/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
33 #define B7 0.2758993792829430123360 // cos(pi*7/16)sqrt(2)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
34
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
35 #define A4 0.70710678118654752438 // cos(pi*4/16)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
36 #define A2 0.92387953251128675613 // cos(pi*2/16)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
37
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
38 static const FLOAT prescale[64]={
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
39 B0*B0/8, B0*B1/8, B0*B2/8, B0*B3/8, B0*B4/8, B0*B5/8, B0*B6/8, B0*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
40 B1*B0/8, B1*B1/8, B1*B2/8, B1*B3/8, B1*B4/8, B1*B5/8, B1*B6/8, B1*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
41 B2*B0/8, B2*B1/8, B2*B2/8, B2*B3/8, B2*B4/8, B2*B5/8, B2*B6/8, B2*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
42 B3*B0/8, B3*B1/8, B3*B2/8, B3*B3/8, B3*B4/8, B3*B5/8, B3*B6/8, B3*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
43 B4*B0/8, B4*B1/8, B4*B2/8, B4*B3/8, B4*B4/8, B4*B5/8, B4*B6/8, B4*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
44 B5*B0/8, B5*B1/8, B5*B2/8, B5*B3/8, B5*B4/8, B5*B5/8, B5*B6/8, B5*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
45 B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
46 B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8,
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
47 };
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
48
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
49 static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
50 int i;
6471
b72f6c4cee12 Fix unused variable warnings.
diego
parents: 6421
diff changeset
51 FLOAT av_unused tmp0;
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
52 FLOAT s04, d04, s17, d17, s26, d26, s53, d53;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
53 FLOAT os07, os16, os25, os34;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
54 FLOAT od07, od16, od25, od34;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
55
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
56 for(i=0; i<y*8; i+=y){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
57 s17= temp[1*x + i] + temp[7*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
58 d17= temp[1*x + i] - temp[7*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
59 s53= temp[5*x + i] + temp[3*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
60 d53= temp[5*x + i] - temp[3*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
61
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
62 od07= s17 + s53;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
63 od25= (s17 - s53)*(2*A4);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
64
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
65 #if 0 //these 2 are equivalent
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
66 tmp0= (d17 + d53)*(2*A2);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
67 od34= d17*( 2*B6) - tmp0;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
68 od16= d53*(-2*B2) + tmp0;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
69 #else
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
70 od34= d17*(2*(B6-A2)) - d53*(2*A2);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
71 od16= d53*(2*(A2-B2)) + d17*(2*A2);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
72 #endif
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
73
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
74 od16 -= od07;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
75 od25 -= od16;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
76 od34 += od25;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
77
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
78 s26 = temp[2*x + i] + temp[6*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
79 d26 = temp[2*x + i] - temp[6*x + i];
6415
2eb1b18d6282 Remove another temporary variable with which gcc has problems.
michael
parents: 6407
diff changeset
80 d26*= 2*A4;
2eb1b18d6282 Remove another temporary variable with which gcc has problems.
michael
parents: 6407
diff changeset
81 d26-= s26;
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
82
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
83 s04= temp[0*x + i] + temp[4*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
84 d04= temp[0*x + i] - temp[4*x + i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
85
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
86 os07= s04 + s26;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
87 os34= s04 - s26;
6415
2eb1b18d6282 Remove another temporary variable with which gcc has problems.
michael
parents: 6407
diff changeset
88 os16= d04 + d26;
2eb1b18d6282 Remove another temporary variable with which gcc has problems.
michael
parents: 6407
diff changeset
89 os25= d04 - d26;
6407
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
90
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
91 if(type==0){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
92 temp[0*x + i]= os07 + od07;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
93 temp[7*x + i]= os07 - od07;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
94 temp[1*x + i]= os16 + od16;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
95 temp[6*x + i]= os16 - od16;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
96 temp[2*x + i]= os25 + od25;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
97 temp[5*x + i]= os25 - od25;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
98 temp[3*x + i]= os34 - od34;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
99 temp[4*x + i]= os34 + od34;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
100 }else if(type==1){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
101 data[0*x + i]= lrintf(os07 + od07);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
102 data[7*x + i]= lrintf(os07 - od07);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
103 data[1*x + i]= lrintf(os16 + od16);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
104 data[6*x + i]= lrintf(os16 - od16);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
105 data[2*x + i]= lrintf(os25 + od25);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
106 data[5*x + i]= lrintf(os25 - od25);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
107 data[3*x + i]= lrintf(os34 - od34);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
108 data[4*x + i]= lrintf(os34 + od34);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
109 }else if(type==2){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
110 dest[0*stride + i]= av_clip_uint8(((int)dest[0*stride + i]) + lrintf(os07 + od07));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
111 dest[7*stride + i]= av_clip_uint8(((int)dest[7*stride + i]) + lrintf(os07 - od07));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
112 dest[1*stride + i]= av_clip_uint8(((int)dest[1*stride + i]) + lrintf(os16 + od16));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
113 dest[6*stride + i]= av_clip_uint8(((int)dest[6*stride + i]) + lrintf(os16 - od16));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
114 dest[2*stride + i]= av_clip_uint8(((int)dest[2*stride + i]) + lrintf(os25 + od25));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
115 dest[5*stride + i]= av_clip_uint8(((int)dest[5*stride + i]) + lrintf(os25 - od25));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
116 dest[3*stride + i]= av_clip_uint8(((int)dest[3*stride + i]) + lrintf(os34 - od34));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
117 dest[4*stride + i]= av_clip_uint8(((int)dest[4*stride + i]) + lrintf(os34 + od34));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
118 }else{
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
119 dest[0*stride + i]= av_clip_uint8(lrintf(os07 + od07));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
120 dest[7*stride + i]= av_clip_uint8(lrintf(os07 - od07));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
121 dest[1*stride + i]= av_clip_uint8(lrintf(os16 + od16));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
122 dest[6*stride + i]= av_clip_uint8(lrintf(os16 - od16));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
123 dest[2*stride + i]= av_clip_uint8(lrintf(os25 + od25));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
124 dest[5*stride + i]= av_clip_uint8(lrintf(os25 - od25));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
125 dest[3*stride + i]= av_clip_uint8(lrintf(os34 - od34));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
126 dest[4*stride + i]= av_clip_uint8(lrintf(os34 + od34));
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
127 }
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
128 }
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
129 }
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
130
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
131 void ff_faanidct(DCTELEM block[64]){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
132 FLOAT temp[64];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
133 int i;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
134
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
135 emms_c();
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
136
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
137 for(i=0; i<64; i++)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
138 temp[i] = block[i] * prescale[i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
139
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
140 p8idct(block, temp, NULL, 0, 1, 8, 0);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
141 p8idct(block, temp, NULL, 0, 8, 1, 1);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
142 }
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
143
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
144 void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
145 FLOAT temp[64];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
146 int i;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
147
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
148 emms_c();
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
149
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
150 for(i=0; i<64; i++)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
151 temp[i] = block[i] * prescale[i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
152
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
153 p8idct(block, temp, NULL, 0, 1, 8, 0);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
154 p8idct(NULL , temp, dest, line_size, 8, 1, 2);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
155 }
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
156
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
157 void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]){
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
158 FLOAT temp[64];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
159 int i;
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
160
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
161 emms_c();
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
162
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
163 for(i=0; i<64; i++)
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
164 temp[i] = block[i] * prescale[i];
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
165
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
166 p8idct(block, temp, NULL, 0, 1, 8, 0);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
167 p8idct(NULL , temp, dest, line_size, 8, 1, 3);
7f9e2b5893fc floating point AAN IDCT
michael
parents:
diff changeset
168 }