comparison gifdec.c @ 4080:f426c81afc9e libavcodec

LZW decoder as separate module plus TIFF LZW support
author kostya
date Thu, 26 Oct 2006 04:15:48 +0000
parents e46fa0f9192a
children a8e3a116b41f
comparison
equal deleted inserted replaced
4079:00a0b18cfb92 4080:f426c81afc9e
22 22
23 //#define DEBUG 23 //#define DEBUG
24 24
25 #include "avcodec.h" 25 #include "avcodec.h"
26 #include "bytestream.h" 26 #include "bytestream.h"
27 27 #include "lzw.h"
28 #define MAXBITS 12
29 #define SIZTABLE (1<<MAXBITS)
30 28
31 #define GCE_DISPOSAL_NONE 0 29 #define GCE_DISPOSAL_NONE 0
32 #define GCE_DISPOSAL_INPLACE 1 30 #define GCE_DISPOSAL_INPLACE 1
33 #define GCE_DISPOSAL_BACKGROUND 2 31 #define GCE_DISPOSAL_BACKGROUND 2
34 #define GCE_DISPOSAL_RESTORE 3 32 #define GCE_DISPOSAL_RESTORE 3
48 /* delay during which the frame is shown */ 46 /* delay during which the frame is shown */
49 int gce_delay; 47 int gce_delay;
50 48
51 /* LZW compatible decoder */ 49 /* LZW compatible decoder */
52 uint8_t *bytestream; 50 uint8_t *bytestream;
53 int eob_reached; 51 LZWState *lzw;
54 uint8_t *pbuf, *ebuf;
55 int bbits;
56 unsigned int bbuf;
57
58 int cursize; /* The current code size */
59 int curmask;
60 int codesize;
61 int clear_code;
62 int end_code;
63 int newcodes; /* First available code */
64 int top_slot; /* Highest code for current size */
65 int slot; /* Last read code */
66 int fc, oc;
67 uint8_t *sp;
68 uint8_t stack[SIZTABLE];
69 uint8_t suffix[SIZTABLE];
70 uint16_t prefix[SIZTABLE];
71 52
72 /* aux buffers */ 53 /* aux buffers */
73 uint8_t global_palette[256 * 3]; 54 uint8_t global_palette[256 * 3];
74 uint8_t local_palette[256 * 3]; 55 uint8_t local_palette[256 * 3];
75 uint8_t buf[256];
76 } GifState; 56 } GifState;
77 57
78 static const uint8_t gif87a_sig[6] = "GIF87a"; 58 static const uint8_t gif87a_sig[6] = "GIF87a";
79 static const uint8_t gif89a_sig[6] = "GIF89a"; 59 static const uint8_t gif89a_sig[6] = "GIF89a";
80
81 static const uint16_t mask[17] =
82 {
83 0x0000, 0x0001, 0x0003, 0x0007,
84 0x000F, 0x001F, 0x003F, 0x007F,
85 0x00FF, 0x01FF, 0x03FF, 0x07FF,
86 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
87 };
88
89 static void GLZWDecodeInit(GifState * s, int csize)
90 {
91 /* read buffer */
92 s->eob_reached = 0;
93 s->pbuf = s->buf;
94 s->ebuf = s->buf;
95 s->bbuf = 0;
96 s->bbits = 0;
97
98 /* decoder */
99 s->codesize = csize;
100 s->cursize = s->codesize + 1;
101 s->curmask = mask[s->cursize];
102 s->top_slot = 1 << s->cursize;
103 s->clear_code = 1 << s->codesize;
104 s->end_code = s->clear_code + 1;
105 s->slot = s->newcodes = s->clear_code + 2;
106 s->oc = s->fc = 0;
107 s->sp = s->stack;
108 }
109
110 /* XXX: optimize */
111 static inline int GetCode(GifState * s)
112 {
113 int c, sizbuf;
114 uint8_t *ptr;
115
116 while (s->bbits < s->cursize) {
117 ptr = s->pbuf;
118 if (ptr >= s->ebuf) {
119 if (!s->eob_reached) {
120 sizbuf = bytestream_get_byte(&s->bytestream);
121 s->ebuf = s->buf + sizbuf;
122 s->pbuf = s->buf;
123 if (sizbuf > 0) {
124 bytestream_get_buffer(&s->bytestream, s->buf, sizbuf);
125 } else {
126 s->eob_reached = 1;
127 }
128 }
129 ptr = s->pbuf;
130 }
131 s->bbuf |= ptr[0] << s->bbits;
132 ptr++;
133 s->pbuf = ptr;
134 s->bbits += 8;
135 }
136 c = s->bbuf & s->curmask;
137 s->bbuf >>= s->cursize;
138 s->bbits -= s->cursize;
139 return c;
140 }
141
142 /* NOTE: the algorithm here is inspired from the LZW GIF decoder
143 written by Steven A. Bennett in 1987. */
144 /* return the number of byte decoded */
145 static int GLZWDecode(GifState * s, uint8_t * buf, int len)
146 {
147 int l, c, code, oc, fc;
148 uint8_t *sp;
149
150 if (s->end_code < 0)
151 return 0;
152
153 l = len;
154 sp = s->sp;
155 oc = s->oc;
156 fc = s->fc;
157
158 while (sp > s->stack) {
159 *buf++ = *(--sp);
160 if ((--l) == 0)
161 goto the_end;
162 }
163
164 for (;;) {
165 c = GetCode(s);
166 if (c == s->end_code) {
167 s->end_code = -1;
168 break;
169 } else if (c == s->clear_code) {
170 s->cursize = s->codesize + 1;
171 s->curmask = mask[s->cursize];
172 s->slot = s->newcodes;
173 s->top_slot = 1 << s->cursize;
174 while ((c = GetCode(s)) == s->clear_code);
175 if (c == s->end_code) {
176 s->end_code = -1;
177 break;
178 }
179 /* test error */
180 if (c >= s->slot)
181 c = 0;
182 fc = oc = c;
183 *buf++ = c;
184 if ((--l) == 0)
185 break;
186 } else {
187 code = c;
188 if (code >= s->slot) {
189 *sp++ = fc;
190 code = oc;
191 }
192 while (code >= s->newcodes) {
193 *sp++ = s->suffix[code];
194 code = s->prefix[code];
195 }
196 *sp++ = code;
197 if (s->slot < s->top_slot) {
198 s->suffix[s->slot] = fc = code;
199 s->prefix[s->slot++] = oc;
200 oc = c;
201 }
202 if (s->slot >= s->top_slot) {
203 if (s->cursize < MAXBITS) {
204 s->top_slot <<= 1;
205 s->curmask = mask[++s->cursize];
206 }
207 }
208 while (sp > s->stack) {
209 *buf++ = *(--sp);
210 if ((--l) == 0)
211 goto the_end;
212 }
213 }
214 }
215 the_end:
216 s->sp = sp;
217 s->oc = oc;
218 s->fc = fc;
219 return len - l;
220 }
221 60
222 static int gif_read_image(GifState *s) 61 static int gif_read_image(GifState *s)
223 { 62 {
224 int left, top, width, height, bits_per_pixel, code_size, flags; 63 int left, top, width, height, bits_per_pixel, code_size, flags;
225 int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; 64 int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i;
265 s->image_palette[s->transparent_color_index] = 0; 104 s->image_palette[s->transparent_color_index] = 0;
266 line = NULL; 105 line = NULL;
267 106
268 /* now get the image data */ 107 /* now get the image data */
269 code_size = bytestream_get_byte(&s->bytestream); 108 code_size = bytestream_get_byte(&s->bytestream);
270 GLZWDecodeInit(s, code_size); 109 //TODO: add proper data size
110 ff_lzw_decode_init(s->lzw, code_size, s->bytestream, 0, FF_LZW_GIF);
271 111
272 /* read all the image */ 112 /* read all the image */
273 linesize = s->picture.linesize[0]; 113 linesize = s->picture.linesize[0];
274 ptr1 = s->picture.data[0] + top * linesize + (left * 3); 114 ptr1 = s->picture.data[0] + top * linesize + (left * 3);
275 ptr = ptr1; 115 ptr = ptr1;
276 pass = 0; 116 pass = 0;
277 y1 = 0; 117 y1 = 0;
278 for (y = 0; y < height; y++) { 118 for (y = 0; y < height; y++) {
279 GLZWDecode(s, ptr, width); 119 ff_lzw_decode(s->lzw, ptr, width);
280 if (is_interleaved) { 120 if (is_interleaved) {
281 switch(pass) { 121 switch(pass) {
282 default: 122 default:
283 case 0: 123 case 0:
284 case 1: 124 case 1:
312 } 152 }
313 } 153 }
314 av_free(line); 154 av_free(line);
315 155
316 /* read the garbage data until end marker is found */ 156 /* read the garbage data until end marker is found */
317 while (!s->eob_reached) 157 ff_lzw_decode_tail(s->lzw);
318 GetCode(s); 158 s->bytestream = ff_lzw_cur_ptr(s->lzw);
319 return 0; 159 return 0;
320 } 160 }
321 161
322 static int gif_read_extension(GifState *s) 162 static int gif_read_extension(GifState *s)
323 { 163 {
443 GifState *s = avctx->priv_data; 283 GifState *s = avctx->priv_data;
444 284
445 avcodec_get_frame_defaults(&s->picture); 285 avcodec_get_frame_defaults(&s->picture);
446 avctx->coded_frame= &s->picture; 286 avctx->coded_frame= &s->picture;
447 s->picture.data[0] = NULL; 287 s->picture.data[0] = NULL;
288 ff_lzw_decode_open(&s->lzw);
448 return 0; 289 return 0;
449 } 290 }
450 291
451 static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) 292 static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
452 { 293 {
481 322
482 static int gif_decode_close(AVCodecContext *avctx) 323 static int gif_decode_close(AVCodecContext *avctx)
483 { 324 {
484 GifState *s = avctx->priv_data; 325 GifState *s = avctx->priv_data;
485 326
327 ff_lzw_decode_close(&s->lzw);
486 if(s->picture.data[0]) 328 if(s->picture.data[0])
487 avctx->release_buffer(avctx, &s->picture); 329 avctx->release_buffer(avctx, &s->picture);
488 return 0; 330 return 0;
489 } 331 }
490 332