Modify #includes of imported files
[firmware_extractor.git] / lzw_decode.c
1 /*
2  * LZW decoder
3  * Copyright (c) 2003 Fabrice Bellard.
4  * Copyright (c) 2006 Konstantin Shishkov.
5  *
6  * This file is part of FFmpeg.
7  *
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.
12  *
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.
17  *
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
21  */
22
23
24 #ifdef COMPRESSED_CONFIG_FILE
25
26 #include "firmware_extractor.h"
27 #include "cms_lzw.h"
28
29
30
31 static const uint16_t mask[17] =
32 {
33     0x0000, 0x0001, 0x0003, 0x0007,
34     0x000F, 0x001F, 0x003F, 0x007F,
35     0x00FF, 0x01FF, 0x03FF, 0x07FF,
36     0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
37 };
38
39
40 enum FF_LZW_MODES{
41     FF_LZW_GIF,
42     FF_LZW_TIFF
43 };
44
45
46 /* get one code from stream */
47 static int lzw_get_code(LZWDecoderState *s)
48 {
49     int c;
50
51     /* always use TIFF mode */
52
53     while (s->bbits < s->cursize) {
54         s->bbuf = (s->bbuf << 8) | (*s->pbuf++);
55         s->bbits += 8;
56     }
57     //    printf("TIFF: bbuf=0x%08x bbits=%d cursize=%d\n", s->bbuf, s->bbits, s->cursize);
58     c = s->bbuf >> (s->bbits - s->cursize);
59
60     s->bbits -= s->cursize;
61
62     //    printf("bbits=%d c=0x%08x curmask=0x%08x\n", s->bbits, c, s->curmask);
63     return c & s->curmask;
64 }
65
66
67 void ff_lzw_decode_tail(LZWDecoderState *s)
68 {
69     /* always use TIFF mode */
70     s->pbuf= s->ebuf;
71 }
72
73
74 CmsRet cmsLzw_initDecoder(LZWDecoderState **p, UINT8 *inbuf, UINT32 inbuf_size)
75 {
76     LZWDecoderState *s;
77     int mode = FF_LZW_TIFF;  /* always use TIFF mode */
78     int csize = 8;  /* the encoder side has this hardcoded, so hardcode here too */
79
80     *p = (LZWDecoderState *) cmsMem_alloc(sizeof(LZWDecoderState), ALLOC_ZEROIZE);
81     if (*p == NULL)
82     {
83        cmsLog_error("could not allocate %d bytes for decoder state", sizeof(LZWDecoderState));
84        return CMSRET_RESOURCE_EXCEEDED;
85     }
86     else
87     {
88        cmsLog_debug("%d bytes allocated for decoder state", sizeof(LZWDecoderState));
89     }
90
91     s = *p;
92
93     /* read buffer */
94     s->pbuf = inbuf;
95     s->ebuf = s->pbuf + inbuf_size;
96     s->bbuf = 0;
97     s->bbits = 0;
98     s->bs = 0;
99
100     /* decoder */
101     s->codesize = csize;
102     s->cursize = s->codesize + 1;
103     s->curmask = mask[s->cursize];
104     s->top_slot = 1 << s->cursize;
105     s->clear_code = 1 << s->codesize;
106     s->end_code = s->clear_code + 1;
107     s->slot = s->newcodes = s->clear_code + 2;
108     s->oc = s->fc = -1;
109     s->sp = s->stack;
110
111     s->mode = mode;
112     s->extra_slot = (s->mode == FF_LZW_TIFF);
113
114     return CMSRET_SUCCESS;
115 }
116
117
118 SINT32 cmsLzw_decode(LZWDecoderState *s, UINT8 *outbuf, UINT32 outlen)
119 {
120     UINT32 l;
121     int c, code, oc, fc;
122     uint8_t *sp;
123
124     if (s->end_code < 0)
125         return -1;
126
127     l = outlen;
128     sp = s->sp;
129     oc = s->oc;
130     fc = s->fc;
131
132     for (;;) {
133
134         while (sp > s->stack) {
135            //           printf("transfer stack to buf, sp=0x%02x buf=%p\n", *sp, outbuf);
136             *outbuf++ = *(--sp);
137             if ((--l) == 0)
138                 goto the_end;
139         }
140
141         c = lzw_get_code(s);
142         if (c == s->end_code) {
143             cmsLog_debug("got end code %d", c);
144             break;
145         } else if (c == s->clear_code) {
146             cmsLog_debug("got clear code %d", c);
147             s->cursize = s->codesize + 1;
148             s->curmask = mask[s->cursize];
149             s->slot = s->newcodes;
150             s->top_slot = 1 << s->cursize;
151             fc= oc= -1;
152         } else {
153             code = c;
154             //            printf("got valid code %d (0x%02x)\n", c, c);
155
156             if (code == s->slot && fc>=0) {
157                 *sp++ = fc;
158                 code = oc;
159             }else if(code >= s->slot) {
160                 cmsLog_error("code %d greater than slot %d", code, s->slot);
161                 break;
162             }
163
164             while (code >= s->newcodes) {
165                //               printf("transfer suffix to to sp \n");
166                 *sp++ = s->suffix[code];
167                 code = s->prefix[code];
168             }
169
170             //            printf("sp=%p gets code %d\n", sp, code);
171             *sp++ = code;
172
173
174             if (s->slot < s->top_slot && oc>=0) {
175                //                printf("suffix[%d]=%d prefix[%d]=%d\n", s->slot, code, s->slot, oc);
176                 s->suffix[s->slot] = code;
177                 s->prefix[s->slot++] = oc;
178             }
179             fc = code;
180             oc = c;
181
182             if (s->slot >= s->top_slot - s->extra_slot) {
183                 if (s->cursize < LZW_MAXBITS) {
184                     s->top_slot <<= 1;
185                     s->curmask = mask[++s->cursize];
186                     //                    printf("new top_slot=0x%x curmask=0x%x\n", s->top_slot, s->curmask);
187                 }
188             }
189         }
190     }  // end of for loop
191
192
193     s->end_code = -1;
194   the_end:
195     s->sp = sp;
196     s->oc = oc;
197     s->fc = fc;
198
199     cmsLog_debug("about to return, outlen=%d l=%d\n", outlen, l);
200     return outlen - l;
201 }
202
203
204
205 void cmsLzw_cleanupDecoder(LZWDecoderState **s)
206 {
207    cmsMem_free(*s);
208    *s = NULL;
209 }
210
211
212
213 #endif /* COMPRESSED_CONFIG_FILE */