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