3 * Copyright (c) 2003 Fabrice Bellard.
4 * Copyright (c) 2006 Konstantin Shishkov.
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #ifdef COMPRESSED_CONFIG_FILE
30 static const uint16_t mask[17] =
32 0x0000, 0x0001, 0x0003, 0x0007,
33 0x000F, 0x001F, 0x003F, 0x007F,
34 0x00FF, 0x01FF, 0x03FF, 0x07FF,
35 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
45 /* get one code from stream */
46 static int lzw_get_code(LZWDecoderState *s)
50 /* always use TIFF mode */
52 while (s->bbits < s->cursize) {
53 s->bbuf = (s->bbuf << 8) | (*s->pbuf++);
56 // printf("TIFF: bbuf=0x%08x bbits=%d cursize=%d\n", s->bbuf, s->bbits, s->cursize);
57 c = s->bbuf >> (s->bbits - s->cursize);
59 s->bbits -= s->cursize;
61 // printf("bbits=%d c=0x%08x curmask=0x%08x\n", s->bbits, c, s->curmask);
62 return c & s->curmask;
66 void ff_lzw_decode_tail(LZWDecoderState *s)
68 /* always use TIFF mode */
73 CmsRet cmsLzw_initDecoder(LZWDecoderState **p, UINT8 *inbuf, UINT32 inbuf_size)
76 int mode = FF_LZW_TIFF; /* always use TIFF mode */
77 int csize = 8; /* the encoder side has this hardcoded, so hardcode here too */
79 *p = (LZWDecoderState *) cmsMem_alloc(sizeof(LZWDecoderState), ALLOC_ZEROIZE);
82 cmsLog_error("could not allocate %d bytes for decoder state", sizeof(LZWDecoderState));
83 return CMSRET_RESOURCE_EXCEEDED;
87 cmsLog_debug("%d bytes allocated for decoder state", sizeof(LZWDecoderState));
94 s->ebuf = s->pbuf + inbuf_size;
101 s->cursize = s->codesize + 1;
102 s->curmask = mask[s->cursize];
103 s->top_slot = 1 << s->cursize;
104 s->clear_code = 1 << s->codesize;
105 s->end_code = s->clear_code + 1;
106 s->slot = s->newcodes = s->clear_code + 2;
111 s->extra_slot = (s->mode == FF_LZW_TIFF);
113 return CMSRET_SUCCESS;
117 SINT32 cmsLzw_decode(LZWDecoderState *s, UINT8 *outbuf, UINT32 outlen)
133 while (sp > s->stack) {
134 // printf("transfer stack to buf, sp=0x%02x buf=%p\n", *sp, outbuf);
141 if (c == s->end_code) {
142 cmsLog_debug("got end code %d", c);
144 } else if (c == s->clear_code) {
145 cmsLog_debug("got clear code %d", c);
146 s->cursize = s->codesize + 1;
147 s->curmask = mask[s->cursize];
148 s->slot = s->newcodes;
149 s->top_slot = 1 << s->cursize;
153 // printf("got valid code %d (0x%02x)\n", c, c);
155 if (code == s->slot && fc>=0) {
158 }else if(code >= s->slot) {
159 cmsLog_error("code %d greater than slot %d", code, s->slot);
163 while (code >= s->newcodes) {
164 // printf("transfer suffix to to sp \n");
165 *sp++ = s->suffix[code];
166 code = s->prefix[code];
169 // printf("sp=%p gets code %d\n", sp, code);
173 if (s->slot < s->top_slot && oc>=0) {
174 // printf("suffix[%d]=%d prefix[%d]=%d\n", s->slot, code, s->slot, oc);
175 s->suffix[s->slot] = code;
176 s->prefix[s->slot++] = oc;
181 if (s->slot >= s->top_slot - s->extra_slot) {
182 if (s->cursize < LZW_MAXBITS) {
184 s->curmask = mask[++s->cursize];
185 // printf("new top_slot=0x%x curmask=0x%x\n", s->top_slot, s->curmask);
198 cmsLog_debug("about to return, outlen=%d l=%d\n", outlen, l);
204 void cmsLzw_cleanupDecoder(LZWDecoderState **s)
212 #endif /* COMPRESSED_CONFIG_FILE */