2 * CCITT Fax Group 3 and 4 decompression
3 * Copyright (c) 2008 Konstantin Shishkov
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * CCITT Fax Group 3 and 4 decompression
25 * @author Konstantin Shishkov
32 #define CCITT_SYMS 104
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
45 static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] =
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
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
69 static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] =
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,
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,
89 static const uint8_t ccitt_group3_2d_bits[11] = {
90 1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1
93 static const uint8_t ccitt_group3_2d_lens[11] = {
94 4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9
97 static VLC ccitt_vlc[2], ccitt_group3_2d_vlc;
99 av_cold void ff_ccitt_unpack_init(void)
101 static VLC_TYPE code_table1[528][2];
102 static VLC_TYPE code_table2[648][2];
104 static int initialized = 0;
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 ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
114 ccitt_codes_lens[i], 1, 1,
115 ccitt_codes_bits[i], 1, 1,
117 INIT_VLC_USE_NEW_STATIC);
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);
126 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
127 unsigned int pix_left, int *runs,
131 unsigned int run = 0;
134 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
138 if (runs >= runend) {
139 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
140 return AVERROR_INVALIDDATA;
142 if (pix_left <= run) {
145 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
146 return AVERROR_INVALIDDATA;
151 } else if ((int)t == -1) {
152 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
153 return AVERROR_INVALIDDATA;
160 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
161 unsigned int width, int *runs,
162 const int *runend, const int *ref)
164 int mode = 0, saved_run = 0, t;
165 int run_off = *ref++;
166 unsigned int offs = 0, run = 0;
168 runend--; // for the last written 0
170 while (offs < width) {
171 int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
173 av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
174 return AVERROR_INVALIDDATA;
176 if (!cmode) { //pass mode
178 run = run_off - offs;
182 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
183 return AVERROR_INVALIDDATA;
186 } else if (cmode == 1) { //horizontal mode
188 for (k = 0; k < 2; k++) {
191 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
193 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
194 return AVERROR_INVALIDDATA;
200 *runs++ = run + saved_run;
201 if (runs >= runend) {
202 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
203 return AVERROR_INVALIDDATA;
207 if (offs > width || run > width) {
208 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
209 return AVERROR_INVALIDDATA;
213 } else if (cmode == 9 || cmode == 10) {
214 avpriv_report_missing_feature(avctx, "Special modes support");
215 return AVERROR_PATCHWELCOME;
216 } else { //vertical mode
217 run = run_off - offs + (cmode - 5);
220 if (offs > width || run > width) {
221 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
222 return AVERROR_INVALIDDATA;
224 *runs++ = run + saved_run;
225 if (runs >= runend) {
226 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
227 return AVERROR_INVALIDDATA;
233 while (run_off <= offs) {
243 static void put_line(uint8_t *dst, int size, int width, const int *runs)
246 int run, mode = ~0, pix_left = width, run_idx = 0;
248 init_put_bits(&pb, dst, size * 8);
249 while (pix_left > 0) {
250 run = runs[run_idx++];
253 for (; run > 16; run -= 16)
254 put_sbits(&pb, 16, mode);
256 put_sbits(&pb, run, mode);
261 static int find_group3_syncmarker(GetBitContext *gb, int srcsize)
263 unsigned int state = -1;
264 srcsize -= get_bits_count(gb);
265 while (srcsize-- > 0) {
266 state += state + get_bits1(gb);
267 if ((state & 0xFFF) == 1)
273 int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize,
274 uint8_t *dst, int height, int stride,
275 enum TiffCompr compr, int opts)
279 int *runs, *ref = NULL, *runend;
281 int runsize = avctx->width + 2;
283 runs = av_malloc(runsize * sizeof(runs[0]));
284 ref = av_malloc(runsize * sizeof(ref[0]));
286 ret = AVERROR(ENOMEM);
289 ref[0] = avctx->width;
292 init_get_bits(&gb, src, srcsize * 8);
293 for (j = 0; j < height; j++) {
294 runend = runs + runsize;
295 if (compr == TIFF_G4) {
296 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend,
301 int g3d1 = (compr == TIFF_G3) && !(opts & 1);
302 if (compr != TIFF_CCITT_RLE &&
303 find_group3_syncmarker(&gb, srcsize * 8) < 0)
305 if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
306 ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs,
309 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs,
311 if (compr == TIFF_CCITT_RLE)
314 if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0)
318 put_line(dst, stride, avctx->width, ref);
320 put_line(dst, stride, avctx->width, runs);
321 FFSWAP(int *, runs, ref);