Mercurial > libavcodec.hg
annotate faxcompr.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 27cb9c2c0c6b |
children | 7dd2a45249a9 |
rev | line source |
---|---|
8466 | 1 /* |
2 * CCITT Fax Group 3 and 4 decompression | |
3 * Copyright (c) 2008 Konstantin Shishkov | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * CCITT Fax Group 3 and 4 decompression | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8693
diff
changeset
|
24 * @file libavcodec/faxcompr.c |
8466 | 25 * @author Konstantin Shishkov |
26 */ | |
27 #include "avcodec.h" | |
9428 | 28 #include "get_bits.h" |
9411
4cb7c65fc775
Split bitstream.h, put the bitstream writer stuff in the new file
stefano
parents:
8718
diff
changeset
|
29 #include "put_bits.h" |
8466 | 30 #include "faxcompr.h" |
31 | |
32 #define CCITT_SYMS 104 | |
33 | |
34 static const uint16_t ccitt_syms[CCITT_SYMS] = { | |
35 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, | |
36 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, | |
37 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, | |
38 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, | |
39 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, | |
40 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, | |
41 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, | |
42 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560 | |
43 }; | |
44 | |
45 static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] = | |
46 { | |
47 { | |
48 0x35, 0x07, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, 0x13, 0x14, 0x07, 0x08, 0x08, | |
49 0x03, 0x34, 0x35, 0x2A, 0x2B, 0x27, 0x0C, 0x08, 0x17, 0x03, 0x04, 0x28, 0x2B, | |
50 0x13, 0x24, 0x18, 0x02, 0x03, 0x1A, 0x1B, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | |
51 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x04, 0x05, 0x0A, 0x0B, 0x52, 0x53, 0x54, | |
52 0x55, 0x24, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x4A, 0x4B, 0x32, 0x33, 0x34, 0x1B, | |
53 0x12, 0x17, 0x37, 0x36, 0x37, 0x64, 0x65, 0x68, 0x67, 0xCC, 0xCD, 0xD2, 0xD3, | |
54 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0x98, 0x99, 0x9A, 0x18, 0x9B, | |
55 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F | |
56 }, | |
57 { | |
58 0x37, 0x02, 0x03, 0x02, 0x03, 0x03, 0x02, 0x03, 0x05, 0x04, 0x04, 0x05, 0x07, | |
59 0x04, 0x07, 0x18, 0x17, 0x18, 0x08, 0x67, 0x68, 0x6C, 0x37, 0x28, 0x17, 0x18, | |
60 0xCA, 0xCB, 0xCC, 0xCD, 0x68, 0x69, 0x6A, 0x6B, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, | |
61 0xD7, 0x6C, 0x6D, 0xDA, 0xDB, 0x54, 0x55, 0x56, 0x57, 0x64, 0x65, 0x52, 0x53, | |
62 0x24, 0x37, 0x38, 0x27, 0x28, 0x58, 0x59, 0x2B, 0x2C, 0x5A, 0x66, 0x67, 0x0F, | |
63 0xC8, 0xC9, 0x5B, 0x33, 0x34, 0x35, 0x6C, 0x6D, 0x4A, 0x4B, 0x4C, 0x4D, 0x72, | |
64 0x73, 0x74, 0x75, 0x76, 0x77, 0x52, 0x53, 0x54, 0x55, 0x5A, 0x5B, 0x64, 0x65, | |
65 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F | |
66 } | |
67 }; | |
68 | |
69 static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] = | |
70 { | |
71 { | |
72 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, | |
73 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
74 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
75 8, 8, 8, 8, 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, | |
76 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12, | |
77 12, 12, 12, 12 | |
78 }, | |
79 { | |
80 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 11, | |
81 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, | |
82 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, | |
83 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, | |
84 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12, | |
85 12, 12, 12, 12 | |
86 } | |
87 }; | |
88 | |
89 static const uint8_t ccitt_group3_2d_bits[11] = { | |
90 1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1 | |
91 }; | |
92 | |
93 static const uint8_t ccitt_group3_2d_lens[11] = { | |
94 4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9 | |
95 }; | |
96 | |
97 static VLC ccitt_vlc[2], ccitt_group3_2d_vlc; | |
98 | |
8693
18737839ed27
Add missing void keyword to parameterless function declarations.
diego
parents:
8490
diff
changeset
|
99 av_cold void ff_ccitt_unpack_init(void) |
8466 | 100 { |
101 static VLC_TYPE code_table1[528][2]; | |
102 static VLC_TYPE code_table2[648][2]; | |
103 int i; | |
104 static int initialized = 0; | |
105 | |
106 if(initialized) | |
107 return; | |
108 ccitt_vlc[0].table = code_table1; | |
109 ccitt_vlc[0].table_allocated = 528; | |
110 ccitt_vlc[1].table = code_table2; | |
111 ccitt_vlc[1].table_allocated = 648; | |
112 for(i = 0; i < 2; i++){ | |
113 init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS, | |
114 ccitt_codes_lens[i], 1, 1, | |
115 ccitt_codes_bits[i], 1, 1, | |
116 ccitt_syms, 2, 2, | |
117 INIT_VLC_USE_NEW_STATIC); | |
118 } | |
119 INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11, | |
120 ccitt_group3_2d_lens, 1, 1, | |
121 ccitt_group3_2d_bits, 1, 1, 512); | |
122 initialized = 1; | |
123 } | |
124 | |
125 | |
126 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, | |
8486 | 127 unsigned int pix_left, int *runs, const int *runend) |
8466 | 128 { |
8486 | 129 int mode = 0; |
130 unsigned int run=0; | |
8466 | 131 unsigned int t; |
132 for(;;){ | |
133 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); | |
134 run += t; | |
135 if(t < 64){ | |
136 *runs++ = run; | |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
137 if(runs >= runend){ |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
138 av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
139 return -1; |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
140 } |
8486 | 141 if(pix_left <= run){ |
142 if(pix_left == run) | |
8466 | 143 break; |
144 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); | |
145 return -1; | |
146 } | |
8486 | 147 pix_left -= run; |
8466 | 148 run = 0; |
149 mode = !mode; | |
150 }else if((int)t == -1){ | |
151 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); | |
152 return -1; | |
153 } | |
154 } | |
155 *runs++ = 0; | |
156 return 0; | |
157 } | |
158 | |
159 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, | |
8487 | 160 unsigned int width, int *runs, const int *runend, const int *ref) |
8466 | 161 { |
8487 | 162 int mode = 0, saved_run = 0, t; |
8466 | 163 int run_off = *ref++; |
8487 | 164 unsigned int offs=0, run= 0; |
8466 | 165 |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
166 runend--; // for the last written 0 |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
167 |
8481
f456c3aebe1c
Get rid of pix_left in the 2d code, it is simpler that way.
michael
parents:
8478
diff
changeset
|
168 while(offs < width){ |
8466 | 169 int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); |
170 if(cmode == -1){ | |
171 av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); | |
172 return -1; | |
173 } | |
174 if(!cmode){//pass mode | |
175 run_off += *ref++; | |
176 run = run_off - offs; | |
8485 | 177 offs= run_off; |
8466 | 178 run_off += *ref++; |
8481
f456c3aebe1c
Get rid of pix_left in the 2d code, it is simpler that way.
michael
parents:
8478
diff
changeset
|
179 if(offs > width){ |
8466 | 180 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
181 return -1; | |
182 } | |
183 saved_run += run; | |
184 }else if(cmode == 1){//horizontal mode | |
185 int k; | |
186 for(k = 0; k < 2; k++){ | |
187 run = 0; | |
188 for(;;){ | |
189 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); | |
190 if(t == -1){ | |
191 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); | |
192 return -1; | |
193 } | |
194 run += t; | |
195 if(t < 64) | |
196 break; | |
197 } | |
198 *runs++ = run + saved_run; | |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
199 if(runs >= runend){ |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
200 av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
201 return -1; |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
202 } |
8466 | 203 saved_run = 0; |
8481
f456c3aebe1c
Get rid of pix_left in the 2d code, it is simpler that way.
michael
parents:
8478
diff
changeset
|
204 offs += run; |
8487 | 205 if(offs > width || run > width){ |
8466 | 206 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
207 return -1; | |
208 } | |
209 mode = !mode; | |
210 } | |
211 }else if(cmode == 9 || cmode == 10){ | |
212 av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n"); | |
213 return -1; | |
214 }else{//vertical mode | |
215 run = run_off - offs + (cmode - 5); | |
8490 | 216 run_off -= *--ref; |
8481
f456c3aebe1c
Get rid of pix_left in the 2d code, it is simpler that way.
michael
parents:
8478
diff
changeset
|
217 offs += run; |
8488 | 218 if(offs > width || run > width){ |
8466 | 219 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
220 return -1; | |
221 } | |
222 *runs++ = run + saved_run; | |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
223 if(runs >= runend){ |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
224 av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
225 return -1; |
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
226 } |
8466 | 227 saved_run = 0; |
228 mode = !mode; | |
229 } | |
8483
c8113e1e91c0
Move sync line pointers code to the end of the loop, it is simpler that way.
michael
parents:
8482
diff
changeset
|
230 //sync line pointers |
c8113e1e91c0
Move sync line pointers code to the end of the loop, it is simpler that way.
michael
parents:
8482
diff
changeset
|
231 while(run_off <= offs){ |
c8113e1e91c0
Move sync line pointers code to the end of the loop, it is simpler that way.
michael
parents:
8482
diff
changeset
|
232 run_off += *ref++; |
c8113e1e91c0
Move sync line pointers code to the end of the loop, it is simpler that way.
michael
parents:
8482
diff
changeset
|
233 run_off += *ref++; |
c8113e1e91c0
Move sync line pointers code to the end of the loop, it is simpler that way.
michael
parents:
8482
diff
changeset
|
234 } |
8466 | 235 } |
236 *runs++ = saved_run; | |
237 *runs++ = 0; | |
238 return 0; | |
239 } | |
240 | |
241 static void put_line(uint8_t *dst, int size, int width, const int *runs) | |
242 { | |
243 PutBitContext pb; | |
8469 | 244 int run, mode = ~0, pix_left = width, run_idx = 0; |
8466 | 245 |
246 init_put_bits(&pb, dst, size*8); | |
247 while(pix_left > 0){ | |
248 run = runs[run_idx++]; | |
8469 | 249 mode = ~mode; |
8466 | 250 pix_left -= run; |
251 for(; run > 16; run -= 16) | |
8469 | 252 put_sbits(&pb, 16, mode); |
8470 | 253 if(run) |
8471 | 254 put_sbits(&pb, run, mode); |
8466 | 255 } |
10311
943b63f364ca
Make sure all the bits are written to output in fax data decoder.
kostya
parents:
10305
diff
changeset
|
256 flush_put_bits(&pb); |
8466 | 257 } |
258 | |
259 static int find_group3_syncmarker(GetBitContext *gb, int srcsize) | |
260 { | |
8467 | 261 unsigned int state = -1; |
262 srcsize -= get_bits_count(gb); | |
263 while(srcsize-- > 0){ | |
264 state+= state + get_bits1(gb); | |
8472 | 265 if((state & 0xFFF) == 1) |
8467 | 266 return 0; |
8466 | 267 } |
8467 | 268 return -1; |
8466 | 269 } |
270 | |
8474 | 271 int ff_ccitt_unpack(AVCodecContext *avctx, |
10305
86fadefa1143
cosmetics: reindent and reformat function declarations
kostya
parents:
10304
diff
changeset
|
272 const uint8_t *src, int srcsize, |
86fadefa1143
cosmetics: reindent and reformat function declarations
kostya
parents:
10304
diff
changeset
|
273 uint8_t *dst, int height, int stride, |
86fadefa1143
cosmetics: reindent and reformat function declarations
kostya
parents:
10304
diff
changeset
|
274 enum TiffCompr compr, int opts) |
8466 | 275 { |
276 int j; | |
277 GetBitContext gb; | |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
278 int *runs, *ref, *runend; |
8466 | 279 int ret; |
8478
2f7c09bb6bfb
Factorize "avctx->width + 2" out to avoid someone mistakenly changing
michael
parents:
8477
diff
changeset
|
280 int runsize= avctx->width + 2; |
8466 | 281 |
8478
2f7c09bb6bfb
Factorize "avctx->width + 2" out to avoid someone mistakenly changing
michael
parents:
8477
diff
changeset
|
282 runs = av_malloc(runsize * sizeof(runs[0])); |
2f7c09bb6bfb
Factorize "avctx->width + 2" out to avoid someone mistakenly changing
michael
parents:
8477
diff
changeset
|
283 ref = av_malloc(runsize * sizeof(ref[0])); |
8466 | 284 ref[0] = avctx->width; |
285 ref[1] = 0; | |
286 ref[2] = 0; | |
287 init_get_bits(&gb, src, srcsize*8); | |
288 for(j = 0; j < height; j++){ | |
8478
2f7c09bb6bfb
Factorize "avctx->width + 2" out to avoid someone mistakenly changing
michael
parents:
8477
diff
changeset
|
289 runend = runs + runsize; |
8474 | 290 if(compr == TIFF_G4){ |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
291 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); |
8466 | 292 if(ret < 0){ |
293 av_free(runs); | |
294 av_free(ref); | |
295 return -1; | |
296 } | |
297 }else{ | |
10304
370d05e51d90
Finally distinguish TIFF_CCITT_RLE and TIFF_G3 1-D case, so both of them
kostya
parents:
10272
diff
changeset
|
298 int g3d1 = (compr == TIFF_G3) && !(opts & 1); |
10272 | 299 if(compr!=TIFF_CCITT_RLE && find_group3_syncmarker(&gb, srcsize*8) < 0) |
8466 | 300 break; |
10304
370d05e51d90
Finally distinguish TIFF_CCITT_RLE and TIFF_G3 1-D case, so both of them
kostya
parents:
10272
diff
changeset
|
301 if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
302 ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend); |
8466 | 303 else |
8476
0a0d7c4f2cf3
Close gaping sechole. That is, a series of run=0 allows arbitrary data to
michael
parents:
8475
diff
changeset
|
304 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); |
10315
27cb9c2c0c6b
Simplify r20025: use align_get_bits instead of reimplementing it.
reimar
parents:
10311
diff
changeset
|
305 if(compr==TIFF_CCITT_RLE) |
27cb9c2c0c6b
Simplify r20025: use align_get_bits instead of reimplementing it.
reimar
parents:
10311
diff
changeset
|
306 align_get_bits(&gb); |
8466 | 307 } |
308 if(ret < 0){ | |
309 put_line(dst, stride, avctx->width, ref); | |
310 }else{ | |
311 put_line(dst, stride, avctx->width, runs); | |
312 FFSWAP(int*, runs, ref); | |
313 } | |
314 dst += stride; | |
315 } | |
316 av_free(runs); | |
317 av_free(ref); | |
318 return 0; | |
319 } |