1 /****************************************************************************** 2 * "Gif-Lib" - Yet another gif library. 3 * 4 * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 5 ****************************************************************************** 6 * The kernel of the GIF Decoding process can be found here. 7 ****************************************************************************** 8 * History: 9 * 16 Jun 89 - Version 1.0 by Gershon Elber. 10 * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). 11 *****************************************************************************/ 12 13 #ifdef HAVE_CONFIG_H 14 #include <config.h> 15 #endif 16 17 #include <stdlib.h> 18 #if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__) 19 #include <io.h> 20 #include <alloc.h> 21 #include <sys\stat.h> 22 #else 23 #include <sys/types.h> 24 #include <sys/stat.h> 25 #endif /* __MSDOS__ */ 26 27 #ifdef HAVE_IO_H 28 #include <io.h> 29 #endif 30 31 #ifdef HAVE_FCNTL_H 32 #include <fcntl.h> 33 #endif /* HAVE_FCNTL_H */ 34 #ifdef HAVE_UNISTD_H 35 #include <unistd.h> 36 #endif /* HAVE_UNISTD_H */ 37 #include <stdio.h> 38 #include <string.h> 39 #include "gif_lib.h" 40 #include "gif_lib_private.h" 41 42 #define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for 43 comment. */ 44 45 /* avoid extra function call in case we use fread (TVT) */ 46 #define READ(_gif,_buf,_len) \ 47 (((GifFilePrivateType*)_gif->Private)->Read ? \ 48 ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ 49 fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File)) 50 51 static int DGifGetWord(GifFileType *GifFile, GifWord *Word); 52 static int DGifSetupDecompress(GifFileType *GifFile); 53 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, 54 int LineLen); 55 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode); 56 static int DGifDecompressInput(GifFileType *GifFile, int *Code); 57 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, 58 GifByteType *NextByte); 59 #ifndef _GBA_NO_FILEIO 60 61 /****************************************************************************** 62 * Open a new gif file for read, given by its name. 63 * Returns GifFileType pointer dynamically allocated which serves as the gif 64 * info record. _GifError is cleared if succesfull. 65 *****************************************************************************/ 66 GifFileType * 67 DGifOpenFileName(const char *FileName) { 68 int FileHandle; 69 GifFileType *GifFile; 70 71 if ((FileHandle = open(FileName, O_RDONLY 72 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) 73 | O_BINARY 74 #endif /* __MSDOS__ || _OPEN_BINARY */ 75 )) == -1) { 76 _GifError = D_GIF_ERR_OPEN_FAILED; 77 return NULL; 78 } 79 80 GifFile = DGifOpenFileHandle(FileHandle); 81 return GifFile; 82 } 83 84 /****************************************************************************** 85 * Update a new gif file, given its file handle. 86 * Returns GifFileType pointer dynamically allocated which serves as the gif 87 * info record. _GifError is cleared if succesfull. 88 *****************************************************************************/ 89 GifFileType * 90 DGifOpenFileHandle(int FileHandle) { 91 92 unsigned char Buf[GIF_STAMP_LEN + 1]; 93 GifFileType *GifFile; 94 GifFilePrivateType *Private; 95 FILE *f; 96 97 GifFile = (GifFileType *)malloc(sizeof(GifFileType)); 98 if (GifFile == NULL) { 99 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 100 close(FileHandle); 101 return NULL; 102 } 103 104 memset(GifFile, '\0', sizeof(GifFileType)); 105 106 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); 107 if (Private == NULL) { 108 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 109 close(FileHandle); 110 free((char *)GifFile); 111 return NULL; 112 } 113 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) 114 setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ 115 #endif /* __MSDOS__ */ 116 117 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ 118 119 #if defined(__MSDOS__) || defined(WINDOWS32) 120 setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream 121 buffer. */ 122 #endif /* __MSDOS__ */ 123 124 GifFile->Private = (VoidPtr)Private; 125 Private->FileHandle = FileHandle; 126 Private->File = f; 127 Private->FileState = FILE_STATE_READ; 128 Private->Read = 0; /* don't use alternate input method (TVT) */ 129 GifFile->UserData = 0; /* TVT */ 130 131 /* Lets see if this is a GIF file: */ 132 if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { 133 _GifError = D_GIF_ERR_READ_FAILED; 134 fclose(f); 135 free((char *)Private); 136 free((char *)GifFile); 137 return NULL; 138 } 139 140 /* The GIF Version number is ignored at this time. Maybe we should do 141 * something more useful with it. */ 142 Buf[GIF_STAMP_LEN] = 0; 143 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { 144 _GifError = D_GIF_ERR_NOT_GIF_FILE; 145 fclose(f); 146 free((char *)Private); 147 free((char *)GifFile); 148 return NULL; 149 } 150 151 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { 152 fclose(f); 153 free((char *)Private); 154 free((char *)GifFile); 155 return NULL; 156 } 157 158 _GifError = 0; 159 160 return GifFile; 161 } 162 163 #endif /* _GBA_NO_FILEIO */ 164 165 /****************************************************************************** 166 * GifFileType constructor with user supplied input function (TVT) 167 *****************************************************************************/ 168 GifFileType * 169 DGifOpen(void *userData, 170 InputFunc readFunc) { 171 172 unsigned char Buf[GIF_STAMP_LEN + 1]; 173 GifFileType *GifFile; 174 GifFilePrivateType *Private; 175 176 GifFile = (GifFileType *)malloc(sizeof(GifFileType)); 177 if (GifFile == NULL) { 178 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 179 return NULL; 180 } 181 182 memset(GifFile, '\0', sizeof(GifFileType)); 183 184 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); 185 if (!Private) { 186 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 187 free((char *)GifFile); 188 return NULL; 189 } 190 191 GifFile->Private = (VoidPtr)Private; 192 Private->FileHandle = 0; 193 Private->File = 0; 194 Private->FileState = FILE_STATE_READ; 195 196 Private->Read = readFunc; /* TVT */ 197 GifFile->UserData = userData; /* TVT */ 198 199 /* Lets see if this is a GIF file: */ 200 if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { 201 _GifError = D_GIF_ERR_READ_FAILED; 202 free((char *)Private); 203 free((char *)GifFile); 204 return NULL; 205 } 206 207 /* The GIF Version number is ignored at this time. Maybe we should do 208 * something more useful with it. */ 209 Buf[GIF_STAMP_LEN] = 0; 210 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { 211 _GifError = D_GIF_ERR_NOT_GIF_FILE; 212 free((char *)Private); 213 free((char *)GifFile); 214 return NULL; 215 } 216 217 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { 218 free((char *)Private); 219 free((char *)GifFile); 220 return NULL; 221 } 222 223 _GifError = 0; 224 225 return GifFile; 226 } 227 228 /****************************************************************************** 229 * This routine should be called before any other DGif calls. Note that 230 * this routine is called automatically from DGif file open routines. 231 *****************************************************************************/ 232 int 233 DGifGetScreenDesc(GifFileType * GifFile) { 234 235 int i, BitsPerPixel; 236 GifByteType Buf[3]; 237 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 238 239 if (!IS_READABLE(Private)) { 240 /* This file was NOT open for reading: */ 241 _GifError = D_GIF_ERR_NOT_READABLE; 242 return GIF_ERROR; 243 } 244 245 /* Put the screen descriptor into the file: */ 246 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || 247 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) 248 return GIF_ERROR; 249 250 if (READ(GifFile, Buf, 3) != 3) { 251 _GifError = D_GIF_ERR_READ_FAILED; 252 return GIF_ERROR; 253 } 254 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; 255 BitsPerPixel = (Buf[0] & 0x07) + 1; 256 GifFile->SBackGroundColor = Buf[1]; 257 if (Buf[0] & 0x80) { /* Do we have global color map? */ 258 259 GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); 260 if (GifFile->SColorMap == NULL) { 261 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 262 return GIF_ERROR; 263 } 264 265 /* Get the global color map: */ 266 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { 267 if (READ(GifFile, Buf, 3) != 3) { 268 FreeMapObject(GifFile->SColorMap); 269 GifFile->SColorMap = NULL; 270 _GifError = D_GIF_ERR_READ_FAILED; 271 return GIF_ERROR; 272 } 273 GifFile->SColorMap->Colors[i].Red = Buf[0]; 274 GifFile->SColorMap->Colors[i].Green = Buf[1]; 275 GifFile->SColorMap->Colors[i].Blue = Buf[2]; 276 } 277 } else { 278 GifFile->SColorMap = NULL; 279 } 280 281 return GIF_OK; 282 } 283 284 /****************************************************************************** 285 * This routine should be called before any attempt to read an image. 286 *****************************************************************************/ 287 int 288 DGifGetRecordType(GifFileType * GifFile, 289 GifRecordType * Type) { 290 291 GifByteType Buf; 292 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 293 294 if (!IS_READABLE(Private)) { 295 /* This file was NOT open for reading: */ 296 _GifError = D_GIF_ERR_NOT_READABLE; 297 return GIF_ERROR; 298 } 299 300 if (READ(GifFile, &Buf, 1) != 1) { 301 _GifError = D_GIF_ERR_READ_FAILED; 302 return GIF_ERROR; 303 } 304 305 switch (Buf) { 306 case ',': 307 *Type = IMAGE_DESC_RECORD_TYPE; 308 break; 309 case '!': 310 *Type = EXTENSION_RECORD_TYPE; 311 break; 312 case ';': 313 *Type = TERMINATE_RECORD_TYPE; 314 break; 315 default: 316 *Type = UNDEFINED_RECORD_TYPE; 317 _GifError = D_GIF_ERR_WRONG_RECORD; 318 return GIF_ERROR; 319 } 320 321 return GIF_OK; 322 } 323 324 /****************************************************************************** 325 * This routine should be called before any attempt to read an image. 326 * Note it is assumed the Image desc. header (',') has been read. 327 *****************************************************************************/ 328 int 329 DGifGetImageDesc(GifFileType * GifFile) { 330 331 int i, BitsPerPixel; 332 GifByteType Buf[3]; 333 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 334 SavedImage *sp; 335 336 if (!IS_READABLE(Private)) { 337 /* This file was NOT open for reading: */ 338 _GifError = D_GIF_ERR_NOT_READABLE; 339 return GIF_ERROR; 340 } 341 342 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || 343 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || 344 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR || 345 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) 346 return GIF_ERROR; 347 if (READ(GifFile, Buf, 1) != 1) { 348 _GifError = D_GIF_ERR_READ_FAILED; 349 return GIF_ERROR; 350 } 351 BitsPerPixel = (Buf[0] & 0x07) + 1; 352 GifFile->Image.Interlace = (Buf[0] & 0x40); 353 if (Buf[0] & 0x80) { /* Does this image have local color map? */ 354 355 /*** FIXME: Why do we check both of these in order to do this? 356 * Why do we have both Image and SavedImages? */ 357 if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL) 358 FreeMapObject(GifFile->Image.ColorMap); 359 360 GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); 361 if (GifFile->Image.ColorMap == NULL) { 362 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 363 return GIF_ERROR; 364 } 365 366 /* Get the image local color map: */ 367 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { 368 if (READ(GifFile, Buf, 3) != 3) { 369 FreeMapObject(GifFile->Image.ColorMap); 370 _GifError = D_GIF_ERR_READ_FAILED; 371 GifFile->Image.ColorMap = NULL; 372 return GIF_ERROR; 373 } 374 GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; 375 GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; 376 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; 377 } 378 } else if (GifFile->Image.ColorMap) { 379 FreeMapObject(GifFile->Image.ColorMap); 380 GifFile->Image.ColorMap = NULL; 381 } 382 383 if (GifFile->SavedImages) { 384 if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, 385 sizeof(SavedImage) * 386 (GifFile->ImageCount + 1))) == NULL) { 387 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 388 return GIF_ERROR; 389 } 390 } else { 391 if ((GifFile->SavedImages = 392 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) { 393 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 394 return GIF_ERROR; 395 } 396 } 397 398 sp = &GifFile->SavedImages[GifFile->ImageCount]; 399 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); 400 if (GifFile->Image.ColorMap != NULL) { 401 sp->ImageDesc.ColorMap = MakeMapObject( 402 GifFile->Image.ColorMap->ColorCount, 403 GifFile->Image.ColorMap->Colors); 404 if (sp->ImageDesc.ColorMap == NULL) { 405 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; 406 return GIF_ERROR; 407 } 408 } 409 sp->RasterBits = (unsigned char *)NULL; 410 sp->ExtensionBlockCount = 0; 411 sp->ExtensionBlocks = (ExtensionBlock *) NULL; 412 413 GifFile->ImageCount++; 414 415 Private->PixelCount = (long)GifFile->Image.Width * 416 (long)GifFile->Image.Height; 417 418 DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ 419 420 return GIF_OK; 421 } 422 423 /****************************************************************************** 424 * Get one full scanned line (Line) of length LineLen from GIF file. 425 *****************************************************************************/ 426 int 427 DGifGetLine(GifFileType * GifFile, 428 GifPixelType * Line, 429 int LineLen) { 430 431 GifByteType *Dummy; 432 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; 433 434 if (!IS_READABLE(Private)) { 435 /* This file was NOT open for reading: */ 436 _GifError = D_GIF_ERR_NOT_READABLE; 437 return GIF_ERROR; 438 } 439 440 if (!LineLen) 441 LineLen = GifFile->Image.Width; 442 443 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__) 444 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { 445 #else 446 if ((Private->PixelCount -= LineLen) > 0xffff0000) { 447 #endif /* __MSDOS__ */ 448 _GifError = D_GIF_ERR_DATA_TOO_BIG; 449 return GIF_ERROR; 450 } 451 452 if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { 453 if (Private->PixelCount == 0) { 454 /* We probably would not be called any more, so lets clean 455 * everything before we return: need to flush out all rest of 456 * image until empty block (size 0) detected. We use GetCodeNext. */ 457 do 458 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) 459 return GIF_ERROR; 460 while (Dummy != NULL) ; 461 } 462 return GIF_OK; 463 } else 464 return GIF_ERROR; 465 } 466 467 /****************************************************************************** 468 * Put one pixel (Pixel) into GIF file. 469 *****************************************************************************/ 470 int 471 DGifGetPixel(GifFileType * GifFile, 472 GifPixelType Pixel) { 473 474 GifByteType *Dummy; 475 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; 476 477 if (!IS_READABLE(Private)) { 478 /* This file was NOT open for reading: */ 479 _GifError = D_GIF_ERR_NOT_READABLE; 480 return GIF_ERROR; 481 } 482 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__) 483 if (--Private->PixelCount > 0xffff0000UL) 484 #else 485 if (--Private->PixelCount > 0xffff0000) 486 #endif /* __MSDOS__ */ 487 { 488 _GifError = D_GIF_ERR_DATA_TOO_BIG; 489 return GIF_ERROR; 490 } 491 492 if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { 493 if (Private->PixelCount == 0) { 494 /* We probably would not be called any more, so lets clean 495 * everything before we return: need to flush out all rest of 496 * image until empty block (size 0) detected. We use GetCodeNext. */ 497 do 498 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) 499 return GIF_ERROR; 500 while (Dummy != NULL) ; 501 } 502 return GIF_OK; 503 } else 504 return GIF_ERROR; 505 } 506 507 /****************************************************************************** 508 * Get an extension block (see GIF manual) from gif file. This routine only 509 * returns the first data block, and DGifGetExtensionNext should be called 510 * after this one until NULL extension is returned. 511 * The Extension should NOT be freed by the user (not dynamically allocated). 512 * Note it is assumed the Extension desc. header ('!') has been read. 513 *****************************************************************************/ 514 int 515 DGifGetExtension(GifFileType * GifFile, 516 int *ExtCode, 517 GifByteType ** Extension) { 518 519 GifByteType Buf; 520 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 521 522 if (!IS_READABLE(Private)) { 523 /* This file was NOT open for reading: */ 524 _GifError = D_GIF_ERR_NOT_READABLE; 525 return GIF_ERROR; 526 } 527 528 if (READ(GifFile, &Buf, 1) != 1) { 529 _GifError = D_GIF_ERR_READ_FAILED; 530 return GIF_ERROR; 531 } 532 *ExtCode = Buf; 533 534 return DGifGetExtensionNext(GifFile, Extension); 535 } 536 537 /****************************************************************************** 538 * Get a following extension block (see GIF manual) from gif file. This 539 * routine should be called until NULL Extension is returned. 540 * The Extension should NOT be freed by the user (not dynamically allocated). 541 *****************************************************************************/ 542 int 543 DGifGetExtensionNext(GifFileType * GifFile, 544 GifByteType ** Extension) { 545 546 GifByteType Buf; 547 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 548 549 if (READ(GifFile, &Buf, 1) != 1) { 550 _GifError = D_GIF_ERR_READ_FAILED; 551 return GIF_ERROR; 552 } 553 if (Buf > 0) { 554 *Extension = Private->Buf; /* Use private unused buffer. */ 555 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ 556 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) { 557 _GifError = D_GIF_ERR_READ_FAILED; 558 return GIF_ERROR; 559 } 560 } else 561 *Extension = NULL; 562 563 return GIF_OK; 564 } 565 566 /****************************************************************************** 567 * This routine should be called last, to close the GIF file. 568 *****************************************************************************/ 569 int 570 DGifCloseFile(GifFileType * GifFile) { 571 572 GifFilePrivateType *Private; 573 FILE *File; 574 575 if (GifFile == NULL) 576 return GIF_ERROR; 577 578 Private = (GifFilePrivateType *) GifFile->Private; 579 580 if (!IS_READABLE(Private)) { 581 /* This file was NOT open for reading: */ 582 _GifError = D_GIF_ERR_NOT_READABLE; 583 return GIF_ERROR; 584 } 585 586 File = Private->File; 587 588 if (GifFile->Image.ColorMap) { 589 FreeMapObject(GifFile->Image.ColorMap); 590 GifFile->Image.ColorMap = NULL; 591 } 592 593 if (GifFile->SColorMap) { 594 FreeMapObject(GifFile->SColorMap); 595 GifFile->SColorMap = NULL; 596 } 597 598 if (Private) { 599 free((char *)Private); 600 Private = NULL; 601 } 602 603 if (GifFile->SavedImages) { 604 FreeSavedImages(GifFile); 605 GifFile->SavedImages = NULL; 606 } 607 608 free(GifFile); 609 610 if (File && (fclose(File) != 0)) { 611 _GifError = D_GIF_ERR_CLOSE_FAILED; 612 return GIF_ERROR; 613 } 614 return GIF_OK; 615 } 616 617 /****************************************************************************** 618 * Get 2 bytes (word) from the given file: 619 *****************************************************************************/ 620 static int 621 DGifGetWord(GifFileType * GifFile, 622 GifWord *Word) { 623 624 unsigned char c[2]; 625 626 if (READ(GifFile, c, 2) != 2) { 627 _GifError = D_GIF_ERR_READ_FAILED; 628 return GIF_ERROR; 629 } 630 631 *Word = (((unsigned int)c[1]) << 8) + c[0]; 632 return GIF_OK; 633 } 634 635 /****************************************************************************** 636 * Get the image code in compressed form. This routine can be called if the 637 * information needed to be piped out as is. Obviously this is much faster 638 * than decoding and encoding again. This routine should be followed by calls 639 * to DGifGetCodeNext, until NULL block is returned. 640 * The block should NOT be freed by the user (not dynamically allocated). 641 *****************************************************************************/ 642 int 643 DGifGetCode(GifFileType * GifFile, 644 int *CodeSize, 645 GifByteType ** CodeBlock) { 646 647 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 648 649 if (!IS_READABLE(Private)) { 650 /* This file was NOT open for reading: */ 651 _GifError = D_GIF_ERR_NOT_READABLE; 652 return GIF_ERROR; 653 } 654 655 *CodeSize = Private->BitsPerPixel; 656 657 return DGifGetCodeNext(GifFile, CodeBlock); 658 } 659 660 /****************************************************************************** 661 * Continue to get the image code in compressed form. This routine should be 662 * called until NULL block is returned. 663 * The block should NOT be freed by the user (not dynamically allocated). 664 *****************************************************************************/ 665 int 666 DGifGetCodeNext(GifFileType * GifFile, 667 GifByteType ** CodeBlock) { 668 669 GifByteType Buf; 670 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 671 672 if (READ(GifFile, &Buf, 1) != 1) { 673 _GifError = D_GIF_ERR_READ_FAILED; 674 return GIF_ERROR; 675 } 676 677 if (Buf > 0) { 678 *CodeBlock = Private->Buf; /* Use private unused buffer. */ 679 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ 680 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { 681 _GifError = D_GIF_ERR_READ_FAILED; 682 return GIF_ERROR; 683 } 684 } else { 685 *CodeBlock = NULL; 686 Private->Buf[0] = 0; /* Make sure the buffer is empty! */ 687 Private->PixelCount = 0; /* And local info. indicate image read. */ 688 } 689 690 return GIF_OK; 691 } 692 693 /****************************************************************************** 694 * Setup the LZ decompression for this image: 695 *****************************************************************************/ 696 static int 697 DGifSetupDecompress(GifFileType * GifFile) { 698 699 int i, BitsPerPixel; 700 GifByteType CodeSize; 701 GifPrefixType *Prefix; 702 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 703 704 READ(GifFile, &CodeSize, 1); /* Read Code size from file. */ 705 BitsPerPixel = CodeSize; 706 707 Private->Buf[0] = 0; /* Input Buffer empty. */ 708 Private->BitsPerPixel = BitsPerPixel; 709 Private->ClearCode = (1 << BitsPerPixel); 710 Private->EOFCode = Private->ClearCode + 1; 711 Private->RunningCode = Private->EOFCode + 1; 712 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ 713 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ 714 Private->StackPtr = 0; /* No pixels on the pixel stack. */ 715 Private->LastCode = NO_SUCH_CODE; 716 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ 717 Private->CrntShiftDWord = 0; 718 719 Prefix = Private->Prefix; 720 for (i = 0; i <= LZ_MAX_CODE; i++) 721 Prefix[i] = NO_SUCH_CODE; 722 723 return GIF_OK; 724 } 725 726 /****************************************************************************** 727 * The LZ decompression routine: 728 * This version decompress the given gif file into Line of length LineLen. 729 * This routine can be called few times (one per scan line, for example), in 730 * order the complete the whole image. 731 *****************************************************************************/ 732 static int 733 DGifDecompressLine(GifFileType * GifFile, 734 GifPixelType * Line, 735 int LineLen) { 736 737 int i = 0; 738 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; 739 GifByteType *Stack, *Suffix; 740 GifPrefixType *Prefix; 741 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; 742 743 StackPtr = Private->StackPtr; 744 Prefix = Private->Prefix; 745 Suffix = Private->Suffix; 746 Stack = Private->Stack; 747 EOFCode = Private->EOFCode; 748 ClearCode = Private->ClearCode; 749 LastCode = Private->LastCode; 750 751 if (StackPtr > LZ_MAX_CODE) { 752 return GIF_ERROR; 753 } 754 755 if (StackPtr != 0) { 756 /* Let pop the stack off before continueing to read the gif file: */ 757 while (StackPtr != 0 && i < LineLen) 758 Line[i++] = Stack[--StackPtr]; 759 } 760 761 while (i < LineLen) { /* Decode LineLen items. */ 762 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) 763 return GIF_ERROR; 764 765 if (CrntCode == EOFCode) { 766 /* Note however that usually we will not be here as we will stop 767 * decoding as soon as we got all the pixel, or EOF code will 768 * not be read at all, and DGifGetLine/Pixel clean everything. */ 769 if (i != LineLen - 1 || Private->PixelCount != 0) { 770 _GifError = D_GIF_ERR_EOF_TOO_SOON; 771 return GIF_ERROR; 772 } 773 i++; 774 } else if (CrntCode == ClearCode) { 775 /* We need to start over again: */ 776 for (j = 0; j <= LZ_MAX_CODE; j++) 777 Prefix[j] = NO_SUCH_CODE; 778 Private->RunningCode = Private->EOFCode + 1; 779 Private->RunningBits = Private->BitsPerPixel + 1; 780 Private->MaxCode1 = 1 << Private->RunningBits; 781 LastCode = Private->LastCode = NO_SUCH_CODE; 782 } else { 783 /* Its regular code - if in pixel range simply add it to output 784 * stream, otherwise trace to codes linked list until the prefix 785 * is in pixel range: */ 786 if (CrntCode < ClearCode) { 787 /* This is simple - its pixel scalar, so add it to output: */ 788 Line[i++] = CrntCode; 789 } else { 790 /* Its a code to needed to be traced: trace the linked list 791 * until the prefix is a pixel, while pushing the suffix 792 * pixels on our stack. If we done, pop the stack in reverse 793 * (thats what stack is good for!) order to output. */ 794 if (Prefix[CrntCode] == NO_SUCH_CODE) { 795 /* Only allowed if CrntCode is exactly the running code: 796 * In that case CrntCode = XXXCode, CrntCode or the 797 * prefix code is last code and the suffix char is 798 * exactly the prefix of last code! */ 799 if (CrntCode == Private->RunningCode - 2) { 800 CrntPrefix = LastCode; 801 Suffix[Private->RunningCode - 2] = 802 Stack[StackPtr++] = DGifGetPrefixChar(Prefix, 803 LastCode, 804 ClearCode); 805 } else { 806 _GifError = D_GIF_ERR_IMAGE_DEFECT; 807 return GIF_ERROR; 808 } 809 } else 810 CrntPrefix = CrntCode; 811 812 /* Now (if image is O.K.) we should not get an NO_SUCH_CODE 813 * During the trace. As we might loop forever, in case of 814 * defective image, we count the number of loops we trace 815 * and stop if we got LZ_MAX_CODE. obviously we can not 816 * loop more than that. */ 817 j = 0; 818 while (j++ <= LZ_MAX_CODE && 819 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { 820 Stack[StackPtr++] = Suffix[CrntPrefix]; 821 CrntPrefix = Prefix[CrntPrefix]; 822 } 823 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { 824 _GifError = D_GIF_ERR_IMAGE_DEFECT; 825 return GIF_ERROR; 826 } 827 /* Push the last character on stack: */ 828 Stack[StackPtr++] = CrntPrefix; 829 830 /* Now lets pop all the stack into output: */ 831 while (StackPtr != 0 && i < LineLen) 832 Line[i++] = Stack[--StackPtr]; 833 } 834 if (LastCode != NO_SUCH_CODE) { 835 Prefix[Private->RunningCode - 2] = LastCode; 836 837 if (CrntCode == Private->RunningCode - 2) { 838 /* Only allowed if CrntCode is exactly the running code: 839 * In that case CrntCode = XXXCode, CrntCode or the 840 * prefix code is last code and the suffix char is 841 * exactly the prefix of last code! */ 842 Suffix[Private->RunningCode - 2] = 843 DGifGetPrefixChar(Prefix, LastCode, ClearCode); 844 } else { 845 Suffix[Private->RunningCode - 2] = 846 DGifGetPrefixChar(Prefix, CrntCode, ClearCode); 847 } 848 } 849 LastCode = CrntCode; 850 } 851 } 852 853 Private->LastCode = LastCode; 854 Private->StackPtr = StackPtr; 855 856 return GIF_OK; 857 } 858 859 /****************************************************************************** 860 * Routine to trace the Prefixes linked list until we get a prefix which is 861 * not code, but a pixel value (less than ClearCode). Returns that pixel value. 862 * If image is defective, we might loop here forever, so we limit the loops to 863 * the maximum possible if image O.k. - LZ_MAX_CODE times. 864 *****************************************************************************/ 865 static int 866 DGifGetPrefixChar(GifPrefixType *Prefix, 867 int Code, 868 int ClearCode) { 869 870 int i = 0; 871 872 while (Code > ClearCode && i++ <= LZ_MAX_CODE) { 873 if (Code > LZ_MAX_CODE) { 874 return NO_SUCH_CODE; 875 } 876 Code = Prefix[Code]; 877 } 878 return Code; 879 } 880 881 /****************************************************************************** 882 * Interface for accessing the LZ codes directly. Set Code to the real code 883 * (12bits), or to -1 if EOF code is returned. 884 *****************************************************************************/ 885 int 886 DGifGetLZCodes(GifFileType * GifFile, 887 int *Code) { 888 889 GifByteType *CodeBlock; 890 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 891 892 if (!IS_READABLE(Private)) { 893 /* This file was NOT open for reading: */ 894 _GifError = D_GIF_ERR_NOT_READABLE; 895 return GIF_ERROR; 896 } 897 898 if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) 899 return GIF_ERROR; 900 901 if (*Code == Private->EOFCode) { 902 /* Skip rest of codes (hopefully only NULL terminating block): */ 903 do { 904 if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) 905 return GIF_ERROR; 906 } while (CodeBlock != NULL) ; 907 908 *Code = -1; 909 } else if (*Code == Private->ClearCode) { 910 /* We need to start over again: */ 911 Private->RunningCode = Private->EOFCode + 1; 912 Private->RunningBits = Private->BitsPerPixel + 1; 913 Private->MaxCode1 = 1 << Private->RunningBits; 914 } 915 916 return GIF_OK; 917 } 918 919 /****************************************************************************** 920 * The LZ decompression input routine: 921 * This routine is responsable for the decompression of the bit stream from 922 * 8 bits (bytes) packets, into the real codes. 923 * Returns GIF_OK if read succesfully. 924 *****************************************************************************/ 925 static int 926 DGifDecompressInput(GifFileType * GifFile, 927 int *Code) { 928 929 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; 930 931 GifByteType NextByte; 932 static unsigned short CodeMasks[] = { 933 0x0000, 0x0001, 0x0003, 0x0007, 934 0x000f, 0x001f, 0x003f, 0x007f, 935 0x00ff, 0x01ff, 0x03ff, 0x07ff, 936 0x0fff 937 }; 938 /* The image can't contain more than LZ_BITS per code. */ 939 if (Private->RunningBits > LZ_BITS) { 940 _GifError = D_GIF_ERR_IMAGE_DEFECT; 941 return GIF_ERROR; 942 } 943 944 while (Private->CrntShiftState < Private->RunningBits) { 945 /* Needs to get more bytes from input stream for next code: */ 946 if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { 947 return GIF_ERROR; 948 } 949 Private->CrntShiftDWord |= 950 ((unsigned long)NextByte) << Private->CrntShiftState; 951 Private->CrntShiftState += 8; 952 } 953 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; 954 955 Private->CrntShiftDWord >>= Private->RunningBits; 956 Private->CrntShiftState -= Private->RunningBits; 957 958 /* If code cannot fit into RunningBits bits, must raise its size. Note 959 * however that codes above 4095 are used for special signaling. 960 * If we're using LZ_BITS bits already and we're at the max code, just 961 * keep using the table as it is, don't increment Private->RunningCode. 962 */ 963 if (Private->RunningCode < LZ_MAX_CODE + 2 && 964 ++Private->RunningCode > Private->MaxCode1 && 965 Private->RunningBits < LZ_BITS) { 966 Private->MaxCode1 <<= 1; 967 Private->RunningBits++; 968 } 969 return GIF_OK; 970 } 971 972 /****************************************************************************** 973 * This routines read one gif data block at a time and buffers it internally 974 * so that the decompression routine could access it. 975 * The routine returns the next byte from its internal buffer (or read next 976 * block in if buffer empty) and returns GIF_OK if succesful. 977 *****************************************************************************/ 978 static int 979 DGifBufferedInput(GifFileType * GifFile, 980 GifByteType * Buf, 981 GifByteType * NextByte) { 982 983 if (Buf[0] == 0) { 984 /* Needs to read the next buffer - this one is empty: */ 985 if (READ(GifFile, Buf, 1) != 1) { 986 _GifError = D_GIF_ERR_READ_FAILED; 987 return GIF_ERROR; 988 } 989 /* There shouldn't be any empty data blocks here as the LZW spec 990 * says the LZW termination code should come first. Therefore we 991 * shouldn't be inside this routine at that point. 992 */ 993 if (Buf[0] == 0) { 994 _GifError = D_GIF_ERR_IMAGE_DEFECT; 995 return GIF_ERROR; 996 } 997 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) { 998 _GifError = D_GIF_ERR_READ_FAILED; 999 return GIF_ERROR; 1000 } 1001 *NextByte = Buf[1]; 1002 Buf[1] = 2; /* We use now the second place as last char read! */ 1003 Buf[0]--; 1004 } else { 1005 *NextByte = Buf[Buf[1]++]; 1006 Buf[0]--; 1007 } 1008 1009 return GIF_OK; 1010 } 1011 #ifndef _GBA_NO_FILEIO 1012 1013 /****************************************************************************** 1014 * This routine reads an entire GIF into core, hanging all its state info off 1015 * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() 1016 * first to initialize I/O. Its inverse is EGifSpew(). 1017 ******************************************************************************/ 1018 int 1019 DGifSlurp(GifFileType * GifFile) { 1020 1021 int ImageSize; 1022 GifRecordType RecordType; 1023 SavedImage *sp; 1024 GifByteType *ExtData; 1025 SavedImage temp_save; 1026 1027 temp_save.ExtensionBlocks = NULL; 1028 temp_save.ExtensionBlockCount = 0; 1029 1030 do { 1031 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) 1032 return (GIF_ERROR); 1033 1034 switch (RecordType) { 1035 case IMAGE_DESC_RECORD_TYPE: 1036 if (DGifGetImageDesc(GifFile) == GIF_ERROR) 1037 return (GIF_ERROR); 1038 1039 sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; 1040 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; 1041 1042 sp->RasterBits = (unsigned char *)malloc(ImageSize * 1043 sizeof(GifPixelType)); 1044 if (sp->RasterBits == NULL) { 1045 return GIF_ERROR; 1046 } 1047 if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == 1048 GIF_ERROR) 1049 return (GIF_ERROR); 1050 if (temp_save.ExtensionBlocks) { 1051 sp->ExtensionBlocks = temp_save.ExtensionBlocks; 1052 sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; 1053 1054 temp_save.ExtensionBlocks = NULL; 1055 temp_save.ExtensionBlockCount = 0; 1056 1057 /* FIXME: The following is wrong. It is left in only for 1058 * backwards compatibility. Someday it should go away. Use 1059 * the sp->ExtensionBlocks->Function variable instead. */ 1060 sp->Function = sp->ExtensionBlocks[0].Function; 1061 } 1062 break; 1063 1064 case EXTENSION_RECORD_TYPE: 1065 if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) == 1066 GIF_ERROR) 1067 return (GIF_ERROR); 1068 while (ExtData != NULL) { 1069 1070 /* Create an extension block with our data */ 1071 if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) 1072 == GIF_ERROR) 1073 return (GIF_ERROR); 1074 1075 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) 1076 return (GIF_ERROR); 1077 temp_save.Function = 0; 1078 } 1079 break; 1080 1081 case TERMINATE_RECORD_TYPE: 1082 break; 1083 1084 default: /* Should be trapped by DGifGetRecordType */ 1085 break; 1086 } 1087 } while (RecordType != TERMINATE_RECORD_TYPE); 1088 1089 /* Just in case the Gif has an extension block without an associated 1090 * image... (Should we save this into a savefile structure with no image 1091 * instead? Have to check if the present writing code can handle that as 1092 * well.... */ 1093 if (temp_save.ExtensionBlocks) 1094 FreeExtension(&temp_save); 1095 1096 return (GIF_OK); 1097 } 1098 #endif /* _GBA_NO_FILEIO */ 1099