Libav 0.7.1
|
00001 /* 00002 * LZW decoder 00003 * Copyright (c) 2003 Fabrice Bellard 00004 * Copyright (c) 2006 Konstantin Shishkov 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00030 #include "avcodec.h" 00031 #include "lzw.h" 00032 00033 #define LZW_MAXBITS 12 00034 #define LZW_SIZTABLE (1<<LZW_MAXBITS) 00035 00036 static const uint16_t mask[17] = 00037 { 00038 0x0000, 0x0001, 0x0003, 0x0007, 00039 0x000F, 0x001F, 0x003F, 0x007F, 00040 0x00FF, 0x01FF, 0x03FF, 0x07FF, 00041 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF 00042 }; 00043 00044 struct LZWState { 00045 const uint8_t *pbuf, *ebuf; 00046 int bbits; 00047 unsigned int bbuf; 00048 00049 int mode; 00050 int cursize; 00051 int curmask; 00052 int codesize; 00053 int clear_code; 00054 int end_code; 00055 int newcodes; 00056 int top_slot; 00057 int extra_slot; 00058 int slot; 00059 int fc, oc; 00060 uint8_t *sp; 00061 uint8_t stack[LZW_SIZTABLE]; 00062 uint8_t suffix[LZW_SIZTABLE]; 00063 uint16_t prefix[LZW_SIZTABLE]; 00064 int bs; 00065 }; 00066 00067 /* get one code from stream */ 00068 static int lzw_get_code(struct LZWState * s) 00069 { 00070 int c; 00071 00072 if(s->mode == FF_LZW_GIF) { 00073 while (s->bbits < s->cursize) { 00074 if (!s->bs) { 00075 s->bs = *s->pbuf++; 00076 } 00077 s->bbuf |= (*s->pbuf++) << s->bbits; 00078 s->bbits += 8; 00079 s->bs--; 00080 } 00081 c = s->bbuf; 00082 s->bbuf >>= s->cursize; 00083 } else { // TIFF 00084 while (s->bbits < s->cursize) { 00085 s->bbuf = (s->bbuf << 8) | (*s->pbuf++); 00086 s->bbits += 8; 00087 } 00088 c = s->bbuf >> (s->bbits - s->cursize); 00089 } 00090 s->bbits -= s->cursize; 00091 return c & s->curmask; 00092 } 00093 00094 const uint8_t* ff_lzw_cur_ptr(LZWState *p) 00095 { 00096 return ((struct LZWState*)p)->pbuf; 00097 } 00098 00099 void ff_lzw_decode_tail(LZWState *p) 00100 { 00101 struct LZWState *s = (struct LZWState *)p; 00102 00103 if(s->mode == FF_LZW_GIF) { 00104 while(s->pbuf < s->ebuf && s->bs>0){ 00105 s->pbuf += s->bs; 00106 s->bs = *s->pbuf++; 00107 } 00108 }else 00109 s->pbuf= s->ebuf; 00110 } 00111 00112 av_cold void ff_lzw_decode_open(LZWState **p) 00113 { 00114 *p = av_mallocz(sizeof(struct LZWState)); 00115 } 00116 00117 av_cold void ff_lzw_decode_close(LZWState **p) 00118 { 00119 av_freep(p); 00120 } 00121 00130 int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, int mode) 00131 { 00132 struct LZWState *s = (struct LZWState *)p; 00133 00134 if(csize < 1 || csize >= LZW_MAXBITS) 00135 return -1; 00136 /* read buffer */ 00137 s->pbuf = buf; 00138 s->ebuf = s->pbuf + buf_size; 00139 s->bbuf = 0; 00140 s->bbits = 0; 00141 s->bs = 0; 00142 00143 /* decoder */ 00144 s->codesize = csize; 00145 s->cursize = s->codesize + 1; 00146 s->curmask = mask[s->cursize]; 00147 s->top_slot = 1 << s->cursize; 00148 s->clear_code = 1 << s->codesize; 00149 s->end_code = s->clear_code + 1; 00150 s->slot = s->newcodes = s->clear_code + 2; 00151 s->oc = s->fc = -1; 00152 s->sp = s->stack; 00153 00154 s->mode = mode; 00155 s->extra_slot = s->mode == FF_LZW_TIFF; 00156 return 0; 00157 } 00158 00169 int ff_lzw_decode(LZWState *p, uint8_t *buf, int len){ 00170 int l, c, code, oc, fc; 00171 uint8_t *sp; 00172 struct LZWState *s = (struct LZWState *)p; 00173 00174 if (s->end_code < 0) 00175 return 0; 00176 00177 l = len; 00178 sp = s->sp; 00179 oc = s->oc; 00180 fc = s->fc; 00181 00182 for (;;) { 00183 while (sp > s->stack) { 00184 *buf++ = *(--sp); 00185 if ((--l) == 0) 00186 goto the_end; 00187 } 00188 c = lzw_get_code(s); 00189 if (c == s->end_code) { 00190 break; 00191 } else if (c == s->clear_code) { 00192 s->cursize = s->codesize + 1; 00193 s->curmask = mask[s->cursize]; 00194 s->slot = s->newcodes; 00195 s->top_slot = 1 << s->cursize; 00196 fc= oc= -1; 00197 } else { 00198 code = c; 00199 if (code == s->slot && fc>=0) { 00200 *sp++ = fc; 00201 code = oc; 00202 }else if(code >= s->slot) 00203 break; 00204 while (code >= s->newcodes) { 00205 *sp++ = s->suffix[code]; 00206 code = s->prefix[code]; 00207 } 00208 *sp++ = code; 00209 if (s->slot < s->top_slot && oc>=0) { 00210 s->suffix[s->slot] = code; 00211 s->prefix[s->slot++] = oc; 00212 } 00213 fc = code; 00214 oc = c; 00215 if (s->slot >= s->top_slot - s->extra_slot) { 00216 if (s->cursize < LZW_MAXBITS) { 00217 s->top_slot <<= 1; 00218 s->curmask = mask[++s->cursize]; 00219 } 00220 } 00221 } 00222 } 00223 s->end_code = -1; 00224 the_end: 00225 s->sp = sp; 00226 s->oc = oc; 00227 s->fc = fc; 00228 return len - l; 00229 }