ReactOS 0.4.16-dev-981-g80eb313
ungif.c
Go to the documentation of this file.
1/*
2 * Gif extracting routines - derived from libungif
3 *
4 * Portions Copyright 2006 Mike McCormack
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/*
22 * Original copyright notice:
23 *
24 * The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a copy
27 * of this software and associated documentation files (the "Software"), to deal
28 * in the Software without restriction, including without limitation the rights
29 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30 * copies of the Software, and to permit persons to whom the Software is
31 * furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
35 */
36
37
38/******************************************************************************
39 * "Gif-Lib" - Yet another gif library.
40 *
41 * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
42 ******************************************************************************
43 * The kernel of the GIF Decoding process can be found here.
44 ******************************************************************************
45 * History:
46 * 16 Jun 89 - Version 1.0 by Gershon Elber.
47 * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
48 *****************************************************************************/
49
50#include <stdlib.h>
51#include <string.h>
52
53#include <stdarg.h>
54#include "windef.h"
55#include "winbase.h"
56#include "ungif.h"
57#include "wine/debug.h"
58
60
61#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
62#define LZ_BITS 12
63
64#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
65
66typedef struct GifFilePrivateType {
67 GifWord BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
68 ClearCode, /* The CLEAR LZ code. */
69 EOFCode, /* The EOF LZ code. */
70 RunningCode, /* The next code algorithm can generate. */
71 RunningBits, /* The number of bits required to represent RunningCode. */
72 MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
73 LastCode, /* The code before the current code. */
74 CrntCode, /* Current algorithm code. */
75 StackPtr, /* For character stack (see below). */
76 CrntShiftState; /* Number of bits in CrntShiftDWord. */
77 unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
78 unsigned long PixelCount; /* Number of pixels in image. */
79 InputFunc Read; /* function to read gif input (TVT) */
80 GifByteType Buf[256]; /* Compressed input is buffered here. */
81 GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
82 GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
85
86/* avoid extra function call in case we use fread (TVT) */
87#define READ(_gif,_buf,_len) \
88 ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len)
89
90static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
91static int DGifSetupDecompress(GifFileType *GifFile);
92static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen);
93static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode);
94static int DGifDecompressInput(GifFileType *GifFile, int *Code);
95static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
96 GifByteType *NextByte);
97
98static int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
99static int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
100
101/******************************************************************************
102 * Miscellaneous utility functions
103 *****************************************************************************/
104
105/* return smallest bitfield size n will fit in */
106static int
107BitSize(int n) {
108
109 register int i;
110
111 for (i = 1; i <= 8; i++)
112 if ((1 << i) >= n)
113 break;
114 return (i);
115}
116
117/******************************************************************************
118 * Color map object functions
119 *****************************************************************************/
120
121/*
122 * Allocate a color map of given size; initialize with contents of
123 * ColorMap if that pointer is non-NULL.
124 */
125static ColorMapObject *
126MakeMapObject(int ColorCount,
127 const GifColorType * ColorMap) {
128
130
131 /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
132 * make the user know that or should we automatically round up instead? */
133 if (ColorCount != (1 << BitSize(ColorCount))) {
134 return NULL;
135 }
136
137 Object = malloc(sizeof(ColorMapObject));
138 if (Object == NULL) {
139 return NULL;
140 }
141
142 Object->Colors = calloc(ColorCount, sizeof(GifColorType));
143 if (Object->Colors == NULL) {
144 free(Object);
145 return NULL;
146 }
147
148 Object->ColorCount = ColorCount;
149 Object->BitsPerPixel = BitSize(ColorCount);
150
151 if (ColorMap) {
152 memcpy(Object->Colors, ColorMap, ColorCount * sizeof(GifColorType));
153 }
154
155 return (Object);
156}
157
158/*
159 * Free a color map object
160 */
161static void
163
164 if (Object != NULL) {
165 free(Object->Colors);
166 free(Object);
167 /*** FIXME:
168 * When we are willing to break API we need to make this function
169 * FreeMapObject(ColorMapObject **Object)
170 * and do this assignment to NULL here:
171 * *Object = NULL;
172 */
173 }
174}
175
176static int
178 int Len,
179 const unsigned char ExtData[]) {
180
181 ExtensionBlock *ep;
182
183 New->ExtensionBlocks = realloc(New->ExtensionBlocks,
184 sizeof(ExtensionBlock) *
185 (New->ExtensionBlockCount + 1));
186
187 if (New->ExtensionBlocks == NULL)
188 return (GIF_ERROR);
189
190 ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
191
192 ep->ByteCount=Len + 3;
193 ep->Bytes = malloc(ep->ByteCount + 3);
194 if (ep->Bytes == NULL)
195 return (GIF_ERROR);
196
197 /* Extension Header */
198 ep->Bytes[0] = 0x21;
199 ep->Bytes[1] = New->Function;
200 ep->Bytes[2] = Len;
201
202 if (ExtData) {
203 memcpy(ep->Bytes + 3, ExtData, Len);
204 ep->Function = New->Function;
205 }
206
207 return (GIF_OK);
208}
209
210static int
212 int Len,
213 const unsigned char ExtData[])
214{
215 ExtensionBlock *ep;
216
217 if (New->ExtensionBlocks == NULL)
218 return (GIF_ERROR);
219
220 ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1];
221
222 ep->Bytes = realloc(ep->Bytes, ep->ByteCount + Len + 1);
223 if (ep->Bytes == NULL)
224 return (GIF_ERROR);
225
226 ep->Bytes[ep->ByteCount] = Len;
227
228 if (ExtData)
229 memcpy(ep->Bytes + ep->ByteCount + 1, ExtData, Len);
230
231 ep->ByteCount += Len + 1;
232
233 return (GIF_OK);
234}
235
236static void
238{
239 ExtensionBlock *ep;
240
241 if ((Extensions == NULL) || (Extensions->ExtensionBlocks == NULL)) {
242 return;
243 }
244 for (ep = Extensions->ExtensionBlocks;
246 free(ep->Bytes);
249}
250
251/******************************************************************************
252 * Image block allocation functions
253******************************************************************************/
254
255static void
257
258 SavedImage *sp;
259
260 if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
261 return;
262 }
263 for (sp = GifFile->SavedImages;
264 sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
265 if (sp->ImageDesc.ColorMap) {
266 FreeMapObject(sp->ImageDesc.ColorMap);
267 sp->ImageDesc.ColorMap = NULL;
268 }
269
270 free(sp->RasterBits);
271
272 if (sp->Extensions.ExtensionBlocks)
273 FreeExtension(&sp->Extensions);
274 }
275 free(GifFile->SavedImages);
276 GifFile->SavedImages=NULL;
277}
278
279/******************************************************************************
280 * This routine should be called before any other DGif calls. Note that
281 * this routine is called automatically from DGif file open routines.
282 *****************************************************************************/
283static int
285
286 int i, BitsPerPixel, SortFlag;
287 GifByteType Buf[3];
288
289 /* Put the screen descriptor into the file: */
290 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
291 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
292 return GIF_ERROR;
293
294 if (READ(GifFile, Buf, 3) != 3) {
295 return GIF_ERROR;
296 }
297 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
298 SortFlag = (Buf[0] & 0x08) != 0;
299 BitsPerPixel = (Buf[0] & 0x07) + 1;
300 GifFile->SColorTableSize = 1 << BitsPerPixel;
301 GifFile->SBackGroundColor = Buf[1];
302 GifFile->SAspectRatio = Buf[2];
303 if (Buf[0] & 0x80) { /* Do we have global color map? */
304
305 GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
306 if (GifFile->SColorMap == NULL) {
307 return GIF_ERROR;
308 }
309
310 /* Get the global color map: */
311 GifFile->SColorMap->SortFlag = SortFlag;
312 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
313 if (READ(GifFile, Buf, 3) != 3) {
314 FreeMapObject(GifFile->SColorMap);
315 GifFile->SColorMap = NULL;
316 return GIF_ERROR;
317 }
318 GifFile->SColorMap->Colors[i].Red = Buf[0];
319 GifFile->SColorMap->Colors[i].Green = Buf[1];
320 GifFile->SColorMap->Colors[i].Blue = Buf[2];
321 }
322 } else {
323 GifFile->SColorMap = NULL;
324 }
325
326 return GIF_OK;
327}
328
329/******************************************************************************
330 * This routine should be called before any attempt to read an image.
331 *****************************************************************************/
332static int
335
336 GifByteType Buf;
337
338 if (READ(GifFile, &Buf, 1) != 1) {
339 /* Wine-specific behavior: Native accepts broken GIF files that have no
340 * terminator, so we match this by treating EOF as a terminator. */
342 return GIF_OK;
343 }
344
345 switch (Buf) {
346 case ',':
348 break;
349 case '!':
351 break;
352 case ';':
354 break;
355 default:
357 return GIF_ERROR;
358 }
359
360 return GIF_OK;
361}
362
363/******************************************************************************
364 * This routine should be called before any attempt to read an image.
365 * Note it is assumed the Image desc. header (',') has been read.
366 *****************************************************************************/
367static int
369
370 int i, BitsPerPixel, SortFlag;
371 GifByteType Buf[3];
372 GifFilePrivateType *Private = GifFile->Private;
373 SavedImage *sp;
374
375 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
376 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
377 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
378 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
379 return GIF_ERROR;
380 if (READ(GifFile, Buf, 1) != 1) {
381 return GIF_ERROR;
382 }
383 BitsPerPixel = (Buf[0] & 0x07) + 1;
384 SortFlag = (Buf[0] & 0x20) != 0;
385 GifFile->Image.Interlace = (Buf[0] & 0x40);
386 if (Buf[0] & 0x80) { /* Does this image have local color map? */
387
388 FreeMapObject(GifFile->Image.ColorMap);
389
390 GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
391 if (GifFile->Image.ColorMap == NULL) {
392 return GIF_ERROR;
393 }
394
395 /* Get the image local color map: */
396 GifFile->Image.ColorMap->SortFlag = SortFlag;
397 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
398 if (READ(GifFile, Buf, 3) != 3) {
399 FreeMapObject(GifFile->Image.ColorMap);
400 GifFile->Image.ColorMap = NULL;
401 return GIF_ERROR;
402 }
403 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
404 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
405 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
406 }
407 } else if (GifFile->Image.ColorMap) {
408 FreeMapObject(GifFile->Image.ColorMap);
409 GifFile->Image.ColorMap = NULL;
410 }
411
412 if ((GifFile->SavedImages = realloc(GifFile->SavedImages,
413 sizeof(SavedImage) *
414 (GifFile->ImageCount + 1))) == NULL) {
415 return GIF_ERROR;
416 }
417
418 sp = &GifFile->SavedImages[GifFile->ImageCount];
419 sp->ImageDesc = GifFile->Image;
420 if (GifFile->Image.ColorMap != NULL) {
421 sp->ImageDesc.ColorMap = MakeMapObject(
422 GifFile->Image.ColorMap->ColorCount,
423 GifFile->Image.ColorMap->Colors);
424 if (sp->ImageDesc.ColorMap == NULL) {
425 return GIF_ERROR;
426 }
427 sp->ImageDesc.ColorMap->SortFlag = GifFile->Image.ColorMap->SortFlag;
428 }
429 sp->RasterBits = NULL;
430 sp->Extensions.ExtensionBlockCount = 0;
431 sp->Extensions.ExtensionBlocks = NULL;
432
433 GifFile->ImageCount++;
434
435 Private->PixelCount = GifFile->Image.Width * GifFile->Image.Height;
436
437 DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
438
439 return GIF_OK;
440}
441
442/******************************************************************************
443 * Get one full scanned line (Line) of length LineLen from GIF file.
444 *****************************************************************************/
445static int
448 int LineLen) {
449
450 GifByteType *Dummy;
451 GifFilePrivateType *Private = GifFile->Private;
452
453 if (!LineLen)
454 LineLen = GifFile->Image.Width;
455
456 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
457 return GIF_ERROR;
458 }
459
460 if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
461 if (Private->PixelCount == 0) {
462 /* We probably would not be called any more, so lets clean
463 * everything before we return: need to flush out all rest of
464 * image until empty block (size 0) detected. We use GetCodeNext. */
465 do
466 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
467 {
468 WARN("GIF is not properly terminated\n");
469 break;
470 }
471 while (Dummy != NULL) ;
472 }
473 return GIF_OK;
474 } else
475 return GIF_ERROR;
476}
477
478/******************************************************************************
479 * Get an extension block (see GIF manual) from gif file. This routine only
480 * returns the first data block, and DGifGetExtensionNext should be called
481 * after this one until NULL extension is returned.
482 * The Extension should NOT be freed by the user (not dynamically allocated).
483 * Note it is assumed the Extension desc. header ('!') has been read.
484 *****************************************************************************/
485static int
487 int *ExtCode,
489
490 GifByteType Buf;
491
492 if (READ(GifFile, &Buf, 1) != 1) {
493 return GIF_ERROR;
494 }
495 *ExtCode = Buf;
496
497 return DGifGetExtensionNext(GifFile, Extension);
498}
499
500/******************************************************************************
501 * Get a following extension block (see GIF manual) from gif file. This
502 * routine should be called until NULL Extension is returned.
503 * The Extension should NOT be freed by the user (not dynamically allocated).
504 *****************************************************************************/
505static int
508
509 GifByteType Buf;
510 GifFilePrivateType *Private = GifFile->Private;
511
512 if (READ(GifFile, &Buf, 1) != 1) {
513 return GIF_ERROR;
514 }
515 if (Buf > 0) {
516 *Extension = Private->Buf; /* Use private unused buffer. */
517 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
518 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
519 return GIF_ERROR;
520 }
521 } else
522 *Extension = NULL;
523
524 return GIF_OK;
525}
526
527/******************************************************************************
528 * Get 2 bytes (word) from the given file:
529 *****************************************************************************/
530static int
532 GifWord *Word) {
533
534 unsigned char c[2];
535
536 if (READ(GifFile, c, 2) != 2) {
537 return GIF_ERROR;
538 }
539
540 *Word = (((unsigned int)c[1]) << 8) + c[0];
541 return GIF_OK;
542}
543
544/******************************************************************************
545 * Continue to get the image code in compressed form. This routine should be
546 * called until NULL block is returned.
547 * The block should NOT be freed by the user (not dynamically allocated).
548 *****************************************************************************/
549static int
551 GifByteType ** CodeBlock) {
552
553 GifByteType Buf;
554 GifFilePrivateType *Private = GifFile->Private;
555
556 if (READ(GifFile, &Buf, 1) != 1) {
557 return GIF_ERROR;
558 }
559
560 if (Buf > 0) {
561 *CodeBlock = Private->Buf; /* Use private unused buffer. */
562 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
563 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
564 return GIF_ERROR;
565 }
566 } else {
567 *CodeBlock = NULL;
568 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
569 Private->PixelCount = 0; /* And local info. indicate image read. */
570 }
571
572 return GIF_OK;
573}
574
575/******************************************************************************
576 * Setup the LZ decompression for this image:
577 *****************************************************************************/
578static int
580
581 int i, BitsPerPixel;
582 GifByteType CodeSize;
584 GifFilePrivateType *Private = GifFile->Private;
585
586 READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
587 BitsPerPixel = CodeSize;
588
589 Private->Buf[0] = 0; /* Input Buffer empty. */
590 Private->BitsPerPixel = BitsPerPixel;
591 Private->ClearCode = (1 << BitsPerPixel);
592 Private->EOFCode = Private->ClearCode + 1;
593 Private->RunningCode = Private->EOFCode + 1;
594 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
595 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
596 Private->StackPtr = 0; /* No pixels on the pixel stack. */
597 Private->LastCode = NO_SUCH_CODE;
598 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
599 Private->CrntShiftDWord = 0;
600
601 Prefix = Private->Prefix;
602 for (i = 0; i <= LZ_MAX_CODE; i++)
604
605 return GIF_OK;
606}
607
608/******************************************************************************
609 * The LZ decompression routine:
610 * This version decompress the given gif file into Line of length LineLen.
611 * This routine can be called few times (one per scan line, for example), in
612 * order the complete the whole image.
613 *****************************************************************************/
614static int
617 int LineLen) {
618
619 int i = 0;
620 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
621 GifByteType *Stack, *Suffix;
623 GifFilePrivateType *Private = GifFile->Private;
624
625 StackPtr = Private->StackPtr;
626 Prefix = Private->Prefix;
627 Suffix = Private->Suffix;
628 Stack = Private->Stack;
629 EOFCode = Private->EOFCode;
630 ClearCode = Private->ClearCode;
631 LastCode = Private->LastCode;
632
633 if (StackPtr != 0) {
634 /* Let pop the stack off before continuing to read the gif file: */
635 while (StackPtr != 0 && i < LineLen)
636 Line[i++] = Stack[--StackPtr];
637 }
638
639 while (i < LineLen) { /* Decode LineLen items. */
640 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
641 return GIF_ERROR;
642
643 if (CrntCode == EOFCode) {
644 /* Note, however, that usually we will not be here as we will stop
645 * decoding as soon as we got all the pixel, or EOF code will
646 * not be read at all, and DGifGetLine/Pixel clean everything. */
647 if (i != LineLen - 1 || Private->PixelCount != 0) {
648 return GIF_ERROR;
649 }
650 i++;
651 } else if (CrntCode == ClearCode) {
652 /* We need to start over again: */
653 for (j = 0; j <= LZ_MAX_CODE; j++)
655 Private->RunningCode = Private->EOFCode + 1;
656 Private->RunningBits = Private->BitsPerPixel + 1;
657 Private->MaxCode1 = 1 << Private->RunningBits;
658 LastCode = Private->LastCode = NO_SUCH_CODE;
659 } else {
660 /* It's a regular code - if in pixel range simply add it to output
661 * stream, otherwise trace to codes linked list until the prefix
662 * is in pixel range: */
663 if (CrntCode < ClearCode) {
664 /* This is simple - its pixel scalar, so add it to output: */
665 Line[i++] = CrntCode;
666 } else {
667 /* It's a code to be traced: trace the linked list
668 * until the prefix is a pixel, while pushing the suffix
669 * pixels on our stack. If we done, pop the stack in reverse
670 * order (that's what stack is good for!) for output. */
671 if (Prefix[CrntCode] == NO_SUCH_CODE) {
672 /* Only allowed if CrntCode is exactly the running code:
673 * In that case CrntCode = XXXCode, CrntCode or the
674 * prefix code is last code and the suffix char is
675 * exactly the prefix of last code! */
676 if (CrntCode == Private->RunningCode - 2) {
677 CrntPrefix = LastCode;
678 Suffix[Private->RunningCode - 2] =
679 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
680 LastCode,
681 ClearCode);
682 } else {
683 return GIF_ERROR;
684 }
685 } else
686 CrntPrefix = CrntCode;
687
688 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
689 * during the trace. As we might loop forever, in case of
690 * defective image, we count the number of loops we trace
691 * and stop if we got LZ_MAX_CODE. Obviously we cannot
692 * loop more than that. */
693 j = 0;
694 while (j++ <= LZ_MAX_CODE &&
695 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
696 Stack[StackPtr++] = Suffix[CrntPrefix];
697 CrntPrefix = Prefix[CrntPrefix];
698 }
699 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
700 return GIF_ERROR;
701 }
702 /* Push the last character on stack: */
703 Stack[StackPtr++] = CrntPrefix;
704
705 /* Now lets pop all the stack into output: */
706 while (StackPtr != 0 && i < LineLen)
707 Line[i++] = Stack[--StackPtr];
708 }
709 if (LastCode != NO_SUCH_CODE) {
710 Prefix[Private->RunningCode - 2] = LastCode;
711
712 if (CrntCode == Private->RunningCode - 2) {
713 /* Only allowed if CrntCode is exactly the running code:
714 * In that case CrntCode = XXXCode, CrntCode or the
715 * prefix code is last code and the suffix char is
716 * exactly the prefix of last code! */
717 Suffix[Private->RunningCode - 2] =
718 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
719 } else {
720 Suffix[Private->RunningCode - 2] =
721 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
722 }
723 }
724 LastCode = CrntCode;
725 }
726 }
727
728 Private->LastCode = LastCode;
729 Private->StackPtr = StackPtr;
730
731 return GIF_OK;
732}
733
734/******************************************************************************
735 * Routine to trace the Prefixes linked list until we get a prefix which is
736 * not code, but a pixel value (less than ClearCode). Returns that pixel value.
737 * If image is defective, we might loop here forever, so we limit the loops to
738 * the maximum possible if image O.k. - LZ_MAX_CODE times.
739 *****************************************************************************/
740static int
742 int Code,
743 int ClearCode) {
744
745 int i = 0;
746
747 while (Code > ClearCode && i++ <= LZ_MAX_CODE)
748 Code = Prefix[Code];
749 return Code;
750}
751
752/******************************************************************************
753 * The LZ decompression input routine:
754 * This routine is responsible for the decompression of the bit stream from
755 * 8 bits (bytes) packets, into the real codes.
756 * Returns GIF_OK if read successfully.
757 *****************************************************************************/
758static int
760 int *Code) {
761
762 GifFilePrivateType *Private = GifFile->Private;
763
764 GifByteType NextByte;
765 static const unsigned short CodeMasks[] = {
766 0x0000, 0x0001, 0x0003, 0x0007,
767 0x000f, 0x001f, 0x003f, 0x007f,
768 0x00ff, 0x01ff, 0x03ff, 0x07ff,
769 0x0fff
770 };
771 /* The image can't contain more than LZ_BITS per code. */
772 if (Private->RunningBits > LZ_BITS) {
773 return GIF_ERROR;
774 }
775
776 while (Private->CrntShiftState < Private->RunningBits) {
777 /* Needs to get more bytes from input stream for next code: */
778 if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
779 return GIF_ERROR;
780 }
781 Private->CrntShiftDWord |=
782 ((unsigned long)NextByte) << Private->CrntShiftState;
783 Private->CrntShiftState += 8;
784 }
785 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
786
787 Private->CrntShiftDWord >>= Private->RunningBits;
788 Private->CrntShiftState -= Private->RunningBits;
789
790 /* If code cannot fit into RunningBits bits, must raise its size. Note
791 * however that codes above 4095 are used for special signaling.
792 * If we're using LZ_BITS bits already and we're at the max code, just
793 * keep using the table as it is, don't increment Private->RunningCode.
794 */
795 if (Private->RunningCode < LZ_MAX_CODE + 2 &&
796 ++Private->RunningCode > Private->MaxCode1 &&
797 Private->RunningBits < LZ_BITS) {
798 Private->MaxCode1 <<= 1;
799 Private->RunningBits++;
800 }
801 return GIF_OK;
802}
803
804/******************************************************************************
805 * This routines read one gif data block at a time and buffers it internally
806 * so that the decompression routine could access it.
807 * The routine returns the next byte from its internal buffer (or read next
808 * block in if buffer empty) and returns GIF_OK if successful.
809 *****************************************************************************/
810static int
812 GifByteType * Buf,
813 GifByteType * NextByte) {
814
815 if (Buf[0] == 0) {
816 /* Needs to read the next buffer - this one is empty: */
817 if (READ(GifFile, Buf, 1) != 1) {
818 return GIF_ERROR;
819 }
820 /* There shouldn't be any empty data blocks here as the LZW spec
821 * says the LZW termination code should come first. Therefore we
822 * shouldn't be inside this routine at that point.
823 */
824 if (Buf[0] == 0) {
825 return GIF_ERROR;
826 }
827 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
828 return GIF_ERROR;
829 }
830 *NextByte = Buf[1];
831 Buf[1] = 2; /* We use now the second place as last char read! */
832 Buf[0]--;
833 } else {
834 *NextByte = Buf[Buf[1]++];
835 Buf[0]--;
836 }
837
838 return GIF_OK;
839}
840
841/******************************************************************************
842 * This routine reads an entire GIF into core, hanging all its state info off
843 * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
844 * first to initialize I/O. Its inverse is EGifSpew().
845 ******************************************************************************/
846int
848
849 int ImageSize;
850 GifRecordType RecordType;
851 SavedImage *sp;
852 GifByteType *ExtData;
853 Extensions temp_save;
854
855 temp_save.ExtensionBlocks = NULL;
856 temp_save.ExtensionBlockCount = 0;
857
858 do {
859 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
860 return (GIF_ERROR);
861
862 switch (RecordType) {
864 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
865 return (GIF_ERROR);
866
867 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
868 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
869
870 sp->RasterBits = malloc(ImageSize * sizeof(GifPixelType));
871 if (sp->RasterBits == NULL) {
872 return GIF_ERROR;
873 }
874 if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
875 GIF_ERROR)
876 return (GIF_ERROR);
877 if (temp_save.ExtensionBlocks) {
878 sp->Extensions.ExtensionBlocks = temp_save.ExtensionBlocks;
879 sp->Extensions.ExtensionBlockCount = temp_save.ExtensionBlockCount;
880
881 temp_save.ExtensionBlocks = NULL;
882 temp_save.ExtensionBlockCount = 0;
883
884 /* FIXME: The following is wrong. It is left in only for
885 * backwards compatibility. Someday it should go away. Use
886 * the sp->ExtensionBlocks->Function variable instead. */
887 sp->Extensions.Function = sp->Extensions.ExtensionBlocks[0].Function;
888 }
889 break;
890
892 {
893 int Function;
895
896 if (DGifGetExtension(GifFile, &Function, &ExtData) == GIF_ERROR)
897 return (GIF_ERROR);
898
899 if (GifFile->ImageCount || Function == GRAPHICS_EXT_FUNC_CODE)
900 Extensions = &temp_save;
901 else
902 Extensions = &GifFile->Extensions;
903
905
906 if (ExtData)
907 {
908 /* Create an extension block with our data */
909 if (AddExtensionBlock(Extensions, ExtData[0], &ExtData[1]) == GIF_ERROR)
910 return (GIF_ERROR);
911 }
912 else /* Empty extension block */
913 {
915 return (GIF_ERROR);
916 }
917
918 while (ExtData != NULL) {
919 int Len;
921
922 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
923 return (GIF_ERROR);
924
925 if (ExtData)
926 {
927 Len = ExtData[0];
928 Data = &ExtData[1];
929 }
930 else
931 {
932 Len = 0;
933 Data = NULL;
934 }
935
937 return (GIF_ERROR);
938 }
939 break;
940 }
941
943 break;
944
945 default: /* Should be trapped by DGifGetRecordType */
946 break;
947 }
948 } while (RecordType != TERMINATE_RECORD_TYPE);
949
950 /* Just in case the Gif has an extension block without an associated
951 * image... (Should we save this into a savefile structure with no image
952 * instead? Have to check if the present writing code can handle that as
953 * well.... */
954 if (temp_save.ExtensionBlocks)
955 FreeExtension(&temp_save);
956
957 return (GIF_OK);
958}
959
960/******************************************************************************
961 * GifFileType constructor with user supplied input function (TVT)
962 *****************************************************************************/
964DGifOpen(void *userData,
965 InputFunc readFunc) {
966
967 unsigned char Buf[GIF_STAMP_LEN + 1];
968 GifFileType *GifFile;
969 GifFilePrivateType *Private;
970
971 GifFile = malloc(sizeof(GifFileType));
972 if (GifFile == NULL) {
973 return NULL;
974 }
975
976 memset(GifFile, '\0', sizeof(GifFileType));
977
978 Private = malloc(sizeof(GifFilePrivateType));
979 if (!Private) {
980 free(GifFile);
981 return NULL;
982 }
983
984 GifFile->Private = (void*)Private;
985
986 Private->Read = readFunc; /* TVT */
987 GifFile->UserData = userData; /* TVT */
988
989 /* Lets see if this is a GIF file: */
990 if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
991 free(Private);
992 free(GifFile);
993 return NULL;
994 }
995
996 /* The GIF Version number is ignored at this time. Maybe we should do
997 * something more useful with it. */
998 Buf[GIF_STAMP_LEN] = 0;
999 if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
1000 free(Private);
1001 free(GifFile);
1002 return NULL;
1003 }
1004
1005 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
1006 free(Private);
1007 free(GifFile);
1008 return NULL;
1009 }
1010
1011 return GifFile;
1012}
1013
1014/******************************************************************************
1015 * This routine should be called last, to close the GIF file.
1016 *****************************************************************************/
1017int
1019
1020 GifFilePrivateType *Private;
1021
1022 if (GifFile == NULL)
1023 return GIF_ERROR;
1024
1025 Private = GifFile->Private;
1026
1027 if (GifFile->Image.ColorMap) {
1028 FreeMapObject(GifFile->Image.ColorMap);
1029 GifFile->Image.ColorMap = NULL;
1030 }
1031
1032 if (GifFile->SColorMap) {
1033 FreeMapObject(GifFile->SColorMap);
1034 GifFile->SColorMap = NULL;
1035 }
1036
1037 free(Private);
1038 Private = NULL;
1039
1040 if (GifFile->SavedImages) {
1041 FreeSavedImages(GifFile);
1042 GifFile->SavedImages = NULL;
1043 }
1044
1045 FreeExtension(&GifFile->Extensions);
1046
1047 free(GifFile);
1048
1049 return GIF_OK;
1050}
Type
Definition: Type.h:7
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: precomp.h:61
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define Code
Definition: deflate.h:80
#define Len
Definition: deflate.h:82
#define NULL
Definition: types.h:112
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const WCHAR sp[]
Definition: suminfo.c:287
#define long
Definition: qsort.c:33
#define calloc
Definition: rosglue.h:14
#define New(t)
Definition: rtf.h:1086
#define memset(x, y, z)
Definition: compat.h:39
GifColorType * Colors
Definition: ungif.h:92
int SortFlag
Definition: ungif.h:91
int ColorCount
Definition: ungif.h:89
char * Bytes
Definition: ungif.h:105
int ByteCount
Definition: ungif.h:104
int Function
Definition: ungif.h:103
int Function
Definition: ungif.h:109
ExtensionBlock * ExtensionBlocks
Definition: ungif.h:111
int ExtensionBlockCount
Definition: ungif.h:110
GifByteType Blue
Definition: ungif.h:85
GifByteType Green
Definition: ungif.h:85
GifByteType Red
Definition: ungif.h:85
GifWord CrntCode
Definition: ungif.c:74
GifWord MaxCode1
Definition: ungif.c:72
GifByteType Stack[LZ_MAX_CODE]
Definition: ungif.c:81
GifWord EOFCode
Definition: ungif.c:69
GifWord RunningBits
Definition: ungif.c:71
GifWord LastCode
Definition: ungif.c:73
unsigned long PixelCount
Definition: ungif.c:78
InputFunc Read
Definition: ungif.c:79
GifByteType Suffix[LZ_MAX_CODE+1]
Definition: ungif.c:82
GifWord CrntShiftState
Definition: ungif.c:76
GifWord StackPtr
Definition: ungif.c:75
GifWord BitsPerPixel
Definition: ungif.c:67
GifByteType Buf[256]
Definition: ungif.c:80
GifWord ClearCode
Definition: ungif.c:68
GifPrefixType Prefix[LZ_MAX_CODE+1]
Definition: ungif.c:83
GifWord RunningCode
Definition: ungif.c:70
unsigned long CrntShiftDWord
Definition: ungif.c:77
GifWord SAspectRatio
Definition: ungif.h:119
Extensions Extensions
Definition: ungif.h:121
GifWord SWidth
Definition: ungif.h:115
GifImageDesc Image
Definition: ungif.h:123
struct SavedImage * SavedImages
Definition: ungif.h:124
GifWord SColorResolution
Definition: ungif.h:116
ColorMapObject * SColorMap
Definition: ungif.h:120
void * Private
Definition: ungif.h:126
GifWord SBackGroundColor
Definition: ungif.h:118
GifWord SColorTableSize
Definition: ungif.h:117
GifWord SHeight
Definition: ungif.h:115
int ImageCount
Definition: ungif.h:122
void * UserData
Definition: ungif.h:125
ColorMapObject * ColorMap
Definition: ungif.h:98
GifWord Interlace
Definition: ungif.h:97
GifWord Top
Definition: ungif.h:96
GifWord Left
Definition: ungif.h:96
GifWord Width
Definition: ungif.h:96
GifWord Height
Definition: ungif.h:96
Definition: ncftp.h:79
static int DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
Definition: ungif.c:486
static void FreeMapObject(ColorMapObject *Object)
Definition: ungif.c:162
static int AppendExtensionBlock(Extensions *New, int Len, const unsigned char ExtData[])
Definition: ungif.c:211
static int DGifGetScreenDesc(GifFileType *GifFile)
Definition: ungif.c:284
static void FreeExtension(Extensions *Extensions)
Definition: ungif.c:237
static int DGifSetupDecompress(GifFileType *GifFile)
Definition: ungif.c:579
static int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type)
Definition: ungif.c:333
static int DGifGetImageDesc(GifFileType *GifFile)
Definition: ungif.c:368
GifFileType * DGifOpen(void *userData, InputFunc readFunc)
Definition: ungif.c:964
int DGifCloseFile(GifFileType *GifFile)
Definition: ungif.c:1018
#define LZ_MAX_CODE
Definition: ungif.c:61
int DGifSlurp(GifFileType *GifFile)
Definition: ungif.c:847
#define READ(_gif, _buf, _len)
Definition: ungif.c:87
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
Definition: ungif.c:811
static int DGifDecompressInput(GifFileType *GifFile, int *Code)
Definition: ungif.c:759
static int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock)
Definition: ungif.c:550
#define LZ_BITS
Definition: ungif.c:62
static int DGifGetWord(GifFileType *GifFile, GifWord *Word)
Definition: ungif.c:531
static int AddExtensionBlock(Extensions *New, int Len, const unsigned char ExtData[])
Definition: ungif.c:177
static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode)
Definition: ungif.c:741
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
Definition: ungif.c:615
#define NO_SUCH_CODE
Definition: ungif.c:64
static void FreeSavedImages(GifFileType *GifFile)
Definition: ungif.c:256
static int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
Definition: ungif.c:446
static ColorMapObject * MakeMapObject(int ColorCount, const GifColorType *ColorMap)
Definition: ungif.c:126
static int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension)
Definition: ungif.c:506
static int BitSize(int n)
Definition: ungif.c:107
#define GIF_VERSION_POS
Definition: ungif.h:71
unsigned int GifPrefixType
Definition: ungif.h:81
unsigned char GifPixelType
Definition: ungif.h:78
unsigned char GifByteType
Definition: ungif.h:80
#define GIF_STAMP_LEN
Definition: ungif.h:70
GifRecordType
Definition: ungif.h:129
@ EXTENSION_RECORD_TYPE
Definition: ungif.h:133
@ UNDEFINED_RECORD_TYPE
Definition: ungif.h:130
@ IMAGE_DESC_RECORD_TYPE
Definition: ungif.h:132
@ TERMINATE_RECORD_TYPE
Definition: ungif.h:134
#define GIF_OK
Definition: ungif.h:56
#define GRAPHICS_EXT_FUNC_CODE
Definition: ungif.h:143
int(* InputFunc)(GifFileType *, GifByteType *, int)
Definition: ungif.h:138
int GifWord
Definition: ungif.h:82
#define GIF_STAMP
Definition: ungif.h:69
#define GIF_ERROR
Definition: ungif.h:55
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1701
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1647