• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/faxcompr.c

Go to the documentation of this file.
00001 /*
00002  * CCITT Fax Group 3 and 4 decompression
00003  * Copyright (c) 2008 Konstantin Shishkov
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "avcodec.h"
00028 #include "bitstream.h"
00029 #include "faxcompr.h"
00030 
00031 #define CCITT_SYMS 104
00032 
00033 static const uint16_t ccitt_syms[CCITT_SYMS] = {
00034     0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,
00035    13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,
00036    26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
00037    39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
00038    52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,
00039   128,  192,  256,  320,  384,  448,  512,  576,  640,  704,  768,  832,  896,
00040   960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728,
00041  1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560
00042 };
00043 
00044 static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] =
00045 {
00046   {
00047     0x35, 0x07, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, 0x13, 0x14, 0x07, 0x08, 0x08,
00048     0x03, 0x34, 0x35, 0x2A, 0x2B, 0x27, 0x0C, 0x08, 0x17, 0x03, 0x04, 0x28, 0x2B,
00049     0x13, 0x24, 0x18, 0x02, 0x03, 0x1A, 0x1B, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00050     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x04, 0x05, 0x0A, 0x0B, 0x52, 0x53, 0x54,
00051     0x55, 0x24, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x4A, 0x4B, 0x32, 0x33, 0x34, 0x1B,
00052     0x12, 0x17, 0x37, 0x36, 0x37, 0x64, 0x65, 0x68, 0x67, 0xCC, 0xCD, 0xD2, 0xD3,
00053     0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0x98, 0x99, 0x9A, 0x18, 0x9B,
00054     0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
00055   },
00056   {
00057     0x37, 0x02, 0x03, 0x02, 0x03, 0x03, 0x02, 0x03, 0x05, 0x04, 0x04, 0x05, 0x07,
00058     0x04, 0x07, 0x18, 0x17, 0x18, 0x08, 0x67, 0x68, 0x6C, 0x37, 0x28, 0x17, 0x18,
00059     0xCA, 0xCB, 0xCC, 0xCD, 0x68, 0x69, 0x6A, 0x6B, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
00060     0xD7, 0x6C, 0x6D, 0xDA, 0xDB, 0x54, 0x55, 0x56, 0x57, 0x64, 0x65, 0x52, 0x53,
00061     0x24, 0x37, 0x38, 0x27, 0x28, 0x58, 0x59, 0x2B, 0x2C, 0x5A, 0x66, 0x67, 0x0F,
00062     0xC8, 0xC9, 0x5B, 0x33, 0x34, 0x35, 0x6C, 0x6D, 0x4A, 0x4B, 0x4C, 0x4D, 0x72,
00063     0x73, 0x74, 0x75, 0x76, 0x77, 0x52, 0x53, 0x54, 0x55, 0x5A, 0x5B, 0x64, 0x65,
00064     0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F
00065   }
00066 };
00067 
00068 static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] =
00069 {
00070   {
00071      8,  6,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  7,  7,
00072      7,  7,  7,  7,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
00073      8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
00074      8,  8,  8,  8,  5,  5,  6,  7,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,
00075      9,  9,  9,  9,  9,  9,  9,  9,  9,  6,  9, 11, 11, 11, 12, 12, 12, 12, 12, 12,
00076     12, 12, 12, 12
00077   },
00078   {
00079     10,  3,  2,  2,  3,  4,  4,  5,  6,  6,  7,  7,  7,  8,  8,  9, 10, 10, 10, 11,
00080     11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
00081     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
00082     12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
00083     13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12,
00084     12, 12, 12, 12
00085   }
00086 };
00087 
00088 static const uint8_t ccitt_group3_2d_bits[11] = {
00089     1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1
00090 };
00091 
00092 static const uint8_t ccitt_group3_2d_lens[11] = {
00093     4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9
00094 };
00095 
00096 static VLC ccitt_vlc[2], ccitt_group3_2d_vlc;
00097 
00098 av_cold void ff_ccitt_unpack_init(void)
00099 {
00100     static VLC_TYPE code_table1[528][2];
00101     static VLC_TYPE code_table2[648][2];
00102     int i;
00103     static int initialized = 0;
00104 
00105     if(initialized)
00106         return;
00107     ccitt_vlc[0].table = code_table1;
00108     ccitt_vlc[0].table_allocated = 528;
00109     ccitt_vlc[1].table = code_table2;
00110     ccitt_vlc[1].table_allocated = 648;
00111     for(i = 0; i < 2; i++){
00112         init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
00113                         ccitt_codes_lens[i], 1, 1,
00114                         ccitt_codes_bits[i], 1, 1,
00115                         ccitt_syms, 2, 2,
00116                         INIT_VLC_USE_NEW_STATIC);
00117     }
00118     INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11,
00119                     ccitt_group3_2d_lens, 1, 1,
00120                     ccitt_group3_2d_bits, 1, 1, 512);
00121     initialized = 1;
00122 }
00123 
00124 
00125 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
00126                                  unsigned int pix_left, int *runs, const int *runend)
00127 {
00128     int mode = 0;
00129     unsigned int run=0;
00130     unsigned int t;
00131     for(;;){
00132         t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
00133         run += t;
00134         if(t < 64){
00135             *runs++ = run;
00136             if(runs >= runend){
00137                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
00138                 return -1;
00139             }
00140             if(pix_left <= run){
00141                 if(pix_left == run)
00142                     break;
00143                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00144                 return -1;
00145             }
00146             pix_left -= run;
00147             run = 0;
00148             mode = !mode;
00149         }else if((int)t == -1){
00150             av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
00151             return -1;
00152         }
00153     }
00154     *runs++ = 0;
00155     return 0;
00156 }
00157 
00158 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
00159                                  unsigned int width, int *runs, const int *runend, const int *ref)
00160 {
00161     int mode = 0, saved_run = 0, t;
00162     int run_off = *ref++;
00163     unsigned int offs=0, run= 0;
00164 
00165     runend--; // for the last written 0
00166 
00167     while(offs < width){
00168         int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
00169         if(cmode == -1){
00170             av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
00171             return -1;
00172         }
00173         if(!cmode){//pass mode
00174             run_off += *ref++;
00175             run = run_off - offs;
00176             offs= run_off;
00177             run_off += *ref++;
00178             if(offs > width){
00179                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00180                 return -1;
00181             }
00182             saved_run += run;
00183         }else if(cmode == 1){//horizontal mode
00184             int k;
00185             for(k = 0; k < 2; k++){
00186                 run = 0;
00187                 for(;;){
00188                     t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
00189                     if(t == -1){
00190                         av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
00191                         return -1;
00192                     }
00193                     run += t;
00194                     if(t < 64)
00195                         break;
00196                 }
00197                 *runs++ = run + saved_run;
00198                 if(runs >= runend){
00199                     av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
00200                     return -1;
00201                 }
00202                 saved_run = 0;
00203                 offs += run;
00204                 if(offs > width || run > width){
00205                     av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00206                     return -1;
00207                 }
00208                 mode = !mode;
00209             }
00210         }else if(cmode == 9 || cmode == 10){
00211             av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n");
00212             return -1;
00213         }else{//vertical mode
00214             run = run_off - offs + (cmode - 5);
00215             run_off -= *--ref;
00216             offs += run;
00217             if(offs > width || run > width){
00218                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00219                 return -1;
00220             }
00221             *runs++ = run + saved_run;
00222             if(runs >= runend){
00223                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
00224                 return -1;
00225             }
00226             saved_run = 0;
00227             mode = !mode;
00228         }
00229         //sync line pointers
00230         while(run_off <= offs){
00231             run_off += *ref++;
00232             run_off += *ref++;
00233         }
00234     }
00235     *runs++ = saved_run;
00236     *runs++ = 0;
00237     return 0;
00238 }
00239 
00240 static void put_line(uint8_t *dst, int size, int width, const int *runs)
00241 {
00242     PutBitContext pb;
00243     int run, mode = ~0, pix_left = width, run_idx = 0;
00244 
00245     init_put_bits(&pb, dst, size*8);
00246     while(pix_left > 0){
00247         run = runs[run_idx++];
00248         mode = ~mode;
00249         pix_left -= run;
00250         for(; run > 16; run -= 16)
00251             put_sbits(&pb, 16, mode);
00252         if(run)
00253             put_sbits(&pb, run, mode);
00254     }
00255 }
00256 
00257 static int find_group3_syncmarker(GetBitContext *gb, int srcsize)
00258 {
00259     unsigned int state = -1;
00260     srcsize -= get_bits_count(gb);
00261     while(srcsize-- > 0){
00262         state+= state + get_bits1(gb);
00263         if((state & 0xFFF) == 1)
00264             return 0;
00265     }
00266     return -1;
00267 }
00268 
00269 int ff_ccitt_unpack(AVCodecContext *avctx,
00270                        const uint8_t *src, int srcsize,
00271                        uint8_t *dst, int height, int stride, enum TiffCompr compr)
00272 {
00273     int j;
00274     GetBitContext gb;
00275     int *runs, *ref, *runend;
00276     int ret;
00277     int runsize= avctx->width + 2;
00278 
00279     runs = av_malloc(runsize * sizeof(runs[0]));
00280     ref  = av_malloc(runsize * sizeof(ref[0]));
00281     ref[0] = avctx->width;
00282     ref[1] = 0;
00283     ref[2] = 0;
00284     init_get_bits(&gb, src, srcsize*8);
00285     for(j = 0; j < height; j++){
00286         runend = runs + runsize;
00287         if(compr == TIFF_G4){
00288             ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
00289             if(ret < 0){
00290                 av_free(runs);
00291                 av_free(ref);
00292                 return -1;
00293             }
00294         }else{
00295             if(find_group3_syncmarker(&gb, srcsize*8) < 0)
00296                 break;
00297             if(compr==TIFF_CCITT_RLE || get_bits1(&gb))
00298                 ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend);
00299             else
00300                 ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
00301         }
00302         if(ret < 0){
00303             put_line(dst, stride, avctx->width, ref);
00304         }else{
00305             put_line(dst, stride, avctx->width, runs);
00306             FFSWAP(int*, runs, ref);
00307         }
00308         dst += stride;
00309     }
00310     av_free(runs);
00311     av_free(ref);
00312     return 0;
00313 }

Generated on Sat Feb 16 2013 09:23:12 for ffmpeg by  doxygen 1.7.1