annotate ffmpeg/libavcodec/faxcompr.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * CCITT Fax Group 3 and 4 decompression
yading@10 3 * Copyright (c) 2008 Konstantin Shishkov
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * CCITT Fax Group 3 and 4 decompression
yading@10 25 * @author Konstantin Shishkov
yading@10 26 */
yading@10 27 #include "avcodec.h"
yading@10 28 #include "get_bits.h"
yading@10 29 #include "put_bits.h"
yading@10 30 #include "faxcompr.h"
yading@10 31
yading@10 32 #define CCITT_SYMS 104
yading@10 33
yading@10 34 static const uint16_t ccitt_syms[CCITT_SYMS] = {
yading@10 35 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
yading@10 36 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
yading@10 37 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
yading@10 38 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
yading@10 39 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
yading@10 40 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
yading@10 41 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728,
yading@10 42 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560
yading@10 43 };
yading@10 44
yading@10 45 static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] =
yading@10 46 {
yading@10 47 {
yading@10 48 0x35, 0x07, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, 0x13, 0x14, 0x07, 0x08, 0x08,
yading@10 49 0x03, 0x34, 0x35, 0x2A, 0x2B, 0x27, 0x0C, 0x08, 0x17, 0x03, 0x04, 0x28, 0x2B,
yading@10 50 0x13, 0x24, 0x18, 0x02, 0x03, 0x1A, 0x1B, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
yading@10 51 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x04, 0x05, 0x0A, 0x0B, 0x52, 0x53, 0x54,
yading@10 52 0x55, 0x24, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x4A, 0x4B, 0x32, 0x33, 0x34, 0x1B,
yading@10 53 0x12, 0x17, 0x37, 0x36, 0x37, 0x64, 0x65, 0x68, 0x67, 0xCC, 0xCD, 0xD2, 0xD3,
yading@10 54 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0x98, 0x99, 0x9A, 0x18, 0x9B,
yading@10 55 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
yading@10 56 },
yading@10 57 {
yading@10 58 0x37, 0x02, 0x03, 0x02, 0x03, 0x03, 0x02, 0x03, 0x05, 0x04, 0x04, 0x05, 0x07,
yading@10 59 0x04, 0x07, 0x18, 0x17, 0x18, 0x08, 0x67, 0x68, 0x6C, 0x37, 0x28, 0x17, 0x18,
yading@10 60 0xCA, 0xCB, 0xCC, 0xCD, 0x68, 0x69, 0x6A, 0x6B, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
yading@10 61 0xD7, 0x6C, 0x6D, 0xDA, 0xDB, 0x54, 0x55, 0x56, 0x57, 0x64, 0x65, 0x52, 0x53,
yading@10 62 0x24, 0x37, 0x38, 0x27, 0x28, 0x58, 0x59, 0x2B, 0x2C, 0x5A, 0x66, 0x67, 0x0F,
yading@10 63 0xC8, 0xC9, 0x5B, 0x33, 0x34, 0x35, 0x6C, 0x6D, 0x4A, 0x4B, 0x4C, 0x4D, 0x72,
yading@10 64 0x73, 0x74, 0x75, 0x76, 0x77, 0x52, 0x53, 0x54, 0x55, 0x5A, 0x5B, 0x64, 0x65,
yading@10 65 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
yading@10 66 }
yading@10 67 };
yading@10 68
yading@10 69 static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] =
yading@10 70 {
yading@10 71 {
yading@10 72 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7,
yading@10 73 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
yading@10 74 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
yading@10 75 8, 8, 8, 8, 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
yading@10 76 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12,
yading@10 77 12, 12, 12, 12
yading@10 78 },
yading@10 79 {
yading@10 80 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 11,
yading@10 81 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
yading@10 82 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
yading@10 83 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
yading@10 84 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12,
yading@10 85 12, 12, 12, 12
yading@10 86 }
yading@10 87 };
yading@10 88
yading@10 89 static const uint8_t ccitt_group3_2d_bits[11] = {
yading@10 90 1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1
yading@10 91 };
yading@10 92
yading@10 93 static const uint8_t ccitt_group3_2d_lens[11] = {
yading@10 94 4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9
yading@10 95 };
yading@10 96
yading@10 97 static VLC ccitt_vlc[2], ccitt_group3_2d_vlc;
yading@10 98
yading@10 99 av_cold void ff_ccitt_unpack_init(void)
yading@10 100 {
yading@10 101 static VLC_TYPE code_table1[528][2];
yading@10 102 static VLC_TYPE code_table2[648][2];
yading@10 103 int i;
yading@10 104 static int initialized = 0;
yading@10 105
yading@10 106 if(initialized)
yading@10 107 return;
yading@10 108 ccitt_vlc[0].table = code_table1;
yading@10 109 ccitt_vlc[0].table_allocated = 528;
yading@10 110 ccitt_vlc[1].table = code_table2;
yading@10 111 ccitt_vlc[1].table_allocated = 648;
yading@10 112 for(i = 0; i < 2; i++){
yading@10 113 ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
yading@10 114 ccitt_codes_lens[i], 1, 1,
yading@10 115 ccitt_codes_bits[i], 1, 1,
yading@10 116 ccitt_syms, 2, 2,
yading@10 117 INIT_VLC_USE_NEW_STATIC);
yading@10 118 }
yading@10 119 INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11,
yading@10 120 ccitt_group3_2d_lens, 1, 1,
yading@10 121 ccitt_group3_2d_bits, 1, 1, 512);
yading@10 122 initialized = 1;
yading@10 123 }
yading@10 124
yading@10 125
yading@10 126 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
yading@10 127 unsigned int pix_left, int *runs, const int *runend)
yading@10 128 {
yading@10 129 int mode = 0;
yading@10 130 unsigned int run=0;
yading@10 131 unsigned int t;
yading@10 132 for(;;){
yading@10 133 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
yading@10 134 run += t;
yading@10 135 if(t < 64){
yading@10 136 *runs++ = run;
yading@10 137 if(runs >= runend){
yading@10 138 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
yading@10 139 return -1;
yading@10 140 }
yading@10 141 if(pix_left <= run){
yading@10 142 if(pix_left == run)
yading@10 143 break;
yading@10 144 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
yading@10 145 return -1;
yading@10 146 }
yading@10 147 pix_left -= run;
yading@10 148 run = 0;
yading@10 149 mode = !mode;
yading@10 150 }else if((int)t == -1){
yading@10 151 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
yading@10 152 return -1;
yading@10 153 }
yading@10 154 }
yading@10 155 *runs++ = 0;
yading@10 156 return 0;
yading@10 157 }
yading@10 158
yading@10 159 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
yading@10 160 unsigned int width, int *runs, const int *runend, const int *ref)
yading@10 161 {
yading@10 162 int mode = 0, saved_run = 0, t;
yading@10 163 int run_off = *ref++;
yading@10 164 unsigned int offs=0, run= 0;
yading@10 165
yading@10 166 while(offs < width){
yading@10 167 int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
yading@10 168 if(cmode == -1){
yading@10 169 av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
yading@10 170 return -1;
yading@10 171 }
yading@10 172 if(!cmode){//pass mode
yading@10 173 if(run_off < width)
yading@10 174 run_off += *ref++;
yading@10 175 run = run_off - offs;
yading@10 176 offs= run_off;
yading@10 177 if(run_off < width)
yading@10 178 run_off += *ref++;
yading@10 179 if(offs > width){
yading@10 180 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
yading@10 181 return -1;
yading@10 182 }
yading@10 183 saved_run += run;
yading@10 184 }else if(cmode == 1){//horizontal mode
yading@10 185 int k;
yading@10 186 for(k = 0; k < 2; k++){
yading@10 187 run = 0;
yading@10 188 for(;;){
yading@10 189 t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
yading@10 190 if(t == -1){
yading@10 191 av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
yading@10 192 return -1;
yading@10 193 }
yading@10 194 run += t;
yading@10 195 if(t < 64)
yading@10 196 break;
yading@10 197 }
yading@10 198 *runs++ = run + saved_run;
yading@10 199 if(runs >= runend){
yading@10 200 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
yading@10 201 return -1;
yading@10 202 }
yading@10 203 saved_run = 0;
yading@10 204 offs += run;
yading@10 205 if(offs > width || run > width){
yading@10 206 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
yading@10 207 return -1;
yading@10 208 }
yading@10 209 mode = !mode;
yading@10 210 }
yading@10 211 }else if(cmode == 9 || cmode == 10){
yading@10 212 av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n");
yading@10 213 return -1;
yading@10 214 }else{//vertical mode
yading@10 215 run = run_off - offs + (cmode - 5);
yading@10 216 run_off -= *--ref;
yading@10 217 offs += run;
yading@10 218 if(offs > width || run > width){
yading@10 219 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
yading@10 220 return -1;
yading@10 221 }
yading@10 222 *runs++ = run + saved_run;
yading@10 223 if(runs >= runend){
yading@10 224 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
yading@10 225 return -1;
yading@10 226 }
yading@10 227 saved_run = 0;
yading@10 228 mode = !mode;
yading@10 229 }
yading@10 230 //sync line pointers
yading@10 231 while(offs < width && run_off <= offs){
yading@10 232 run_off += *ref++;
yading@10 233 run_off += *ref++;
yading@10 234 }
yading@10 235 }
yading@10 236 *runs++ = saved_run;
yading@10 237 if (saved_run) {
yading@10 238 if(runs >= runend){
yading@10 239 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
yading@10 240 return -1;
yading@10 241 }
yading@10 242 *runs++ = 0;
yading@10 243 }
yading@10 244 return 0;
yading@10 245 }
yading@10 246
yading@10 247 static void put_line(uint8_t *dst, int size, int width, const int *runs)
yading@10 248 {
yading@10 249 PutBitContext pb;
yading@10 250 int run, mode = ~0, pix_left = width, run_idx = 0;
yading@10 251
yading@10 252 init_put_bits(&pb, dst, size*8);
yading@10 253 while(pix_left > 0){
yading@10 254 run = runs[run_idx++];
yading@10 255 mode = ~mode;
yading@10 256 pix_left -= run;
yading@10 257 for(; run > 16; run -= 16)
yading@10 258 put_sbits(&pb, 16, mode);
yading@10 259 if(run)
yading@10 260 put_sbits(&pb, run, mode);
yading@10 261 }
yading@10 262 flush_put_bits(&pb);
yading@10 263 }
yading@10 264
yading@10 265 static int find_group3_syncmarker(GetBitContext *gb, int srcsize)
yading@10 266 {
yading@10 267 unsigned int state = -1;
yading@10 268 srcsize -= get_bits_count(gb);
yading@10 269 while(srcsize-- > 0){
yading@10 270 state+= state + get_bits1(gb);
yading@10 271 if((state & 0xFFF) == 1)
yading@10 272 return 0;
yading@10 273 }
yading@10 274 return -1;
yading@10 275 }
yading@10 276
yading@10 277 int ff_ccitt_unpack(AVCodecContext *avctx,
yading@10 278 const uint8_t *src, int srcsize,
yading@10 279 uint8_t *dst, int height, int stride,
yading@10 280 enum TiffCompr compr, int opts)
yading@10 281 {
yading@10 282 int j;
yading@10 283 GetBitContext gb;
yading@10 284 int *runs, *ref = NULL, *runend;
yading@10 285 int ret;
yading@10 286 int runsize= avctx->width + 2;
yading@10 287 int err = 0;
yading@10 288 int has_eol;
yading@10 289
yading@10 290 runs = av_malloc(runsize * sizeof(runs[0]));
yading@10 291 ref = av_malloc(runsize * sizeof(ref[0]));
yading@10 292 if (!runs || ! ref) {
yading@10 293 err = AVERROR(ENOMEM);
yading@10 294 goto fail;
yading@10 295 }
yading@10 296 ref[0] = avctx->width;
yading@10 297 ref[1] = 0;
yading@10 298 ref[2] = 0;
yading@10 299 init_get_bits(&gb, src, srcsize*8);
yading@10 300 has_eol = show_bits(&gb, 12) == 1 || show_bits(&gb, 16) == 1;
yading@10 301
yading@10 302 for(j = 0; j < height; j++){
yading@10 303 runend = runs + runsize;
yading@10 304 if(compr == TIFF_G4){
yading@10 305 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
yading@10 306 if(ret < 0){
yading@10 307 err = -1;
yading@10 308 goto fail;
yading@10 309 }
yading@10 310 }else{
yading@10 311 int g3d1 = (compr == TIFF_G3) && !(opts & 1);
yading@10 312 if(compr!=TIFF_CCITT_RLE && has_eol && find_group3_syncmarker(&gb, srcsize*8) < 0)
yading@10 313 break;
yading@10 314 if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
yading@10 315 ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend);
yading@10 316 else
yading@10 317 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
yading@10 318 if(compr==TIFF_CCITT_RLE)
yading@10 319 align_get_bits(&gb);
yading@10 320 }
yading@10 321 if(ret < 0){
yading@10 322 put_line(dst, stride, avctx->width, ref);
yading@10 323 }else{
yading@10 324 put_line(dst, stride, avctx->width, runs);
yading@10 325 FFSWAP(int*, runs, ref);
yading@10 326 }
yading@10 327 dst += stride;
yading@10 328 }
yading@10 329 fail:
yading@10 330 av_free(runs);
yading@10 331 av_free(ref);
yading@10 332 return err;
yading@10 333 }