?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik #define __GIFDECODER_C__
2 /******************************************************************************
3  
4 * FileName: GifDecoder.c
5 * Dependencies: Image decoding library; project requires File System library
6 * Processor: PIC24/dsPIC30/dsPIC33/PIC32MX
7 * Compiler: C30 v2.01/C32 v0.00.18
8 * Company: Microchip Technology, Inc.
9  
10 * Software License Agreement
11 *
12 * Copyright © 2008 Microchip Technology Inc. All rights reserved.
13 * Microchip licenses to you the right to use, modify, copy and distribute
14 * Software only when embedded on a Microchip microcontroller or digital
15 * signal controller, which is integrated into your product or third party
16 * product (pursuant to the sublicense terms in the accompanying license
17 * agreement).
18 *
19 * You should refer to the license agreement accompanying this Software
20 * for additional information regarding your rights and obligations.
21 *
22 * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
23 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
24 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
25 * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
26 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
27 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
28 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
29 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
30 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
31 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
32 * OR OTHER SIMILAR COSTS.
33  
34 Author Date Comments
35 --------------------------------------------------------------------------------
36 Pradeep Budagutta 03-Mar-2008 First release
37 *******************************************************************************/
38  
39 #include "Image Decoders\ImageDecoder.h"
40  
41 #ifdef IMG_SUPPORT_GIF
42  
43 /*************************/
44 /**** DATA STRUCTURES ****/
45 /*************************/
46 typedef struct _GIFDECODER
47 {
48 IMG_FILE *pImageFile; /* Image file pointer */
49 WORD wImageWidth;
50 WORD wImageHeight;
51 WORD wImageX;
52 WORD wImageY;
53 WORD wScreenWidth;
54 WORD wScreenHeight;
55 WORD wGlobalPaletteEntries;
56 WORD wLocalPaletteEntries;
57 BYTE bBgColorIndex;
58 BYTE bPixelAspectRatio;
59 BYTE blGifMarkerFlag : 1;
60 BYTE blGloabalColorTableFlag : 1;
61 BYTE blLocalColorTableFlag : 1;
62 BYTE blInterlacedFlag : 1;
63 BYTE blFirstcodeFlag : 1;
64 BYTE bInterlacePass : 3;
65 #if GIF_USE_16_BITS_PER_PIXEL == 0
66 BYTE aPalette[256][3]; /* Each palette entry has RGB */
67 #else
68 WORD awPalette[256]; /* Each palette entry has RGB */
69 #endif
70 /* For decoding */
71 BYTE abSymbol[4096];
72  
73 #if GIF_CRUSH_PREV_SYMBOL_PTR_TABLE == 0
74 WORD awPrevSymbolPtr[4096];
75 #else
76 WORD awPrevSymbolPtr[(4096 * 3)/4];
77 #endif
78  
79 WORD wInitialSymbols;
80 WORD wMaxSymbol;
81 BYTE bInitialSymbolBits;
82 BYTE bMaxSymbolBits;
83 LONG lGlobalColorTablePos;
84 /* Work memory */
85 BYTE bWorkBits;
86 BYTE bRemainingDataInBlock;
87 BYTE bRemainingBits;
88 WORD wCurrentX;
89 WORD wCurrentY;
90 } GIFDECODER;
91  
92  
93 /**************************/
94 /****** LOOKUP TABLE ******/
95 /**************************/
96 static const WORD GIF_awMask[] = { 0x000, 0x001, 0x003, 0x007, 0x00F, 0x01F, 0x03F, 0x07F, 0x0FF, 0x1FF, 0x3FF, 0x7FF, 0xFFF };
97  
98 /**************************/
99 /******* FUNCTIONS *******/
100 /**************************/
101 /*******************************************************************************
102 Function: void GIF_vResetData(GIFDECODER *pGifDec)
103  
104 Precondition: None
105  
106 Overview: This function resets the variables so that new GIF image
107 can be decoded
108  
109 Input: GIF decoder's data structure
110  
111 Output: None
112 *******************************************************************************/
113 static void GIF_vResetData(GIFDECODER *pGifDec)
114 {
115 pGifDec->pImageFile = NULL;
116 pGifDec->wImageWidth = 0;
117 pGifDec->wImageHeight = 0;
118 pGifDec->wImageX = 0;
119 pGifDec->wImageY = 0;
120 pGifDec->wScreenWidth = 0;
121 pGifDec->wScreenHeight = 0;
122 pGifDec->wGlobalPaletteEntries = 0;
123 pGifDec->wLocalPaletteEntries = 0;
124 pGifDec->bBgColorIndex = 0;
125 pGifDec->bPixelAspectRatio = 0;
126 pGifDec->blGifMarkerFlag = 0;
127 pGifDec->blGloabalColorTableFlag = 0;
128 pGifDec->blLocalColorTableFlag = 0;
129 pGifDec->blInterlacedFlag = 0;
130 pGifDec->blFirstcodeFlag = 1;
131 pGifDec->bInterlacePass = 0;
132 pGifDec->wMaxSymbol = 0;
133 pGifDec->bMaxSymbolBits = 0;
134 pGifDec->wInitialSymbols = 0;
135 pGifDec->bInitialSymbolBits = 0;
136 pGifDec->bWorkBits = 0;
137 pGifDec->bRemainingDataInBlock = 0;
138 pGifDec->bRemainingBits = 0;
139 pGifDec->wCurrentX = 0;
140 pGifDec->wCurrentY = 0;
141 pGifDec->lGlobalColorTablePos = 0;
142 }
143  
144 /*******************************************************************************
145 Function: void GIF_vPutPrevCode(GIFDECODER *pGifDec, WORD wAddress, WORD wCode)
146  
147 Precondition: None
148  
149 Overview: This function puts the data(code) to the provided address
150  
151 Input: GIF decoder's data structure, Address, Data(Code)
152  
153 Output: None
154 *******************************************************************************/
155 static void GIF_vPutPrevCode(GIFDECODER *pGifDec, WORD wAddress, WORD wCode)
156 {
157 #if GIF_CRUSH_PREV_SYMBOL_PTR_TABLE == 0
158 pGifDec->awPrevSymbolPtr[wAddress] = wCode;
159 #else
160 WORD wCrushedAddress = (wAddress * 3) / 4;
161 if((wAddress & 0x03) == 0)
162 {
163 pGifDec->awPrevSymbolPtr[wCrushedAddress] &= 0xF000;
164 pGifDec->awPrevSymbolPtr[wCrushedAddress] |= (wCode & 0x0FFF);
165 }
166 else if((wAddress & 0x03) == 1)
167 {
168 pGifDec->awPrevSymbolPtr[wCrushedAddress] &= 0x0FFF;
169 pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] &= 0xFF00;
170 pGifDec->awPrevSymbolPtr[wCrushedAddress] |= (wCode << 12);
171 pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] |= ((wCode >> 4) & 0x00FF);
172 }
173 else if((wAddress & 0x03) == 2)
174 {
175 pGifDec->awPrevSymbolPtr[wCrushedAddress] &= 0x00FF;
176 pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] &= 0xFFF0;
177 pGifDec->awPrevSymbolPtr[wCrushedAddress] |= (wCode << 8);
178 pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] |= ((wCode >> 8) & 0x000F);
179 }
180 else
181 {
182 pGifDec->awPrevSymbolPtr[wCrushedAddress] &= 0x000F;
183 pGifDec->awPrevSymbolPtr[wCrushedAddress] |= (wCode << 4);
184 }
185 #endif
186 }
187  
188 /*******************************************************************************
189 Function: WORD GIF_wGetPrevCode(GIFDECODER *pGifDec, WORD wAddress)
190  
191 Precondition: None
192  
193 Overview: This function gets the data(code) from the provided address
194  
195 Input: GIF decoder's data structure, Address
196  
197 Output: Data(Code)
198 *******************************************************************************/
199 static WORD GIF_wGetPrevCode(GIFDECODER *pGifDec, WORD wAddress)
200 {
201 WORD wCode;
202 #if GIF_CRUSH_PREV_SYMBOL_PTR_TABLE == 0
203 wCode = pGifDec->awPrevSymbolPtr[wAddress];
204 #else
205 WORD wCrushedAddress = (wAddress * 3) / 4;
206 if((wAddress & 0x03) == 0)
207 {
208 wCode = (pGifDec->awPrevSymbolPtr[wCrushedAddress] & 0x0FFF);
209 }
210 else if((wAddress & 0x03) == 1)
211 {
212 wCode = (pGifDec->awPrevSymbolPtr[wCrushedAddress] >> 12);
213 wCode |= ((pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] & 0x00FF) << 4);
214 }
215 else if((wAddress & 0x03) == 2)
216 {
217 wCode = (pGifDec->awPrevSymbolPtr[wCrushedAddress] >> 8);
218 wCode |= ((pGifDec->awPrevSymbolPtr[wCrushedAddress + 1] & 0x000F) << 8);
219 }
220 else
221 {
222 wCode = (pGifDec->awPrevSymbolPtr[wCrushedAddress] >> 4);
223 }
224 #endif
225 return wCode;
226 }
227  
228 /*******************************************************************************
229 Function: void GIF_vInitializeTable(GIFDECODER *pGifDec)
230  
231 Precondition: pGifDec->wInitialSymbols must be set to a proper value by
232 reading the Header
233  
234 Overview: This function initializes the code table to the initial number
235 of symbols
236  
237 Input: GIF decoder's data structure
238  
239 Output: None
240 *******************************************************************************/
241 static void GIF_vInitializeTable(GIFDECODER *pGifDec)
242 {
243 WORD wCounter;
244 for(wCounter = 0; wCounter < pGifDec->wInitialSymbols; wCounter++)
245 {
246 pGifDec->abSymbol[wCounter] = wCounter;
247 GIF_vPutPrevCode(pGifDec, wCounter, pGifDec->wInitialSymbols);
248 }
249 }
250  
251 /*******************************************************************************
252 Function: void GIF_vReadColorTable(GIFDECODER *pGifDec, WORD wNumberOfEntries)
253  
254 Precondition: None
255  
256 Overview: This function initializes the code table to the initial number
257 of symbols
258  
259 Input: GIF decoder's data structure
260  
261 Output: None
262 *******************************************************************************/
263 static void GIF_vReadColorTable(GIFDECODER *pGifDec, WORD wNumberOfEntries)
264 {
265 BYTE r, g, b;
266 WORD wCounter;
267 for(wCounter = 0; wCounter < wNumberOfEntries; wCounter++)
268 {
269 IMG_FREAD(&r, sizeof(BYTE), 1, pGifDec->pImageFile); /* R */
270 IMG_FREAD(&g, sizeof(BYTE), 1, pGifDec->pImageFile); /* G */
271 IMG_FREAD(&b, sizeof(BYTE), 1, pGifDec->pImageFile); /* B */
272 #if GIF_USE_16_BITS_PER_PIXEL == 0
273 pGifDec->aPalette[wCounter][0] = r;
274 pGifDec->aPalette[wCounter][1] = g;
275 pGifDec->aPalette[wCounter][2] = b;
276 #else
277 pGifDec->awPalette[wCounter] = RGB565CONVERT(r, g, b);
278 #endif
279 }
280 }
281  
282 /*******************************************************************************
283 Function: BYTE GIF_bReadHeader(GIFDECODER *pGifDec)
284  
285 Precondition: None
286  
287 Overview: This function reads the GIF file's header information
288  
289 Input: GIF decoder's data structure
290  
291 Output: Error code - '0' means no error
292 *******************************************************************************/
293 static BYTE GIF_bReadHeader(GIFDECODER *pGifDec)
294 {
295 BYTE abByte[6];
296 BYTE bFlags;
297  
298 IMG_FREAD(abByte, sizeof(BYTE), 6, pGifDec->pImageFile); /* Marker */
299 if(abByte[0] == 'G' && abByte[1] == 'I' && abByte[2] == 'F' &&
300 abByte[3] == '8' && (abByte[4] == '7' || abByte[4] == '9') &&
301 abByte[5] == 'a')
302 {
303 pGifDec->blGifMarkerFlag = 1;
304 }
305 else
306 {
307 return(100);
308 }
309  
310 IMG_FREAD(&pGifDec->wScreenWidth, sizeof(WORD), 1, pGifDec->pImageFile);
311 IMG_FREAD(&pGifDec->wScreenHeight, sizeof(WORD), 1, pGifDec->pImageFile);
312 IMG_FREAD(&bFlags, sizeof(BYTE), 1, pGifDec->pImageFile); /* Packed fields */
313 IMG_FREAD(&pGifDec->bBgColorIndex, sizeof(BYTE), 1, pGifDec->pImageFile);
314 IMG_FREAD(&pGifDec->bPixelAspectRatio, sizeof(BYTE), 1, pGifDec->pImageFile);
315 if(bFlags & 0x80)
316 {
317 pGifDec->blGloabalColorTableFlag = 1;
318 }
319 pGifDec->wGlobalPaletteEntries = 0x01 << ((bFlags & 0x07) + 1);
320  
321 if(pGifDec->blGloabalColorTableFlag == 1)
322 {
323 pGifDec->lGlobalColorTablePos = IMG_FTELL(pGifDec->pImageFile);
324 GIF_vReadColorTable(pGifDec, pGifDec->wGlobalPaletteEntries);
325 }
326 return(0);
327 }
328  
329 /*******************************************************************************
330 Function: BYTE GIF_bReadNextImageDescriptor(GIFDECODER *pGifDec)
331  
332 Precondition: File pointer must be pointing to proper location (Like start of
333 extension)
334  
335 Overview: This function reads the next image descriptor
336  
337 Input: GIF decoder's data structure
338  
339 Output: Error code - '0' means no error
340 *******************************************************************************/
341 static BYTE GIF_bReadNextImageDescriptor(GIFDECODER *pGifDec)
342 {
343 BYTE bSection, bSectionDetails, bBlockSize, bTemp;
344 BYTE bFlags;
345 BYTE bCounter;
346 do
347 {
348 IMG_FREAD(&bSection, sizeof(BYTE), 1, pGifDec->pImageFile);
349 if(bSection == 0x21) /* Extension block */
350 {
351 IMG_FREAD(&bSectionDetails, sizeof(BYTE), 1, pGifDec->pImageFile);
352 switch(bSectionDetails)
353 {
354 /* GRAPHICS EXTENSION */ case 0xF9: IMG_FREAD(&bBlockSize, sizeof(BYTE), 1, pGifDec->pImageFile);
355 IMG_FSEEK(pGifDec->pImageFile, bBlockSize, 1);
356 break;
357 /* PLAIN TEXT EXTENSION */ case 0x01:
358 /* APPLICATION EXTENSION */ case 0xFF: IMG_FREAD(&bBlockSize, sizeof(BYTE), 1, pGifDec->pImageFile);
359 IMG_FSEEK(pGifDec->pImageFile, bBlockSize, 1);
360 /* COMMENT EXTENSION */ case 0xFE: IMG_FREAD(&bBlockSize, sizeof(BYTE), 1, pGifDec->pImageFile);
361 for(bCounter = 0; bCounter < bBlockSize; bCounter++)
362 {
363 IMG_FREAD(&bTemp, sizeof(BYTE), 1, pGifDec->pImageFile);
364 }
365 break;
366  
367 default: return(100);
368 }
369 /* BLOCK TERMINATOR */ IMG_FREAD(&bTemp, sizeof(BYTE), 1, pGifDec->pImageFile);
370 if(bTemp != 0)
371 {
372 return(100);
373 }
374 }
375 else if(bSection != 0x2C)
376 {
377 return(100);
378 }
379 }
380 while(bSection != 0x2C);
381  
382 pGifDec->blFirstcodeFlag = 1;
383 pGifDec->bInterlacePass = 0;
384 pGifDec->bWorkBits = 0;
385 pGifDec->bRemainingDataInBlock = 0;
386 pGifDec->bRemainingBits = 0;
387 IMG_FREAD(&pGifDec->wImageX, sizeof(WORD), 1, pGifDec->pImageFile);
388 IMG_FREAD(&pGifDec->wImageY, sizeof(WORD), 1, pGifDec->pImageFile);
389 IMG_FREAD(&pGifDec->wImageWidth, sizeof(WORD), 1, pGifDec->pImageFile);
390 IMG_FREAD(&pGifDec->wImageHeight, sizeof(WORD), 1, pGifDec->pImageFile);
391 IMG_FREAD(&bFlags, sizeof(BYTE), 1, pGifDec->pImageFile); /* Packed fields */
392 if(bFlags & 0x40)
393 {
394 pGifDec->blInterlacedFlag = 1;
395 }
396 if(bFlags & 0x80)
397 {
398 pGifDec->blLocalColorTableFlag = 1;
399 }
400 pGifDec->wLocalPaletteEntries = 0x01 << ((bFlags & 0x07) + 1);
401 if(pGifDec->blLocalColorTableFlag == 1)
402 {
403 GIF_vReadColorTable(pGifDec, pGifDec->wLocalPaletteEntries);
404 }
405 pGifDec->wCurrentX = pGifDec->wImageX;
406 pGifDec->wCurrentY = pGifDec->wImageY;
407 return 0;
408 }
409  
410 /*******************************************************************************
411 Function: WORD GIF_wGetNextByte(GIFDECODER *pGifDec)
412  
413 Precondition: None
414  
415 Overview: This function reads the next data byte. It also handles the
416 data block intra-boundaries
417  
418 Input: GIF decoder's data structure
419  
420 Output: Data byte, 0xFFFF means error
421 *******************************************************************************/
422 static WORD GIF_wGetNextByte(GIFDECODER *pGifDec)
423 {
424 BYTE bByte;
425 if(pGifDec->bRemainingDataInBlock == 0)
426 {
427 IMG_FREAD(&pGifDec->bRemainingDataInBlock, sizeof(BYTE), 1, pGifDec->pImageFile);
428 if(pGifDec->bRemainingDataInBlock == 0)
429 {
430 return 0xFFFF; /* End of data */
431 }
432 }
433 IMG_FREAD(&bByte, sizeof(BYTE), 1, pGifDec->pImageFile);
434 pGifDec->bRemainingDataInBlock--;
435 return (WORD)bByte;
436 }
437  
438 /*******************************************************************************
439 Function: WORD GIF_wGetNextSymbol(GIFDECODER *pGifDec)
440  
441 Precondition: pGifDec->bMaxSymbolBits must be properly updated
442  
443 Overview: This function reads the next code symbol brom the data stream
444  
445 Input: GIF decoder's data structure
446  
447 Output: Next Code, 0xFFFF means error
448 *******************************************************************************/
449 static WORD GIF_wGetNextSymbol(GIFDECODER *pGifDec)
450 {
451 WORD wDataBits = 0xFFFF;
452 if(pGifDec->bRemainingBits < pGifDec->bMaxSymbolBits)
453 {
454 WORD wTemp1, wTemp2;
455 BYTE bBitsRequired;
456  
457 bBitsRequired = pGifDec->bMaxSymbolBits - pGifDec->bRemainingBits;
458 wDataBits = pGifDec->bWorkBits & GIF_awMask[pGifDec->bRemainingBits];
459 wTemp1 = GIF_wGetNextByte(pGifDec);
460 if(wTemp1 == 0xFFFF)
461 {
462 return 0xFFFF;
463 }
464 pGifDec->bWorkBits = (BYTE)wTemp1;
465 if(bBitsRequired > 8)
466 {
467 wTemp2 = GIF_wGetNextByte(pGifDec);
468 if(wTemp2 == 0xFFFF)
469 {
470 return 0xFFFF;
471 }
472 pGifDec->bWorkBits = (BYTE)wTemp2;
473 wTemp1 |= wTemp2 << 8;
474 }
475 wDataBits |= wTemp1 << pGifDec->bRemainingBits;
476 pGifDec->bRemainingBits = 8 - (bBitsRequired % 8);
477 if(bBitsRequired == 8)
478 {
479 pGifDec->bRemainingBits = 0;
480 }
481 pGifDec->bWorkBits >>= 8 - pGifDec->bRemainingBits;
482 }
483 else
484 {
485 wDataBits = pGifDec->bWorkBits;
486 pGifDec->bRemainingBits -= pGifDec->bMaxSymbolBits;
487 pGifDec->bWorkBits >>= pGifDec->bMaxSymbolBits;
488 }
489 wDataBits &= GIF_awMask[pGifDec->bMaxSymbolBits];
490 return wDataBits;
491 }
492  
493 /*******************************************************************************
494 Function: void GIF_vPaintData(GIFDECODER *pGifDec, BYTE bData)
495  
496 Precondition: pGifDec->blInterlacedFlag must be properly set
497  
498 Overview: This function puts the actual pixel on the display. It also
499 takes care of the interlaced pixel arrangement.
500  
501 Input: GIF decoder's data structure, palette index
502  
503 Output: None
504 *******************************************************************************/
505 static void GIF_vPaintData(GIFDECODER *pGifDec, BYTE bData)
506 {
507 #if GIF_USE_16_BITS_PER_PIXEL == 0
508 IMG_vSetColor(pGifDec->aPalette[bData][0], pGifDec->aPalette[bData][1], pGifDec->aPalette[bData][2]);
509 #else
510 IMG_vSetColor565(pGifDec->awPalette[bData]);
511 #endif
512 IMG_vPutPixel(pGifDec->wCurrentX, pGifDec->wCurrentY);
513 pGifDec->wCurrentX++;
514 if(pGifDec->wCurrentX >= pGifDec->wImageWidth)
515 {
516 IMG_vLoopCallback();
517 pGifDec->wCurrentX = pGifDec->wImageX;
518 if(pGifDec->blInterlacedFlag == 0)
519 {
520 pGifDec->wCurrentY++;
521 }
522 else
523 {
524 switch(pGifDec->bInterlacePass)
525 {
526 case 0: pGifDec->wCurrentY += 8;
527 break;
528 case 1: pGifDec->wCurrentY += 8;
529 break;
530 case 2: pGifDec->wCurrentY += 4;
531 break;
532 case 3: pGifDec->wCurrentY += 2;
533 break;
534 }
535 if(pGifDec->wCurrentY - pGifDec->wImageY >= pGifDec->wImageHeight)
536 {
537 switch(pGifDec->bInterlacePass)
538 {
539 case 0: pGifDec->wCurrentY = pGifDec->wImageY + 4;
540 break;
541 case 1: pGifDec->wCurrentY = pGifDec->wImageY + 2;
542 break;
543 case 2: pGifDec->wCurrentY = pGifDec->wImageY + 1;
544 break;
545 case 3: pGifDec->wCurrentY = pGifDec->wImageY + 0;
546 break;
547 }
548 pGifDec->bInterlacePass++;
549 }
550 }
551 }
552 }
553  
554 /*******************************************************************************
555 Function: void GIF_vDisplayCode(GIFDECODER *pGifDec, WORD wCode)
556  
557 Precondition: None
558  
559 Overview: This function puts the stream of pixels corresponding to the
560 code. This uses recursion.
561  
562 Input: GIF decoder's data structure, code
563  
564 Output: None
565 *******************************************************************************/
566 static void GIF_vDisplayCode(GIFDECODER *pGifDec, WORD wCode)
567 {
568 WORD wPrevCode = GIF_wGetPrevCode(pGifDec, wCode);
569 if(wPrevCode != pGifDec->wInitialSymbols)
570 {
571 GIF_vDisplayCode(pGifDec, wPrevCode);
572 }
573 GIF_vPaintData(pGifDec, pGifDec->abSymbol[wCode]);
574 }
575  
576 /*******************************************************************************
577 Function: BYTE GIF_bTraceFirstData(GIFDECODER *pGifDec, WORD wCode)
578  
579 Precondition: None
580  
581 Overview: This function gets the first symbol of the code
582  
583 Input: GIF decoder's data structure, code
584  
585 Output: First symbol of the code
586 *******************************************************************************/
587 static BYTE GIF_bTraceFirstData(GIFDECODER *pGifDec, WORD wCode)
588 {
589 while(GIF_wGetPrevCode(pGifDec, wCode) != pGifDec->wInitialSymbols)
590 {
591 wCode = GIF_wGetPrevCode(pGifDec, wCode);
592 }
593 return pGifDec->abSymbol[wCode];
594 }
595  
596 /*******************************************************************************
597 Function: GIF_vExecuteClearCode(GIFDECODER *pGifDec)
598  
599 Precondition: None
600  
601 Overview: This function sets the code table to the initial condition
602  
603 Input: GIF decoder's data structure
604  
605 Output: None
606 *******************************************************************************/
607 static void GIF_vExecuteClearCode(GIFDECODER *pGifDec)
608 {
609 pGifDec->wMaxSymbol = pGifDec->wInitialSymbols;
610 pGifDec->bMaxSymbolBits = pGifDec->bInitialSymbolBits;
611 pGifDec->blFirstcodeFlag = 1;
612 }
613  
614 /*******************************************************************************
615 Function: BYTE GIF_bDecodeNextImage(GIFDECODER *pGifDec)
616  
617 Precondition: Header must be read and file pointer should point to the end
618 of the previous image
619  
620 Overview: This function sets the code table to the initial condition
621  
622 Input: GIF decoder's data structure
623  
624 Output: Error code - '0' means no error
625 *******************************************************************************/
626 static BYTE GIF_bDecodeNextImage(GIFDECODER *pGifDec)
627 {
628 BYTE bBlockTerminator;
629 WORD wCode;
630 if(GIF_bReadNextImageDescriptor(pGifDec) != 0)
631 {
632 return(100);
633 }
634  
635 IMG_FREAD(&pGifDec->bMaxSymbolBits, sizeof(BYTE), 1, pGifDec->pImageFile);
636 if(pGifDec->bMaxSymbolBits > 11)
637 {
638 return(100);
639 }
640 pGifDec->wMaxSymbol = (0x01 << pGifDec->bMaxSymbolBits) + 1;
641 pGifDec->bMaxSymbolBits++;
642 pGifDec->wInitialSymbols = pGifDec->wMaxSymbol;
643 pGifDec->bInitialSymbolBits = pGifDec->bMaxSymbolBits;
644 GIF_vInitializeTable(pGifDec);
645  
646 /* Actual decoding starts here */
647 while(!IMG_FEOF(pGifDec->pImageFile))
648 {
649 IMG_vCheckAndAbort();
650 wCode = GIF_wGetNextSymbol(pGifDec);
651 if(wCode >= 4096)
652 {
653 return(100);
654 }
655 if(wCode == pGifDec->wInitialSymbols) /* End code */
656 {
657 break;
658 }
659 if(wCode == pGifDec->wInitialSymbols - 1) /* Clear code */
660 {
661 GIF_vExecuteClearCode(pGifDec);
662 continue;
663 }
664 if(wCode <= pGifDec->wMaxSymbol) /* Code exists */
665 {
666 GIF_vDisplayCode(pGifDec, wCode);
667 if(pGifDec->blFirstcodeFlag == 0 && pGifDec->wMaxSymbol < 4095)
668 {
669 pGifDec->wMaxSymbol++;
670 pGifDec->abSymbol[pGifDec->wMaxSymbol] = GIF_bTraceFirstData(pGifDec, wCode);
671 }
672 if(pGifDec->wMaxSymbol < 4095)
673 {
674 GIF_vPutPrevCode(pGifDec, pGifDec->wMaxSymbol + 1, wCode);
675 }
676 pGifDec->blFirstcodeFlag = 0;
677 }
678 else if(wCode == pGifDec->wMaxSymbol + 1 && wCode <= 4095)
679 {
680 if(pGifDec->blFirstcodeFlag == 1)
681 {
682 return(100);
683 }
684 pGifDec->wMaxSymbol++;
685 pGifDec->abSymbol[pGifDec->wMaxSymbol] = GIF_bTraceFirstData(pGifDec, GIF_wGetPrevCode(pGifDec, pGifDec->wMaxSymbol));
686 GIF_vDisplayCode(pGifDec, wCode);
687 if(pGifDec->wMaxSymbol < 4095)
688 {
689 GIF_vPutPrevCode(pGifDec, pGifDec->wMaxSymbol + 1, wCode);
690 }
691 }
692 else
693 {
694 return(100);
695 }
696  
697 if((pGifDec->bMaxSymbolBits < 12) && (pGifDec->wMaxSymbol >= (0x01 << pGifDec->bMaxSymbolBits) - 1))
698 {
699 pGifDec->bMaxSymbolBits++;
700 }
701 }
702 if(pGifDec->blLocalColorTableFlag == 1) /* Restore Global color table */
703 {
704 if(pGifDec->lGlobalColorTablePos > 0)
705 {
706 LONG lFilePos = IMG_FTELL(pGifDec->pImageFile);
707 IMG_FSEEK(pGifDec->pImageFile, pGifDec->lGlobalColorTablePos, 0);
708 GIF_vReadColorTable(pGifDec, pGifDec->wGlobalPaletteEntries);
709 IMG_FSEEK(pGifDec->pImageFile, lFilePos, 0);
710 }
711 }
712 IMG_FREAD(&bBlockTerminator, sizeof(BYTE), 1, pGifDec->pImageFile);
713 if(bBlockTerminator == 0)
714 {
715 BYTE bTemp;
716 IMG_FREAD(&bTemp, sizeof(BYTE), 1, pGifDec->pImageFile);
717 if(bTemp == 0x3B) /* End of GIF stream */
718 {
719 return 0x3B;
720 }
721 IMG_FSEEK(pGifDec->pImageFile, -1, 1);
722 }
723 return bBlockTerminator;
724 }
725  
726 /*******************************************************************************
727 Function: BYTE GIF_bDecode(IMG_FILE *pFile)
728  
729 Precondition: None
730  
731 Overview: This function decodes and displays a GIF image
732  
733 Input: Image file
734  
735 Output: Error code - '0' means no error
736 *******************************************************************************/
737 BYTE GIF_bDecode(IMG_FILE *pFile)
738 {
739 GIFDECODER GifDec;
740  
741 GIF_vResetData(&GifDec);
742 GifDec.pImageFile = pFile;
743 GIF_bReadHeader(&GifDec);
744 if(GifDec.blGifMarkerFlag == 0)
745 {
746 return(100);
747 }
748 IMG_wImageWidth = GifDec.wScreenWidth;
749 IMG_wImageHeight = GifDec.wScreenHeight;
750 IMG_vSetboundaries();
751 return GIF_bDecodeNextImage(&GifDec);
752 }
753  
754 #endif
755 #undef __GIFDECODER_C__
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3