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

Generated on Fri Sep 16 2011 17:17:36 for FFmpeg by  doxygen 1.7.1