annotate lzw.c @ 11694:5e8fdcac294e libavcodec

Add support to the Y411 codec tag, corresponding to the rawvideo pixel format uyyvyy411. The codec tag is referenced in fourcc.org.
author stefano
date Sun, 09 May 2010 22:56:04 +0000
parents 7dd2a45249a9
children 25e9cb2b9477
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
1 /*
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
2 * LZW decoder
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 7266
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 7266
diff changeset
4 * Copyright (c) 2006 Konstantin Shishkov
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
5 *
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
6 * This file is part of FFmpeg.
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
7 *
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
12 *
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
16 * Lesser General Public License for more details.
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
17 *
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
21 */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
22
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
23 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 8718
diff changeset
24 * @file
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
25 * @brief LZW decoding routines
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
26 * @author Fabrice Bellard
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
27 * Modified for use in TIFF by Konstantin Shishkov
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
28 */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
29
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
30 #include "avcodec.h"
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
31 #include "lzw.h"
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
32
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
33 #define LZW_MAXBITS 12
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
34 #define LZW_SIZTABLE (1<<LZW_MAXBITS)
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
35
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
36 static const uint16_t mask[17] =
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
37 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
38 0x0000, 0x0001, 0x0003, 0x0007,
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
39 0x000F, 0x001F, 0x003F, 0x007F,
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
40 0x00FF, 0x01FF, 0x03FF, 0x07FF,
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
41 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
42 };
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
43
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
44 struct LZWState {
6218
michael
parents: 4736
diff changeset
45 const uint8_t *pbuf, *ebuf;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
46 int bbits;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
47 unsigned int bbuf;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
48
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
49 int mode; ///< Decoder mode
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
50 int cursize; ///< The current code size
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
51 int curmask;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
52 int codesize;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
53 int clear_code;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
54 int end_code;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
55 int newcodes; ///< First available code
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
56 int top_slot; ///< Highest code for current size
4725
74caca70e2b3 simplify
michael
parents: 4716
diff changeset
57 int extra_slot;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
58 int slot; ///< Last read code
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
59 int fc, oc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
60 uint8_t *sp;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
61 uint8_t stack[LZW_SIZTABLE];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
62 uint8_t suffix[LZW_SIZTABLE];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
63 uint16_t prefix[LZW_SIZTABLE];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
64 int bs; ///< current buffer size for GIF
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
65 };
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
66
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
67 /* get one code from stream */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
68 static int lzw_get_code(struct LZWState * s)
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
69 {
4727
23f8f6efc870 simplify
michael
parents: 4726
diff changeset
70 int c;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
71
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
72 if(s->mode == FF_LZW_GIF) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
73 while (s->bbits < s->cursize) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
74 if (!s->bs) {
4727
23f8f6efc870 simplify
michael
parents: 4726
diff changeset
75 s->bs = *s->pbuf++;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
76 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
77 s->bbuf |= (*s->pbuf++) << s->bbits;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
78 s->bbits += 8;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
79 s->bs--;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
80 }
4736
59649ebd5ed8 factorize &
michael
parents: 4735
diff changeset
81 c = s->bbuf;
4716
8c00d22d45a0 fix indentation
bcoudurier
parents: 4715
diff changeset
82 s->bbuf >>= s->cursize;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
83 } else { // TIFF
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
84 while (s->bbits < s->cursize) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
85 s->bbuf = (s->bbuf << 8) | (*s->pbuf++);
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
86 s->bbits += 8;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
87 }
4736
59649ebd5ed8 factorize &
michael
parents: 4735
diff changeset
88 c = s->bbuf >> (s->bbits - s->cursize);
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
89 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
90 s->bbits -= s->cursize;
4736
59649ebd5ed8 factorize &
michael
parents: 4735
diff changeset
91 return c & s->curmask;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
92 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
93
6218
michael
parents: 4736
diff changeset
94 const uint8_t* ff_lzw_cur_ptr(LZWState *p)
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
95 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
96 return ((struct LZWState*)p)->pbuf;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
97 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
98
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
99 void ff_lzw_decode_tail(LZWState *p)
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
100 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
101 struct LZWState *s = (struct LZWState *)p;
4728
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
102
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
103 if(s->mode == FF_LZW_GIF) {
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
104 while(s->pbuf < s->ebuf && s->bs>0){
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
105 s->pbuf += s->bs;
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
106 s->bs = *s->pbuf++;
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
107 }
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
108 }else
5db8e9e8f71d move eob_reached logic into ff_lzw_decode_tail() which simplifies the code, avoids some checks in the innermost loop and also gets rid of the controversal break while hopefully retaining the last byte in a valid bytestream, invalid bytestreams still can have very significant overread
michael
parents: 4727
diff changeset
109 s->pbuf= s->ebuf;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
110 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
111
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6218
diff changeset
112 av_cold void ff_lzw_decode_open(LZWState **p)
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
113 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
114 *p = av_mallocz(sizeof(struct LZWState));
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
115 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
116
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6218
diff changeset
117 av_cold void ff_lzw_decode_close(LZWState **p)
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
118 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
119 av_freep(p);
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
120 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
121
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
122 /**
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
123 * Initialize LZW decoder
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
124 * @param s LZW context
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
125 * @param csize initial code size in bits
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
126 * @param buf input data
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
127 * @param buf_size input data size
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
128 * @param mode decoder working mode - either GIF or TIFF
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
129 */
6218
michael
parents: 4736
diff changeset
130 int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, int mode)
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
131 {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
132 struct LZWState *s = (struct LZWState *)p;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
133
7266
451bc2b25bcb check that csize in ff_lzw_decode_init is < LZW_MAXBITS, <= is not enough and
reimar
parents: 6517
diff changeset
134 if(csize < 1 || csize >= LZW_MAXBITS)
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
135 return -1;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
136 /* read buffer */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
137 s->pbuf = buf;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
138 s->ebuf = s->pbuf + buf_size;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
139 s->bbuf = 0;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
140 s->bbits = 0;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
141 s->bs = 0;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
142
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
143 /* decoder */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
144 s->codesize = csize;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
145 s->cursize = s->codesize + 1;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
146 s->curmask = mask[s->cursize];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
147 s->top_slot = 1 << s->cursize;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
148 s->clear_code = 1 << s->codesize;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
149 s->end_code = s->clear_code + 1;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
150 s->slot = s->newcodes = s->clear_code + 2;
4732
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
151 s->oc = s->fc = -1;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
152 s->sp = s->stack;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
153
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
154 s->mode = mode;
4735
8903c1d6db18 simplify
michael
parents: 4733
diff changeset
155 s->extra_slot = s->mode == FF_LZW_TIFF;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
156 return 0;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
157 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
158
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
159 /**
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
160 * Decode given number of bytes
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
161 * NOTE: the algorithm here is inspired from the LZW GIF decoder
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
162 * written by Steven A. Bennett in 1987.
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
163 *
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
164 * @param s LZW context
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
165 * @param buf output buffer
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
166 * @param len number of bytes to decode
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
167 * @return number of bytes decoded
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
168 */
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
169 int ff_lzw_decode(LZWState *p, uint8_t *buf, int len){
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
170 int l, c, code, oc, fc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
171 uint8_t *sp;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
172 struct LZWState *s = (struct LZWState *)p;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
173
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
174 if (s->end_code < 0)
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
175 return 0;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
176
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
177 l = len;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
178 sp = s->sp;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
179 oc = s->oc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
180 fc = s->fc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
181
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
182 for (;;) {
4726
ecb663d00b6b factorize
michael
parents: 4725
diff changeset
183 while (sp > s->stack) {
ecb663d00b6b factorize
michael
parents: 4725
diff changeset
184 *buf++ = *(--sp);
ecb663d00b6b factorize
michael
parents: 4725
diff changeset
185 if ((--l) == 0)
ecb663d00b6b factorize
michael
parents: 4725
diff changeset
186 goto the_end;
ecb663d00b6b factorize
michael
parents: 4725
diff changeset
187 }
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
188 c = lzw_get_code(s);
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
189 if (c == s->end_code) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
190 break;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
191 } else if (c == s->clear_code) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
192 s->cursize = s->codesize + 1;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
193 s->curmask = mask[s->cursize];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
194 s->slot = s->newcodes;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
195 s->top_slot = 1 << s->cursize;
4732
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
196 fc= oc= -1;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
197 } else {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
198 code = c;
4733
507d08212e36 check input validity, this prevents a few variables from reachin odd values which might have lead to out of array writes and thus might have been exploitable
michael
parents: 4732
diff changeset
199 if (code == s->slot && fc>=0) {
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
200 *sp++ = fc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
201 code = oc;
4733
507d08212e36 check input validity, this prevents a few variables from reachin odd values which might have lead to out of array writes and thus might have been exploitable
michael
parents: 4732
diff changeset
202 }else if(code >= s->slot)
507d08212e36 check input validity, this prevents a few variables from reachin odd values which might have lead to out of array writes and thus might have been exploitable
michael
parents: 4732
diff changeset
203 break;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
204 while (code >= s->newcodes) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
205 *sp++ = s->suffix[code];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
206 code = s->prefix[code];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
207 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
208 *sp++ = code;
4732
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
209 if (s->slot < s->top_slot && oc>=0) {
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
210 s->suffix[s->slot] = code;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
211 s->prefix[s->slot++] = oc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
212 }
4732
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
213 fc = code;
8583aa3c21bc simplify
michael
parents: 4728
diff changeset
214 oc = c;
4725
74caca70e2b3 simplify
michael
parents: 4716
diff changeset
215 if (s->slot >= s->top_slot - s->extra_slot) {
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
216 if (s->cursize < LZW_MAXBITS) {
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
217 s->top_slot <<= 1;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
218 s->curmask = mask[++s->cursize];
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
219 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
220 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
221 }
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
222 }
4733
507d08212e36 check input validity, this prevents a few variables from reachin odd values which might have lead to out of array writes and thus might have been exploitable
michael
parents: 4732
diff changeset
223 s->end_code = -1;
4080
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
224 the_end:
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
225 s->sp = sp;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
226 s->oc = oc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
227 s->fc = fc;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
228 return len - l;
f426c81afc9e LZW decoder as separate module plus TIFF LZW support
kostya
parents:
diff changeset
229 }