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
28 #include "bitstream.h"
33 #define CCITT_SYMS 104
35 static const uint16_t ccitt_syms[CCITT_SYMS] = {
36 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
37 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
38 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
40 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
41 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
42 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728,
43 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560
46 static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] =
49 0x35, 0x07, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, 0x13, 0x14, 0x07, 0x08, 0x08,
50 0x03, 0x34, 0x35, 0x2A, 0x2B, 0x27, 0x0C, 0x08, 0x17, 0x03, 0x04, 0x28, 0x2B,
51 0x13, 0x24, 0x18, 0x02, 0x03, 0x1A, 0x1B, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
52 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x04, 0x05, 0x0A, 0x0B, 0x52, 0x53, 0x54,
53 0x55, 0x24, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x4A, 0x4B, 0x32, 0x33, 0x34, 0x1B,
54 0x12, 0x17, 0x37, 0x36, 0x37, 0x64, 0x65, 0x68, 0x67, 0xCC, 0xCD, 0xD2, 0xD3,
55 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0x98, 0x99, 0x9A, 0x18, 0x9B,
56 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
59 0x37, 0x02, 0x03, 0x02, 0x03, 0x03, 0x02, 0x03, 0x05, 0x04, 0x04, 0x05, 0x07,
60 0x04, 0x07, 0x18, 0x17, 0x18, 0x08, 0x67, 0x68, 0x6C, 0x37, 0x28, 0x17, 0x18,
61 0xCA, 0xCB, 0xCC, 0xCD, 0x68, 0x69, 0x6A, 0x6B, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
62 0xD7, 0x6C, 0x6D, 0xDA, 0xDB, 0x54, 0x55, 0x56, 0x57, 0x64, 0x65, 0x52, 0x53,
63 0x24, 0x37, 0x38, 0x27, 0x28, 0x58, 0x59, 0x2B, 0x2C, 0x5A, 0x66, 0x67, 0x0F,
64 0xC8, 0xC9, 0x5B, 0x33, 0x34, 0x35, 0x6C, 0x6D, 0x4A, 0x4B, 0x4C, 0x4D, 0x72,
65 0x73, 0x74, 0x75, 0x76, 0x77, 0x52, 0x53, 0x54, 0x55, 0x5A, 0x5B, 0x64, 0x65,
66 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
70 static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] =
73 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7,
74 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
75 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
76 8, 8, 8, 8, 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
77 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12,
81 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 11,
82 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
83 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
84 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
85 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12,
90 static const uint8_t ccitt_group3_2d_bits[11] = {
91 1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1
94 static const uint8_t ccitt_group3_2d_lens[11] = {
95 4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9
98 static VLC ccitt_vlc[2], ccitt_group3_2d_vlc;
100 av_cold void ff_ccitt_unpack_init(void)
102 static VLC_TYPE code_table1[528][2];
103 static VLC_TYPE code_table2[648][2];
105 static int initialized = 0;
109 ccitt_vlc[0].table = code_table1;
110 ccitt_vlc[0].table_allocated = 528;
111 ccitt_vlc[1].table = code_table2;
112 ccitt_vlc[1].table_allocated = 648;
113 for (i = 0; i < 2; i++) {
114 ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
115 ccitt_codes_lens[i], 1, 1,
116 ccitt_codes_bits[i], 1, 1,
118 INIT_VLC_USE_NEW_STATIC);
120 INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11,
121 ccitt_group3_2d_lens, 1, 1,
122 ccitt_group3_2d_bits, 1, 1, 512);
127 static int decode_group3_1d_line(AVCodecContext *avctx, BitstreamContext *bc,
128 unsigned int pix_left, int *runs,
132 unsigned int run = 0;
135 t = bitstream_read_vlc(bc, ccitt_vlc[mode].table, 9, 2);
139 if (runs >= runend) {
140 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
141 return AVERROR_INVALIDDATA;
143 if (pix_left <= run) {
146 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
147 return AVERROR_INVALIDDATA;
152 } else if ((int)t == -1) {
153 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
154 return AVERROR_INVALIDDATA;
161 static int decode_group3_2d_line(AVCodecContext *avctx, BitstreamContext *bc,
162 unsigned int width, int *runs,
163 const int *runend, const int *ref)
165 int mode = 0, saved_run = 0, t;
166 int run_off = *ref++;
167 unsigned int offs = 0, run = 0;
169 runend--; // for the last written 0
171 while (offs < width) {
172 int cmode = bitstream_read_vlc(bc, ccitt_group3_2d_vlc.table, 9, 1);
174 av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
175 return AVERROR_INVALIDDATA;
177 if (!cmode) { //pass mode
179 run = run_off - offs;
183 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
184 return AVERROR_INVALIDDATA;
187 } else if (cmode == 1) { //horizontal mode
189 for (k = 0; k < 2; k++) {
192 t = bitstream_read_vlc(bc, ccitt_vlc[mode].table, 9, 2);
194 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
195 return AVERROR_INVALIDDATA;
201 *runs++ = run + saved_run;
202 if (runs >= runend) {
203 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
204 return AVERROR_INVALIDDATA;
208 if (offs > width || run > width) {
209 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
210 return AVERROR_INVALIDDATA;
214 } else if (cmode == 9 || cmode == 10) {
215 avpriv_report_missing_feature(avctx, "Special modes support");
216 return AVERROR_PATCHWELCOME;
217 } else { //vertical mode
218 run = run_off - offs + (cmode - 5);
221 if (offs > width || run > width) {
222 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
223 return AVERROR_INVALIDDATA;
225 *runs++ = run + saved_run;
226 if (runs >= runend) {
227 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
228 return AVERROR_INVALIDDATA;
234 while (run_off <= offs) {
244 static void put_line(uint8_t *dst, int size, int width, const int *runs)
247 int run, mode = ~0, pix_left = width, run_idx = 0;
249 init_put_bits(&pb, dst, size * 8);
250 while (pix_left > 0) {
251 run = runs[run_idx++];
254 for (; run > 16; run -= 16)
255 put_sbits(&pb, 16, mode);
257 put_sbits(&pb, run, mode);
262 static int find_group3_syncmarker(BitstreamContext *bc, int srcsize)
264 unsigned int state = -1;
265 srcsize -= bitstream_tell(bc);
266 while (srcsize-- > 0) {
267 state += state + bitstream_read_bit(bc);
268 if ((state & 0xFFF) == 1)
274 int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize,
275 uint8_t *dst, int height, int stride,
276 enum TiffCompr compr, int opts)
280 int *runs, *ref = NULL, *runend;
282 int runsize = avctx->width + 2;
284 runs = av_malloc(runsize * sizeof(runs[0]));
285 ref = av_malloc(runsize * sizeof(ref[0]));
287 ret = AVERROR(ENOMEM);
290 ref[0] = avctx->width;
293 bitstream_init8(&bc, src, srcsize);
294 for (j = 0; j < height; j++) {
295 runend = runs + runsize;
296 if (compr == TIFF_G4) {
297 ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs, runend,
302 int g3d1 = (compr == TIFF_G3) && !(opts & 1);
303 if (compr != TIFF_CCITT_RLE &&
304 find_group3_syncmarker(&bc, srcsize * 8) < 0)
306 if (compr == TIFF_CCITT_RLE || g3d1 || bitstream_read_bit(&bc))
307 ret = decode_group3_1d_line(avctx, &bc, avctx->width, runs,
310 ret = decode_group3_2d_line(avctx, &bc, avctx->width, runs,
312 if (compr == TIFF_CCITT_RLE)
313 bitstream_align(&bc);
315 if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0)
319 put_line(dst, stride, avctx->width, ref);
321 put_line(dst, stride, avctx->width, runs);
322 FFSWAP(int *, runs, ref);