diff --git a/src/app/file/gif_format.cpp b/src/app/file/gif_format.cpp index 924db38e5..c25dc0cdb 100644 --- a/src/app/file/gif_format.cpp +++ b/src/app/file/gif_format.cpp @@ -103,11 +103,36 @@ FileFormat* CreateGifFormat() static int interlaced_offset[] = { 0, 4, 2, 1 }; static int interlaced_jumps[] = { 8, 8, 4, 2 }; +struct GifFilePtr { +public: + typedef int (*CloseFunc)(GifFileType*, int*); + + GifFilePtr(GifFileType* ptr, CloseFunc closeFunc) : + m_ptr(ptr), m_closeFunc(closeFunc) { + } + + ~GifFilePtr() { + int errCode; + m_closeFunc(m_ptr, &errCode); + } + + operator GifFileType*() { + return m_ptr; + } + + GifFileType* operator->() { + return m_ptr; + } + +private: + GifFileType* m_ptr; + CloseFunc m_closeFunc; +}; + bool GifFormat::onLoad(FileOp* fop) { - UniquePtr gif_file - (DGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "rb")), - DGifCloseFile); + int errCode; + GifFilePtr gif_file(DGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "rb"), &errCode), &DGifCloseFile); if (!gif_file) { fop_error(fop, "Error loading GIF header.\n"); @@ -131,9 +156,10 @@ bool GifFormat::onLoad(FileOp* fop) // Setup the first palette using the global color map. ColorMapObject* colormap = gif_file->SColorMap; for (int i=0; iColorCount; ++i) { - current_palette->setEntry(i, rgba(colormap->Colors[i].Red, - colormap->Colors[i].Green, - colormap->Colors[i].Blue, 255)); + current_palette->setEntry(i, + rgba(colormap->Colors[i].Red, + colormap->Colors[i].Green, + colormap->Colors[i].Blue, 255)); } } else { @@ -214,7 +240,7 @@ bool GifFormat::onLoad(FileOp* fop) for (int y = 0; y < frame_h; ++y) { addr = frame_image->getPixelAddress(0, y); if (DGifGetLine(gif_file, addr, frame_w) == GIF_ERROR) - throw Exception("Invalid image data (%d).\n", GifLastError()); + throw Exception("Invalid image data (%d).\n", gif_file->Error); } } @@ -492,9 +518,8 @@ void GifFormat::onDestroyData(FileOp* fop) #ifdef ENABLE_SAVE bool GifFormat::onSave(FileOp* fop) { - UniquePtr gif_file - (EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb")), - EGifCloseFile); + int errCode; + GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb"), &errCode), &EGifCloseFile); if (!gif_file) throw Exception("Error creating GIF file.\n"); @@ -510,7 +535,7 @@ bool GifFormat::onSave(FileOp* fop) Palette* current_palette = sprite->getPalette(FrameNumber(0)); Palette* previous_palette = current_palette; - ColorMapObject* color_map = MakeMapObject(current_palette->size(), NULL); + ColorMapObject* color_map = GifMakeMapObject(current_palette->size(), NULL); for (int i = 0; i < current_palette->size(); ++i) { color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i)); color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i)); @@ -605,17 +630,20 @@ bool GifFormat::onSave(FileOp* fop) if (frame_num == 0 && loop >= 0) { unsigned char extension_bytes[11]; + if (EGifPutExtensionLeader(gif_file, APPLICATION_EXT_FUNC_CODE) == GIF_ERROR) + throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); + memcpy(extension_bytes, "NETSCAPE2.0", 11); - if (EGifPutExtensionFirst(gif_file, APPLICATION_EXT_FUNC_CODE, 11, extension_bytes) == GIF_ERROR) + if (EGifPutExtensionBlock(gif_file, 11, extension_bytes) == GIF_ERROR) throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); extension_bytes[0] = 1; extension_bytes[1] = (loop & 0xff); extension_bytes[2] = (loop >> 8) & 0xff; - if (EGifPutExtensionNext(gif_file, APPLICATION_EXT_FUNC_CODE, 3, extension_bytes) == GIF_ERROR) + if (EGifPutExtensionBlock(gif_file, 3, extension_bytes) == GIF_ERROR) throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); - if (EGifPutExtensionLast(gif_file, APPLICATION_EXT_FUNC_CODE, 0, NULL) == GIF_ERROR) + if (EGifPutExtensionTrailer(gif_file) == GIF_ERROR) throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); } @@ -640,7 +668,7 @@ bool GifFormat::onSave(FileOp* fop) // Image color map ColorMapObject* image_color_map = NULL; if (current_palette != previous_palette) { - image_color_map = MakeMapObject(current_palette->size(), NULL); + image_color_map = GifMakeMapObject(current_palette->size(), NULL); for (int i = 0; i < current_palette->size(); ++i) { image_color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i)); image_color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i)); diff --git a/third_party/giflib/AUTHORS b/third_party/giflib/AUTHORS index 7f1aee2c5..78611cac2 100644 --- a/third_party/giflib/AUTHORS +++ b/third_party/giflib/AUTHORS @@ -1,15 +1,12 @@ -Lennie Araki - Windows code providing a nicer interface and example program - Michael Brown callbacks to write data via user defined function Daniel Eisenbud - Fixes for crashes with invalid gif files and double freeing of - colormaps + Fixes for crashes with invalid gif files and double freeing of + colormaps -Gershon Elber - original giflib code +Gershon Elber + original giflib code Marc Ewing spec file (for rpms) updates @@ -17,11 +14,11 @@ Marc Ewing Toshio Kuratomi uncompressed gif writing code autoconf/automake process - current maintainer + former maintainer marek - Gif initialization fix - windows build code + Gif initialization fix + windows build code Peter Mehlitz callbacks to read data from arbitrary sources (like libjpeg/libpng) @@ -30,10 +27,10 @@ Dick Porter int/pointer fixes for Alpha Eric Raymond - long time former maintainer of giflib code + current as well as long time former maintainer of giflib code Petter Reinholdtsen - Tru64 build fixs - + Tru64 build fixs + Georg Schwarz - IRIX fixes + IRIX fixes diff --git a/third_party/giflib/CMakeLists.txt b/third_party/giflib/CMakeLists.txt index 0469af4ed..9aa705011 100644 --- a/third_party/giflib/CMakeLists.txt +++ b/third_party/giflib/CMakeLists.txt @@ -43,12 +43,10 @@ add_definitions(-DWINDOWS32=1) endif() add_library(giflib - lib/dev2gif.c lib/dgif_lib.c lib/egif_lib.c lib/gif_err.c lib/gif_font.c lib/gif_hash.c lib/gifalloc.c - lib/qprintf.c lib/quantize.c) diff --git a/third_party/giflib/ChangeLog b/third_party/giflib/ChangeLog index 6a6870457..a723ed690 100644 --- a/third_party/giflib/ChangeLog +++ b/third_party/giflib/ChangeLog @@ -1,128 +1,133 @@ +shipper: ignore this. + It's retained for archival purposes only, and because +autotools throws a hissy fit if there isn't one. The single point of +truth about changes and the reasons for them is the repository. + 2007-11-10 14:50 abadger1999 - * NEWS, configure.ac, lib/Makefile.am, lib/egif_lib.c, - lib/gif_hash.c: 4.1.6 update. Errors in including headers could - lead to build problems on some platforms. + * NEWS, configure.ac, lib/Makefile.am, lib/egif_lib.c, + lib/gif_hash.c: 4.1.6 update. Errors in including headers could + lead to build problems on some platforms. 2007-11-10 13:16 abadger1999 - * configure.ac: Bump release version in configure.ac. + * configure.ac: Bump release version in configure.ac. 2007-11-10 13:15 abadger1999 - * Makefile.am: Remove PATENT_PROBLEMS from build rules as well. + * Makefile.am: Remove PATENT_PROBLEMS from build rules as well. 2007-11-10 13:09 abadger1999 - * NEWS, PATENT_PROBLEMS, lib/Makefile.am: Remove PATENT_PROBLEMS as - it's no longer covered. Update NEWS and Makefile.am for the new - release. + * NEWS, PATENT_PROBLEMS, lib/Makefile.am: Remove PATENT_PROBLEMS as + it's no longer covered. Update NEWS and Makefile.am for the new + release. 2007-11-10 10:46 abadger1999 - * configure.ac, util/gif2epsn.c, util/gif2iris.c, util/gif2ps.c, - util/gif2rgb.c, util/gif2rle.c, util/gif2x11.c: Find and fix - segfaults in the gif2* programs due to referencing the ColorMap - beforefinding out if hte GifFile produced a valid colormap or was - corrupt. + * configure.ac, util/gif2epsn.c, util/gif2iris.c, util/gif2ps.c, + util/gif2rgb.c, util/gif2rle.c, util/gif2x11.c: Find and fix + segfaults in the gif2* programs due to referencing the ColorMap + beforefinding out if hte GifFile produced a valid colormap or was + corrupt. 2007-11-10 09:30 abadger1999 - * lib/dgif_lib.c: Add checks to fail gracefully when corrupted - images are submitted that have improper LZ codes. + * lib/dgif_lib.c: Add checks to fail gracefully when corrupted + images are submitted that have improper LZ codes. 2007-11-10 09:22 abadger1999 - * lib/: dgif_lib.c, egif_lib.c: Further checks to compile correctly - on WIN32. + * lib/: dgif_lib.c, egif_lib.c: Further checks to compile correctly + on WIN32. 2007-11-09 20:28 abadger1999 - * util/giftext.c: Fix a SegFault when a GifFile does not store a - global colormap. + * util/giftext.c: Fix a SegFault when a GifFile does not store a + global colormap. 2007-11-09 20:13 abadger1999 - * util/gif2x11.c: Fix gif2x11 to work with modern, 24 bit displays. + * util/gif2x11.c: Fix gif2x11 to work with modern, 24 bit displays. 2007-11-09 14:18 abadger1999 - * configure.ac: Check for headers as well as the libraries for rle, - X11, and gl_s. + * configure.ac: Check for headers as well as the libraries for rle, + X11, and gl_s. 2007-11-09 13:24 abadger1999 - * configure.ac: Merge better fix for finding an unsignd 32 bit - integer type. + * configure.ac: Merge better fix for finding an unsignd 32 bit + integer type. 2007-11-09 13:01 abadger1999 - * configure.ac: Add configure comman line switches to turn off X11, - rle, and gl support. + * configure.ac: Add configure comman line switches to turn off X11, + rle, and gl support. 2007-11-09 12:36 abadger1999 - * configure.ac, util/Makefile.am: Fixes to build under cygwin. + * configure.ac, util/Makefile.am: Fixes to build under cygwin. 2007-11-09 11:49 abadger1999 - * configure.ac: Make GCC check more robust. Add a needed automake - check. + * configure.ac: Make GCC check more robust. Add a needed automake + check. 2007-11-09 11:48 abadger1999 - * lib/dgif_lib.c: Fix closing file handles on failure in - DGifOpenFileHandle(). + * lib/dgif_lib.c: Fix closing file handles on failure in + DGifOpenFileHandle(). 2007-11-09 11:33 abadger1999 - * lib/egif_lib.c: Save files in binary mode for WIN32 as well as - MSDOS. + * lib/egif_lib.c: Save files in binary mode for WIN32 as well as + MSDOS. 2007-11-09 11:25 abadger1999 - * lib/Makefile.ms: * Makefile for building under Visual C++ from - Bug #981209. + * lib/Makefile.ms: * Makefile for building under Visual C++ from + Bug #981209. 2005-11-13 20:14 abadger1999 - * configure.ac, lib/Makefile.am, util/Makefile.am: Changes to - conditionalize -Wall upon compiling with gcc. + * configure.ac, lib/Makefile.am, util/Makefile.am: Changes to + conditionalize -Wall upon compiling with gcc. 2005-11-06 08:45 abadger1999 - * lib/: gif_hash.c, gif_hash.h: Add inttypes.h to the headers we - could include to get a 32-it int type. + * lib/: gif_hash.c, gif_hash.h: Add inttypes.h to the headers we + could include to get a 32-it int type. 2005-11-06 08:34 abadger1999 - * configure.ac: Search for ISO/ANSI definitions of uint32_t in - stdint.h _and_ inttypes.h before POSIX u_int32_t in sys/types.h - as some systems have sys/types.h without the definition. - Eventually we need to code a test that the expected UINT32 - definition exists in the header we select so order does not - matter. + * configure.ac: Search for ISO/ANSI definitions of uint32_t in + stdint.h _and_ inttypes.h before POSIX u_int32_t in sys/types.h + as some systems have sys/types.h without the definition. + Eventually we need to code a test that the expected UINT32 + definition exists in the header we select so order does not + matter. 2005-11-06 08:32 abadger1999 - * AUTHORS, README: Modify so that it no longer appears that esr - still maintains this package. + * AUTHORS, README: Modify so that it no longer appears that esr + still maintains this package. = giflib-4.1.4 = -2005-10-09 Toshio Kuratomi - r94 +2005-10-09 Toshio Kuratomi - r94 * Sync with libungif r93. * ChangeLog: Update to r92. * NEWS: Update with combined libungif/giflib changes. - -2005-10-09 Toshio Kuratomi - r92 + +2005-10-09 Toshio Kuratomi - r92 * lib/gif_lib.h: Change GifPrefixType to unsigned. - -2005-10-09 Toshio Kuratomi - r91 + +2005-10-09 Toshio Kuratomi - r91 * ChangeLog: Update to r90. * NEWS: Update on GBA and Windows fixes. - -2005-10-06 Toshio Kuratomi - r90 + +2005-10-06 Toshio Kuratomi - r90 Changes from Lennie Araki: * gba/giftest.mak: Prefix the names of defines for the GBA build with _GBA. * lib/dgif_lib.c, lib/gif_lib_private.h, lib/gif_err.c: @@ -137,11 +142,11 @@ respectively. - Fix a problem with the API on _WIN32. DrawText conflicts with the Windows API. Call it DrawGifText instead. - -2005-09-27 Toshio Kuratomi - r86 + +2005-09-27 Toshio Kuratomi - r86 * Sync with libungif r85. - -2005-09-27 Toshio Kuratomi - r82 + +2005-09-27 Toshio Kuratomi - r82 * AUTHORS: Add Daniel Eisenbud. Obscure email addresses. * libungif.spec: Bump to version 4.1.4. * configure.ac: Bump to 4.1.4. No longer check for ranlib. @@ -154,30 +159,30 @@ * lib/dev2gif.c: Fix redefinition problem on IRIX. * NEWS: Update to 4.1.4 * util/gifcomb.c: Set a olorMap to NULL. - -2004-07-11 Toshio Kuratomi - r79 + +2004-07-11 Toshio Kuratomi - r79 * gif2iris.c: Fixes from Georg Schwarz . - stdlib.h is available and needs to be included on IRIX. - ColorMapSize was being set from non-existent variables. - -2004-05-29 Toshio Kuratomi - r76 + +2004-05-29 Toshio Kuratomi - r76 * Sync with libungif-4.1.3. -2004-05-29 Toshio Kuratomi - r74 +2004-05-29 Toshio Kuratomi - r74 * ChangeLog, prop=lastlog: Sync with the subversion logs. - -2004-05-29 Toshio Kuratomi - r73 + +2004-05-29 Toshio Kuratomi - r73 * test-unx: Add a test of extension code. * lib/egif_lib.c: Remove a debugging statement - -2004-05-29 Toshio Kuratomi - r72 + +2004-05-29 Toshio Kuratomi - r72 * Makefile.am, doc/Makefile.am, pic/Makefile.am: Change wildcarded entries into explicit filenames so make distcheck will succeed. - -2004-05-29 Toshio Kuratomi - r71 + +2004-05-29 Toshio Kuratomi - r71 * ChangeLog, prop=lastlog: Sync the ChangeLog for the release. - -2004-05-29 Toshio Kuratomi - r70 + +2004-05-29 Toshio Kuratomi - r70 * AUTHORS: Add Lennie Araki to the list of contributers. * windows: The windows subdirectory and all files under it are contributions from Lennie Araki to provide a nice interface on MS Windows. @@ -186,8 +191,8 @@ so people know they should use it instead of EGifPutExtension. * Makefile.am: Mark the windows files to be distributed. * NEWS: Complete the NEWS item for 4.1.3. - -2004-05-29 Toshio Kuratomi - r69 + +2004-05-29 Toshio Kuratomi - r69 * libungif.spec: Some updates from the latest RedHat spec. * configure.ac: Bump version to 4.1.3. * lib/gifalloc.c: Add to my comments on ESR's note about Extension blocks. @@ -196,8 +201,8 @@ Last so that it won't break on unusually long comments. - EGifPutExtension{First,Next,Last}: Changed fwrites to WRITE so any user defined write function will get called properly. - - EGifPutExtensionLast: if the Extension block is empty (Zero length) - then don't attempt to output a last extension block, just output the + - EGifPutExtensionTerminate: if the Extension block is empty (Zero length) + then don't attempt to output a last extension block, just output the block terminator. - EGifPutExtension: Comment that this function does not work when there are multiple subblocks in an Extension block. Use the functions @@ -209,32 +214,32 @@ * NEWS: Begin writing an entry for 4.1.3. * util/icon2gif.c: Few casting fixes to make gcc -Wall happy. * util/gif2ps.c: printf format string corrections. - -2004-05-26 Toshio Kuratomi - r67 + +2004-05-26 Toshio Kuratomi - r67 * Clean up some typos. - + 2004-05-25 Toshio Kuratomi - r66 * Sync with libungif-4.1.2. -2004-03-03 Toshio Kuratomi - r64 +2004-03-03 Toshio Kuratomi - r64 Last minute updates to the release notes in various files. -2004-03-03 Toshio Kuratomi - r63 +2004-03-03 Toshio Kuratomi - r63 * Set property lastlog to remind me when I last synced the ChangeLog -2004-03-03 Toshio Kuratomi - r62 +2004-03-03 Toshio Kuratomi - r62 * ChangeLog: Update -2004-03-03 Toshio Kuratomi - r61 +2004-03-03 Toshio Kuratomi - r61 * configure.ac: Bump version to 4.1.2 - -2004-02-22 Toshio Kuratomi - r59 + +2004-02-22 Toshio Kuratomi - r59 * configure.ac, lib/Makefile.am: Bump version. Forgot to do this for 4.1.1... -2004-02-22 Toshio Kuratomi - r58 +2004-02-22 Toshio Kuratomi - r58 * TODO: Take out -Wall as that's all ready now. -2004-02-22 Toshio Kuratomi - r57 +2004-02-22 Toshio Kuratomi - r57 Merge changes to the code from branch indent-audit r55 * README: MakeExtension deprecation note. * TODO: Bunch of things I need to fix or check that I saw while doing the @@ -261,8 +266,8 @@ the memory. * lib/egif_lib.c: indent changes - EGifPutScreenDesc: If we have no colormap, output a default value for - its size instead of trying to reference its unallocated BitsPerPixel - field. (Fixes bug noted in r46) + its size instead of trying to reference its unallocated BitsPerPixel + field. (Fixes bug noted in r46) * lib/gif_lib.h: indent changes - Condense the #else #if VARARGS to #elif VARARGS check. * lib/qprintf.c: indent changes @@ -272,23 +277,23 @@ * lib/gif_lib_private.h: indent changes * lib/gif_font.c: indent changes * lib/gif_err.c: indent changes - -2004-02-22 Toshio Kuratomi - r56 + +2004-02-22 Toshio Kuratomi - r56 * lib/Makefile.am, util/Makefile.am: Add -Wall to the compilation flags so we can keep the code from acquiring too much bad style. - -2004-02-20 Toshio Kuratomi - r46 + +2004-02-20 Toshio Kuratomi - r46 * egif_lib.c: Note for a bug fix (Can wait until after indent because there's no patch.) * gif_lib.h, dev2gif.c: Change int type to explicit long type in DumpScreen2Gif. * util/gifinto.c: Give the fprintf back its %d format. GifFile->ImageCount is used as the Image number. - -2004-02-20 Toshio Kuratomi - r45 + +2004-02-20 Toshio Kuratomi - r45 * README: add varargs to the deprecation list -2004-02-20 Toshio Kuratomi - r44 +2004-02-20 Toshio Kuratomi - r44 * test-unx: Quote the program names. * lib/dgif_lib.c: - Make sure memory was allocated for the colormap @@ -299,17 +304,17 @@ * lib/qprintf.c, lib/getarg.c: Update the varargs code. Some users reported that not all systems can handle the hybridized varargs parameter lists we had. Need to use old-style declarations instead. - -2004-02-20 Toshio Kuratomi - r43 + +2004-02-20 Toshio Kuratomi - r43 * NEWS: Note bugfixes and deprecations * README: Deprecation list is now being compiled in this file. * TODO: Notes about interlace bug, -Wall status, merging of old bug status - -2004-02-19 Toshio Kuratomi - r42 + +2004-02-19 Toshio Kuratomi - r42 * Makefile.am: Disable testing for now because gif2x11 is broken so none of the tests _appear_ to complete successfully. - -2004-02-19 Toshio Kuratomi - r38 + +2004-02-19 Toshio Kuratomi - r38 Merge -Wall fixes from branches/Wall-audit r29 * configure.ac: - Make the stdarg vs varargs check simpler by relying on @@ -329,109 +334,109 @@ gif_lib_private.h * gif_lib.h, gif_lib_private.h: Moved the VersionStr into gif_lib_private.h and made it a #define instead of a static char *. - -2004-02-19 Toshio Kuratomi - r37 + +2004-02-19 Toshio Kuratomi - r37 Deprecation notes -2004-02-19 Toshio Kuratomi - r36 +2004-02-19 Toshio Kuratomi - r36 Add notes about security things to do and giflib syncing -2004-02-18 Toshio Kuratomi - r32 +2004-02-18 Toshio Kuratomi - r32 * TODO: Add notes about how to go about syncing Wall-audit and indent changes into giflib. It won't be pretty. * svn:ignore: Change the tarball names from libungif to giflib -2004-02-18 Toshio Kuratomi - r31 +2004-02-18 Toshio Kuratomi - r31 Add config.h include to gif_hash.c -2004-02-17 Toshio Kuratomi - r30 +2004-02-17 Toshio Kuratomi - r30 Sync up with libungif 4.1.1 -2004-02-17 Toshio Kuratomi - r26 +2004-02-17 Toshio Kuratomi - r26 Updated ChangeLog 2004-02-17 Toshio Kuratomi - * Updated libungif.spec to look more like fedora core spec - * Updated version numbers in all files + * Updated libungif.spec to look more like fedora core spec + * Updated version numbers in all files 2004-02-17 Toshio Kuratomi - * Add the libungif*.tar.bz2 distribution tarball to the ignored files - * configure.ac, lib/getarg.c, lib/getarg.h, lib/gif_lib.h, lib/qprintf.c: - Prefer stdarg.h over vararg.h - * TODO: Add information about functions that will go away in 5.0 - (In reality, I don't think new software uses libungif, so there may never - be a 5.0 release.) - * lib/gif_lib.h: Change version from 4.0 to 4.1 - * NEWS: add deprecation warning for the qprintf stuff: GifQuietPrint var and - GifQprintf function. + * Add the libungif*.tar.bz2 distribution tarball to the ignored files + * configure.ac, lib/getarg.c, lib/getarg.h, lib/gif_lib.h, lib/qprintf.c: + Prefer stdarg.h over vararg.h + * TODO: Add information about functions that will go away in 5.0 + (In reality, I don't think new software uses libungif, so there may never + be a 5.0 release.) + * lib/gif_lib.h: Change version from 4.0 to 4.1 + * NEWS: add deprecation warning for the qprintf stuff: GifQuietPrint var and + GifQprintf function. 2004-02-16 Toshio Kuratomi - * util/gif2iris.c, util/gif2rle.c, util/gifinfo.c: Fix problems with fprintf error statements in the utils + * util/gif2iris.c, util/gif2rle.c, util/gifinfo.c: Fix problems with fprintf error statements in the utils 2004-02-16 Toshio Kuratomi - Add DEVELOPERS file to the distribution. + Add DEVELOPERS file to the distribution. 2004-02-16 Toshio Kuratomi - * AUTHORS, libungif.spec, libungif.lsm, README, BUGS, NEWS: - Lots of changes to my email address and the website/download. (libungif is - moving to sourceforge.) - * TODO: Few notes on cleanups that need to happen. State what needs to be done - for 4.1.1 to be released. + * AUTHORS, libungif.spec, libungif.lsm, README, BUGS, NEWS: + Lots of changes to my email address and the website/download. (libungif is + moving to sourceforge.) + * TODO: Few notes on cleanups that need to happen. State what needs to be done + for 4.1.1 to be released. 2004-02-15 Toshio Kuratomi - Changes imported from last cvs checkout - * TODO: note to check return of malloc everywhere - * lib/dgif_lib.c, lib/egif_lib.c: Fix some deallocation bugs - * lib/gifalloc.c: Fix a colormap allocation problem - * lib/gif_font.c: Fix to drawing text + Changes imported from last cvs checkout + * TODO: note to check return of malloc everywhere + * lib/dgif_lib.c, lib/egif_lib.c: Fix some deallocation bugs + * lib/gifalloc.c: Fix a colormap allocation problem + * lib/gif_font.c: Fix to drawing text 2004-02-15 Toshio Kuratomi - Added libgetarg.a to the ignore list. + Added libgetarg.a to the ignore list. 2004-02-15 Toshio Kuratomi - Changes to the build infrastructure to build under current libtool, automake, - and libtool. - * configure.in: renamed to configure.ac - * acconfig.h: deleted. Functionality moved into the configure.ac - * autogen.sh: now runs libtoolize --automake - * lib/Makefile.am, util/Makefile.am: CFLAGS=>AM_CFLAGS; INCLUDES=>AM_CPPFLAGS - * configure.ac: - - initialization macros for automake and autoconf have changed - - removed checks for C++ compiler and Awk - - acconfig.h functionality moved here. - - add other X11 libraries to the X11_LIB define + Changes to the build infrastructure to build under current libtool, automake, + and libtool. + * configure.in: renamed to configure.ac + * acconfig.h: deleted. Functionality moved into the configure.ac + * autogen.sh: now runs libtoolize --automake + * lib/Makefile.am, util/Makefile.am: CFLAGS=>AM_CFLAGS; INCLUDES=>AM_CPPFLAGS + * configure.ac: + - initialization macros for automake and autoconf have changed + - removed checks for C++ compiler and Awk + - acconfig.h functionality moved here. + - add other X11 libraries to the X11_LIB define 2004-02-15 Toshio Kuratomi - * Remove INSTALL file as it's autogenerated.\n* Add stamp-h1 to ignored files + * Remove INSTALL file as it's autogenerated.\n* Add stamp-h1 to ignored files 2004-02-15 Toshio Kuratomi - Additional adds and deletes to make version 4.1.0b1 + Additional adds and deletes to make version 4.1.0b1 2004-02-15 Toshio Kuratomi - Import of version 4.1.0b1 + Import of version 4.1.0b1 -2004-02-15 Toshio Kuratomi - r10 +2004-02-15 Toshio Kuratomi - r10 Import giflib 4.1.0 -2004-02-15 Toshio Kuratomi - r9 +2004-02-15 Toshio Kuratomi - r9 Copy the 4.1.0 libungif release to be the base of the 4.1.0 giflib release. -2004-02-15 Toshio Kuratomi - r7 +2004-02-15 Toshio Kuratomi - r7 Release 4.1.0 -2004-02-15 Toshio Kuratomi - r6 +2004-02-15 Toshio Kuratomi - r6 Import of version 4.1.0 -2004-02-15 Toshio Kuratomi - r5 +2004-02-15 Toshio Kuratomi - r5 Set ignore patterns on the project directories. -2004-02-15 Toshio Kuratomi - r3 +2004-02-15 Toshio Kuratomi - r3 Remove a Makefile.in that was left in in the first commit. -2004-02-14 Toshio Kuratomi - r2 +2004-02-14 Toshio Kuratomi - r2 Commit revision 3.1.0 to subversion -2004-02-14 Toshio Kuratomi - r1 +2004-02-14 Toshio Kuratomi - r1 Initial SVN Repository Layout 2000 6 Feb Toshio Kuratomi @@ -539,7 +544,7 @@ * libungif.spec: Rename to giflib.spec and change to reflect giflib rather than libungif. * UNCOMPRESSED_GIF: Removed from this branch. - * PATENT_PROBLEMS: Add file explaining Unisys's patent claims. + * PATENT_PROBLEMS: Add file explaining Unisys's patent claims. * Makefile.am: Replace libungif with giflib. * README: Adapted language to giflib. * lib/Makefile.am: Changed references to libungif to libgif. @@ -641,7 +646,7 @@ * lib/egif_lib.c: Remove all references to the hash functions. * lib/Makefile.am: Remove gif_hash.c gif_hash.h from the source files. * libungif.lsm: added this file - + 1998 7 Sep Toshio Kuratomi * lib/dgif_lib.c, lib/gif_lib.h: (DGifOpen) Add callback to read gif image through user supplied function (Peter Mehlitz). diff --git a/third_party/giflib/DEVELOPERS b/third_party/giflib/DEVELOPERS deleted file mode 100644 index 4cfac1048..000000000 --- a/third_party/giflib/DEVELOPERS +++ /dev/null @@ -1,29 +0,0 @@ -Things to tell developers of libungif.... - -======= -Build Tools: -libungif presently uses autoconf, automake, and libtool in order to build -shared libraries for a wide variety of platforms. The distributed tarball has -files prebuilt from these tools. The cvs repository does not. If you want to -build libungif you will need to have these tools available. I currently run -with the following versions: -autoconf 2.57 -automake 1.7.8 -libtool 1.5 - -(P.S. I use the autogen.sh script in the top level directory to generate -configure, Makefile.in, etc using these tools.) - -======= -cvs: -I currently do my work in a subversion repository. Since sourceforge is still -using cvs and not subversion, there's nothing in the sourceforge tree. - -If someone else wants to do development we can definitely talk about the best -way to share version control access. - -======= -I create the distribution tar ball by using the `make dist` command.... After -hacking all I want, I check my sources into cvs, checkout a clean tree, run -./autogen.sh; make dist and then attempt to compile from the libungif-*.tar.gz -file that is generated. diff --git a/third_party/giflib/NEWS b/third_party/giflib/NEWS index 3e17aa4ca..4652fd390 100644 --- a/third_party/giflib/NEWS +++ b/third_party/giflib/NEWS @@ -1,3 +1,324 @@ + GIFLIB NEWS + +Short summary of recent news: + Minor API change to assist library wrappers in dynamic languages. + The gif2raw utility has been removed. + Various minor fix patches for unusual edge cases. + +Version 5.1.0 +============= + +Changes to the API require a library major-version bump. + +Code Fixes +---------- + +* A small change to the API: DGifClose() and EGifClose() now take a + pointer-to-int second argument (like the corresponding openers) + where a diagnostic code will be deposited when they return + GIF_ERROR. This replaces the old behavior in which the GifFile + structure was left unfreed so the Error member in it could be filled + and remain available. The change was was required because it's + not always possible to free the struct afterwards. Case in point is + a C# wrapper for giflib (or any language/environment where you can't + just free objects allocated in a foreign shared library.) + +* Minor fix for SF bug #56; BitsPerPixel may be left as uninitialized + value when reading (truncated) gif. + +* Applied SF patch #17: Use a fallback on Windows where mkstemp is not + available. + +* Applied SF patch #15: Code hardening, preventing spurious + defective-image messages. + +Retirements +----------- + +* Removed gif2raw from utils. Its blithe assumption that the EGA16 + palette is a reliable default is now about 20 years obsolete. Format + conversion is better done with convert(1) from the ImageMagick suite, + anyway. + +Version 5.0.6 +============= + +Minor fix for a rare memory leak (SF bug #55). + +MinGW port fixes. + +Repair the internal quantization function used in gif2rgb so it's +less vulnerable to cross-platform skew due to qsort() being unstable. +This shouldn't affect production use, it's just a cross-platform +issue for regression testing + +Version 5.0.5 +============= + +Set the error return properly when a screen descriptor read fails. +Fixes for some minor API documentation bugs. Some internal manual +pages are not to be installed. + +Version 5.0.4 +============= + +Fix for a rare misrendering bug when a GIF overruns the decompression-code +table. The image on which this was spotted was a relatively long-running +animated GIF; still images of ordinary size should have been immune. + +Version 5.0.3 +============= + +Fix a build-system glitch so it will install manpages. + +Version 5.0.2 +============= + +Documentation and polish +------------------------ +* Partial build is now possible on systems without xmlto. + +Code Fixes +---------- +* Change unused return of EGifSetGifVersion() to void. +* Buffer overrun prevention in gifinto. + +Version 5.0.1 +============= + +Documentation and polish +------------------------ +* There is now an installable manual page for the GIFLIB utility kit. + +Retirements +----------- +* gifinter is gone. Use convert -interlace from the ImageMagic suite. + +Code Fixes +---------- +* In 5.0.0 the private gif89 bit wasn't being guaranteed cleared at + the beginning of EGifGetGifVersion(); this occasionally led to an + incorrect version prefix being issued dependent on the state of + malloced memory. +* An EGifSetGifVersion() function taking a GifFile argument has been + added for use with the low-level sequential API. This change requires + a bump of the library revision number. + +Version 5.0.0 +============= + +Changes to the API require a library major-version bump. Certain +initialization functions have acquired an integer address argument for +passing back an error code, in order to avoid thread-unsafe static +storage. Application code using extension blocks will require minor +changes. A few functions have been renamed. + +Code Fixes +---------- +* Fixes applied for CVE-2005-2974 and CVE-2005-3350 + This closes Debian bug #337972. + +New API Features +---------------- + +Thread Safety +~~~~~~~~~~~~~ +The library is now completely re-entrant and thread-safe. + +* Library error handling no longer uses a static cell to store the last + error code registered; that made the library thread-unsafe. For functions + other than GIF file openers, the code is now put in an Error member of + the GifFileType structure. The GifError() amd GifLastError() functions + that referenced that static cell are gone, and the GifErrorString() + function introduced in the 4.2 release now takes an explicit error code + argument. +* GIF file openers - DGifOpenFileName(), DGifOpenFileHandle(), DGifOpen(), + EGifOpenFileName(), EGifOpenFileHandle(), and EGifOpen() - all now take + a final integer address argument. If non-null, this is used to pass + back an error code when the function returns NULL. + +Extensions +~~~~~~~~~~ +The ExtensionBlock API has been repaired, solving some problems with GIF89 +extension handling in earlier versions. + +* DGifSlurp() and EGifSpew() now preserve trailing extension blocks with + no following image file. +* Three documented functions - EGifPutExtensionFirst(), EGifPutExtensionNext(), + and EGifPutExtensionLast() - have been relaced by new functions + EGifPutExtensionLeader(), EGifPutExtensionBlock(), and + EGifPutExtensionTrailer(). See the Compatibility section of + the library API documentation for details. +* New functions DGifSavedExtensionToGCB() and EGifGCBToSavedExtension() + make it easy to read and edit GIF89 graphics control blocks in saved images. + +Namespacing +~~~~~~~~~~~ +All functions exported by giflib now have DGif, EGif, or Gif as a name prefix. + +* Three documented functions - MakeMapObject(), FreeMapObject(), and + UnionColorMap() - have been renamed to GifMakeMapObject(), + GifFreeMapObject(), and GifUnionColorMap() respectively. +* The library Draw* functions are now prefixed GifDraw*, and the + text-drawing ones are suffixed with "8x8". This fixes a conflict + with the Windows API and leaves the door open for more general text-drawing + functions with different font sizes. + +Other changes +~~~~~~~~~~~~~ +* DGifSlurp() and EGifSpew() now read and write interlaced images properly. +* The amazingly obscure colormap sort flag and pixel aspect ratio + features of GIF are now read and preserved, for whatever good that + may do. +* Six undocumented functions have been renamed; five of these take additional + or slightly different argument types. See the Compatibility section of + the library API documentation for details. +* There's now an EGifGetGifVersion() that computes the version EGifSpew() + will write. +* QuantizeBuffer() has been returned to the core library as GifQuantizeBuffer() + - turns out some important applications (notably mplayer) were using it. +* TRUE and FALSE macros are gone, also VoidPtr. No more namespace pollution. +* Various arguments have been made const where possible. + +Retirements +----------- +* The (undocumented) gifinfo utility is gone. Use giftool -f instead. +* The gifburst utility is gone. Everybody has image viewers that + can pan now, and removing it gets rid of a dependency on Perl. +* gifcompose is gone. It was a decent idea when I wrote it in 1989, + but I did the same thing better and cleaner a decade later with + PILdriver in the PIL package. Removing it gets rid of a dependency + on shell. +* gif2x11 gifasm, gifcomb, gifflip, gifovly, gifpos, gifresize, and gifrotate + are all gone. The ImageMagick display(1)/convert(1) utilities and PILdriver + do these things better and in a format-independent way. +* Lennie Araki's Windows C++ wrapper is gone. It's eight years old, + unmaintained, he has dropped out of sight, and a better one needs to + be written to use the high-level GIFLIB API and GIF89 graphics + control extension support. We'll carry such a wrapper when we have + a maintainer for it. +* EGifSetVersion(), introduced in 4.2, is gone. The library always + writes GIF87 or GIF89 as required by the data. This change helps + with thread safety. + +Utilities +--------- +* Several utilities have been renamed to (a) fix last-century's habit + of arbitarily smashing vowels out of names to make them just one or two + characters shorter, (b) ensure that every utility in this set has 'gif' + as a name prefix. Here's the list: + + giffiltr -> giffilter + gifspnge -> gifsponge + icon2gif -> gifbuild + text2gif -> gifecho + raw2gif -> gif2raw + +* To go with its new name, gif2raw now dumps raw pixels from a GIF if the + (previously required) size option is missing. +* Standalone rgb2gif is gone; the same capability is now a mode of gif2rgb. +* giftext displays the parsed contents of GIF89 graphics control blocks. +* gifbuild handles GIF89 graphics control blocks and Netscape animation + loop blocks; it can can display and update either. +* gifrotate and other filter utilities now preserve extension blocks, + including the graphics control information for transparency and delay time. +* A new utility, giftool, supports a wide variety of filtering operations + on GIFs, including: setting background and transparency colors, changing + interlacing, setting image delays, setting the user-input flag, and setting + the aspect-ratio byte. It can sequence multiple operations. +* The test-pattern generators gifbg, gifcolor, gihisto and gifwedge and the + code templates giffilter and gifsponge are no longer installed by default. + +Documentation and polish +------------------------ +* The history.txt and build.txt and files from 4.2.0 now have .asc extensions + to indicate that they use asciidoc markup, contrasting with the txt + standards files from CompuServe. +* The documentation now includes "What's In A GIF", a very detailed narrative + description of the file format. +* The -A option of gifasm (for inserting a loop control block) is documented. +* The documentation directory includes a copy of the original GIF87 + specification as well as GIF89's. +* The project now has a logo. + +Version 4.2.0 +============= + +Now maintained by ESR again after handoff by Toshio Kuratomi. + +Code Fixes +---------- +* Code updated internally to C99 to enable more correctness checks by + the compiler. Compiles under GCC 4.6.1 without errors or warnings. +* A rare resource leak in the colormap-object maker was found with + Coverity and fixed. +* The code now audits clean under Coverity and cppcheck. +* splint cleanup begun, there's a lot of work still to do on this. + +New API Features +---------------- +* The default GIF version to write is now computed at write time from + the types of an image's extension blocks, but can be overridden with + EGifSetGifVersion(). +* EGifSpew() is now thread-safe. +* Two new functions, GifError() and GifErrorString(), + return the error state in a form that can be used by programs. +* Two library functions - EGifOpenFileName() and EGifPutImageDesc() - + now have bool rather than int flag arguments. Since bool is a + typedef of int and TRUE/FALSE have been redefined to true/false, + both source and object compatibility with older library versions + should be preserved. +* GAGetArgs(), used only in the utilities, now returns bool rather + than int. +* The undocumented GIF_LIB_VERSION symbol is gone from the library header. + It has been replaced with three documented symbols: GIFLIB_MAJOR, + GIFLIB_MINOR, and GIFLIB_RELEASE. + +Retirements +----------- +* The gif2epsn and gif2iris utilities are gone. They were full of + platform dependencies for platforms long dead. There are enough + platform-independent GIF viewers in the world that these weren't + adding any value. Removing these gets rid of a dependency on GL. +* The rle2gif, gif2rle, and gif2ps utilities are also gone. There are enough + multiformat image converters in the world that these weren't adding + any value either. Removing them reduces the codebase's dependencies. +* The undocumented DumpScreen2Gif() is gone from the library. The + only non-obsolete capture mode it supported was through X, and that + probably hasn't been used in years and is replaceable by any number + of capture utilities. Dropping this code makes the library's + portability issues go away. +* QuantizeBuffer(), GifQprintf(), PrintGifError(), GIF_ERROR() + and GIF_MESSAGE() have been removed from the core library. + They were used only by the utilities. QuantizeBuffer() has been + inlined where it was used and the latter three are now part of the + utility support library. +* The Game Boy Advanced test code is gone. The platform was discontinued + in 2008; more to the point, nobody ever documented the code's assumptions + or expected results. +* The Changelog file is now retained for archival purposes only, and because + autotools throws a hissy fit if there isn't one. The single point of + truth about changes and the reasons for them is the repository history. + +Behavior changes +---------------- +* The -q option of the utilities is replaced by an opposite -v (verbose) + option; the default is now quiet for all platforms. Defaulting to chattiness + on MSDOS made sense in a world of slow text consoles, but not today. + +Testing +------- +* There is now a proper regression-test suite; run 'make' in tests/. + The old test-unx script is now tests/visual-check and can be run + occasionally for a check with the Mark One Eyeball. + +Documentation +------------- +* Build instructions now live in build.txt +* An overview of the giflib API now lives in api.txt. +* Documentation is now in DocBook-XML, so either HTML or man pages can + be generated from it. + Version 4.1.6 ============= Brown paper bag release. Fix a problem with header inclusion that could @@ -72,7 +393,7 @@ long Comments, and multi-block extensions read in from another file. but maybe someone out there will find it useful. Caveat hacker. Version 4.1.2 -=============== +============= * Numerous bug fixes from people on the old libungif mailing list. * GIF_ERROR and GIF_MESSAGE are on the deprecation list as they are also utility helper functions rather than essential to the functioning of the @@ -80,12 +401,12 @@ Version 4.1.2 * Complete deprecation list is now in the README file * Audited the sources with gcc -Wall. Everything detectable has now been fixed. * Ran the library code through indent. - + Version 4.1.1 ============= * Merge in many bug fixes that were sent in while I was hiking the Appalachian Trail. -* The qprintf methods of the library are now deprecated. Do not use +* The qprintf methods of the library are now deprecated. Do not use GifQuietPrint or GifQprintf. These should have been pushed out into the utility helper library instead of sitting around in the library proper at the same time as the getarg functions were moved out. Getting rid of these @@ -93,7 +414,7 @@ Version 4.1.1 reading library has no business requiring.) Version 4.1.0 -============ +============= * Several minor memory leaks in error conditions have been plugged. * New Function EGifOpen(void *userData, OutputFunc writeFunc) allows user specified gif writing functions. @@ -124,7 +445,6 @@ Version 3.1.1 * When closing a gif that had a local colormap, DGifCloseFile would attempt to free the colormap twice. * Fix a potential memory leak in DGifSlurp. -The following enhancements have been made: * New function DGifOpen to allow specifying a user definable gif reading function. @@ -137,22 +457,135 @@ Version 3.1.0 Version 3.0 =========== -Changes from Eric Raymond's libgif: - * A new gif encoder that makes uncompressed gifs rather than standard, - LZW-compressed gifs. This is actually the major motivating factor behind - libungif; to provide third-party distributors a means to provide a gif - library without the patented LZW encoder. - * A new configure script to make compilation of the library on multiple - platforms easier. The package should now build shared libraries on all - platforms supported by GNU libtool. +Changes from Eric Raymond's libgif +---------------------------------- +* A new gif encoder that makes uncompressed gifs rather than standard, + LZW-compressed gifs. This is actually the major motivating factor behind + libungif; to provide third-party distributors a means to provide a gif + library without the patented LZW encoder. +* A new configure script to make compilation of the library on multiple + platforms easier. The package should now build shared libraries on all + platforms supported by GNU libtool. +* Removed the getarg functions from libgif. These were not part of the + public API and only used by the tools in the utils directory so I separated + them from the rest of the library. +* Fixed a few bugs in the tools in the utils directory. + +Version 3.0 +=========== + +New features +------------ +* Incorporated Sirtaj Kang's changes to make both static and shared libs. +* All the utility and library docs are HTML now. +* The library and relevant utilities are now fully GIF89-aware. +* Functions for drawing text and boxes on saved images are documented. +* The distribution is now issued under a simple X-Consortium-style license. +* Can now generate package RPMs and LSM automatically. +* Home page with Web-acessible documentation at http://www.ccil.org/~esr/giflib + +Bug fixes +--------- +* Fix giftext to not core dump on a null extension record. +* Incorporate Philip VanBaren's change to prevent a core dump in gifasm. + +Version 2.3 +=========== +* Fixed a core-dump bug in gifcomb revealed by ELF environment in Linux 1.2.13. + +Version 2.2b +============ +* Added gifburst tool. + +Version 2.2 +=========== +* Linux is supported. + +Version 2.1 +=========== +* Added the gifovly tool, which supports making a composite from several GIF + images. +* Used gifovly to implement a full-fledged pasteup program in shell. It's + called gifcompose and lives in the util directory. +* Added a copy of the GIF89 standard to the doc directory (gif89.txt); + also a description of the preferred compression method (lzgif.txt). + +Version 2.0 +=========== + With this version, development was taken over from Gershon Elber by Eric +S. Raymond . Note that I, esr, have pretty much +adhered to Gershon's coding style, even though it's quite baroque and DOS- +headed by my standards. + +Library Improvements +-------------------- +* New DGifSlurp() and EGifSpew() library entry points allow all GIF-bashing + to be done in core on machines with sufficient memory. Writing code to + slice'n'dice multiple GIFs in non-sequential ways is now much easier (send + kudos and brickbats to esr, small unmarked bills preferred). +* The interface has changed somewhat. Members in the GifFileType structure + have been renamed and regrouped. This was required for support of the + SavedImages member (which enables the new functions mentioned in 1). Also, + there is a new data type for allocated color maps and routines to handle + it conveniently. +* Some minor bugs have been fixed. Most notably, the DGif code now correctly + handles the possibility of more than one code block per extension record, + as per the GIF spec. It's not clear, however, that anyone ever has or + ever will use this feature for anything... + +New Tools and Options +--------------------- +* A brand new, ultra-spiffy tool `icon2gif' is included. It assembles named + GIFs with editable text color map & icon raster representations to produce + multi-image GIFs usable as graphical resource files. It can also dump most + GIFs in the same text-only form it parses. This makes it easy to edit GIFs + even if you don't have a graphics editor. +* The gifclip utility supports a new `-c' (complement) option that allows you + to perform an `inverse clip', removing horizontal or vertical bands from an + image. +* The gifclrmp utility supports a new `-t' switch for shuffling color index + values. +* A new tool `gifcolor' generates test pattern from colormap input. + +New Documentation and Examples +------------------------------ +* The documentation has been overhauled completely and translated out of the + dialect spoken by the estimable Mr. Elber into something like standard + English :-). +* Two source code files gifspnge.c and giffiltr.c have been added to the + util directory. These are GIF copiers that exercise the I/O routines, + provided as skeletons for your applications. Read the comments in them + for more info. +* The util Makefile for UNIX has been improved. It now uses the cc/gcc -s + option rather than strip(1). There are now separate install productions, + so you can test new versions in util before installation for production + (the top-level make script still does an install). + +Version 1.2 +=========== +* GIFFIX - a new tool to attempt and fix broken GIF images. Currently fix + images that has EOF prematurely by padding with the darkest color. +* Make GIF2BGI display as much as it can considering the mem. avail. +* Add -q flag to all tools for quite running scan line number mode. +* Fix a (minor!?) bug in the GIF decoder when encountering code 4095. +* New tools (RGB2GIF and GIF2RGB) to convert GIF to/from 24 bits RGB images. +* New tool GIFROTAT to rotate a gif image by an arbitrary angle. +* GifRSize was updated to resize by an arbitrary factor. + +Version 1.1 +=========== +* GIF2BGI - a new utility to display GIF images using Borland's BGI drivers + (if you have one...) +* TEXT2GIF - Converts plain text into GIF images. +* GIF2IRIS - SGI4D display program for GIF images. +* GIF_LIB naming convension has been modified to make sure it has unique + names (see gif_lib.h). +* Support for SGI4D gl and X11 window grabbing has been added to the + library. SGI4D input is quantizied into 8 bits. + Also support for EGA/VGA devices has been added as well. + see Dev2gif.c module. +* Support for the new gif89a format has been added. - * Removed the getarg functions from libgif. These were not part of the - public API and only used by the tools in the utils directory so I separated - them from the rest of the library. - * Fixed a few bugs in the tools in the utils directory. -======== -Changes predating libungif 3.0 (news in the original libgif, in other words.) -is in ONEWS diff --git a/third_party/giflib/ONEWS b/third_party/giflib/ONEWS deleted file mode 100644 index 7cbcf166e..000000000 --- a/third_party/giflib/ONEWS +++ /dev/null @@ -1,133 +0,0 @@ -Note: to change the version, you have to hack both Makefile and lib/Makefile. - -Version 3.0: ------------- - -New features: -* Incorporated Sirtaj Kang's changes to make both static and shared libs. -* All the utility and library docs are HTML now. -* The library and relevant utilities are now fully GIF89-aware. -* Functions for drawing text and boxes on saved images are documented. -* The distribution is now issued under a simple X-Consortium-style license. -* Can now generate package RPMs and LSM automatically. -* Home page with Web-acessible documentation at http://www.ccil.org/~esr/giflib - -Bug fixes: -* Fix giftext to not core dump on a null extension record. -* Incorporate Philip VanBaren's change to prevent a core dump in gifasm. - -Version 2.3: -------------- -1. Fixed a core-dump bug in gifcomb revealed by the ELF environment in Linux - 1.2.13. - -Version 2.2b: ------------- -1. Added gifburst tool. - -Version 2.2 ------------ -1. Linux is supported. - -Version 2.1 ------------ -1. Added the gifovly tool, which supports making a composite from several GIF - images. - -2. Used gifovly to implement a full-fledged pasteup program in shell. It's - called gifcompose and lives in the util directory. - -3. Added a copy of the GIF89 standard to the doc directory (gif89.txt); - also a description of the preferred compression method (lzgif.txt). - -Version 2.0 ------------ - With this version, development was taken over from Gershon Elber by Eric -S. Raymond . Note that I, esr, have pretty much -adhered to Gershon's coding style, even though it's quite baroque and DOS- -headed by my standards. - -Library Improvements - -1. New DGifSlurp() and EGifSpew() library entry points allow all GIF-bashing - to be done in core on machines with sufficient memory. Writing code to - slice'n'dice multiple GIFs in non-sequential ways is now much easier (send - kudos and brickbats to esr, small unmarked bills preferred). - -2. The interface has changed somewhat. Members in the GifFileType structure - have been renamed and regrouped. This was required for support of the - SavedImages member (which enables the new functions mentioned in 1). Also, - there is a new data type for allocated color maps and routines to handle - it conveniently. - -3. Some minor bugs have been fixed. Most notably, the DGif code now correctly - handles the possibility of more than one code block per extension record, - as per the GIF spec. It's not clear, however, that anyone ever has or - ever will use this feature for anything... - -New Tools and Options - -4. A brand new, ultra-spiffy tool `icon2gif' is included. It assembles named - GIFs with editable text color map & icon raster representations to produce - multi-image GIFs usable as graphical resource files. It can also dump most - GIFs in the same text-only form it parses. This makes it easy to edit GIFs - even if you don't have a graphics editor. - -5. The gifclip utility supports a new `-c' (complement) option that allows you - to perform an `inverse clip', removing horizontal or vertical bands from an - image. - -6. The gifclrmp utility supports a new `-t' switch for shuffling color index - values. - -7. A new tool `gifcolor' generates test pattern from colormap input. - -New Documentation and Examples - -8. The documentation has been overhauled completely and translated out of the - dialect spoken by the estimable Mr. Elber into something like standard - English :-). - -9. Two source code files gifspnge.c and giffiltr.c have been added to the - util directory. These are GIF copiers that exercise the I/O routines, - provided as skeletons for your applications. Read the comments in them - for more info. - -10. The util Makefile for UNIX has been improved. It now uses the cc/gcc -s - option rather than strip(1). There are now separate install productions, - so you can test new versions in util before installation for production - (the top-level make script still does an install). - - -Version 1.2 ------------ -1. GIFFIX - a new tool to attempt and fix broken GIF images. Currently fix - images that has EOF prematurely by padding with the darkest color. -2. Make GIF2BGI display as much as it can considering the mem. avail. -3. Add -q flag to all tools for quite running scan line number mode. -4. Fix a (minor!?) bug in the GIF decoder when encountering code 4095. -5. New tools (RGB2GIF and GIF2RGB) to convert GIF to/from 24 bits RGB images. -6. New tool GIFROTAT to rotate a gif image by an arbitrary angle. -7. GifRSize was updated to resize by an arbitrary factor. - -Version 1.1 ------------ -1. GIF2BGI - a new utility to display GIF images using Borland's BGI drivers - (if you have one...) -2. TEXT2GIF - Converts plain text into GIF images. -3. GIF2IRIS - SGI4D display program for GIF images. -4. GIF_LIB naming convension has been modified to make sure it has unique - names (see gif_lib.h). -5. Support for SGI4D gl and X11 window grabbing has been added to the - library. SGI4D input is quantizied into 8 bits. - Also support for EGA/VGA devices has been added as well. - see Dev2gif.c module. -6. Support for the new gif89a format has been added. - -Enjoy, - -Gershon Elber -gershon@cs.utah.edu - -Eric S. Raymond -esr@snark.thyrsus.com diff --git a/third_party/giflib/README b/third_party/giflib/README index 50513aa03..38a9233c0 100644 --- a/third_party/giflib/README +++ b/third_party/giflib/README @@ -1,47 +1,27 @@ -This is giflib version 4.1.2, a library for manipulating gif files. -Latest versions of giflib are currently hosted at: - http://sourceforge.net/projects/libungif += GIFLIB = -==== -Building this package should be as simple as: +This is the README file of GIFLIB, a library for manipulating GIF files. - ./configure - gmake - gmake install +Latest versions of GIFLIB are currently hosted at: + http://sourceforge.net/projects/giflib -==== -Deprecation list. Will be removed in giflib 5.0: -* GIF_ERROR and GIF_MESSAGE are on the deprecation list as they are also - utility helper functions rather than essential to the functioning of the - library. -* The qprintf methods of the library are now deprecated. Do not use - GifQuietPrint or GifQprintf. These should have been pushed out into the - utility helper library instead of sitting around in the library proper at - the same time as the getarg functions were moved out. Getting rid of these - will let us get rid of our dependence on stdarg.h/varargs.h (Which a Gif - reading library has no business requiring.) -* In the SavedImage struct: int Function will be removed. Use - SavedImage.ExtensionBlocks[x].Function instead. -* In gifalloc.c: MakeExtension is deprecated as well. Use AddExtensionBlock - instead. (This and the previous int Function were deprecated because they - only handle one Extension per image. The new code handles multiple - extensions.) -* varargs style interface in qprintf and getarg: It's a mistake to have two - different interfaces that depend on compile time choices between varargs - and stdargs. The future is to get rid of varargs style altogether. - (Also: these are probably going strictly into the utility functions so - the library won't have to worry about them at all.) -==== +== Overview == -I have found that automake currently generates Makefile's containing some -GNUmake specific syntax. If you're having troubles building with your -system provided make, please install GNU make and try rebuilding. +GIF is a legacy format; we recommend against generating new images in +it. For a cleaner, more extensible design with better color support +and compression, look up PNG. -==== -This package uses autoconf, automake, and libtool to create the configure -script, so if you need to edit the configure.ac or change a makefile target -you should read the DEVELOPER file for hints on recreating the distribution -using these tools. +giflib provides code for reading GIF files and transforming them into +RGB bitmaps, and for writing RGB bitmaps as GIF files. + +The (permissive) open-source license is in the file COPYING. + +You will find build instructions in build.asc + +You will find full documentation of the API in doc/ and on the +project website. + +The project has a long and confusing history, described in history.asc + +The project to-do list is in TODO. -Good luck! --Toshio Kuratomi diff --git a/third_party/giflib/TODO b/third_party/giflib/TODO index 5121c80cb..488a3307f 100644 --- a/third_party/giflib/TODO +++ b/third_party/giflib/TODO @@ -1,140 +1,3 @@ -Edit utils to get rid of use of all deprecated Functions. -- icon2gif has MakeExtension += GIFLIB TODO list = -Check how the library uses MakeExtension and AddExtensionBlock. I have the -vague impression that the library currently requires a two step process: -MakeExtension adds the Function type to deprecated: SavedImage->Function. -Then, AddExtensionBlock must be called to add it to SavedImage->ExtensionBlock -(The Function type is passed in via the SavedImage->Function so that's why we -have to do that step first. Need to untangle those functions.) -- Why do we have so many colormaps? GifFile->SColorMap is the screen - descriptor colormap. - GifFile->Image.ColorMap ? - GifFile->SavedImages[x].ColorMap = Local colormap - -- Also check how we push the Extensions out to a gif file. We should never -touch SavedImage->Function when we write to file. All information is saved in -the ExtensionBlock. - -EGifPutExtension*/DGifGetExtension* needs to be looked at. Why is there a -First, Next, Last, and generic version of these functions? Does the -application programmer really need to know all this? Shouldn't the library -take care of it? Also, they should use WRITE rather than fwrite directly to -output the data. - -Make sure we set pointers that we don't fill to NULL. (gifalloc.c seems -pretty clean. But GifFile isn't allocated in gifalloc.c) - -I found a reported bug about libungif not handling interlaced images -correctly. However, the latest library seems to work. Need to figure out -what change fixed it and if it fixed it correctly or in a manner that is -apt to break later. - -Make sure tmpnam is secure in gifinto.c (Use mkstemp if possible..) - -Audit for sprintf => snprintf - -# Make sure all malloc calls check their return value. -Still need to check dev2gif.c (Know there's problems there) -dgif_lib.c -egif_lib.c - -Merge the windows changes from the last cvs version. Contact Lennie Araki -about whether he is interested in maintaining the windows changes - -Run the utils through indent - -Make sure the backlog is really all merged and then delete things from there. -Some is in my mailbox at home. Others were on the old CVS server. I think -most of the CVS backlog has been merged but I've just started ot look at -the stuff at home. - -Start thinking about function naming and standardizing things. The MakeXXX, -FreeXXX is a good step, but should things operate on GifFiles or the interior -data structures? What about the functions in the rest of the library? -Should I be able to (MakeGifFileType(), FreeGifFileType(GifFile *) just like -MakeMapObject?) - -Start thinking about namespacing all our code! This will break so many things -in simple ways. Need to deprecate so we can do this in 5.0 - -Release 4.1.3 - -sync giflib - -======= - -Theoretical release 5.0 - -Move utilities into a separate package. - - Move GIF_ERROR and GIF_MESSAGE from gif_lib.h into getarg. - - Move qprintf into getarg - - Rename getarg utilsupport.a and move to the util directory. - -Now that we have sourceforge hosting, look into putting documentation and a -website onto sourceforge. Don't know how much stuff I want to sync into this, -though, as I keep hoping gif's will take their last gasp and die. (Why do we -need gif now that we have png and mng?) - -====== - -Besides fixing bugs, what's really needed is for someone to work out how to -calculate a colormap for writing gifs from rgb sources. Right now, an rgb -source that has only two colors (b/w) is being converted into an 8 bit gif.... -Which is horrendously wasteful without compression. - -Any volunteers? - -======= -The Present Extension code is pretty hacky. It looks like giflib's ability to -do Extension code was added on at a later time and also was not implemented -entirely in conformance with the gif89a spec. I've hacked it further to make -it conform to the spec, but it would benefit greatly from a complete rewrite. - -If there is ever a version-5.0 of this library (with API level changes), this -should definitely be one of the areas that gets worked on. - -======= -Documentation needs updating to reflect additions to the API. This would best -be done with auto-extraction from the SOURCES.... - -======= -[UPDATE at bottom] -Here's a change to the library code that has been proposed: Pulling known -extensions (comment blocks, etc) out of the Extensions array and putting them -in actual places within the GifType structure so application programmers don't -have to search through the Extension array for them. - -I'm not sure how I want to implemement this yet -- Actually removing them from -the extension array would break the API compatibility with libungif. Making -copies would waste resources needlessly. Making convenience links with the -idea of deprecating the access of the extension block directly for standard -features would be okay, but creates extra work in the long run -- really we -need to put the convenience links into the current Extension array. - -We have to decide where in the structure each extension belongs, generalize -the AddExtensionBlock function to be able to add the extensionblock to any -area of the structure, rework the gif writing code to place the structures -where they belong, rework the code writing to the Extension Array so that it -can handle links as well as blocks. - -And on the other hand, it could turn out that putting extensions into the main -structure is not intuitive to everyone. Extensions are "extensions" and -people may want to look for them grouped together.... I suppose this could -either mean leaving everything in the extension array, or creating a new -extension field that has the extensions dangling off of it (comment, gifanim -stuff, unknown, etc.) This is okay except that it'd be best to have real -copies of the extension in the fields instead of links (so that we could make -arrays rather than arrays of pointers.) - -[UPDATE:1998 3 Dec] -After reading through the gif89a specification, I'm not sure this is all that -great. It seems that each image in a gif stream needs to have separate -extension blocks. This means that an animated gif will have a Graphics -Extension Block for each Image in the animation. Linking this up to the -GifFileType is wrong. Making a link in each SaveFile is correct, but will -take space that won't be needed when that particular extension doesn't appear -in this file.... - -Unless someone wants to correct me here, I don't think I'm going to implement -this. +Currently empty. diff --git a/third_party/giflib/lib/dev2gif.c b/third_party/giflib/lib/dev2gif.c deleted file mode 100644 index 3dd7143d4..000000000 --- a/third_party/giflib/lib/dev2gif.c +++ /dev/null @@ -1,510 +0,0 @@ -/***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 1.1, Jun. 1989 - ***************************************************************************** - * Module to dump graphic devices into a GIF file. Current supported devices: - * 1. EGA, VGA, SVGA (800x600), Hercules on the IBM PC (#define __MSDOS__). - * 2. SGI 4D Irix using gl library (#define SGI_GL__). - * 3. X11 using libX.a (#define __X11__). - * 4. (2 & 3 have been changed to HAVE_GL_S and HAVE_LIBX11 and should be set - * by the configure script.) - ***************************************************************************** - * History: - * 22 Jun 89 - Version 1.0 by Gershon Elber. - * 12 Aug 90 - Version 1.1 by Gershon Elber (added devices). - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef __MSDOS__ -#include -#include -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_LIBX11 -#include -#include -#endif /* HAVE_LIBX11 */ - -#ifdef HAVE_LIBGL_S -#include -#endif /* HAVE_LIBGL_S */ - -#include -#include -#include -#include "gif_lib.h" - -#define SVGA_SPECIAL 999 /* 800 by 600 Super VGA mode. */ - -static int GraphDriver = -1, /* Device parameters - reasonable values. */ - GraphMode = -1, ScreenColorBits = 1; -static long ScreenXMax = 100, ScreenYMax = 100; - -#ifdef __MSDOS__ -static unsigned int ScreenBase; -#endif /* __MSDOS__ */ - -#if defined(HAVE_LIBGL_S) || defined(HAVE_LIBX11) -GifByteType *GlblGifBuffer = NULL, *GlblGifBufferPtr = NULL; -#endif /* HAVE_LIBGL_S || HAVE_LIBX11 */ - -#ifdef HAVE_LIBGL_S -static int QuantizeRGBBuffer(int Width, int Height, long *RGBBuffer, - GifColorType * ColorMap, - GifByteType * GIFBuffer); -#endif /* HAVE_LIBGL_S */ - -static void GetScanLine(GifPixelType * ScanLine, int Y); -static int HandleGifError(GifFileType * GifFile); - -/****************************************************************************** - * Dump the given Device, into given File as GIF format: - * Return 0 on success, -1 if device not supported, or GIF-LIB error number. - * Device is selected via the ReqGraphDriver. Device mode is selected via - * ReqGraphMode1/2 as follows: - * 1. IBM PC Hercules card: HERCMONO (one mode only) in ReqGraphMode1, - * ReqGraphMode2/3 are ignored. - * 2. IBM PC EGA card: EGALO/EGAHI in ReqGraphMode1, - * ReqGraphMode2/3 are ignored. - * 3. IBM PC EGA64 card: EGA64LO/EGA64HI in ReqGraphMode1, - * ReqGraphMode2/3 are ignored. - * 4. IBM PC EGAMONO card: EGAMONOHI (one mode only) in ReqGraphMode1, - * ReqGraphMode2/3 are ignored. - * 5. IBM PC VGA card: VGALO/VGAMED/VGAHI in ReqGraphMode1, - * ReqGraphMode2/3 are ignored. - * 6. IBM PC SVGA card: ReqGraphMode1/2 are both ignored. Fixed mode (800x600 - * 16 colors) is assumed. - * 7. SGI 4D using GL: window id to dump (as returned by winget()) in - * ReqGraphMode1, ReqGraphMode2/3 are ignored. - * 8. X11: Window id in ReqGraphMode1, Display id in ReqGraphMode2, Color - * map id in ReqGraphMode3. - *****************************************************************************/ -int -DumpScreen2Gif(const char *FileName, - int ReqGraphDriver, - long ReqGraphMode1, - long ReqGraphMode2, - long ReqGraphMode3) { - - int i, j, k; - GifPixelType *ScanLine; - GifFileType *GifFile; - ColorMapObject *ColorMap = NULL; -#ifdef __MSDOS__ - static GifColorType MonoChromeColorMap[] = { - {0, 0, 0}, - {255, 255, 255} - }; - /* I have no idea what default EGA64 (4 colors) should be (I guessed...). */ - static GifColorType EGA64ColorMap[] = { - {0, 0, 0}, /* 0. Black */ - {255, 0, 0}, /* 1. Red */ - {0, 255, 0}, /* 2. Green */ - {0, 0, 255}, /* 3. Blue */ - }; - static GifColorType EGAColorMap[] = { - {0, 0, 0}, /* 0. Black */ - {0, 0, 170}, /* 1. Blue */ - {0, 170, 0}, /* 2. Green */ - {0, 170, 170}, /* 3. Cyan */ - {170, 0, 0}, /* 4. Red */ - {170, 0, 170}, /* 5. Magenta */ - {170, 170, 0}, /* 6. Brown */ - {170, 170, 170}, /* 7. LightGray */ - {85, 85, 85}, /* 8. DarkGray */ - {85, 85, 255}, /* 9. LightBlue */ - {85, 255, 85}, /* 10. LightGreen */ - {85, 255, 255}, /* 11. LightCyan */ - {255, 85, 85}, /* 12. LightRed */ - {255, 85, 255}, /* 13. LightMagenta */ - {255, 255, 85}, /* 14. Yellow */ - {255, 255, 255}, /* 15. White */ - }; -#endif /* __MSDOS__ */ -#if defined(HAVE_LIBGL_S) - long *RGBBuffer; -#ifndef HAVE_LIBX11 - GifColorType ColorMap256[256]; -#endif /* Undefined HAVE_LIBX11 */ -#endif /* HAVE_LIBGL_S */ -#ifdef HAVE_LIBX11 - XImage *XImg; - unsigned long XPixel; - GifColorType ColorMap256[256]; - XColor XColorTable[256]; /* Up to 256 colors in X. */ - XWindowAttributes WinAttr; -#endif /* HAVE_LIBX11 */ - switch (ReqGraphDriver) { /* Return on non supported screens. */ -#ifdef __MSDOS__ - case HERCMONO: - ScreenXMax = 720; - ScreenYMax = 350; - ScreenColorBits = 1; - ScreenBase = 0xb000; - ColorMap = MakeMapObject(2, MonoChromeColorMap); - break; - case EGA: - switch (ReqGraphMode1) { - case EGALO: - ScreenYMax = 200; - break; - case EGAHI: - ScreenYMax = 350; - break; - default: - return -1; - } - ScreenXMax = 640; - ScreenColorBits = 4; - ScreenBase = 0xa000; - ColorMap = MakeMapObject(16, EGAColorMap); - break; - case EGA64: - switch (ReqGraphMode1) { - case EGA64LO: - ScreenYMax = 200; - break; - case EGA64HI: - ScreenYMax = 350; - break; - default: - return -1; - } - ScreenXMax = 640; - ScreenColorBits = 2; - ScreenBase = 0xa000; - ColorMap = MakeMapObject(4, EGA64ColorMap); - break; - case EGAMONO: - switch (ReqGraphMode1) { - case EGAMONOHI: - ScreenYMax = 350; - break; - default: - return -1; - } - ScreenXMax = 640; - ScreenColorBits = 1; - ScreenBase = 0xa000; - ColorMap = MakeMapObject(2, MonoChromeColorMap); - break; - case VGA: - switch (ReqGraphMode1) { - case VGALO: - ScreenYMax = 200; - break; - case VGAMED: - ScreenYMax = 350; - break; - case VGAHI: - ScreenYMax = 480; - break; - default: - return -1; - } - ScreenXMax = 640; - ScreenColorBits = 4; - ScreenBase = 0xa000; - ColorMap = MakeMapObject(16, EGAColorMap); - break; - case SVGA_SPECIAL: - ScreenXMax = 800; - ScreenYMax = 600; - ScreenColorBits = 4; - ScreenBase = 0xa000; - ColorMap = MakeMapObject(16, EGAColorMap); - break; -#endif /* __MSDOS__ */ -#ifdef HAVE_LIBGL_S - case GIF_DUMP_SGI_WINDOW: - winset(ReqGraphMode1); /* Select window as active window. */ - getsize(&ScreenXMax, &ScreenYMax); - - RGBBuffer = (long *)malloc(sizeof(long) * ScreenXMax * ScreenYMax); - readsource(SRC_FRONT); - if (lrectread((short)0, (short)0, (short)(ScreenXMax - 1), - (short)(ScreenYMax - 1), RGBBuffer) != - ScreenXMax * ScreenYMax) { /* Get data. */ - free(RGBBuffer); - return -1; - } - GlblGifBuffer = (GifByteType *) malloc(sizeof(GifByteType) * - ScreenXMax * ScreenYMax); - i = QuantizeRGBBuffer(ScreenXMax, ScreenYMax, RGBBuffer, - ColorMap256, GlblGifBuffer); - /* Find minimum color map size to hold all quantized colors. */ - for (ScreenColorBits = 1; - (1 << ScreenColorBits) < i && ScreenColorBits < 8; - ScreenColorBits++) ; - - /* Start to dump with top line as GIF expects it. */ - GlblGifBufferPtr = GlblGifBuffer + ScreenXMax * (ScreenYMax - 1); - ColorMap = MakeMapObject(256, ColorMap256); - free(RGBBuffer); - break; -#endif /* HAVE_LIBGL_S */ -#ifdef HAVE_LIBX11 - case GIF_DUMP_X_WINDOW: - XGetWindowAttributes((Display *) ReqGraphMode2, - (Window) ReqGraphMode1, &WinAttr); - ScreenXMax = WinAttr.width; - ScreenYMax = WinAttr.height; - - XImg = XGetImage((Display *) ReqGraphMode2, - (Window) ReqGraphMode1, - 0, 0, ScreenXMax - 1, ScreenYMax - 1, - AllPlanes, XYPixmap); - - GlblGifBuffer = (GifByteType *)malloc(sizeof(GifByteType) * - ScreenXMax * ScreenYMax); - - /* Scan the image for all different colors exists. */ - for (i = 0; i < 256; i++) - XColorTable[i].pixel = 0; - k = FALSE; - for (i = 0; i < ScreenXMax; i++) - for (j = 0; j < ScreenYMax; j++) { - XPixel = XGetPixel(XImg, i, j); - if (XPixel > 255) { - if (!k) { - /* Make sure we state it once only. */ - fprintf(stderr, "X Color table - truncated.\n"); - k = TRUE; - } - XPixel = 255; - } - XColorTable[XPixel].pixel = XPixel; - } - /* Find the RGB representation of the colors. */ - XQueryColors((Display *) ReqGraphMode2, - (Colormap) ReqGraphMode3, XColorTable, 256); - /* Count number of active colors (Note color 0 is always in) */ - /* and create the Gif color map from it. */ - ColorMap = MakeMapObject(256, ColorMap256); - ColorMap->Colors[0].Red = ColorMap->Colors[0].Green = - ColorMap->Colors[0].Blue = 0; - for (i = j = 1; i < 256; i++) - if (XColorTable[i].pixel) { - ColorMap->Colors[j].Red = XColorTable[i].red / 256; - ColorMap->Colors[j].Green = XColorTable[i].green / 256; - ColorMap->Colors[j].Blue = XColorTable[i].blue / 256; - /* Save the X color index into the Gif table: */ - XColorTable[i].pixel = j++; - } - /* and set the number of colors in the Gif color map. */ - for (ScreenColorBits = 1; - (1 << ScreenColorBits) < j && ScreenColorBits < 8; - ScreenColorBits++) ; - - /* Prepare the Gif image buffer as indices into the Gif color */ - /* map from the X image. */ - GlblGifBufferPtr = GlblGifBuffer; - for (i = 0; i < ScreenXMax; i++) - for (j = 0; j < ScreenYMax; j++) - *GlblGifBufferPtr++ = - XColorTable[XGetPixel(XImg, j, i) & 0xff].pixel; - XDestroyImage(XImg); - - GlblGifBufferPtr = GlblGifBuffer; - ColorMap = MakeMapObject(256, ColorMap256); - break; -#endif /* HAVE_LIBX11 */ - default: - return -1; - } - - ScanLine = (GifPixelType *)malloc(sizeof(GifPixelType) * ScreenXMax); - - GraphDriver = ReqGraphDriver; - GraphMode = ReqGraphMode1; - - if ((GifFile = EGifOpenFileName(FileName, FALSE)) == NULL || - EGifPutScreenDesc(GifFile, ScreenXMax, ScreenYMax, ScreenColorBits, - 0, ColorMap) == GIF_ERROR || - EGifPutImageDesc(GifFile, 0, 0, ScreenXMax, ScreenYMax, FALSE, - NULL) == GIF_ERROR) { - free((char *)ScanLine); -#if defined(HAVE_LIBGL_S) || defined(HAVE_LIBX11) - free((char *)GlblGifBuffer); -#endif - return HandleGifError(GifFile); - } - - for (i = 0; i < ScreenYMax; i++) { - GetScanLine(ScanLine, i); - if (EGifPutLine(GifFile, ScanLine, ScreenXMax) == GIF_ERROR) { - free((char *)ScanLine); -#if defined(HAVE_LIBGL_S) || defined(HAVE_LIBX11) - free((char *)GlblGifBuffer); -#endif - return HandleGifError(GifFile); - } - } - - if (EGifCloseFile(GifFile) == GIF_ERROR) { - free((char *)ScanLine); -#if defined(HAVE_LIBGL_S) || defined(HAVE_LIBX11) - free((char *)GlblGifBuffer); -#endif - return HandleGifError(GifFile); - } - - free((char *)ScanLine); -#if defined(HAVE_LIBGL_S) || defined(HAVE_LIBX11) - free((char *)GlblGifBuffer); -#endif - return 0; -} - -#ifdef HAVE_LIBGL_S - -/****************************************************************************** - * Quantize the given 24 bit (8 per RGB) into 256 colors. - *****************************************************************************/ -static int -QuantizeRGBBuffer(int Width, - int Height, - long *RGBBuffer, - GifColorType * ColorMap, - GifByteType * GIFBuffer) { - - int i; - GifByteType *RedInput, *GreenInput, *BlueInput; - - /* Convert the RGB Buffer into 3 seperated buffers: */ - RedInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height); - GreenInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height); - BlueInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height); - - for (i = 0; i < Width * Height; i++) { - RedInput[i] = RGBBuffer[i] & 0xff; - GreenInput[i] = (RGBBuffer[i] >> 8) & 0xff; - BlueInput[i] = (RGBBuffer[i] >> 16) & 0xff; - } - for (i = 0; i < 256; i++) - ColorMap[i].Red = ColorMap[i].Green = ColorMap[i].Blue = 0; - - i = 256; - QuantizeBuffer(Width, Height, &i, - RedInput, GreenInput, BlueInput, GIFBuffer, ColorMap); - - free(RedInput); - free(GreenInput); - free(BlueInput); - - return i; /* Real number of colors in color table. */ -} -#endif /* HAVE_LIBGL_S */ - -/****************************************************************************** - * Update the given scan line buffer with the pixel levels of the Y line. - * This routine is device specific, so make sure you know was you are doing - *****************************************************************************/ -static void -GetScanLine(GifPixelType * ScanLine, - int Y) { - -#ifdef __MSDOS__ - unsigned char ScreenByte; - int i, j, k; - unsigned int BufferOffset, Bit; - union REGS InRegs, OutRegs; -#endif /* __MSDOS__ */ - - switch (GraphDriver) { -#ifdef __MSDOS__ - case HERCMONO: - BufferOffset = 0x2000 * (Y % 4) + (Y / 4) * (ScreenXMax / 8); - /* In one scan lines we have ScreenXMax / 8 bytes: */ - for (i = 0, k = 0; i < ScreenXMax / 8; i++) { - ScreenByte = (unsigned char)peekb(ScreenBase, BufferOffset++); - for (j = 0, Bit = 0x80; j < 8; j++) { - ScanLine[k++] = (ScreenByte & Bit ? 1 : 0); - Bit >>= 1; - } - } - break; - case EGA: - case EGA64: - case EGAMONO: - case VGA: - case SVGA_SPECIAL: - InRegs.x.dx = Y; - InRegs.h.bh = 0; - InRegs.h.ah = 0x0d; /* BIOS Read dot. */ - for (i = 0; i < ScreenXMax; i++) { - InRegs.x.cx = i; - int86(0x10, &InRegs, &OutRegs); - ScanLine[i] = OutRegs.h.al; - } - - /* Makr this line as done by putting a xored dot on the left. */ - InRegs.x.dx = Y; - InRegs.h.bh = 0; - InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */ - InRegs.h.al = 0x81; /* Xor with color 1. */ - InRegs.x.cx = 0; - int86(0x10, &InRegs, &OutRegs); - InRegs.x.dx = Y; - InRegs.h.bh = 0; - InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */ - InRegs.h.al = 0x81; /* Xor with color 1. */ - InRegs.x.cx = 1; - int86(0x10, &InRegs, &OutRegs); - - if (Y == ScreenYMax - 1) { /* Last row - clear all marks we - * made. */ - for (i = 0; i < ScreenYMax; i++) { - InRegs.h.bh = 0; - InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */ - InRegs.h.al = 0x81; /* Xor back with color 1. */ - InRegs.x.dx = i; - InRegs.x.cx = 0; - int86(0x10, &InRegs, &OutRegs); - InRegs.h.bh = 0; - InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */ - InRegs.h.al = 0x81; /* Xor back with color 1. */ - InRegs.x.dx = i; - InRegs.x.cx = 1; - int86(0x10, &InRegs, &OutRegs); - } - } - break; -#endif /* __MSDOS__ */ -#ifdef HAVE_LIBGL_S - case GIF_DUMP_SGI_WINDOW: - memcpy(ScanLine, GlblGifBufferPtr, - ScreenXMax * sizeof(GifPixelType)); - GlblGifBufferPtr -= ScreenXMax; - break; -#endif /* HAVE_LIBGL_S */ -#ifdef HAVE_LIBX11 - case GIF_DUMP_X_WINDOW: - memcpy(ScanLine, GlblGifBufferPtr, - ScreenXMax * sizeof(GifPixelType)); - GlblGifBufferPtr += ScreenXMax; - break; -#endif /* HAVE_LIBX11 */ - default: - break; - } -} - -/****************************************************************************** - * Handle last GIF error. Try to close the file and free all allocated memory. - *****************************************************************************/ -static int -HandleGifError(GifFileType * GifFile) { - - int i = GifLastError(); - - if (EGifCloseFile(GifFile) == GIF_ERROR) { - GifLastError(); - } - return i; -} diff --git a/third_party/giflib/lib/dgif_lib.c b/third_party/giflib/lib/dgif_lib.c index f6ed67d71..331d88a53 100644 --- a/third_party/giflib/lib/dgif_lib.c +++ b/third_party/giflib/lib/dgif_lib.c @@ -1,46 +1,32 @@ /****************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 - ****************************************************************************** - * The kernel of the GIF Decoding process can be found here. - ****************************************************************************** - * History: - * 16 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). - *****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif +dgif_lib.c - GIF decoding + +The functions here and in egif_lib.c are partitioned carefully so that +if you only require one of read and write capability, only one of these +two modules will be linked. Preserve this property! + +*****************************************************************************/ #include -#if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__) -#include -#include -#include -#else -#include -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_FCNTL_H +#include +#include #include -#endif /* HAVE_FCNTL_H */ #ifdef HAVE_UNISTD_H #include -#endif /* HAVE_UNISTD_H */ +#endif #include #include + +#ifdef _WIN32 +#include +#endif /* _WIN32 */ + #include "gif_lib.h" #include "gif_lib_private.h" -#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for - comment. */ +/* compose unsigned little endian value */ +#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8)) /* avoid extra function call in case we use fread (TVT) */ #define READ(_gif,_buf,_len) \ @@ -56,159 +42,167 @@ static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode); static int DGifDecompressInput(GifFileType *GifFile, int *Code); static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte); -#ifndef _GBA_NO_FILEIO /****************************************************************************** - * Open a new gif file for read, given by its name. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ + Open a new GIF file for read, given by its name. + Returns dynamically allocated GifFileType pointer which serves as the GIF + info record. +******************************************************************************/ GifFileType * -DGifOpenFileName(const char *FileName) { +DGifOpenFileName(const char *FileName, int *Error) +{ int FileHandle; GifFileType *GifFile; - if ((FileHandle = open(FileName, O_RDONLY -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) - | O_BINARY -#endif /* __MSDOS__ || _OPEN_BINARY */ - )) == -1) { - _GifError = D_GIF_ERR_OPEN_FAILED; + if ((FileHandle = open(FileName, O_RDONLY)) == -1) { + if (Error != NULL) + *Error = D_GIF_ERR_OPEN_FAILED; return NULL; } - GifFile = DGifOpenFileHandle(FileHandle); + GifFile = DGifOpenFileHandle(FileHandle, Error); return GifFile; } /****************************************************************************** - * Update a new gif file, given its file handle. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ + Update a new GIF file, given its file handle. + Returns dynamically allocated GifFileType pointer which serves as the GIF + info record. +******************************************************************************/ GifFileType * -DGifOpenFileHandle(int FileHandle) { - - unsigned char Buf[GIF_STAMP_LEN + 1]; +DGifOpenFileHandle(int FileHandle, int *Error) +{ + char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - close(FileHandle); + if (Error != NULL) + *Error = D_GIF_ERR_NOT_ENOUGH_MEM; + (void)close(FileHandle); return NULL; } - memset(GifFile, '\0', sizeof(GifFileType)); + /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType)); + + /* Belt and suspenders, in case the null pointer isn't zero */ + GifFile->SavedImages = NULL; + GifFile->SColorMap = NULL; Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; - close(FileHandle); + if (Error != NULL) + *Error = D_GIF_ERR_NOT_ENOUGH_MEM; + (void)close(FileHandle); free((char *)GifFile); return NULL; } -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) - setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ -#endif /* __MSDOS__ */ +#ifdef _WIN32 + _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* _WIN32 */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ -#if defined(__MSDOS__) || defined(WINDOWS32) - setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream - buffer. */ -#endif /* __MSDOS__ */ - - GifFile->Private = (VoidPtr)Private; + /*@-mustfreeonly@*/ + GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_READ; - Private->Read = 0; /* don't use alternate input method (TVT) */ - GifFile->UserData = 0; /* TVT */ + Private->Read = NULL; /* don't use alternate input method (TVT) */ + GifFile->UserData = NULL; /* TVT */ + /*@=mustfreeonly@*/ - /* Lets see if this is a GIF file: */ - if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - _GifError = D_GIF_ERR_READ_FAILED; - fclose(f); + /* Let's see if this is a GIF file: */ + if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { + if (Error != NULL) + *Error = D_GIF_ERR_READ_FAILED; + (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } - /* The GIF Version number is ignored at this time. Maybe we should do - * something more useful with it. */ + /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - _GifError = D_GIF_ERR_NOT_GIF_FILE; - fclose(f); + if (Error != NULL) + *Error = D_GIF_ERR_NOT_GIF_FILE; + (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - fclose(f); + (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } - _GifError = 0; + GifFile->Error = 0; + + /* What version of GIF? */ + Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); return GifFile; } -#endif /* _GBA_NO_FILEIO */ - /****************************************************************************** - * GifFileType constructor with user supplied input function (TVT) - *****************************************************************************/ + GifFileType constructor with user supplied input function (TVT) +******************************************************************************/ GifFileType * -DGifOpen(void *userData, - InputFunc readFunc) { - - unsigned char Buf[GIF_STAMP_LEN + 1]; +DGifOpen(void *userData, InputFunc readFunc, int *Error) +{ + char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = D_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); + /* Belt and suspenders, in case the null pointer isn't zero */ + GifFile->SavedImages = NULL; + GifFile->SColorMap = NULL; + Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (!Private) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = D_GIF_ERR_NOT_ENOUGH_MEM; free((char *)GifFile); return NULL; } - GifFile->Private = (VoidPtr)Private; + GifFile->Private = (void *)Private; Private->FileHandle = 0; - Private->File = 0; + Private->File = NULL; Private->FileState = FILE_STATE_READ; Private->Read = readFunc; /* TVT */ GifFile->UserData = userData; /* TVT */ /* Lets see if this is a GIF file: */ - if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - _GifError = D_GIF_ERR_READ_FAILED; + if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { + if (Error != NULL) + *Error = D_GIF_ERR_READ_FAILED; free((char *)Private); free((char *)GifFile); return NULL; } - /* The GIF Version number is ignored at this time. Maybe we should do - * something more useful with it. */ - Buf[GIF_STAMP_LEN] = 0; + /* Check for GIF prefix at start of file */ + Buf[GIF_STAMP_LEN] = '\0'; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - _GifError = D_GIF_ERR_NOT_GIF_FILE; + if (Error != NULL) + *Error = D_GIF_ERR_NOT_GIF_FILE; free((char *)Private); free((char *)GifFile); return NULL; @@ -217,28 +211,33 @@ DGifOpen(void *userData, if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *)Private); free((char *)GifFile); + *Error = D_GIF_ERR_NO_SCRN_DSCR; return NULL; } - _GifError = 0; + GifFile->Error = 0; + + /* What version of GIF? */ + Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); return GifFile; } /****************************************************************************** - * This routine should be called before any other DGif calls. Note that - * this routine is called automatically from DGif file open routines. - *****************************************************************************/ + This routine should be called before any other DGif calls. Note that + this routine is called automatically from DGif file open routines. +******************************************************************************/ int -DGifGetScreenDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; +DGifGetScreenDesc(GifFileType *GifFile) +{ + int BitsPerPixel; + bool SortFlag; GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } @@ -248,26 +247,32 @@ DGifGetScreenDesc(GifFileType * GifFile) { return GIF_ERROR; if (READ(GifFile, Buf, 3) != 3) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; + GifFreeMapObject(GifFile->SColorMap); + GifFile->SColorMap = NULL; return GIF_ERROR; } GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; + SortFlag = (Buf[0] & 0x08) != 0; BitsPerPixel = (Buf[0] & 0x07) + 1; GifFile->SBackGroundColor = Buf[1]; + GifFile->AspectByte = Buf[2]; if (Buf[0] & 0x80) { /* Do we have global color map? */ + int i; - GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); + GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL); if (GifFile->SColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } /* Get the global color map: */ + GifFile->SColorMap->SortFlag = SortFlag; for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->SColorMap); + GifFreeMapObject(GifFile->SColorMap); GifFile->SColorMap = NULL; - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } GifFile->SColorMap->Colors[i].Red = Buf[0]; @@ -282,39 +287,38 @@ DGifGetScreenDesc(GifFileType * GifFile) { } /****************************************************************************** - * This routine should be called before any attempt to read an image. - *****************************************************************************/ + This routine should be called before any attempt to read an image. +******************************************************************************/ int -DGifGetRecordType(GifFileType * GifFile, - GifRecordType * Type) { - +DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } switch (Buf) { - case ',': + case DESCRIPTOR_INTRODUCER: *Type = IMAGE_DESC_RECORD_TYPE; break; - case '!': + case EXTENSION_INTRODUCER: *Type = EXTENSION_RECORD_TYPE; break; - case ';': + case TERMINATOR_INTRODUCER: *Type = TERMINATE_RECORD_TYPE; break; default: *Type = UNDEFINED_RECORD_TYPE; - _GifError = D_GIF_ERR_WRONG_RECORD; + GifFile->Error = D_GIF_ERR_WRONG_RECORD; return GIF_ERROR; } @@ -322,20 +326,20 @@ DGifGetRecordType(GifFileType * GifFile, } /****************************************************************************** - * This routine should be called before any attempt to read an image. - * Note it is assumed the Image desc. header (',') has been read. - *****************************************************************************/ + This routine should be called before any attempt to read an image. + Note it is assumed the Image desc. header has been read. +******************************************************************************/ int -DGifGetImageDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; +DGifGetImageDesc(GifFileType *GifFile) +{ + unsigned int BitsPerPixel; GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; SavedImage *sp; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } @@ -345,29 +349,34 @@ DGifGetImageDesc(GifFileType * GifFile) { DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) return GIF_ERROR; if (READ(GifFile, Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; + GifFreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; return GIF_ERROR; } BitsPerPixel = (Buf[0] & 0x07) + 1; - GifFile->Image.Interlace = (Buf[0] & 0x40); - if (Buf[0] & 0x80) { /* Does this image have local color map? */ + GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false; - /*** FIXME: Why do we check both of these in order to do this? - * Why do we have both Image and SavedImages? */ - if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL) - FreeMapObject(GifFile->Image.ColorMap); + /* Setup the colormap */ + if (GifFile->Image.ColorMap) { + GifFreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + /* Does this image have local color map? */ + if (Buf[0] & 0x80) { + unsigned int i; - GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); + GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL); if (GifFile->Image.ColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } /* Get the image local color map: */ for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->Image.ColorMap); - _GifError = D_GIF_ERR_READ_FAILED; + GifFreeMapObject(GifFile->Image.ColorMap); + GifFile->Error = D_GIF_ERR_READ_FAILED; GifFile->Image.ColorMap = NULL; return GIF_ERROR; } @@ -375,22 +384,19 @@ DGifGetImageDesc(GifFileType * GifFile) { GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; } - } else if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; } if (GifFile->SavedImages) { if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1))) == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else { if ((GifFile->SavedImages = (SavedImage *) malloc(sizeof(SavedImage))) == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } @@ -398,11 +404,11 @@ DGifGetImageDesc(GifFileType * GifFile) { sp = &GifFile->SavedImages[GifFile->ImageCount]; memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); if (GifFile->Image.ColorMap != NULL) { - sp->ImageDesc.ColorMap = MakeMapObject( + sp->ImageDesc.ColorMap = GifMakeMapObject( GifFile->Image.ColorMap->ColorCount, GifFile->Image.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { - _GifError = D_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } @@ -415,45 +421,40 @@ DGifGetImageDesc(GifFileType * GifFile) { Private->PixelCount = (long)GifFile->Image.Width * (long)GifFile->Image.Height; - DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ - - return GIF_OK; + /* Reset decompress algorithm parameters. */ + return DGifSetupDecompress(GifFile); } /****************************************************************************** - * Get one full scanned line (Line) of length LineLen from GIF file. - *****************************************************************************/ + Get one full scanned line (Line) of length LineLen from GIF file. +******************************************************************************/ int -DGifGetLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - +DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) +{ GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (!LineLen) LineLen = GifFile->Image.Width; -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__) if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { -#else - if ((Private->PixelCount -= LineLen) > 0xffff0000) { -#endif /* __MSDOS__ */ - _GifError = D_GIF_ERR_DATA_TOO_BIG; + GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { if (Private->PixelCount == 0) { - /* We probably would not be called any more, so lets clean - * everything before we return: need to flush out all rest of - * image until empty block (size 0) detected. We use GetCodeNext. */ + /* We probably won't be called any more, so let's clean up + * everything before we return: need to flush out all the + * rest of image until an empty block (size 0) + * detected. We use GetCodeNext. + */ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; @@ -465,35 +466,32 @@ DGifGetLine(GifFileType * GifFile, } /****************************************************************************** - * Put one pixel (Pixel) into GIF file. - *****************************************************************************/ + Put one pixel (Pixel) into GIF file. +******************************************************************************/ int -DGifGetPixel(GifFileType * GifFile, - GifPixelType Pixel) { - +DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel) +{ GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__) if (--Private->PixelCount > 0xffff0000UL) -#else - if (--Private->PixelCount > 0xffff0000) -#endif /* __MSDOS__ */ { - _GifError = D_GIF_ERR_DATA_TOO_BIG; + GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { if (Private->PixelCount == 0) { - /* We probably would not be called any more, so lets clean - * everything before we return: need to flush out all rest of - * image until empty block (size 0) detected. We use GetCodeNext. */ + /* We probably won't be called any more, so let's clean up + * everything before we return: need to flush out all the + * rest of image until an empty block (size 0) + * detected. We use GetCodeNext. + */ do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) return GIF_ERROR; @@ -505,28 +503,26 @@ DGifGetPixel(GifFileType * GifFile, } /****************************************************************************** - * Get an extension block (see GIF manual) from gif file. This routine only - * returns the first data block, and DGifGetExtensionNext should be called - * after this one until NULL extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - * Note it is assumed the Extension desc. header ('!') has been read. - *****************************************************************************/ + Get an extension block (see GIF manual) from GIF file. This routine only + returns the first data block, and DGifGetExtensionNext should be called + after this one until NULL extension is returned. + The Extension should NOT be freed by the user (not dynamically allocated). + Note it is assumed the Extension description header has been read. +******************************************************************************/ int -DGifGetExtension(GifFileType * GifFile, - int *ExtCode, - GifByteType ** Extension) { - +DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *ExtCode = Buf; @@ -535,26 +531,26 @@ DGifGetExtension(GifFileType * GifFile, } /****************************************************************************** - * Get a following extension block (see GIF manual) from gif file. This - * routine should be called until NULL Extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ + Get a following extension block (see GIF manual) from GIF file. This + routine should be called until NULL Extension is returned. + The Extension should NOT be freed by the user (not dynamically allocated). +******************************************************************************/ int -DGifGetExtensionNext(GifFileType * GifFile, - GifByteType ** Extension) { - +DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } if (Buf > 0) { *Extension = Private->Buf; /* Use private unused buffer. */ (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ + /* coverity[tainted_data] */ if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else @@ -564,91 +560,140 @@ DGifGetExtensionNext(GifFileType * GifFile, } /****************************************************************************** - * This routine should be called last, to close the GIF file. - *****************************************************************************/ + Extract a Graphics Control Block from raw extension data +******************************************************************************/ + +int DGifExtensionToGCB(const size_t GifExtensionLength, + const GifByteType *GifExtension, + GraphicsControlBlock *GCB) +{ + if (GifExtensionLength != 4) { + return GIF_ERROR; + } + + GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07; + GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0; + GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]); + if (GifExtension[0] & 0x01) + GCB->TransparentColor = (int)GifExtension[3]; + else + GCB->TransparentColor = NO_TRANSPARENT_COLOR; + + return GIF_OK; +} + +/****************************************************************************** + Extract the Graphics Control Block for a saved image, if it exists. +******************************************************************************/ + +int DGifSavedExtensionToGCB(GifFileType *GifFile, + int ImageIndex, GraphicsControlBlock *GCB) +{ + int i; + + if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) + return GIF_ERROR; + + GCB->DisposalMode = DISPOSAL_UNSPECIFIED; + GCB->UserInputFlag = false; + GCB->DelayTime = 0; + GCB->TransparentColor = NO_TRANSPARENT_COLOR; + + for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) { + ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i]; + if (ep->Function == GRAPHICS_EXT_FUNC_CODE) + return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB); + } + + return GIF_ERROR; +} + +/****************************************************************************** + This routine should be called last, to close the GIF file. +******************************************************************************/ int -DGifCloseFile(GifFileType * GifFile) { - +DGifCloseFile(GifFileType *GifFile, int *ErrorCode) +{ GifFilePrivateType *Private; - FILE *File; - if (GifFile == NULL) + if (GifFile == NULL || GifFile->Private == NULL) return GIF_ERROR; + if (GifFile->Image.ColorMap) { + GifFreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + + if (GifFile->SColorMap) { + GifFreeMapObject(GifFile->SColorMap); + GifFile->SColorMap = NULL; + } + + if (GifFile->SavedImages) { + GifFreeSavedImages(GifFile); + GifFile->SavedImages = NULL; + } + + GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks); + Private = (GifFilePrivateType *) GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + if (ErrorCode != NULL) + *ErrorCode = D_GIF_ERR_NOT_READABLE; + free((char *)GifFile->Private); + free(GifFile); return GIF_ERROR; } - File = Private->File; - - if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - - if (GifFile->SColorMap) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - } - - if (Private) { - free((char *)Private); - Private = NULL; - } - - if (GifFile->SavedImages) { - FreeSavedImages(GifFile); - GifFile->SavedImages = NULL; + if (Private->File && (fclose(Private->File) != 0)) { + if (ErrorCode != NULL) + *ErrorCode = D_GIF_ERR_CLOSE_FAILED; + free((char *)GifFile->Private); + free(GifFile); + return GIF_ERROR; } + free((char *)GifFile->Private); free(GifFile); - - if (File && (fclose(File) != 0)) { - _GifError = D_GIF_ERR_CLOSE_FAILED; - return GIF_ERROR; - } + if (ErrorCode != NULL) + *ErrorCode = D_GIF_SUCCEEDED; return GIF_OK; } /****************************************************************************** - * Get 2 bytes (word) from the given file: - *****************************************************************************/ + Get 2 bytes (word) from the given file: +******************************************************************************/ static int -DGifGetWord(GifFileType * GifFile, - GifWord *Word) { - +DGifGetWord(GifFileType *GifFile, GifWord *Word) +{ unsigned char c[2]; if (READ(GifFile, c, 2) != 2) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } - *Word = (((unsigned int)c[1]) << 8) + c[0]; + *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]); return GIF_OK; } /****************************************************************************** - * Get the image code in compressed form. This routine can be called if the - * information needed to be piped out as is. Obviously this is much faster - * than decoding and encoding again. This routine should be followed by calls - * to DGifGetCodeNext, until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ + Get the image code in compressed form. This routine can be called if the + information needed to be piped out as is. Obviously this is much faster + than decoding and encoding again. This routine should be followed by calls + to DGifGetCodeNext, until NULL block is returned. + The block should NOT be freed by the user (not dynamically allocated). +******************************************************************************/ int -DGifGetCode(GifFileType * GifFile, - int *CodeSize, - GifByteType ** CodeBlock) { - +DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock) +{ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } @@ -658,27 +703,29 @@ DGifGetCode(GifFileType * GifFile, } /****************************************************************************** - * Continue to get the image code in compressed form. This routine should be - * called until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ + Continue to get the image code in compressed form. This routine should be + called until NULL block is returned. + The block should NOT be freed by the user (not dynamically allocated). +******************************************************************************/ int -DGifGetCodeNext(GifFileType * GifFile, - GifByteType ** CodeBlock) { - +DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + /* coverity[tainted_data_argument] */ if (READ(GifFile, &Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } + /* coverity[lower_bounds] */ if (Buf > 0) { *CodeBlock = Private->Buf; /* Use private unused buffer. */ (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ + /* coverity[tainted_data] */ if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else { @@ -691,17 +738,19 @@ DGifGetCodeNext(GifFileType * GifFile, } /****************************************************************************** - * Setup the LZ decompression for this image: - *****************************************************************************/ + Setup the LZ decompression for this image: +******************************************************************************/ static int -DGifSetupDecompress(GifFileType * GifFile) { - +DGifSetupDecompress(GifFileType *GifFile) +{ int i, BitsPerPixel; GifByteType CodeSize; GifPrefixType *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - READ(GifFile, &CodeSize, 1); /* Read Code size from file. */ + if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */ + return GIF_ERROR; /* Failed to read Code size. */ + } BitsPerPixel = CodeSize; Private->Buf[0] = 0; /* Input Buffer empty. */ @@ -724,16 +773,14 @@ DGifSetupDecompress(GifFileType * GifFile) { } /****************************************************************************** - * The LZ decompression routine: - * This version decompress the given gif file into Line of length LineLen. - * This routine can be called few times (one per scan line, for example), in - * order the complete the whole image. - *****************************************************************************/ + The LZ decompression routine: + This version decompress the given GIF file into Line of length LineLen. + This routine can be called few times (one per scan line, for example), in + order the complete the whole image. +******************************************************************************/ static int -DGifDecompressLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - +DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen) +{ int i = 0; int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; GifByteType *Stack, *Suffix; @@ -753,7 +800,7 @@ DGifDecompressLine(GifFileType * GifFile, } if (StackPtr != 0) { - /* Let pop the stack off before continueing to read the gif file: */ + /* Let pop the stack off before continueing to read the GIF file: */ while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr]; } @@ -766,11 +813,8 @@ DGifDecompressLine(GifFileType * GifFile, /* Note however that usually we will not be here as we will stop * decoding as soon as we got all the pixel, or EOF code will * not be read at all, and DGifGetLine/Pixel clean everything. */ - if (i != LineLen - 1 || Private->PixelCount != 0) { - _GifError = D_GIF_ERR_EOF_TOO_SOON; - return GIF_ERROR; - } - i++; + GifFile->Error = D_GIF_ERR_EOF_TOO_SOON; + return GIF_ERROR; } else if (CrntCode == ClearCode) { /* We need to start over again: */ for (j = 0; j <= LZ_MAX_CODE; j++) @@ -792,36 +836,37 @@ DGifDecompressLine(GifFileType * GifFile, * pixels on our stack. If we done, pop the stack in reverse * (thats what stack is good for!) order to output. */ if (Prefix[CrntCode] == NO_SUCH_CODE) { + CrntPrefix = LastCode; + /* Only allowed if CrntCode is exactly the running code: * In that case CrntCode = XXXCode, CrntCode or the * prefix code is last code and the suffix char is * exactly the prefix of last code! */ if (CrntCode == Private->RunningCode - 2) { - CrntPrefix = LastCode; Suffix[Private->RunningCode - 2] = Stack[StackPtr++] = DGifGetPrefixChar(Prefix, LastCode, ClearCode); } else { - _GifError = D_GIF_ERR_IMAGE_DEFECT; - return GIF_ERROR; + Suffix[Private->RunningCode - 2] = + Stack[StackPtr++] = DGifGetPrefixChar(Prefix, + CrntCode, + ClearCode); } } else CrntPrefix = CrntCode; - /* Now (if image is O.K.) we should not get an NO_SUCH_CODE - * During the trace. As we might loop forever, in case of - * defective image, we count the number of loops we trace - * and stop if we got LZ_MAX_CODE. obviously we can not - * loop more than that. */ - j = 0; - while (j++ <= LZ_MAX_CODE && + /* Now (if image is O.K.) we should not get a NO_SUCH_CODE + * during the trace. As we might loop forever, in case of + * defective image, we use StackPtr as loop counter and stop + * before overflowing Stack[]. */ + while (StackPtr < LZ_MAX_CODE && CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { Stack[StackPtr++] = Suffix[CrntPrefix]; CrntPrefix = Prefix[CrntPrefix]; } - if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; + if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { + GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } /* Push the last character on stack: */ @@ -831,7 +876,7 @@ DGifDecompressLine(GifFileType * GifFile, while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr]; } - if (LastCode != NO_SUCH_CODE) { + if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { Prefix[Private->RunningCode - 2] = LastCode; if (CrntCode == Private->RunningCode - 2) { @@ -857,16 +902,14 @@ DGifDecompressLine(GifFileType * GifFile, } /****************************************************************************** - * Routine to trace the Prefixes linked list until we get a prefix which is - * not code, but a pixel value (less than ClearCode). Returns that pixel value. - * If image is defective, we might loop here forever, so we limit the loops to - * the maximum possible if image O.k. - LZ_MAX_CODE times. - *****************************************************************************/ + Routine to trace the Prefixes linked list until we get a prefix which is + not code, but a pixel value (less than ClearCode). Returns that pixel value. + If image is defective, we might loop here forever, so we limit the loops to + the maximum possible if image O.k. - LZ_MAX_CODE times. +******************************************************************************/ static int -DGifGetPrefixChar(GifPrefixType *Prefix, - int Code, - int ClearCode) { - +DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode) +{ int i = 0; while (Code > ClearCode && i++ <= LZ_MAX_CODE) { @@ -879,19 +922,18 @@ DGifGetPrefixChar(GifPrefixType *Prefix, } /****************************************************************************** - * Interface for accessing the LZ codes directly. Set Code to the real code - * (12bits), or to -1 if EOF code is returned. - *****************************************************************************/ + Interface for accessing the LZ codes directly. Set Code to the real code + (12bits), or to -1 if EOF code is returned. +******************************************************************************/ int -DGifGetLZCodes(GifFileType * GifFile, - int *Code) { - +DGifGetLZCodes(GifFileType *GifFile, int *Code) +{ GifByteType *CodeBlock; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ - _GifError = D_GIF_ERR_NOT_READABLE; + GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } @@ -917,37 +959,38 @@ DGifGetLZCodes(GifFileType * GifFile, } /****************************************************************************** - * The LZ decompression input routine: - * This routine is responsable for the decompression of the bit stream from - * 8 bits (bytes) packets, into the real codes. - * Returns GIF_OK if read succesfully. - *****************************************************************************/ + The LZ decompression input routine: + This routine is responsable for the decompression of the bit stream from + 8 bits (bytes) packets, into the real codes. + Returns GIF_OK if read successfully. +******************************************************************************/ static int -DGifDecompressInput(GifFileType * GifFile, - int *Code) { +DGifDecompressInput(GifFileType *GifFile, int *Code) +{ + static const unsigned short CodeMasks[] = { + 0x0000, 0x0001, 0x0003, 0x0007, + 0x000f, 0x001f, 0x003f, 0x007f, + 0x00ff, 0x01ff, 0x03ff, 0x07ff, + 0x0fff + }; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; GifByteType NextByte; - static unsigned short CodeMasks[] = { - 0x0000, 0x0001, 0x0003, 0x0007, - 0x000f, 0x001f, 0x003f, 0x007f, - 0x00ff, 0x01ff, 0x03ff, 0x07ff, - 0x0fff - }; + /* The image can't contain more than LZ_BITS per code. */ if (Private->RunningBits > LZ_BITS) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; + GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } - + while (Private->CrntShiftState < Private->RunningBits) { /* Needs to get more bytes from input stream for next code: */ if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= - ((unsigned long)NextByte) << Private->CrntShiftState; + ((unsigned long)NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; @@ -961,8 +1004,8 @@ DGifDecompressInput(GifFileType * GifFile, * keep using the table as it is, don't increment Private->RunningCode. */ if (Private->RunningCode < LZ_MAX_CODE + 2 && - ++Private->RunningCode > Private->MaxCode1 && - Private->RunningBits < LZ_BITS) { + ++Private->RunningCode > Private->MaxCode1 && + Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } @@ -970,20 +1013,18 @@ DGifDecompressInput(GifFileType * GifFile, } /****************************************************************************** - * This routines read one gif data block at a time and buffers it internally - * so that the decompression routine could access it. - * The routine returns the next byte from its internal buffer (or read next - * block in if buffer empty) and returns GIF_OK if succesful. - *****************************************************************************/ + This routines read one GIF data block at a time and buffers it internally + so that the decompression routine could access it. + The routine returns the next byte from its internal buffer (or read next + block in if buffer empty) and returns GIF_OK if succesful. +******************************************************************************/ static int -DGifBufferedInput(GifFileType * GifFile, - GifByteType * Buf, - GifByteType * NextByte) { - +DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte) +{ if (Buf[0] == 0) { /* Needs to read the next buffer - this one is empty: */ if (READ(GifFile, Buf, 1) != 1) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } /* There shouldn't be any empty data blocks here as the LZW spec @@ -991,11 +1032,11 @@ DGifBufferedInput(GifFileType * GifFile, * shouldn't be inside this routine at that point. */ if (Buf[0] == 0) { - _GifError = D_GIF_ERR_IMAGE_DEFECT; + GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) { - _GifError = D_GIF_ERR_READ_FAILED; + GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *NextByte = Buf[1]; @@ -1008,24 +1049,23 @@ DGifBufferedInput(GifFileType * GifFile, return GIF_OK; } -#ifndef _GBA_NO_FILEIO /****************************************************************************** - * This routine reads an entire GIF into core, hanging all its state info off - * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() - * first to initialize I/O. Its inverse is EGifSpew(). - ******************************************************************************/ + This routine reads an entire GIF into core, hanging all its state info off + the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() + first to initialize I/O. Its inverse is EGifSpew(). +*******************************************************************************/ int -DGifSlurp(GifFileType * GifFile) { - - int ImageSize; +DGifSlurp(GifFileType *GifFile) +{ + size_t ImageSize; GifRecordType RecordType; SavedImage *sp; GifByteType *ExtData; - SavedImage temp_save; + int ExtFunction; - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; + GifFile->ExtensionBlocks = NULL; + GifFile->ExtensionBlockCount = 0; do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) @@ -1037,44 +1077,77 @@ DGifSlurp(GifFileType * GifFile) { return (GIF_ERROR); sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; + /* Allocate memory for the image */ + if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 && + sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) { + return GIF_ERROR; + } ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; + if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) { + return GIF_ERROR; + } sp->RasterBits = (unsigned char *)malloc(ImageSize * - sizeof(GifPixelType)); + sizeof(GifPixelType)); + if (sp->RasterBits == NULL) { return GIF_ERROR; } - if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == - GIF_ERROR) - return (GIF_ERROR); - if (temp_save.ExtensionBlocks) { - sp->ExtensionBlocks = temp_save.ExtensionBlocks; - sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; + if (sp->ImageDesc.Interlace) { + int i, j; + /* + * The way an interlaced image should be read - + * offsets and jumps... + */ + int InterlacedOffset[] = { 0, 4, 2, 1 }; + int InterlacedJumps[] = { 8, 8, 4, 2 }; + /* Need to perform 4 passes on the image */ + for (i = 0; i < 4; i++) + for (j = InterlacedOffset[i]; + j < sp->ImageDesc.Height; + j += InterlacedJumps[i]) { + if (DGifGetLine(GifFile, + sp->RasterBits+j*sp->ImageDesc.Width, + sp->ImageDesc.Width) == GIF_ERROR) + return GIF_ERROR; + } + } + else { + if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR) + return (GIF_ERROR); + } - /* FIXME: The following is wrong. It is left in only for - * backwards compatibility. Someday it should go away. Use - * the sp->ExtensionBlocks->Function variable instead. */ - sp->Function = sp->ExtensionBlocks[0].Function; + if (GifFile->ExtensionBlocks) { + sp->ExtensionBlocks = GifFile->ExtensionBlocks; + sp->ExtensionBlockCount = GifFile->ExtensionBlockCount; + + GifFile->ExtensionBlocks = NULL; + GifFile->ExtensionBlockCount = 0; } break; case EXTENSION_RECORD_TYPE: - if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) == - GIF_ERROR) + if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR) return (GIF_ERROR); + /* Create an extension block with our data */ + if (ExtData != NULL) { + if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount, + &GifFile->ExtensionBlocks, + ExtFunction, ExtData[0], &ExtData[1]) + == GIF_ERROR) + return (GIF_ERROR); + } while (ExtData != NULL) { - - /* Create an extension block with our data */ - if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) - == GIF_ERROR) - return (GIF_ERROR); - if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) return (GIF_ERROR); - temp_save.Function = 0; + /* Continue the extension block */ + if (ExtData != NULL) + if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount, + &GifFile->ExtensionBlocks, + CONTINUE_EXT_FUNC_CODE, + ExtData[0], &ExtData[1]) == GIF_ERROR) + return (GIF_ERROR); } break; @@ -1086,13 +1159,7 @@ DGifSlurp(GifFileType * GifFile) { } } while (RecordType != TERMINATE_RECORD_TYPE); - /* Just in case the Gif has an extension block without an associated - * image... (Should we save this into a savefile structure with no image - * instead? Have to check if the present writing code can handle that as - * well.... */ - if (temp_save.ExtensionBlocks) - FreeExtension(&temp_save); - return (GIF_OK); } -#endif /* _GBA_NO_FILEIO */ + +/* end */ diff --git a/third_party/giflib/lib/egif_lib.c b/third_party/giflib/lib/egif_lib.c index bfa781520..e909311eb 100644 --- a/third_party/giflib/lib/egif_lib.c +++ b/third_party/giflib/lib/egif_lib.c @@ -1,79 +1,38 @@ /****************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber Ver 1.1, Aug. 1990 - ****************************************************************************** - * The kernel of the GIF Encoding process can be found here. - ****************************************************************************** - * History: - * 14 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). - * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) - *****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif +egif_lib.c - GIF encoding -/* Find a thirty-two bit int type */ -#ifdef HAVE_SYS_TYPES_H -#include +The functions here and in dgif_lib.c are partitioned carefully so that +if you only require one of read and write capability, only one of these +two modules will be linked. Preserve this property! + +*****************************************************************************/ + +#ifdef HAVE_UNISTD_H +#include #endif -#ifdef HAVE_STDINT_H #include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif - -#ifdef __MSDOS__ -#include -#include -#include -#else -#include -#include -#ifdef R6000 - -/* FIXME: What is sys/mode.h? Can we substitute a check for this file rather - * than a check based on machine type? - */ -#include -#endif -#endif /* __MSDOS__ */ - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ #include #include #include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif /* _WIN32 */ +#include + #include "gif_lib.h" #include "gif_lib_private.h" -/* #define DEBUG_NO_PREFIX Dump only compressed data. */ - /* Masks given codes to BitsPerPixel, to make sure all codes are in range: */ -static GifPixelType CodeMask[] = { +/*@+charint@*/ +static const GifPixelType CodeMask[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -static char GifVersionPrefix[GIF_STAMP_LEN + 1] = GIF87_STAMP; - -#define WRITE(_gif,_buf,_len) \ - (((GifFilePrivateType*)_gif->Private)->Write ? \ - ((GifFilePrivateType*)_gif->Private)->Write(_gif,_buf,_len) : \ - fwrite(_buf, 1, _len, ((GifFilePrivateType*)_gif->Private)->File)) +/*@-charint@*/ static int EGifPutWord(int Word, GifFileType * GifFile); static int EGifSetupCompress(GifFileType * GifFile); @@ -83,58 +42,57 @@ static int EGifCompressOutput(GifFileType * GifFile, int Code); static int EGifBufferedOutput(GifFileType * GifFile, GifByteType * Buf, int c); +/* extract bytes from an unsigned word */ +#define LOBYTE(x) ((x) & 0xff) +#define HIBYTE(x) (((x) >> 8) & 0xff) + /****************************************************************************** - * Open a new gif file for write, given by its name. If TestExistance then - * if the file exists this routines fails (returns NULL). - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ + Open a new GIF file for write, specified by name. If TestExistance then + if the file exists this routines fails (returns NULL). + Returns a dynamically allocated GifFileType pointer which serves as the GIF + info record. The Error member is cleared if successful. +******************************************************************************/ GifFileType * -EGifOpenFileName(const char *FileName, - int TestExistance) { +EGifOpenFileName(const char *FileName, const bool TestExistence, int *Error) +{ int FileHandle; GifFileType *GifFile; - if (TestExistance) - FileHandle = open(FileName, O_WRONLY | O_CREAT | O_EXCL -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) - | O_BINARY -#endif /* __MSDOS__ */ - , S_IREAD | S_IWRITE); + if (TestExistence) + FileHandle = open(FileName, O_WRONLY | O_CREAT | O_EXCL, + S_IREAD | S_IWRITE); else - FileHandle = open(FileName, O_WRONLY | O_CREAT | O_TRUNC -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) - | O_BINARY -#endif /* __MSDOS__ */ - , S_IREAD | S_IWRITE); + FileHandle = open(FileName, O_WRONLY | O_CREAT | O_TRUNC, + S_IREAD | S_IWRITE); if (FileHandle == -1) { - _GifError = E_GIF_ERR_OPEN_FAILED; + if (Error != NULL) + *Error = E_GIF_ERR_OPEN_FAILED; return NULL; } - GifFile = EGifOpenFileHandle(FileHandle); + GifFile = EGifOpenFileHandle(FileHandle, Error); if (GifFile == (GifFileType *) NULL) - close(FileHandle); + (void)close(FileHandle); return GifFile; } /****************************************************************************** - * Update a new gif file, given its file handle, which must be opened for - * write in binary mode. - * Returns GifFileType pointer dynamically allocated which serves as the gif - * info record. _GifError is cleared if succesfull. - *****************************************************************************/ + Update a new GIF file, given its file handle, which must be opened for + write in binary mode. + Returns dynamically allocated a GifFileType pointer which serves as the GIF + info record. + Only fails on a memory allocation error. +******************************************************************************/ GifFileType * -EGifOpenFileHandle(int FileHandle) { - +EGifOpenFileHandle(const int FileHandle, int *Error) +{ GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *) malloc(sizeof(GifFileType)); if (GifFile == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } @@ -143,54 +101,51 @@ EGifOpenFileHandle(int FileHandle) { Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { free(GifFile); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } if ((Private->HashTable = _InitHashTable()) == NULL) { free(GifFile); free(Private); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY) - setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ -#endif /* __MSDOS__ */ +#ifdef _WIN32 + _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* _WIN32 */ f = fdopen(FileHandle, "wb"); /* Make it into a stream: */ -#if defined (__MSDOS__) || defined(WINDOWS32) - setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream - * buffer. */ -#endif /* __MSDOS__ */ - - GifFile->Private = (VoidPtr)Private; + GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_WRITE; Private->Write = (OutputFunc) 0; /* No user write routine (MRB) */ - GifFile->UserData = (VoidPtr) 0; /* No user write handle (MRB) */ + GifFile->UserData = (void *)NULL; /* No user write handle (MRB) */ - _GifError = 0; + GifFile->Error = 0; return GifFile; } /****************************************************************************** - * Output constructor that takes user supplied output function. - * Basically just a copy of EGifOpenFileHandle. (MRB) - *****************************************************************************/ + Output constructor that takes user supplied output function. + Basically just a copy of EGifOpenFileHandle. (MRB) +******************************************************************************/ GifFileType * -EGifOpen(void *userData, - OutputFunc writeFunc) { - +EGifOpen(void *userData, OutputFunc writeFunc, int *Error) +{ GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } @@ -199,7 +154,8 @@ EGifOpen(void *userData, Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { free(GifFile); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } @@ -207,11 +163,12 @@ EGifOpen(void *userData, if (Private->HashTable == NULL) { free (GifFile); free (Private); - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + if (Error != NULL) + *Error = E_GIF_ERR_NOT_ENOUGH_MEM; return NULL; } - GifFile->Private = (VoidPtr) Private; + GifFile->Private = (void *)Private; Private->FileHandle = 0; Private->File = (FILE *) 0; Private->FileState = FILE_STATE_WRITE; @@ -219,66 +176,128 @@ EGifOpen(void *userData, Private->Write = writeFunc; /* User write routine (MRB) */ GifFile->UserData = userData; /* User write handle (MRB) */ - _GifError = 0; + Private->gif89 = false; /* initially, write GIF87 */ + + GifFile->Error = 0; return GifFile; } /****************************************************************************** - * Routine to set current GIF version. All files open for write will be - * using this version until next call to this routine. Version consists of - * 3 characters as "87a" or "89a". No test is made to validate the version. - *****************************************************************************/ -void -EGifSetGifVersion(const char *Version) { - strncpy(GifVersionPrefix + GIF_VERSION_POS, Version, 3); + Routine to compute the GIF version that will be written on output. +******************************************************************************/ +const char * +EGifGetGifVersion(GifFileType *GifFile) +{ + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + int i, j; + + /* + * Bulletproofing - always write GIF89 if we need to. + * Note, we don't clear the gif89 flag here because + * users of the sequential API might have called EGifSetGifVersion() + * in order to set that flag. + */ + for (i = 0; i < GifFile->ImageCount; i++) { + for (j = 0; j < GifFile->SavedImages[i].ExtensionBlockCount; j++) { + int function = + GifFile->SavedImages[i].ExtensionBlocks[j].Function; + + if (function == COMMENT_EXT_FUNC_CODE + || function == GRAPHICS_EXT_FUNC_CODE + || function == PLAINTEXT_EXT_FUNC_CODE + || function == APPLICATION_EXT_FUNC_CODE) + Private->gif89 = true; + } + } + for (i = 0; i < GifFile->ExtensionBlockCount; i++) { + int function = GifFile->ExtensionBlocks[i].Function; + + if (function == COMMENT_EXT_FUNC_CODE + || function == GRAPHICS_EXT_FUNC_CODE + || function == PLAINTEXT_EXT_FUNC_CODE + || function == APPLICATION_EXT_FUNC_CODE) + Private->gif89 = true; + } + + if (Private->gif89) + return GIF89_STAMP; + else + return GIF87_STAMP; } /****************************************************************************** - * This routine should be called before any other EGif calls, immediately - * follows the GIF file openning. - *****************************************************************************/ -int -EGifPutScreenDesc(GifFileType * GifFile, - int Width, - int Height, - int ColorRes, - int BackGround, - const ColorMapObject * ColorMap) { + Set the GIF version. In the extremely unlikely event that there is ever + another version, replace the bool argument with an enum in which the + GIF87 value is 0 (numerically the same as bool false) and the GIF89 value + is 1 (numerically the same as bool true). That way we'll even preserve + object-file compatibility! +******************************************************************************/ +void EGifSetGifVersion(GifFileType *GifFile, const bool gif89) +{ + GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; - int i; + Private->gif89 = gif89; +} + +/****************************************************************************** + All writes to the GIF should go through this. +******************************************************************************/ +static int InternalWrite(GifFileType *GifFileOut, + const unsigned char *buf, size_t len) +{ + GifFilePrivateType *Private = (GifFilePrivateType*)GifFileOut->Private; + if (Private->Write) + return Private->Write(GifFileOut,buf,len); + else + return fwrite(buf, 1, len, Private->File); +} + +/****************************************************************************** + This routine should be called before any other EGif calls, immediately + following the GIF file opening. +******************************************************************************/ +int +EGifPutScreenDesc(GifFileType *GifFile, + const int Width, + const int Height, + const int ColorRes, + const int BackGround, + const ColorMapObject *ColorMap) +{ GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; + const char *write_version; if (Private->FileState & FILE_STATE_SCREEN) { /* If already has screen descriptor - something is wrong! */ - _GifError = E_GIF_ERR_HAS_SCRN_DSCR; + GifFile->Error = E_GIF_ERR_HAS_SCRN_DSCR; return GIF_ERROR; } if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } -/* First write the version prefix into the file. */ -#ifndef DEBUG_NO_PREFIX - if (WRITE(GifFile, (unsigned char *)GifVersionPrefix, - strlen(GifVersionPrefix)) != strlen(GifVersionPrefix)) { - _GifError = E_GIF_ERR_WRITE_FAILED; + write_version = EGifGetGifVersion(GifFile); + + /* First write the version prefix into the file. */ + if (InternalWrite(GifFile, (unsigned char *)write_version, + strlen(write_version)) != strlen(write_version)) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } -#endif /* DEBUG_NO_PREFIX */ GifFile->SWidth = Width; GifFile->SHeight = Height; GifFile->SColorResolution = ColorRes; GifFile->SBackGroundColor = BackGround; if (ColorMap) { - GifFile->SColorMap = MakeMapObject(ColorMap->ColorCount, + GifFile->SColorMap = GifMakeMapObject(ColorMap->ColorCount, ColorMap->Colors); if (GifFile->SColorMap == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else @@ -288,8 +307,8 @@ EGifPutScreenDesc(GifFileType * GifFile, * Put the logical screen descriptor into the file: */ /* Logical Screen Descriptor: Dimensions */ - EGifPutWord(Width, GifFile); - EGifPutWord(Height, GifFile); + (void)EGifPutWord(Width, GifFile); + (void)EGifPutWord(Height, GifFile); /* Logical Screen Descriptor: Packed Fields */ /* Note: We have actual size of the color table default to the largest @@ -300,26 +319,26 @@ EGifPutScreenDesc(GifFileType * GifFile, ((ColorRes - 1) << 4) | /* Bits allocated to each primary color */ (ColorMap ? ColorMap->BitsPerPixel - 1 : 0x07 ); /* Actual size of the color table. */ + if (ColorMap != NULL && ColorMap->SortFlag) + Buf[0] |= 0x08; Buf[1] = BackGround; /* Index into the ColorTable for background color */ - Buf[2] = 0; /* Pixel Aspect Ratio */ -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 3); -#endif /* DEBUG_NO_PREFIX */ + Buf[2] = GifFile->AspectByte; /* Pixel Aspect Ratio */ + InternalWrite(GifFile, Buf, 3); /* If we have Global color map - dump it also: */ -#ifndef DEBUG_NO_PREFIX - if (ColorMap != NULL) + if (ColorMap != NULL) { + int i; for (i = 0; i < ColorMap->ColorCount; i++) { /* Put the ColorMap out also: */ Buf[0] = ColorMap->Colors[i].Red; Buf[1] = ColorMap->Colors[i].Green; Buf[2] = ColorMap->Colors[i].Blue; - if (WRITE(GifFile, Buf, 3) != 3) { - _GifError = E_GIF_ERR_WRITE_FAILED; + if (InternalWrite(GifFile, Buf, 3) != 3) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } -#endif /* DEBUG_NO_PREFIX */ + } /* Mark this file as has screen descriptor, and no pixel written yet: */ Private->FileState |= FILE_STATE_SCREEN; @@ -328,35 +347,30 @@ EGifPutScreenDesc(GifFileType * GifFile, } /****************************************************************************** - * This routine should be called before any attempt to dump an image - any - * call to any of the pixel dump routines. - *****************************************************************************/ + This routine should be called before any attempt to dump an image - any + call to any of the pixel dump routines. +******************************************************************************/ int -EGifPutImageDesc(GifFileType * GifFile, - int Left, - int Top, - int Width, - int Height, - int Interlace, - const ColorMapObject * ColorMap) { - - int i; +EGifPutImageDesc(GifFileType *GifFile, + const int Left, + const int Top, + const int Width, + const int Height, + const bool Interlace, + const ColorMapObject *ColorMap) +{ GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (Private->FileState & FILE_STATE_IMAGE && -#if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__) Private->PixelCount > 0xffff0000UL) { -#else - Private->PixelCount > 0xffff0000) { -#endif /* __MSDOS__ */ /* If already has active image descriptor - something is wrong! */ - _GifError = E_GIF_ERR_HAS_IMAG_DSCR; + GifFile->Error = E_GIF_ERR_HAS_IMAG_DSCR; return GIF_ERROR; } if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } GifFile->Image.Left = Left; @@ -365,10 +379,14 @@ EGifPutImageDesc(GifFileType * GifFile, GifFile->Image.Height = Height; GifFile->Image.Interlace = Interlace; if (ColorMap) { - GifFile->Image.ColorMap = MakeMapObject(ColorMap->ColorCount, + if (GifFile->Image.ColorMap != NULL) { + GifFreeMapObject(GifFile->Image.ColorMap); + GifFile->Image.ColorMap = NULL; + } + GifFile->Image.ColorMap = GifMakeMapObject(ColorMap->ColorCount, ColorMap->Colors); if (GifFile->Image.ColorMap == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else { @@ -376,37 +394,33 @@ EGifPutImageDesc(GifFileType * GifFile, } /* Put the image descriptor into the file: */ - Buf[0] = ','; /* Image seperator character. */ -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 1); -#endif /* DEBUG_NO_PREFIX */ - EGifPutWord(Left, GifFile); - EGifPutWord(Top, GifFile); - EGifPutWord(Width, GifFile); - EGifPutWord(Height, GifFile); + Buf[0] = DESCRIPTOR_INTRODUCER; /* Image separator character. */ + InternalWrite(GifFile, Buf, 1); + (void)EGifPutWord(Left, GifFile); + (void)EGifPutWord(Top, GifFile); + (void)EGifPutWord(Width, GifFile); + (void)EGifPutWord(Height, GifFile); Buf[0] = (ColorMap ? 0x80 : 0x00) | (Interlace ? 0x40 : 0x00) | (ColorMap ? ColorMap->BitsPerPixel - 1 : 0); -#ifndef DEBUG_NO_PREFIX - WRITE(GifFile, Buf, 1); -#endif /* DEBUG_NO_PREFIX */ + InternalWrite(GifFile, Buf, 1); /* If we have Global color map - dump it also: */ -#ifndef DEBUG_NO_PREFIX - if (ColorMap != NULL) + if (ColorMap != NULL) { + int i; for (i = 0; i < ColorMap->ColorCount; i++) { /* Put the ColorMap out also: */ Buf[0] = ColorMap->Colors[i].Red; Buf[1] = ColorMap->Colors[i].Green; Buf[2] = ColorMap->Colors[i].Blue; - if (WRITE(GifFile, Buf, 3) != 3) { - _GifError = E_GIF_ERR_WRITE_FAILED; + if (InternalWrite(GifFile, Buf, 3) != 3) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } -#endif /* DEBUG_NO_PREFIX */ + } if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) { - _GifError = E_GIF_ERR_NO_COLOR_MAP; + GifFile->Error = E_GIF_ERR_NO_COLOR_MAP; return GIF_ERROR; } @@ -414,33 +428,32 @@ EGifPutImageDesc(GifFileType * GifFile, Private->FileState |= FILE_STATE_IMAGE; Private->PixelCount = (long)Width *(long)Height; - EGifSetupCompress(GifFile); /* Reset compress algorithm parameters. */ + /* Reset compress algorithm parameters. */ + (void)EGifSetupCompress(GifFile); return GIF_OK; } /****************************************************************************** - * Put one full scanned line (Line) of length LineLen into GIF file. - *****************************************************************************/ + Put one full scanned line (Line) of length LineLen into GIF file. +******************************************************************************/ int -EGifPutLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - +EGifPutLine(GifFileType * GifFile, GifPixelType *Line, int LineLen) +{ int i; GifPixelType Mask; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (!LineLen) LineLen = GifFile->Image.Width; if (Private->PixelCount < (unsigned)LineLen) { - _GifError = E_GIF_ERR_DATA_TOO_BIG; + GifFile->Error = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } Private->PixelCount -= LineLen; @@ -455,22 +468,21 @@ EGifPutLine(GifFileType * GifFile, } /****************************************************************************** - * Put one pixel (Pixel) into GIF file. - *****************************************************************************/ + Put one pixel (Pixel) into GIF file. +******************************************************************************/ int -EGifPutPixel(GifFileType * GifFile, - GifPixelType Pixel) { - +EGifPutPixel(GifFileType *GifFile, GifPixelType Pixel) +{ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (Private->PixelCount == 0) { - _GifError = E_GIF_ERR_DATA_TOO_BIG; + GifFile->Error = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } --Private->PixelCount; @@ -483,13 +495,12 @@ EGifPutPixel(GifFileType * GifFile, } /****************************************************************************** - * Put a comment into GIF file using the GIF89 comment extension block. - *****************************************************************************/ + Put a comment into GIF file using the GIF89 comment extension block. +******************************************************************************/ int -EGifPutComment(GifFileType * GifFile, - const char *Comment) { - - unsigned int length = strlen(Comment); +EGifPutComment(GifFileType *GifFile, const char *Comment) +{ + unsigned int length; char *buf; length = strlen(Comment); @@ -498,16 +509,14 @@ EGifPutComment(GifFileType * GifFile, length, Comment); } else { buf = (char *)Comment; - if (EGifPutExtensionFirst(GifFile, COMMENT_EXT_FUNC_CODE, 255, buf) + if (EGifPutExtensionLeader(GifFile, COMMENT_EXT_FUNC_CODE) == GIF_ERROR) { return GIF_ERROR; } - length -= 255; - buf = buf + 255; /* Break the comment into 255 byte sub blocks */ while (length > 255) { - if (EGifPutExtensionNext(GifFile, 0, 255, buf) == GIF_ERROR) { + if (EGifPutExtensionBlock(GifFile, 255, buf) == GIF_ERROR) { return GIF_ERROR; } buf = buf + 255; @@ -515,170 +524,196 @@ EGifPutComment(GifFileType * GifFile, } /* Output any partial block and the clear code. */ if (length > 0) { - if (EGifPutExtensionLast(GifFile, 0, length, buf) == GIF_ERROR) { - return GIF_ERROR; - } - } else { - if (EGifPutExtensionLast(GifFile, 0, 0, NULL) == GIF_ERROR) { + if (EGifPutExtensionBlock(GifFile, length, buf) == GIF_ERROR) { return GIF_ERROR; } } + if (EGifPutExtensionTrailer(GifFile) == GIF_ERROR) { + return GIF_ERROR; + } } return GIF_OK; } /****************************************************************************** - * Put a first extension block (see GIF manual) into gif file. Here more - * extensions can be dumped using EGifPutExtensionNext until - * EGifPutExtensionLast is invoked. - *****************************************************************************/ + Begin an extension block (see GIF manual). More + extensions can be dumped using EGifPutExtensionBlock until + EGifPutExtensionTrailer is invoked. +******************************************************************************/ int -EGifPutExtensionFirst(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - +EGifPutExtensionLeader(GifFileType *GifFile, const int ExtCode) +{ GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } - if (ExtCode == 0) { - WRITE(GifFile, (GifByteType *)&ExtLen, 1); - } else { - Buf[0] = '!'; - Buf[1] = ExtCode; - Buf[2] = ExtLen; - WRITE(GifFile, Buf, 3); - } - - WRITE(GifFile, Extension, ExtLen); + Buf[0] = EXTENSION_INTRODUCER; + Buf[1] = ExtCode; + InternalWrite(GifFile, Buf, 2); return GIF_OK; } /****************************************************************************** - * Put a middle extension block (see GIF manual) into gif file. - *****************************************************************************/ + Put extension block data (see GIF manual) into a GIF file. +******************************************************************************/ int -EGifPutExtensionNext(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { - +EGifPutExtensionBlock(GifFileType *GifFile, + const int ExtLen, + const void *Extension) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } Buf = ExtLen; - WRITE(GifFile, &Buf, 1); - WRITE(GifFile, Extension, ExtLen); + InternalWrite(GifFile, &Buf, 1); + InternalWrite(GifFile, Extension, ExtLen); return GIF_OK; } /****************************************************************************** - * Put a last extension block (see GIF manual) into gif file. - *****************************************************************************/ + Put a terminating block (see GIF manual) into a GIF file. +******************************************************************************/ int -EGifPutExtensionLast(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { +EGifPutExtensionTrailer(GifFileType *GifFile) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } - /* If we are given an extension sub-block output it now. */ - if (ExtLen > 0) { - Buf = ExtLen; - WRITE(GifFile, &Buf, 1); - WRITE(GifFile, Extension, ExtLen); - } - /* Write the block terminator */ Buf = 0; - WRITE(GifFile, &Buf, 1); + InternalWrite(GifFile, &Buf, 1); return GIF_OK; } /****************************************************************************** - * Put an extension block (see GIF manual) into gif file. - * Warning: This function is only useful for Extension blocks that have at - * most one subblock. Extensions with more than one subblock need to use the - * EGifPutExtension{First,Next,Last} functions instead. - *****************************************************************************/ + Put an extension block (see GIF manual) into a GIF file. + Warning: This function is only useful for Extension blocks that have at + most one subblock. Extensions with more than one subblock need to use the + EGifPutExtension{Leader,Block,Trailer} functions instead. +******************************************************************************/ int -EGifPutExtension(GifFileType * GifFile, - int ExtCode, - int ExtLen, - const VoidPtr Extension) { +EGifPutExtension(GifFileType *GifFile, + const int ExtCode, + const int ExtLen, + const void *Extension) { GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (ExtCode == 0) - WRITE(GifFile, (GifByteType *)&ExtLen, 1); + InternalWrite(GifFile, (GifByteType *)&ExtLen, 1); else { - Buf[0] = '!'; /* Extension Introducer 0x21 */ + Buf[0] = EXTENSION_INTRODUCER; Buf[1] = ExtCode; /* Extension Label */ Buf[2] = ExtLen; /* Extension length */ - WRITE(GifFile, Buf, 3); + InternalWrite(GifFile, Buf, 3); } - WRITE(GifFile, Extension, ExtLen); + InternalWrite(GifFile, Extension, ExtLen); Buf[0] = 0; - WRITE(GifFile, Buf, 1); + InternalWrite(GifFile, Buf, 1); return GIF_OK; } /****************************************************************************** - * Put the image code in compressed form. This routine can be called if the - * information needed to be piped out as is. Obviously this is much faster - * than decoding and encoding again. This routine should be followed by calls - * to EGifPutCodeNext, until NULL block is given. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -int -EGifPutCode(GifFileType * GifFile, - int CodeSize, - const GifByteType * CodeBlock) { + Render a Graphics Control Block as raw extension data +******************************************************************************/ +size_t EGifGCBToExtension(const GraphicsControlBlock *GCB, + GifByteType *GifExtension) +{ + GifExtension[0] = 0; + GifExtension[0] |= (GCB->TransparentColor == NO_TRANSPARENT_COLOR) ? 0x00 : 0x01; + GifExtension[0] |= GCB->UserInputFlag ? 0x02 : 0x00; + GifExtension[0] |= ((GCB->DisposalMode & 0x07) << 2); + GifExtension[1] = LOBYTE(GCB->DelayTime); + GifExtension[2] = HIBYTE(GCB->DelayTime); + GifExtension[3] = (char)GCB->TransparentColor; + return 4; +} + +/****************************************************************************** + Replace the Graphics Control Block for a saved image, if it exists. +******************************************************************************/ + +int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, + GifFileType *GifFile, int ImageIndex) +{ + int i; + size_t Len; + GifByteType buf[sizeof(GraphicsControlBlock)]; /* a bit dodgy... */ + + if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) + return GIF_ERROR; + + for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) { + ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i]; + if (ep->Function == GRAPHICS_EXT_FUNC_CODE) { + EGifGCBToExtension(GCB, ep->Bytes); + return GIF_OK; + } + } + + Len = EGifGCBToExtension(GCB, (GifByteType *)buf); + if (GifAddExtensionBlock(&GifFile->SavedImages[ImageIndex].ExtensionBlockCount, + &GifFile->SavedImages[ImageIndex].ExtensionBlocks, + GRAPHICS_EXT_FUNC_CODE, + Len, + (unsigned char *)buf) == GIF_ERROR) + return (GIF_ERROR); + + return (GIF_OK); +} + +/****************************************************************************** + Put the image code in compressed form. This routine can be called if the + information needed to be piped out as is. Obviously this is much faster + than decoding and encoding again. This routine should be followed by calls + to EGifPutCodeNext, until NULL block is given. + The block should NOT be freed by the user (not dynamically allocated). +******************************************************************************/ +int +EGifPutCode(GifFileType *GifFile, int CodeSize, const GifByteType *CodeBlock) +{ GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } /* No need to dump code size as Compression set up does any for us: */ - /* + /* * Buf = CodeSize; - * if (WRITE(GifFile, &Buf, 1) != 1) { - * _GifError = E_GIF_ERR_WRITE_FAILED; + * if (InternalWrite(GifFile, &Buf, 1) != 1) { + * GifFile->Error = E_GIF_ERR_WRITE_FAILED; * return GIF_ERROR; * } */ @@ -687,27 +722,26 @@ EGifPutCode(GifFileType * GifFile, } /****************************************************************************** - * Continue to put the image code in compressed form. This routine should be - * called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If - * given buffer pointer is NULL, empty block is written to mark end of code. - *****************************************************************************/ + Continue to put the image code in compressed form. This routine should be + called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If + given buffer pointer is NULL, empty block is written to mark end of code. +******************************************************************************/ int -EGifPutCodeNext(GifFileType * GifFile, - const GifByteType * CodeBlock) { - +EGifPutCodeNext(GifFileType *GifFile, const GifByteType *CodeBlock) +{ GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (CodeBlock != NULL) { - if (WRITE(GifFile, CodeBlock, CodeBlock[0] + 1) + if (InternalWrite(GifFile, CodeBlock, CodeBlock[0] + 1) != (unsigned)(CodeBlock[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } else { Buf = 0; - if (WRITE(GifFile, &Buf, 1) != 1) { - _GifError = E_GIF_ERR_WRITE_FAILED; + if (InternalWrite(GifFile, &Buf, 1) != 1) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } Private->PixelCount = 0; /* And local info. indicate image read. */ @@ -717,11 +751,11 @@ EGifPutCodeNext(GifFileType * GifFile, } /****************************************************************************** - * This routine should be called last, to close GIF file. - *****************************************************************************/ + This routine should be called last, to close the GIF file. +******************************************************************************/ int -EGifCloseFile(GifFileType * GifFile) { - +EGifCloseFile(GifFileType *GifFile, int *ErrorCode) +{ GifByteType Buf; GifFilePrivateType *Private; FILE *File; @@ -730,67 +764,71 @@ EGifCloseFile(GifFileType * GifFile) { return GIF_ERROR; Private = (GifFilePrivateType *) GifFile->Private; + if (Private == NULL) + return GIF_ERROR; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ - _GifError = E_GIF_ERR_NOT_WRITEABLE; + if (ErrorCode != NULL) + *ErrorCode = E_GIF_ERR_NOT_WRITEABLE; + free(GifFile); return GIF_ERROR; } File = Private->File; - Buf = ';'; - WRITE(GifFile, &Buf, 1); + Buf = TERMINATOR_INTRODUCER; + InternalWrite(GifFile, &Buf, 1); if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); + GifFreeMapObject(GifFile->Image.ColorMap); GifFile->Image.ColorMap = NULL; } if (GifFile->SColorMap) { - FreeMapObject(GifFile->SColorMap); + GifFreeMapObject(GifFile->SColorMap); GifFile->SColorMap = NULL; } if (Private) { if (Private->HashTable) { free((char *) Private->HashTable); } - free((char *) Private); + free((char *) Private); } - free(GifFile); if (File && fclose(File) != 0) { - _GifError = E_GIF_ERR_CLOSE_FAILED; + if (ErrorCode != NULL) + *ErrorCode = E_GIF_ERR_CLOSE_FAILED; + free(GifFile); return GIF_ERROR; } + + free(GifFile); + if (ErrorCode != NULL) + *ErrorCode = E_GIF_SUCCEEDED; return GIF_OK; } /****************************************************************************** - * Put 2 bytes (word) into the given file: - *****************************************************************************/ + Put 2 bytes (a word) into the given file in little-endian order: +******************************************************************************/ static int -EGifPutWord(int Word, - GifFileType * GifFile) { - +EGifPutWord(int Word, GifFileType *GifFile) +{ unsigned char c[2]; - c[0] = Word & 0xff; - c[1] = (Word >> 8) & 0xff; -#ifndef DEBUG_NO_PREFIX - if (WRITE(GifFile, c, 2) == 2) + c[0] = LOBYTE(Word); + c[1] = HIBYTE(Word); + if (InternalWrite(GifFile, c, 2) == 2) return GIF_OK; else return GIF_ERROR; -#else - return GIF_OK; -#endif /* DEBUG_NO_PREFIX */ } /****************************************************************************** - * Setup the LZ compression for this image: - *****************************************************************************/ + Setup the LZ compression for this image: +******************************************************************************/ static int -EGifSetupCompress(GifFileType * GifFile) { - +EGifSetupCompress(GifFileType *GifFile) +{ int BitsPerPixel; GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; @@ -801,12 +839,12 @@ EGifSetupCompress(GifFileType * GifFile) { else if (GifFile->SColorMap) BitsPerPixel = GifFile->SColorMap->BitsPerPixel; else { - _GifError = E_GIF_ERR_NO_COLOR_MAP; + GifFile->Error = E_GIF_ERR_NO_COLOR_MAP; return GIF_ERROR; } Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel); - WRITE(GifFile, &Buf, 1); /* Write the Code size to file. */ + InternalWrite(GifFile, &Buf, 1); /* Write the Code size to file. */ Private->Buf[0] = 0; /* Nothing was output yet. */ Private->BitsPerPixel = BitsPerPixel; @@ -823,23 +861,23 @@ EGifSetupCompress(GifFileType * GifFile) { _ClearHashTable(Private->HashTable); if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } return GIF_OK; } /****************************************************************************** - * The LZ compression routine: - * This version compresses the given buffer Line of length LineLen. - * This routine can be called a few times (one per scan line, for example), in - * order to complete the whole image. + The LZ compression routine: + This version compresses the given buffer Line of length LineLen. + This routine can be called a few times (one per scan line, for example), in + order to complete the whole image. ******************************************************************************/ static int -EGifCompressLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - +EGifCompressLine(GifFileType *GifFile, + GifPixelType *Line, + const int LineLen) +{ int i = 0, CrntCode, NewCode; unsigned long NewKey; GifPixelType Pixel; @@ -855,10 +893,10 @@ EGifCompressLine(GifFileType * GifFile, while (i < LineLen) { /* Decode LineLen items. */ Pixel = Line[i++]; /* Get next pixel from stream. */ - /* Form a new unique key to search hash table for the code combines + /* Form a new unique key to search hash table for the code combines * CrntCode as Prefix string with Pixel as postfix char. */ - NewKey = (((UINT32) CrntCode) << 8) + Pixel; + NewKey = (((uint32_t) CrntCode) << 8) + Pixel; if ((NewCode = _ExistsHashTable(HashTable, NewKey)) >= 0) { /* This Key is already there, or the string is old one, so * simple take new code as our CrntCode: @@ -869,7 +907,7 @@ EGifCompressLine(GifFileType * GifFile, * CrntCode equal to Pixel. */ if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } CrntCode = Pixel; @@ -881,7 +919,7 @@ EGifCompressLine(GifFileType * GifFile, /* Time to do some clearance: */ if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } Private->RunningCode = Private->EOFCode + 1; @@ -902,15 +940,15 @@ EGifCompressLine(GifFileType * GifFile, if (Private->PixelCount == 0) { /* We are done - output last Code and flush output buffers: */ if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) { - _GifError = E_GIF_ERR_DISK_IS_FULL; + GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } } @@ -919,15 +957,15 @@ EGifCompressLine(GifFileType * GifFile, } /****************************************************************************** - * The LZ compression output routine: - * This routine is responsible for the compression of the bit stream into - * 8 bits (bytes) packets. - * Returns GIF_OK if written succesfully. - *****************************************************************************/ + The LZ compression output routine: + This routine is responsible for the compression of the bit stream into + 8 bits (bytes) packets. + Returns GIF_OK if written successfully. +******************************************************************************/ static int -EGifCompressOutput(GifFileType * GifFile, - int Code) { - +EGifCompressOutput(GifFileType *GifFile, + const int Code) +{ GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; int retval = GIF_OK; @@ -967,34 +1005,34 @@ EGifCompressOutput(GifFileType * GifFile, } /****************************************************************************** - * This routines buffers the given characters until 255 characters are ready - * to be output. If Code is equal to -1 the buffer is flushed (EOF). - * The buffer is Dumped with first byte as its size, as GIF format requires. - * Returns GIF_OK if written succesfully. - *****************************************************************************/ + This routines buffers the given characters until 255 characters are ready + to be output. If Code is equal to -1 the buffer is flushed (EOF). + The buffer is Dumped with first byte as its size, as GIF format requires. + Returns GIF_OK if written successfully. +******************************************************************************/ static int -EGifBufferedOutput(GifFileType * GifFile, - GifByteType * Buf, - int c) { - +EGifBufferedOutput(GifFileType *GifFile, + GifByteType *Buf, + int c) +{ if (c == FLUSH_OUTPUT) { /* Flush everything out. */ if (Buf[0] != 0 - && WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; + && InternalWrite(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } /* Mark end of compressed data, by an empty block (see GIF doc): */ Buf[0] = 0; - if (WRITE(GifFile, Buf, 1) != 1) { - _GifError = E_GIF_ERR_WRITE_FAILED; + if (InternalWrite(GifFile, Buf, 1) != 1) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } else { if (Buf[0] == 255) { /* Dump out this buffer - it is full: */ - if (WRITE(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { - _GifError = E_GIF_ERR_WRITE_FAILED; + if (InternalWrite(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { + GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } Buf[0] = 0; @@ -1006,86 +1044,62 @@ EGifBufferedOutput(GifFileType * GifFile, } /****************************************************************************** - * This routine writes to disk an in-core representation of a GIF previously - * created by DGifSlurp(). - *****************************************************************************/ + This routine writes to disk an in-core representation of a GIF previously + created by DGifSlurp(). +******************************************************************************/ + +static int +EGifWriteExtensions(GifFileType *GifFileOut, + ExtensionBlock *ExtensionBlocks, + int ExtensionBlockCount) +{ + if (ExtensionBlocks) { + ExtensionBlock *ep; + int j; + + for (j = 0; j < ExtensionBlockCount; j++) { + ep = &ExtensionBlocks[j]; + if (ep->Function != CONTINUE_EXT_FUNC_CODE) + if (EGifPutExtensionLeader(GifFileOut, ep->Function) == GIF_ERROR) + return (GIF_ERROR); + if (EGifPutExtensionBlock(GifFileOut, ep->ByteCount, ep->Bytes) == GIF_ERROR) + return (GIF_ERROR); + if (j == ExtensionBlockCount - 1 || (ep+1)->Function != CONTINUE_EXT_FUNC_CODE) + if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR) + return (GIF_ERROR); + } + } + + return (GIF_OK); +} + int -EGifSpew(GifFileType * GifFileOut) { +EGifSpew(GifFileType *GifFileOut) +{ + int i, j; - int i, j, gif89 = FALSE; - int bOff; /* Block Offset for adding sub blocks in Extensions */ - char SavedStamp[GIF_STAMP_LEN + 1]; - - for (i = 0; i < GifFileOut->ImageCount; i++) { - for (j = 0; j < GifFileOut->SavedImages[i].ExtensionBlockCount; j++) { - int function = - GifFileOut->SavedImages[i].ExtensionBlocks[j].Function; - - if (function == COMMENT_EXT_FUNC_CODE - || function == GRAPHICS_EXT_FUNC_CODE - || function == PLAINTEXT_EXT_FUNC_CODE - || function == APPLICATION_EXT_FUNC_CODE) - gif89 = TRUE; - } - } - - strncpy(SavedStamp, GifVersionPrefix, GIF_STAMP_LEN); - if (gif89) { - strncpy(GifVersionPrefix, GIF89_STAMP, GIF_STAMP_LEN); - } else { - strncpy(GifVersionPrefix, GIF87_STAMP, GIF_STAMP_LEN); - } if (EGifPutScreenDesc(GifFileOut, GifFileOut->SWidth, GifFileOut->SHeight, GifFileOut->SColorResolution, GifFileOut->SBackGroundColor, GifFileOut->SColorMap) == GIF_ERROR) { - strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); return (GIF_ERROR); } - strncpy(GifVersionPrefix, SavedStamp, GIF_STAMP_LEN); for (i = 0; i < GifFileOut->ImageCount; i++) { SavedImage *sp = &GifFileOut->SavedImages[i]; int SavedHeight = sp->ImageDesc.Height; int SavedWidth = sp->ImageDesc.Width; - ExtensionBlock *ep; /* this allows us to delete images by nuking their rasters */ if (sp->RasterBits == NULL) continue; - if (sp->ExtensionBlocks) { - for (j = 0; j < sp->ExtensionBlockCount; j++) { - ep = &sp->ExtensionBlocks[j]; - if (j == sp->ExtensionBlockCount - 1 || (ep+1)->Function != 0) { - /*** FIXME: Must check whether outputting - * is ever valid or if we should just - * drop anything with a 0 for the Function. (And whether - * we should drop here or in EGifPutExtension) - */ - if (EGifPutExtension(GifFileOut, - (ep->Function != 0) ? ep->Function : '\0', - ep->ByteCount, - ep->Bytes) == GIF_ERROR) { - return (GIF_ERROR); - } - } else { - EGifPutExtensionFirst(GifFileOut, ep->Function, ep->ByteCount, ep->Bytes); - for (bOff = j+1; bOff < sp->ExtensionBlockCount; bOff++) { - ep = &sp->ExtensionBlocks[bOff]; - if (ep->Function != 0) { - break; - } - EGifPutExtensionNext(GifFileOut, 0, - ep->ByteCount, ep->Bytes); - } - EGifPutExtensionLast(GifFileOut, 0, 0, NULL); - j = bOff-1; - } - } - } + if (EGifWriteExtensions(GifFileOut, + sp->ExtensionBlocks, + sp->ExtensionBlockCount) == GIF_ERROR) + return (GIF_ERROR); if (EGifPutImageDesc(GifFileOut, sp->ImageDesc.Left, @@ -1096,16 +1110,43 @@ EGifSpew(GifFileType * GifFileOut) { sp->ImageDesc.ColorMap) == GIF_ERROR) return (GIF_ERROR); - for (j = 0; j < SavedHeight; j++) { - if (EGifPutLine(GifFileOut, - sp->RasterBits + j * SavedWidth, - SavedWidth) == GIF_ERROR) - return (GIF_ERROR); - } + if (sp->ImageDesc.Interlace) { + /* + * The way an interlaced image should be written - + * offsets and jumps... + */ + int InterlacedOffset[] = { 0, 4, 2, 1 }; + int InterlacedJumps[] = { 8, 8, 4, 2 }; + int k; + /* Need to perform 4 passes on the images: */ + for (k = 0; k < 4; k++) + for (j = InterlacedOffset[k]; + j < SavedHeight; + j += InterlacedJumps[k]) { + if (EGifPutLine(GifFileOut, + sp->RasterBits + j * SavedWidth, + SavedWidth) == GIF_ERROR) + return (GIF_ERROR); + } + } else { + for (j = 0; j < SavedHeight; j++) { + if (EGifPutLine(GifFileOut, + sp->RasterBits + j * SavedWidth, + SavedWidth) == GIF_ERROR) + return (GIF_ERROR); + } + } } - if (EGifCloseFile(GifFileOut) == GIF_ERROR) + if (EGifWriteExtensions(GifFileOut, + GifFileOut->ExtensionBlocks, + GifFileOut->ExtensionBlockCount) == GIF_ERROR) + return (GIF_ERROR); + + if (EGifCloseFile(GifFileOut, NULL) == GIF_ERROR) return (GIF_ERROR); return (GIF_OK); } + +/* end */ diff --git a/third_party/giflib/lib/getarg.c b/third_party/giflib/lib/getarg.c deleted file mode 100644 index a85f6b068..000000000 --- a/third_party/giflib/lib/getarg.c +++ /dev/null @@ -1,697 +0,0 @@ -/*************************************************************************** - * Routines to grab the parameters from the command line: - * All the routines except the main one, starts with GA (Get Arguments) to - * prevent from names conflicts. - * It is assumed in these routine that any pointer, for any type has the - * same length (i.e. length of int pointer is equal to char pointer etc.) - * - * The following routines are available in this module: - * 1. int GAGetArgs(argc, argv, CtrlStr, Variables...) - * where argc, argv as received on entry. - * CtrlStr is the contrl string (see below) - * Variables are all the variables to be set according to CtrlStr. - * Note that all the variables MUST be transfered by address. - * return 0 on correct parsing, otherwise error number (see GetArg.h). - * 2. GAPrintHowTo(CtrlStr) - * Print the control string to stderr, in the correct format needed. - * This feature is very useful in case of error during GetArgs parsing. - * Chars equal to SPACE_CHAR are not printed (regular spaces are NOT - * allowed, and so using SPACE_CHAR you can create space in PrintHowTo). - * 3. GAPrintErrMsg(Error) - * Print the error to stderr, according to Error (usually returned by - * GAGetArgs). - * - * CtrlStr format: - * The control string passed to GetArgs controls the way argv (argc) are - * parsed. Each entry in this string must not have any spaces in it. The - * First Entry is the name of the program which is usually ignored except - * when GAPrintHowTo is called. All the other entries (except the last one - * which we will come back to it later) must have the following format: - * 1. One letter which sets the option letter. - * 2. '!' or '%' to determines if this option is really optional ('%') or - * it must exists ('!')... - * 3. '-' allways. - * 4. Alpha numeric string, usually ignored, but used by GAPrintHowTo to - * print the meaning of this input. - * 5. Sequences starts with '!' or '%'. Again if '!' then this sequence - * must exists (only if its option flag is given of course), and if '%' - * it is optional. Each sequence will continue with one or two - * characters which defines the kind of the input: - * a. d, x, o, u - integer is expected (decimal, hex, octal base or - * unsigned). - * b. D, X, O, U - long integer is expected (same as above). - * c. f - float number is expected. - * d. F - double number is expected. - * e. s - string is expected. - * f. *? - any number of '?' kind (d, x, o, u, D, X, O, U, f, F, s) - * will match this one. If '?' is numeric, it scans until - * none numeric input is given. If '?' is 's' then it scans - * up to the next option or end of argv. - * - * If the last parameter given in the CtrlStr, is not an option (i.e. the - * second char is not in ['!', '%'] and the third one is not '-'), all what - * remained from argv is linked to it. - * - * The variables passed to GAGetArgs (starting from 4th parameter) MUST - * match the order of the CtrlStr: - * For each option, one integer address must be passed. This integer must - * initialized by 0. If that option is given in the command line, it will - * be set to one. - * In addition, the sequences that might follow an option require the - * following parameters to pass: - * 1. d, x, o, u - pointer to integer (int *). - * 2. D, X, O, U - pointer to long (long *). - * 3. f - pointer to float (float *). - * 4. F - pointer to double (double *). - * 5. s - pointer to char (char *). NO allocation is needed! - * 6. *? - TWO variables are passed for each wild request. the first - * one is (address of) integer, and it will return number of - * parameters actually matched this sequence, and the second - * one is a pointer to pointer to ? (? **), and will return an - * address to a block of pointers to ? kind, terminated with - * NULL pointer. NO pre-allocation is needed. - * note that these two variables are pretty like the argv/argc - * pair... - * - * Examples: - * - * "Example1 i%-OneInteger!d s%-Strings!*s j%- k!-Float!f Files" - * Will match: Example1 -i 77 -s String1 String2 String3 -k 88.2 File1 File2 - * or match: Example1 -s String1 -k 88.3 -i 999 -j - * but not: Example1 -i 77 78 (option i expects one integer, k must be). - * Note the option k must exists, and that the order of the options is not - * not important. In the first examples File1 & File2 will match the Files - * in the command line. - * A call to GAPrintHowTo with this CtrlStr will print to stderr: - * Example1 [-i OneIngeter] [-s Strings...] [-j] -k Float Files... - * - * Notes: - * - * 1. This module assumes that all the pointers to all kind of data types - * have the same length and format, i.e. sizeof(int *) == sizeof(char *). - * - * Gershon Elber Ver 0.2 Mar 88 - *************************************************************************** - * History: - * 11 Mar 88 - Version 1.0 by Gershon Elber. - **************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef __MSDOS__ -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_STDARG_H -#include -#elif defined(HAVE_VARARGS_H) -#include -#endif - -#include -#include -#include "getarg.h" - -#ifndef MYMALLOC -#define MYMALLOC /* If no "MyMalloc" routine elsewhere define this. */ -#endif - -#define MAX_PARAM 100 /* maximum number of parameters allowed. */ -#define CTRL_STR_MAX_LEN 1024 - -#define SPACE_CHAR '|' /* The character not to print using HowTo. */ - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif /* TRUE */ - -#define ARG_OK 0 - -#define ISSPACE(x) ((x) <= ' ') /* Not conventional - but works fine! */ - -/* The two characters '%' and '!' are used in the control string: */ -#define ISCTRLCHAR(x) (((x) == '%') || ((x) == '!')) - -static char *GAErrorToken; /* On error, ErrorToken is set to point to it. */ -static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr, int *argc, - char ***argv, int *Parameters[MAX_PARAM], - int *ParamCount); -static int GAUpdateParameters(int *Parameters[], int *ParamCount, - char *Option, char *CtrlStrCopy, char *CtrlStr, - int *argc, char ***argv); -static int GAGetParmeters(int *Parameters[], int *ParamCount, - char *CtrlStrCopy, char *Option, int *argc, - char ***argv); -static int GAGetMultiParmeters(int *Parameters[], int *ParamCount, - char *CtrlStrCopy, int *argc, char ***argv); -static void GASetParamCount(char *CtrlStr, int Max, int *ParamCount); -static void GAByteCopy(char *Dst, char *Src, unsigned n); -static int GAOptionExists(int argc, char **argv); -#ifdef MYMALLOC -static char *MyMalloc(unsigned size); -#endif /* MYMALLOC */ - -/*************************************************************************** - * Routine to access the command line argument and interpret them: - * Return ARG_OK (0) is case of succesfull parsing, error code else... - **************************************************************************/ -#ifdef HAVE_STDARG_H -int -GAGetArgs(int argc, - char **argv, - char *CtrlStr, ...) { - - int i, Error = FALSE, ParamCount = 0; - int *Parameters[MAX_PARAM]; /* Save here parameter addresses. */ - char *Option, CtrlStrCopy[CTRL_STR_MAX_LEN]; - va_list ap; - - strcpy(CtrlStrCopy, CtrlStr); - va_start(ap, CtrlStr); - for (i = 1; i <= MAX_PARAM; i++) - Parameters[i - 1] = va_arg(ap, int *); - va_end(ap); - -#elif defined(HAVE_VARARGS_H) -int GAGetArgs(va_alist) - va_dcl -{ - va_list ap; - int argc, i, Error = FALSE, ParamCount = 0; - int *Parameters[MAX_PARAM]; /* Save here parameter addresses. */ - char **argv, *CtrlStr, *Option, CtrlStrCopy[CTRL_STR_MAX_LEN]; - - va_start(ap); - - argc = va_arg(ap, int); - argv = va_arg(ap, char **); - CtrlStr = va_arg(ap, char *); - - va_end(ap); - - strcpy(CtrlStrCopy, CtrlStr); - - /* Using base address of parameters we access other parameters addr: - * Note that me (for sure!) samples data beyond the current function - * frame, but we accesson these set address only by demand. */ - for (i = 1; i <= MAX_PARAM; i++) - Parameters[i - 1] = va_arg(ap, int *); -#endif /* HAVE_STDARG_H */ - - --argc; - argv++; /* Skip the program name (first in argv/c list). */ - while (argc >= 0) { - if (!GAOptionExists(argc, argv)) - break; /* The loop. */ - argc--; - Option = *argv++; - if ((Error = GAUpdateParameters(Parameters, &ParamCount, Option, - CtrlStrCopy, CtrlStr, &argc, - &argv)) != FALSE) - return Error; - } - /* Check for results and update trail of command line: */ - return GATestAllSatis(CtrlStrCopy, CtrlStr, &argc, &argv, Parameters, - &ParamCount); -} - -/*************************************************************************** - * Routine to search for unsatisfied flags - simply scan the list for !- - * sequence. Before this scan, this routine updates the rest of the command - * line into the last two parameters if it is requested by the CtrlStr - * (last item in CtrlStr is NOT an option). - * Return ARG_OK if all satisfied, CMD_ERR_AllSatis error else. - **************************************************************************/ -static int -GATestAllSatis(char *CtrlStrCopy, - char *CtrlStr, - int *argc, - char ***argv, - int *Parameters[MAX_PARAM], - int *ParamCount) { - - int i; - static char *LocalToken = NULL; - - /* If LocalToken is not initialized - do it now. Note that this string - * should be writable as well so we can not assign it directly. - */ - if (LocalToken == NULL) { - LocalToken = (char *)malloc(3); - strcpy(LocalToken, "-?"); - } - - /* Check if last item is an option. If not then copy rest of command - * line into it as 1. NumOfprm, 2. pointer to block of pointers. - */ - for (i = strlen(CtrlStr) - 1; i > 0 && !ISSPACE(CtrlStr[i]); i--) ; - if (!ISCTRLCHAR(CtrlStr[i + 2])) { - GASetParamCount(CtrlStr, i, ParamCount); /* Point in correct param. */ - *Parameters[(*ParamCount)++] = *argc; - GAByteCopy((char *)Parameters[(*ParamCount)++], (char *)argv, - sizeof(char *)); - } - - i = 0; - while (++i < (int)strlen(CtrlStrCopy)) - if ((CtrlStrCopy[i] == '-') && (CtrlStrCopy[i - 1] == '!')) { - GAErrorToken = LocalToken; - LocalToken[1] = CtrlStrCopy[i - 2]; /* Set the correct flag. */ - return CMD_ERR_AllSatis; - } - - return ARG_OK; -} - -/*************************************************************************** - * Routine to update the parameters according to the given Option: - **************************************************************************/ -static int -GAUpdateParameters(int *Parameters[], - int *ParamCount, - char *Option, - char *CtrlStrCopy, - char *CtrlStr, - int *argc, - char ***argv) { - - int i, BooleanTrue = Option[2] != '-'; - - if (Option[0] != '-') { - GAErrorToken = Option; - return CMD_ERR_NotAnOpt; - } - i = 0; /* Scan the CtrlStrCopy for that option: */ - while (i + 2 < (int)strlen(CtrlStrCopy)) { - if ((CtrlStrCopy[i] == Option[1]) && (ISCTRLCHAR(CtrlStrCopy[i + 1])) - && (CtrlStrCopy[i + 2] == '-')) { - /* We found that option! */ - break; - } - i++; - } - if (i + 2 >= (int)strlen(CtrlStrCopy)) { - GAErrorToken = Option; - return CMD_ERR_NoSuchOpt; - } - - /* If we are here, then we found that option in CtrlStr - Strip it off: */ - CtrlStrCopy[i] = CtrlStrCopy[i + 1] = CtrlStrCopy[i + 2] = (char)' '; - GASetParamCount(CtrlStr, i, ParamCount); /* Set it to point in - correct prm. */ - i += 3; - /* Set boolean flag for that option. */ - *Parameters[(*ParamCount)++] = BooleanTrue; - if (ISSPACE(CtrlStrCopy[i])) - return ARG_OK; /* Only a boolean flag is needed. */ - - /* Skip the text between the boolean option and data follows: */ - while (!ISCTRLCHAR(CtrlStrCopy[i])) - i++; - /* Get the parameters and return the appropriete return code: */ - return GAGetParmeters(Parameters, ParamCount, &CtrlStrCopy[i], - Option, argc, argv); -} - -/*************************************************************************** - * Routine to get parameters according to the CtrlStr given from argv/c : - **************************************************************************/ -static int -GAGetParmeters(int *Parameters[], - int *ParamCount, - char *CtrlStrCopy, - char *Option, - int *argc, - char ***argv) { - - int i = 0, ScanRes; - - while (!(ISSPACE(CtrlStrCopy[i]))) { - switch (CtrlStrCopy[i + 1]) { - case 'd': /* Get signed integers. */ - ScanRes = sscanf(*((*argv)++), "%d", - (int *)Parameters[(*ParamCount)++]); - break; - case 'u': /* Get unsigned integers. */ - ScanRes = sscanf(*((*argv)++), "%u", - (unsigned *)Parameters[(*ParamCount)++]); - break; - case 'x': /* Get hex integers. */ - ScanRes = sscanf(*((*argv)++), "%x", - (unsigned int *)Parameters[(*ParamCount)++]); - break; - case 'o': /* Get octal integers. */ - ScanRes = sscanf(*((*argv)++), "%o", - (unsigned int *)Parameters[(*ParamCount)++]); - break; - case 'D': /* Get signed long integers. */ - ScanRes = sscanf(*((*argv)++), "%ld", - (long *)Parameters[(*ParamCount)++]); - break; - case 'U': /* Get unsigned long integers. */ - ScanRes = sscanf(*((*argv)++), "%lu", - (unsigned long *)Parameters[(*ParamCount)++]); - break; - case 'X': /* Get hex long integers. */ - ScanRes = sscanf(*((*argv)++), "%lx", - (unsigned long *)Parameters[(*ParamCount)++]); - break; - case 'O': /* Get octal long integers. */ - ScanRes = sscanf(*((*argv)++), "%lo", - (unsigned long *)Parameters[(*ParamCount)++]); - break; - case 'f': /* Get float number. */ - ScanRes = sscanf(*((*argv)++), "%f", - (float *)Parameters[(*ParamCount)++]); - case 'F': /* Get double float number. */ - ScanRes = sscanf(*((*argv)++), "%lf", - (double *)Parameters[(*ParamCount)++]); - break; - case 's': /* It as a string. */ - ScanRes = 1; /* Allways O.K. */ - GAByteCopy((char *)Parameters[(*ParamCount)++], - (char *)((*argv)++), sizeof(char *)); - break; - case '*': /* Get few parameters into one: */ - ScanRes = GAGetMultiParmeters(Parameters, ParamCount, - &CtrlStrCopy[i], argc, argv); - if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) { - GAErrorToken = Option; - return CMD_ERR_WildEmpty; - } - break; - default: - ScanRes = 0; /* Make optimizer warning silent. */ - } - /* If reading fails and this number is a must (!) then error: */ - if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) { - GAErrorToken = Option; - return CMD_ERR_NumRead; - } - if (CtrlStrCopy[i + 1] != '*') { - (*argc)--; /* Everything is OK - update to next parameter: */ - i += 2; /* Skip to next parameter (if any). */ - } else - i += 3; /* Skip the '*' also! */ - } - - return ARG_OK; -} - -/*************************************************************************** - * Routine to get few parameters into one pointer such that the returned - * pointer actually points on a block of pointers to the parameters... - * For example *F means a pointer to pointers on floats. - * Returns number of parameters actually read. - * This routine assumes that all pointers (on any kind of scalar) has the - * same size (and the union below is totally ovelapped bteween dif. arrays) -***************************************************************************/ -static int -GAGetMultiParmeters(int *Parameters[], - int *ParamCount, - char *CtrlStrCopy, - int *argc, - char ***argv) { - - int i = 0, ScanRes, NumOfPrm = 0, **Pmain, **Ptemp; - union TmpArray { /* Save here the temporary data before copying it to */ - int *IntArray[MAX_PARAM]; /* the returned pointer block. */ - long *LngArray[MAX_PARAM]; - float *FltArray[MAX_PARAM]; - double *DblArray[MAX_PARAM]; - char *ChrArray[MAX_PARAM]; - } TmpArray; - - do { - switch (CtrlStrCopy[2]) { /* CtrlStr == '!*?' or '%*?' where ? is. */ - case 'd': /* Format to read the parameters: */ - TmpArray.IntArray[NumOfPrm] = (int *)MyMalloc(sizeof(int)); - ScanRes = sscanf(*((*argv)++), "%d", - (int *)TmpArray.IntArray[NumOfPrm++]); - break; - case 'u': - TmpArray.IntArray[NumOfPrm] = (int *)MyMalloc(sizeof(int)); - ScanRes = sscanf(*((*argv)++), "%u", - (unsigned int *)TmpArray.IntArray[NumOfPrm++]); - break; - case 'o': - TmpArray.IntArray[NumOfPrm] = (int *)MyMalloc(sizeof(int)); - ScanRes = sscanf(*((*argv)++), "%o", - (unsigned int *)TmpArray.IntArray[NumOfPrm++]); - break; - case 'x': - TmpArray.IntArray[NumOfPrm] = (int *)MyMalloc(sizeof(int)); - ScanRes = sscanf(*((*argv)++), "%x", - (unsigned int *)TmpArray.IntArray[NumOfPrm++]); - break; - case 'D': - TmpArray.LngArray[NumOfPrm] = (long *)MyMalloc(sizeof(long)); - ScanRes = sscanf(*((*argv)++), "%ld", - (long *)TmpArray.IntArray[NumOfPrm++]); - break; - case 'U': - TmpArray.LngArray[NumOfPrm] = (long *)MyMalloc(sizeof(long)); - ScanRes = sscanf(*((*argv)++), "%lu", - (unsigned long *)TmpArray. - IntArray[NumOfPrm++]); - break; - case 'O': - TmpArray.LngArray[NumOfPrm] = (long *)MyMalloc(sizeof(long)); - ScanRes = sscanf(*((*argv)++), "%lo", - (unsigned long *)TmpArray. - IntArray[NumOfPrm++]); - break; - case 'X': - TmpArray.LngArray[NumOfPrm] = (long *)MyMalloc(sizeof(long)); - ScanRes = sscanf(*((*argv)++), "%lx", - (unsigned long *)TmpArray. - IntArray[NumOfPrm++]); - break; - case 'f': - TmpArray.FltArray[NumOfPrm] = (float *)MyMalloc(sizeof(float)); - ScanRes = sscanf(*((*argv)++), "%f", - (float *)TmpArray.LngArray[NumOfPrm++]); - break; - case 'F': - TmpArray.DblArray[NumOfPrm] = - (double *)MyMalloc(sizeof(double)); - ScanRes = sscanf(*((*argv)++), "%lf", - (double *)TmpArray.LngArray[NumOfPrm++]); - break; - case 's': - while ((*argc) && ((**argv)[0] != '-')) { - TmpArray.ChrArray[NumOfPrm++] = *((*argv)++); - (*argc)--; - } - ScanRes = 0; /* Force quit from do - loop. */ - NumOfPrm++; /* Updated again immediately after loop! */ - (*argv)++; /* "" */ - break; - default: - ScanRes = 0; /* Make optimizer warning silent. */ - } - (*argc)--; - } - while (ScanRes == 1); /* Exactly one parameter was read. */ - (*argv)--; - NumOfPrm--; - (*argc)++; - - /* Now allocate the block with the exact size, and set it: */ - Ptemp = Pmain = - (int **)MyMalloc((unsigned)(NumOfPrm + 1) * sizeof(int *)); - /* And here we use the assumption that all pointers are the same: */ - for (i = 0; i < NumOfPrm; i++) - *Ptemp++ = TmpArray.IntArray[i]; - *Ptemp = NULL; /* Close the block with NULL pointer. */ - - /* That it save the number of parameters read as first parameter to - * return and the pointer to the block as second, and return: */ - *Parameters[(*ParamCount)++] = NumOfPrm; - GAByteCopy((char *)Parameters[(*ParamCount)++], (char *)&Pmain, - sizeof(char *)); - return NumOfPrm; -} - -/*************************************************************************** - * Routine to scan the CtrlStr, upto Max and count the number of parameters - * to that point: - * 1. Each option is counted as one parameter - boolean variable (int) - * 2. Within an option, each %? or !? is counted once - pointer to something - * 3. Within an option, %*? or !*? is counted twice - one for item count - * and one for pointer to block pointers. - * Note ALL variables are passed by address and so of fixed size (address). - **************************************************************************/ -static void -GASetParamCount(char *CtrlStr, - int Max, - int *ParamCount) { - int i; - - *ParamCount = 0; - for (i = 0; i < Max; i++) - if (ISCTRLCHAR(CtrlStr[i])) { - if (CtrlStr[i + 1] == '*') - *ParamCount += 2; - else - (*ParamCount)++; - } -} - -/*************************************************************************** - * Routine to copy exactly n bytes from Src to Dst. Note system library - * routine strncpy should do the same, but it stops on NULL char ! - **************************************************************************/ -static void -GAByteCopy(char *Dst, - char *Src, - unsigned n) { - - while (n--) - *(Dst++) = *(Src++); -} - -/*************************************************************************** - * Routine to check if more option (i.e. first char == '-') exists in the - * given list argc, argv: - **************************************************************************/ -static int -GAOptionExists(int argc, - char **argv) { - - while (argc--) - if ((*argv++)[0] == '-') - return TRUE; - return FALSE; -} - -/*************************************************************************** - * Routine to print some error messages, for this module: - **************************************************************************/ -void -GAPrintErrMsg(int Error) { - - fprintf(stderr, "Error in command line parsing - "); - switch (Error) { - case 0:; - fprintf(stderr, "Undefined error"); - break; - case CMD_ERR_NotAnOpt: - fprintf(stderr, "None option Found"); - break; - case CMD_ERR_NoSuchOpt: - fprintf(stderr, "Undefined option Found"); - break; - case CMD_ERR_WildEmpty: - fprintf(stderr, "Empty input for '!*?' seq."); - break; - case CMD_ERR_NumRead: - fprintf(stderr, "Failed on reading number"); - break; - case CMD_ERR_AllSatis: - fprintf(stderr, "Fail to satisfy"); - break; - } - fprintf(stderr, " - '%s'.\n", GAErrorToken); -} - -/*************************************************************************** - * Routine to print correct format of command line allowed: - **************************************************************************/ -void -GAPrintHowTo(char *CtrlStr) { - - int i = 0, SpaceFlag; - - fprintf(stderr, "Usage: "); - /* Print program name - first word in ctrl. str. (optional): */ - while (!(ISSPACE(CtrlStr[i])) && (!ISCTRLCHAR(CtrlStr[i + 1]))) - fprintf(stderr, "%c", CtrlStr[i++]); - - while (i < (int)strlen(CtrlStr)) { - while ((ISSPACE(CtrlStr[i])) && (i < (int)strlen(CtrlStr))) - i++; - switch (CtrlStr[i + 1]) { - case '%': - fprintf(stderr, " [-%c", CtrlStr[i++]); - i += 2; /* Skip the '%-' or '!- after the char! */ - SpaceFlag = TRUE; - while (!ISCTRLCHAR(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) && - (!ISSPACE(CtrlStr[i]))) - if (SpaceFlag) { - if (CtrlStr[i++] == SPACE_CHAR) - fprintf(stderr, " "); - else - fprintf(stderr, " %c", CtrlStr[i - 1]); - SpaceFlag = FALSE; - } else if (CtrlStr[i++] == SPACE_CHAR) - fprintf(stderr, " "); - else - fprintf(stderr, "%c", CtrlStr[i - 1]); - while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr))) { - if (CtrlStr[i] == '*') - fprintf(stderr, "..."); - i++; /* Skip the rest of it. */ - } - fprintf(stderr, "]"); - break; - case '!': - fprintf(stderr, " -%c", CtrlStr[i++]); - i += 2; /* Skip the '%-' or '!- after the char! */ - SpaceFlag = TRUE; - while (!ISCTRLCHAR(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) && - (!ISSPACE(CtrlStr[i]))) - if (SpaceFlag) { - if (CtrlStr[i++] == SPACE_CHAR) - fprintf(stderr, " "); - else - fprintf(stderr, " %c", CtrlStr[i - 1]); - SpaceFlag = FALSE; - } else if (CtrlStr[i++] == SPACE_CHAR) - fprintf(stderr, " "); - else - fprintf(stderr, "%c", CtrlStr[i - 1]); - while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr))) { - if (CtrlStr[i] == '*') - fprintf(stderr, "..."); - i++; /* Skip the rest of it. */ - } - break; - default: /* Not checked, but must be last one! */ - fprintf(stderr, " "); - while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) && - !ISCTRLCHAR(CtrlStr[i])) - fprintf(stderr, "%c", CtrlStr[i++]); - fprintf(stderr, "\n"); - return; - } - } - fprintf(stderr, "\n"); -} - -#ifdef MYMALLOC - -/*************************************************************************** - * My Routine to allocate dynamic memory. All program requests must call - * this routine (no direct call to malloc). Dies if no memory. - **************************************************************************/ -static char * -MyMalloc(unsigned size) { - - char *p; - - if ((p = (char *)malloc(size)) != NULL) - return p; - - fprintf(stderr, "Not enough memory, exit.\n"); - exit(2); - - return NULL; /* Makes warning silent. */ -} - -#endif /* MYMALLOC */ diff --git a/third_party/giflib/lib/getarg.h b/third_party/giflib/lib/getarg.h deleted file mode 100644 index 52c35d56f..000000000 --- a/third_party/giflib/lib/getarg.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************** - * Error numbers as returned by GAGetArg routine: - * - * Gershon Elber Mar 88 - *************************************************************************** - * History: - * 11 Mar 88 - Version 1.0 by Gershon Elber. - **************************************************************************/ - -#ifndef _GETARG_H -#define _GETARG_H - -#define CMD_ERR_NotAnOpt 1 /* None Option found. */ -#define CMD_ERR_NoSuchOpt 2 /* Undefined Option Found. */ -#define CMD_ERR_WildEmpty 3 /* Empty input for !*? seq. */ -#define CMD_ERR_NumRead 4 /* Failed on reading number. */ -#define CMD_ERR_AllSatis 5 /* Fail to satisfy (must-'!') option. */ - -#ifdef HAVE_STDARG_H -int GAGetArgs(int argc, char **argv, char *CtrlStr, ...); -#elif defined (HAVE_VARARGS_H) -int GAGetArgs(int va_alist, ...); -#endif /* HAVE_STDARG_H */ - -void GAPrintErrMsg(int Error); -void GAPrintHowTo(char *CtrlStr); - -#endif /* _GETARG_H */ diff --git a/third_party/giflib/lib/gif_err.c b/third_party/giflib/lib/gif_err.c index 4ab368fbe..3ec2a56f8 100644 --- a/third_party/giflib/lib/gif_err.c +++ b/third_party/giflib/lib/gif_err.c @@ -1,64 +1,43 @@ /***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 - ***************************************************************************** - * Handle error reporting for the GIF library. - ***************************************************************************** - * History: - * 17 Jun 89 - Version 1.0 by Gershon Elber. - ****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif +gif_err.c - handle error reporting for the GIF library. + +****************************************************************************/ #include + #include "gif_lib.h" - -int _GifError = 0; +#include "gif_lib_private.h" /***************************************************************************** - * Return the last GIF error (0 if none) and reset the error. - ****************************************************************************/ -int -GifLastError(void) { - int i = _GifError; + Return a string description of the last GIF error +*****************************************************************************/ +const char * +GifErrorString(int ErrorCode) +{ + const char *Err; - _GifError = 0; - - return i; -} -#ifndef _GBA_NO_FILEIO - -/***************************************************************************** - * Print the last GIF error to stderr. - ****************************************************************************/ -void -PrintGifError(void) { - char *Err; - - switch (_GifError) { + switch (ErrorCode) { case E_GIF_ERR_OPEN_FAILED: Err = "Failed to open given file"; break; case E_GIF_ERR_WRITE_FAILED: - Err = "Failed to Write to given file"; + Err = "Failed to write to given file"; break; case E_GIF_ERR_HAS_SCRN_DSCR: - Err = "Screen Descriptor already been set"; + Err = "Screen descriptor has already been set"; break; case E_GIF_ERR_HAS_IMAG_DSCR: - Err = "Image Descriptor is still active"; + Err = "Image descriptor is still active"; break; case E_GIF_ERR_NO_COLOR_MAP: - Err = "Neither Global Nor Local color map"; + Err = "Neither global nor local color map"; break; case E_GIF_ERR_DATA_TOO_BIG: - Err = "#Pixels bigger than Width * Height"; + Err = "Number of pixels bigger than width * height"; break; case E_GIF_ERR_NOT_ENOUGH_MEM: - Err = "Fail to allocate required memory"; + Err = "Failed to allocate required memory"; break; case E_GIF_ERR_DISK_IS_FULL: Err = "Write failed (disk full?)"; @@ -73,28 +52,28 @@ PrintGifError(void) { Err = "Failed to open given file"; break; case D_GIF_ERR_READ_FAILED: - Err = "Failed to Read from given file"; + Err = "Failed to read from given file"; break; case D_GIF_ERR_NOT_GIF_FILE: - Err = "Given file is NOT GIF file"; + Err = "Data is not in GIF format"; break; case D_GIF_ERR_NO_SCRN_DSCR: - Err = "No Screen Descriptor detected"; + Err = "No screen descriptor detected"; break; case D_GIF_ERR_NO_IMAG_DSCR: Err = "No Image Descriptor detected"; break; case D_GIF_ERR_NO_COLOR_MAP: - Err = "Neither Global Nor Local color map"; + Err = "Neither global nor local color map"; break; case D_GIF_ERR_WRONG_RECORD: Err = "Wrong record type detected"; break; case D_GIF_ERR_DATA_TOO_BIG: - Err = "#Pixels bigger than Width * Height"; + Err = "Number of pixels bigger than width * height"; break; case D_GIF_ERR_NOT_ENOUGH_MEM: - Err = "Fail to allocate required memory"; + Err = "Failed to allocate required memory"; break; case D_GIF_ERR_CLOSE_FAILED: Err = "Failed to close given file"; @@ -106,15 +85,13 @@ PrintGifError(void) { Err = "Image is defective, decoding aborted"; break; case D_GIF_ERR_EOF_TOO_SOON: - Err = "Image EOF detected, before image complete"; + Err = "Image EOF detected before image complete"; break; default: Err = NULL; break; } - if (Err != NULL) - fprintf(stderr, "\nGIF-LIB error: %s.\n", Err); - else - fprintf(stderr, "\nGIF-LIB undefined error %d.\n", _GifError); + return Err; } -#endif /* _GBA_NO_FILEIO */ + +/* end */ diff --git a/third_party/giflib/lib/gif_font.c b/third_party/giflib/lib/gif_font.c index 54327ba81..ba47b29e8 100644 --- a/third_party/giflib/lib/gif_font.c +++ b/third_party/giflib/lib/gif_font.c @@ -1,32 +1,24 @@ /***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 - ***************************************************************************** - * Utility font handling and simple drawing for the GIF library - ***************************************************************************** - * History: - * 17 Jun 89 - Version 1.0 by Gershon Elber. - * 25 Sep 92 - Draw functions added by Eric S. Raymond - ****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif + +gif_font.c - utility font handling and simple drawing for the GIF library + +****************************************************************************/ #include + #include "gif_lib.h" /***************************************************************************** - * Ascii 8 by 8 regular font - only first 128 characters are supported. - ****************************************************************************/ + Ascii 8 by 8 regular font - only first 128 characters are supported. +*****************************************************************************/ /* * Each array entry holds the bits for 8 horizontal scan lines, topmost * first. The most significant bit of each constant is the leftmost bit of * the scan line. */ -unsigned char AsciiTable[][GIF_FONT_WIDTH] = { +/*@+charint@*/ +const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Ascii 0 */ {0x3c, 0x42, 0xa5, 0x81, 0xbd, 0x42, 0x3c, 0x00}, /* Ascii 1 */ {0x3c, 0x7e, 0xdb, 0xff, 0xc3, 0x7e, 0x3c, 0x00}, /* Ascii 2 */ @@ -156,14 +148,14 @@ unsigned char AsciiTable[][GIF_FONT_WIDTH] = { {0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00}, /* ~ */ {0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00} /* Ascii 127 */ }; +/*@=charint@*/ void -DrawText(SavedImage * Image, - const int x, - const int y, - const char *legend, - const int color) { - +GifDrawText8x8(SavedImage *Image, + const int x, const int y, + const char *legend, + const int color) +{ int i, j; int base; const char *cp; @@ -173,7 +165,7 @@ DrawText(SavedImage * Image, for (cp = legend; *cp; cp++) for (j = 0; j < GIF_FONT_WIDTH; j++) { - if (AsciiTable[(short)(*cp)][i] & (1 << (GIF_FONT_WIDTH - j))) + if (GifAsciiTable8x8[(short)(*cp)][i] & (1 << (GIF_FONT_WIDTH - j))) Image->RasterBits[base] = color; base++; } @@ -181,13 +173,11 @@ DrawText(SavedImage * Image, } void -DrawBox(SavedImage * Image, - const int x, - const int y, - const int w, - const int d, - const int color) { - +GifDrawBox(SavedImage *Image, + const int x, const int y, + const int w, const int d, + const int color) +{ int j, base = Image->ImageDesc.Width * y + x; for (j = 0; j < w; j++) @@ -200,29 +190,25 @@ DrawBox(SavedImage * Image, } void -DrawRectangle(SavedImage * Image, - const int x, - const int y, - const int w, - const int d, - const int color) { - +GifDrawRectangle(SavedImage *Image, + const int x, const int y, + const int w, const int d, + const int color) +{ unsigned char *bp = Image->RasterBits + Image->ImageDesc.Width * y + x; int i; for (i = 0; i < d; i++) - memset(bp + (i * Image->ImageDesc.Width), color, w); + memset(bp + (i * Image->ImageDesc.Width), color, (size_t)w); } void -DrawBoxedText(SavedImage * Image, - const int x, - const int y, +GifDrawBoxedText8x8(SavedImage *Image, + const int x, const int y, const char *legend, const int border, - const int bg, - const int fg) { - + const int bg, const int fg) +{ int i, j = 0, LineCount = 0, TextWidth = 0; const char *cp; @@ -240,7 +226,7 @@ DrawBoxedText(SavedImage * Image, TextWidth = j; /* fill the box */ - DrawRectangle(Image, x + 1, y + 1, + GifDrawRectangle(Image, x + 1, y + 1, border + TextWidth * GIF_FONT_WIDTH + border - 1, border + LineCount * GIF_FONT_HEIGHT + border - 1, bg); @@ -253,12 +239,14 @@ DrawBoxedText(SavedImage * Image, if (cp[0] == '\t') leadspace = (TextWidth - strlen(++cp)) / 2; - DrawText(Image, x + border + (leadspace * GIF_FONT_WIDTH), + GifDrawText8x8(Image, x + border + (leadspace * GIF_FONT_WIDTH), y + border + (GIF_FONT_HEIGHT * i++), cp, fg); cp = strtok((char *)NULL, "\r\n"); } while (cp); /* outline the box */ - DrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border, + GifDrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border, border + LineCount * GIF_FONT_HEIGHT + border, fg); } + +/* end */ diff --git a/third_party/giflib/lib/gif_hash.c b/third_party/giflib/lib/gif_hash.c index 9bb4208b7..be48486e8 100644 --- a/third_party/giflib/lib/gif_hash.c +++ b/third_party/giflib/lib/gif_hash.c @@ -1,77 +1,48 @@ /***************************************************************************** -* "Gif-Lib" - Yet another gif library. * -* * -* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * -****************************************************************************** -* Module to support the following operations: * -* * -* 1. InitHashTable - initialize hash table. * -* 2. ClearHashTable - clear the hash table to an empty state. * -* 2. InsertHashTable - insert one item into data structure. * -* 3. ExistsHashTable - test if item exists in data structure. * -* * -* This module is used to hash the GIF codes during encoding. * -****************************************************************************** -* History: * -* 14 Jun 89 - Version 1.0 by Gershon Elber. * + +gif_hash.c -- module to support the following operations: + +1. InitHashTable - initialize hash table. +2. ClearHashTable - clear the hash table to an empty state. +2. InsertHashTable - insert one item into data structure. +3. ExistsHashTable - test if item exists in data structure. + +This module is used to hash the GIF codes during encoding. + *****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif - -/* Find a thirty-two bit int type */ -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif #ifdef HAVE_UNISTD_H #include #endif - -#ifdef __MSDOS__ -#include -#include -#include -#else -#include -#include -#endif /* __MSDOS__ */ - -#ifdef HAVE_FCNTL_H +#include +#include #include -#endif /* HAVE_FCNTL_H */ #include #include -#include + #include "gif_lib.h" #include "gif_hash.h" #include "gif_lib_private.h" /* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */ -#ifdef DEBUG_HIT_RATE +#ifdef DEBUG_HIT_RATE static long NumberOfTests = 0, - NumberOfMisses = 0; -#endif /* DEBUG_HIT_RATE */ + NumberOfMisses = 0; +#endif /* DEBUG_HIT_RATE */ -static int KeyItem(UINT32 Item); +static int KeyItem(uint32_t Item); /****************************************************************************** -* Initialize HashTable - allocate the memory needed and clear it. * + Initialize HashTable - allocate the memory needed and clear it. * ******************************************************************************/ GifHashTableType *_InitHashTable(void) { GifHashTableType *HashTable; if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType))) - == NULL) - return NULL; + == NULL) + return NULL; _ClearHashTable(HashTable); @@ -79,83 +50,85 @@ GifHashTableType *_InitHashTable(void) } /****************************************************************************** -* Routine to clear the HashTable to an empty state. * -* This part is a little machine depended. Use the commented part otherwise. * + Routine to clear the HashTable to an empty state. * + This part is a little machine depended. Use the commented part otherwise. * ******************************************************************************/ void _ClearHashTable(GifHashTableType *HashTable) { - memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(UINT32)); + memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(uint32_t)); } /****************************************************************************** -* Routine to insert a new Item into the HashTable. The data is assumed to be * -* new one. * + Routine to insert a new Item into the HashTable. The data is assumed to be * + new one. * ******************************************************************************/ -void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code) +void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code) { int HKey = KeyItem(Key); - UINT32 *HTable = HashTable -> HTable; + uint32_t *HTable = HashTable -> HTable; #ifdef DEBUG_HIT_RATE - NumberOfTests++; - NumberOfMisses++; + NumberOfTests++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE - NumberOfMisses++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ - HKey = (HKey + 1) & HT_KEY_MASK; + HKey = (HKey + 1) & HT_KEY_MASK; } HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code); } /****************************************************************************** -* Routine to test if given Key exists in HashTable and if so returns its code * -* Returns the Code if key was found, -1 if not. * + Routine to test if given Key exists in HashTable and if so returns its code * + Returns the Code if key was found, -1 if not. * ******************************************************************************/ -int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key) +int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key) { int HKey = KeyItem(Key); - UINT32 *HTable = HashTable -> HTable, HTKey; + uint32_t *HTable = HashTable -> HTable, HTKey; #ifdef DEBUG_HIT_RATE - NumberOfTests++; - NumberOfMisses++; + NumberOfTests++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE - NumberOfMisses++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ - if (Key == HTKey) return HT_GET_CODE(HTable[HKey]); - HKey = (HKey + 1) & HT_KEY_MASK; + if (Key == HTKey) return HT_GET_CODE(HTable[HKey]); + HKey = (HKey + 1) & HT_KEY_MASK; } return -1; } /****************************************************************************** -* Routine to generate an HKey for the hashtable out of the given unique key. * -* The given Key is assumed to be 20 bits as follows: lower 8 bits are the * -* new postfix character, while the upper 12 bits are the prefix code. * -* Because the average hit ratio is only 2 (2 hash references per entry), * -* evaluating more complex keys (such as twin prime keys) does not worth it! * + Routine to generate an HKey for the hashtable out of the given unique key. * + The given Key is assumed to be 20 bits as follows: lower 8 bits are the * + new postfix character, while the upper 12 bits are the prefix code. * + Because the average hit ratio is only 2 (2 hash references per entry), * + evaluating more complex keys (such as twin prime keys) does not worth it! * ******************************************************************************/ -static int KeyItem(UINT32 Item) +static int KeyItem(uint32_t Item) { return ((Item >> 12) ^ Item) & HT_KEY_MASK; } -#ifdef DEBUG_HIT_RATE +#ifdef DEBUG_HIT_RATE /****************************************************************************** -* Debugging routine to print the hit ratio - number of times the hash table * -* was tested per operation. This routine was used to test the KeyItem routine * + Debugging routine to print the hit ratio - number of times the hash table * + was tested per operation. This routine was used to test the KeyItem routine * ******************************************************************************/ void HashTablePrintHitRatio(void) { printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", - NumberOfMisses, NumberOfTests, - NumberOfMisses * 100 / NumberOfTests); + NumberOfMisses, NumberOfTests, + NumberOfMisses * 100 / NumberOfTests); } -#endif /* DEBUG_HIT_RATE */ +#endif /* DEBUG_HIT_RATE */ + +/* end */ diff --git a/third_party/giflib/lib/gif_hash.h b/third_party/giflib/lib/gif_hash.h index 6e14d30f1..800b4bbff 100644 --- a/third_party/giflib/lib/gif_hash.h +++ b/third_party/giflib/lib/gif_hash.h @@ -1,59 +1,42 @@ /****************************************************************************** -* Declarations, global to other of the GIF-HASH.C module. * -* * -* Written by Gershon Elber, Jun 1989 * -******************************************************************************* -* History: * -* 14 Jun 89 - Version 1.0 by Gershon Elber. * + +gif_hash.h - magfic constants and declarations for GIF LZW + ******************************************************************************/ #ifndef _GIF_HASH_H_ #define _GIF_HASH_H_ -#ifdef HAVE_CONFIG_H -#include -#endif - -/* Find a thirty-two bit int type */ -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_BASETSD_H -#include -#endif +#include -#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ -#define HT_KEY_MASK 0x1FFF /* 13bits keys */ -#define HT_KEY_NUM_BITS 13 /* 13bits keys */ -#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ -#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ +#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ +#define HT_KEY_MASK 0x1FFF /* 13bits keys */ +#define HT_KEY_NUM_BITS 13 /* 13bits keys */ +#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ +#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ /* The 32 bits of the long are divided into two parts for the key & code: */ /* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ -/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ +/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ /* The key is the upper 20 bits. The code is the lower 12. */ -#define HT_GET_KEY(l) (l >> 12) -#define HT_GET_CODE(l) (l & 0x0FFF) -#define HT_PUT_KEY(l) (l << 12) -#define HT_PUT_CODE(l) (l & 0x0FFF) +#define HT_GET_KEY(l) (l >> 12) +#define HT_GET_CODE(l) (l & 0x0FFF) +#define HT_PUT_KEY(l) (l << 12) +#define HT_PUT_CODE(l) (l & 0x0FFF) typedef struct GifHashTableType { - UINT32 HTable[HT_SIZE]; + uint32_t HTable[HT_SIZE]; } GifHashTableType; GifHashTableType *_InitHashTable(void); void _ClearHashTable(GifHashTableType *HashTable); -void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code); -int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key); +void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code); +int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key); #endif /* _GIF_HASH_H_ */ + +/* end */ diff --git a/third_party/giflib/lib/gif_lib.h b/third_party/giflib/lib/gif_lib.h index e106f8949..ad3f8f851 100644 --- a/third_party/giflib/lib/gif_lib.h +++ b/third_party/giflib/lib/gif_lib.h @@ -1,17 +1,8 @@ /****************************************************************************** - * In order to make life a little bit easier when using the GIF file format, - * this library was written, and which does all the dirty work... - * - * Written by Gershon Elber, Jun. 1989 - * Hacks by Eric S. Raymond, Sep. 1992 - ****************************************************************************** - * History: - * 14 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names) - * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp) - * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) - * 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code) - *****************************************************************************/ + +gif_lib.h - service library for decoding and encoding GIF images + +*****************************************************************************/ #ifndef _GIF_LIB_H_ #define _GIF_LIB_H_ 1 @@ -20,21 +11,21 @@ extern "C" { #endif /* __cplusplus */ -#define GIF_LIB_VERSION " Version 4.1, " +#define GIFLIB_MAJOR 5 +#define GIFLIB_MINOR 1 +#define GIFLIB_RELEASE 0 #define GIF_ERROR 0 #define GIF_OK 1 -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -#ifndef NULL -#define NULL 0 -#endif /* NULL */ +#include +#ifdef HAVE_STDBOOL_H + #include +#elif !defined __cplusplus + typedef int bool; + #define false 0 + #define true 1 +#endif #define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ #define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 @@ -42,28 +33,11 @@ extern "C" { #define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */ #define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */ -#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */ - -typedef int GifBooleanType; typedef unsigned char GifPixelType; typedef unsigned char *GifRowType; typedef unsigned char GifByteType; -#ifdef _GBA_OPTMEM - typedef unsigned short GifPrefixType; - typedef short GifWord; -#else - typedef unsigned int GifPrefixType; - typedef int GifWord; -#endif - -#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg) -#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); } - -#ifdef SYSV -#define VoidPtr char * -#else -#define VoidPtr void * -#endif /* SYSV */ +typedef unsigned int GifPrefixType; +typedef int GifWord; typedef struct GifColorType { GifByteType Red, Green, Blue; @@ -72,27 +46,52 @@ typedef struct GifColorType { typedef struct ColorMapObject { int ColorCount; int BitsPerPixel; + bool SortFlag; GifColorType *Colors; /* on malloc(3) heap */ } ColorMapObject; typedef struct GifImageDesc { - GifWord Left, Top, Width, Height, /* Current image dimensions. */ - Interlace; /* Sequential/Interlaced lines. */ - ColorMapObject *ColorMap; /* The local color map */ + GifWord Left, Top, Width, Height; /* Current image dimensions. */ + bool Interlace; /* Sequential/Interlaced lines. */ + ColorMapObject *ColorMap; /* The local color map */ } GifImageDesc; +typedef struct ExtensionBlock { + int ByteCount; + GifByteType *Bytes; /* on malloc(3) heap */ + int Function; /* The block function code */ +#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */ +#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ +#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */ +#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ +#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ +} ExtensionBlock; + +typedef struct SavedImage { + GifImageDesc ImageDesc; + GifByteType *RasterBits; /* on malloc(3) heap */ + int ExtensionBlockCount; /* Count of extensions before image */ + ExtensionBlock *ExtensionBlocks; /* Extensions before image */ +} SavedImage; + typedef struct GifFileType { - GifWord SWidth, SHeight, /* Screen dimensions. */ - SColorResolution, /* How many colors can we generate? */ - SBackGroundColor; /* I hope you understand this one... */ - ColorMapObject *SColorMap; /* NULL if not exists. */ - int ImageCount; /* Number of current image */ - GifImageDesc Image; /* Block describing current image */ - struct SavedImage *SavedImages; /* Use this to accumulate file state */ - VoidPtr UserData; /* hook to attach user data (TVT) */ - VoidPtr Private; /* Don't mess with this! */ + GifWord SWidth, SHeight; /* Size of virtual canvas */ + GifWord SColorResolution; /* How many colors can we generate? */ + GifWord SBackGroundColor; /* Background color for virtual canvas */ + GifByteType AspectByte; /* Used to compute pixel aspect ratio */ + ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */ + int ImageCount; /* Number of current image (both APIs) */ + GifImageDesc Image; /* Current image (low-level API) */ + SavedImage *SavedImages; /* Image sequence (high-level API) */ + int ExtensionBlockCount; /* Count extensions past last image */ + ExtensionBlock *ExtensionBlocks; /* Extensions past last image */ + int Error; /* Last error condition reported */ + void *UserData; /* hook to attach user data (TVT) */ + void *Private; /* Don't mess with this! */ } GifFileType; +#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0) + typedef enum { UNDEFINED_RECORD_TYPE, SCREEN_DESC_RECORD_TYPE, @@ -101,70 +100,44 @@ typedef enum { TERMINATE_RECORD_TYPE /* Begin with ';' */ } GifRecordType; -/* DumpScreen2Gif routine constants identify type of window/screen to dump. - * Note all values below 1000 are reserved for the IBMPC different display - * devices (it has many!) and are compatible with the numbering TC2.0 - * (Turbo C 2.0 compiler for IBM PC) gives to these devices. - */ -typedef enum { - GIF_DUMP_SGI_WINDOW = 1000, - GIF_DUMP_X_WINDOW = 1001 -} GifScreenDumpType; - /* func type to read gif data from arbitrary sources (TVT) */ typedef int (*InputFunc) (GifFileType *, GifByteType *, int); -/* func type to write gif data ro arbitrary targets. +/* func type to write gif data to arbitrary targets. * Returns count of bytes written. (MRB) */ typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int); /****************************************************************************** - * GIF89 extension function codes + GIF89 structures ******************************************************************************/ -#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ -#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */ -#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ -#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ +typedef struct GraphicsControlBlock { + int DisposalMode; +#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */ +#define DISPOSE_DO_NOT 1 /* Leave image in place */ +#define DISPOSE_BACKGROUND 2 /* Set area too background color */ +#define DISPOSE_PREVIOUS 3 /* Restore to previous content */ + bool UserInputFlag; /* User confirmation required before disposal */ + int DelayTime; /* pre-display delay in 0.01sec units */ + int TransparentColor; /* Palette index for transparency, -1 if none */ +#define NO_TRANSPARENT_COLOR -1 +} GraphicsControlBlock; /****************************************************************************** - * O.K., here are the routines one can access in order to encode GIF file: - * (GIF_LIB file EGIF_LIB.C). + GIF encoding routines ******************************************************************************/ +/* Main entry points */ GifFileType *EGifOpenFileName(const char *GifFileName, - int GifTestExistance); -GifFileType *EGifOpenFileHandle(int GifFileHandle); -GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc); - + const bool GifTestExistence, int *Error); +GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error); +GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error); int EGifSpew(GifFileType * GifFile); -void EGifSetGifVersion(const char *Version); -int EGifPutScreenDesc(GifFileType * GifFile, - int GifWidth, int GifHeight, int GifColorRes, - int GifBackGround, - const ColorMapObject * GifColorMap); -int EGifPutImageDesc(GifFileType * GifFile, int GifLeft, int GifTop, - int Width, int GifHeight, int GifInterlace, - const ColorMapObject * GifColorMap); -int EGifPutLine(GifFileType * GifFile, GifPixelType * GifLine, - int GifLineLen); -int EGifPutPixel(GifFileType * GifFile, GifPixelType GifPixel); -int EGifPutComment(GifFileType * GifFile, const char *GifComment); -int EGifPutExtensionFirst(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtensionNext(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtensionLast(GifFileType * GifFile, int GifExtCode, - int GifExtLen, const VoidPtr GifExtension); -int EGifPutExtension(GifFileType * GifFile, int GifExtCode, int GifExtLen, - const VoidPtr GifExtension); -int EGifPutCode(GifFileType * GifFile, int GifCodeSize, - const GifByteType * GifCodeBlock); -int EGifPutCodeNext(GifFileType * GifFile, - const GifByteType * GifCodeBlock); -int EGifCloseFile(GifFileType * GifFile); +const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */ +int EGifCloseFile(GifFileType *GifFile, int *ErrorCode); +#define E_GIF_SUCCEEDED 0 #define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */ #define E_GIF_ERR_WRITE_FAILED 2 #define E_GIF_ERR_HAS_SCRN_DSCR 3 @@ -176,32 +149,46 @@ int EGifCloseFile(GifFileType * GifFile); #define E_GIF_ERR_CLOSE_FAILED 9 #define E_GIF_ERR_NOT_WRITEABLE 10 -/****************************************************************************** - * O.K., here are the routines one can access in order to decode GIF file: - * (GIF_LIB file DGIF_LIB.C). - *****************************************************************************/ -#ifndef _GBA_NO_FILEIO -GifFileType *DGifOpenFileName(const char *GifFileName); -GifFileType *DGifOpenFileHandle(int GifFileHandle); -int DGifSlurp(GifFileType * GifFile); -#endif /* _GBA_NO_FILEIO */ -GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); /* new one - * (TVT) */ -int DGifGetScreenDesc(GifFileType * GifFile); -int DGifGetRecordType(GifFileType * GifFile, GifRecordType * GifType); -int DGifGetImageDesc(GifFileType * GifFile); -int DGifGetLine(GifFileType * GifFile, GifPixelType * GifLine, int GifLineLen); -int DGifGetPixel(GifFileType * GifFile, GifPixelType GifPixel); -int DGifGetComment(GifFileType * GifFile, char *GifComment); -int DGifGetExtension(GifFileType * GifFile, int *GifExtCode, - GifByteType ** GifExtension); -int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension); -int DGifGetCode(GifFileType * GifFile, int *GifCodeSize, - GifByteType ** GifCodeBlock); -int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock); -int DGifGetLZCodes(GifFileType * GifFile, int *GifCode); -int DGifCloseFile(GifFileType * GifFile); +/* These are legacy. You probably do not want to call them directly */ +int EGifPutScreenDesc(GifFileType *GifFile, + const int GifWidth, const int GifHeight, + const int GifColorRes, + const int GifBackGround, + const ColorMapObject *GifColorMap); +int EGifPutImageDesc(GifFileType *GifFile, + const int GifLeft, const int GifTop, + const int GifWidth, const int GifHeight, + const bool GifInterlace, + const ColorMapObject *GifColorMap); +void EGifSetGifVersion(GifFileType *GifFile, const bool gif89); +int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, + int GifLineLen); +int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel); +int EGifPutComment(GifFileType *GifFile, const char *GifComment); +int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode); +int EGifPutExtensionBlock(GifFileType *GifFile, + const int GifExtLen, const void *GifExtension); +int EGifPutExtensionTrailer(GifFileType *GifFile); +int EGifPutExtension(GifFileType *GifFile, const int GifExtCode, + const int GifExtLen, + const void *GifExtension); +int EGifPutCode(GifFileType *GifFile, int GifCodeSize, + const GifByteType *GifCodeBlock); +int EGifPutCodeNext(GifFileType *GifFile, + const GifByteType *GifCodeBlock); +/****************************************************************************** + GIF decoding routines +******************************************************************************/ + +/* Main entry points */ +GifFileType *DGifOpenFileName(const char *GifFileName, int *Error); +GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error); +int DGifSlurp(GifFileType * GifFile); +GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */ + int DGifCloseFile(GifFileType * GifFile, int *ErrorCode); + +#define D_GIF_SUCCEEDED 0 #define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ #define D_GIF_ERR_READ_FAILED 102 #define D_GIF_ERR_NOT_GIF_FILE 103 @@ -216,116 +203,106 @@ int DGifCloseFile(GifFileType * GifFile); #define D_GIF_ERR_IMAGE_DEFECT 112 #define D_GIF_ERR_EOF_TOO_SOON 113 +/* These are legacy. You probably do not want to call them directly */ +int DGifGetScreenDesc(GifFileType *GifFile); +int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType); +int DGifGetImageDesc(GifFileType *GifFile); +int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen); +int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel); +int DGifGetComment(GifFileType *GifFile, char *GifComment); +int DGifGetExtension(GifFileType *GifFile, int *GifExtCode, + GifByteType **GifExtension); +int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension); +int DGifGetCode(GifFileType *GifFile, int *GifCodeSize, + GifByteType **GifCodeBlock); +int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock); +int DGifGetLZCodes(GifFileType *GifFile, int *GifCode); + + /****************************************************************************** - * O.K., here are the routines from GIF_LIB file QUANTIZE.C. + Color table quantization (deprecated) ******************************************************************************/ -int QuantizeBuffer(unsigned int Width, unsigned int Height, +int GifQuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize, GifByteType * RedInput, GifByteType * GreenInput, GifByteType * BlueInput, GifByteType * OutputBuffer, GifColorType * OutputColorMap); /****************************************************************************** - * O.K., here are the routines from GIF_LIB file QPRINTF.C. + Error handling and reporting. ******************************************************************************/ -extern int GifQuietPrint; - -#ifdef HAVE_STDARG_H - extern void GifQprintf(char *Format, ...); -#elif defined (HAVE_VARARGS_H) - extern void GifQprintf(); -#endif /* HAVE_STDARG_H */ - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file GIF_ERR.C. -******************************************************************************/ -#ifndef _GBA_NO_FILEIO -extern void PrintGifError(void); -#endif /* _GBA_NO_FILEIO */ -extern int GifLastError(void); - -/****************************************************************************** - * O.K., here are the routines from GIF_LIB file DEV2GIF.C. -******************************************************************************/ -extern int DumpScreen2Gif(const char *FileName, - int ReqGraphDriver, - long ReqGraphMode1, - long ReqGraphMode2, - long ReqGraphMode3); +extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */ /***************************************************************************** - * - * Everything below this point is new after version 1.2, supporting `slurp - * mode' for doing I/O in two big belts with all the image-bashing in core. - * - *****************************************************************************/ + Everything below this point is new after version 1.2, supporting `slurp + mode' for doing I/O in two big belts with all the image-bashing in core. +******************************************************************************/ /****************************************************************************** - * Color Map handling from ALLOCGIF.C - *****************************************************************************/ + Color map handling from gif_alloc.c +******************************************************************************/ -extern ColorMapObject *MakeMapObject(int ColorCount, - const GifColorType * ColorMap); -extern void FreeMapObject(ColorMapObject * Object); -extern ColorMapObject *UnionColorMap(const ColorMapObject * ColorIn1, - const ColorMapObject * ColorIn2, +extern ColorMapObject *GifMakeMapObject(int ColorCount, + const GifColorType *ColorMap); +extern void GifFreeMapObject(ColorMapObject *Object); +extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1, + const ColorMapObject *ColorIn2, GifPixelType ColorTransIn2[]); -extern int BitSize(int n); +extern int GifBitSize(int n); /****************************************************************************** - * Support for the in-core structures allocation (slurp mode). - *****************************************************************************/ + Support for the in-core structures allocation (slurp mode). +******************************************************************************/ -/* This is the in-core version of an extension record */ -typedef struct { - int ByteCount; - char *Bytes; /* on malloc(3) heap */ - int Function; /* Holds the type of the Extension block. */ -} ExtensionBlock; - -/* This holds an image header, its unpacked raster bits, and extensions */ -typedef struct SavedImage { - GifImageDesc ImageDesc; - unsigned char *RasterBits; /* on malloc(3) heap */ - int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */ - int ExtensionBlockCount; - ExtensionBlock *ExtensionBlocks; /* on malloc(3) heap */ -} SavedImage; - -extern void ApplyTranslation(SavedImage * Image, GifPixelType Translation[]); -extern void MakeExtension(SavedImage * New, int Function); -extern int AddExtensionBlock(SavedImage * New, int Len, - unsigned char ExtData[]); -extern void FreeExtension(SavedImage * Image); -extern SavedImage *MakeSavedImage(GifFileType * GifFile, - const SavedImage * CopyFrom); -extern void FreeSavedImages(GifFileType * GifFile); +extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]); +extern int GifAddExtensionBlock(int *ExtensionBlock_Count, + ExtensionBlock **ExtensionBlocks, + int Function, + unsigned int Len, unsigned char ExtData[]); +extern void GifFreeExtensions(int *ExtensionBlock_Count, + ExtensionBlock **ExtensionBlocks); +extern SavedImage *GifMakeSavedImage(GifFileType *GifFile, + const SavedImage *CopyFrom); +extern void GifFreeSavedImages(GifFileType *GifFile); /****************************************************************************** - * The library's internal utility font - *****************************************************************************/ + 5.x functions for GIF89 graphics control blocks +******************************************************************************/ + +int DGifExtensionToGCB(const size_t GifExtensionLength, + const GifByteType *GifExtension, + GraphicsControlBlock *GCB); +size_t EGifGCBToExtension(const GraphicsControlBlock *GCB, + GifByteType *GifExtension); + +int DGifSavedExtensionToGCB(GifFileType *GifFile, + int ImageIndex, + GraphicsControlBlock *GCB); +int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, + GifFileType *GifFile, + int ImageIndex); + +/****************************************************************************** + The library's internal utility font +******************************************************************************/ #define GIF_FONT_WIDTH 8 #define GIF_FONT_HEIGHT 8 -extern unsigned char AsciiTable[][GIF_FONT_WIDTH]; +extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH]; -#ifdef _WIN32 - extern void DrawGifText(SavedImage * Image, -#else - extern void DrawText(SavedImage * Image, -#endif +extern void GifDrawText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int color); -extern void DrawBox(SavedImage * Image, +extern void GifDrawBox(SavedImage *Image, const int x, const int y, const int w, const int d, const int color); -void DrawRectangle(SavedImage * Image, +extern void GifDrawRectangle(SavedImage *Image, const int x, const int y, const int w, const int d, const int color); -extern void DrawBoxedText(SavedImage * Image, +extern void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int border, const int bg, const int fg); @@ -334,3 +311,5 @@ extern void DrawBoxedText(SavedImage * Image, } #endif /* __cplusplus */ #endif /* _GIF_LIB_H */ + +/* end */ diff --git a/third_party/giflib/lib/gif_lib_private.h b/third_party/giflib/lib/gif_lib_private.h index b31c9c5d7..adaf5571e 100644 --- a/third_party/giflib/lib/gif_lib_private.h +++ b/third_party/giflib/lib/gif_lib_private.h @@ -1,19 +1,18 @@ +/**************************************************************************** + +gif_lib_private.h - internal giflib routines and structures + +****************************************************************************/ + #ifndef _GIF_LIB_PRIVATE_H #define _GIF_LIB_PRIVATE_H #include "gif_lib.h" #include "gif_hash.h" -#define PROGRAM_NAME "GIFLIB" - -#ifdef SYSV -#define VersionStr "Gif library module,\t\tEric S. Raymond\n\ - (C) Copyright 1997 Eric S. Raymond\n" -#else -#define VersionStr PROGRAM_NAME " IBMPC " GIF_LIB_VERSION \ - " Eric S. Raymond, " __DATE__ ", " \ - __TIME__ "\n" "(C) Copyright 1997 Eric S. Raymond\n" -#endif /* SYSV */ +#define EXTENSION_INTRODUCER 0x21 +#define DESCRIPTOR_INTRODUCER 0x2c +#define TERMINATOR_INTRODUCER 0x3b #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ #define LZ_BITS 12 @@ -52,8 +51,9 @@ typedef struct GifFilePrivateType { GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */ GifPrefixType Prefix[LZ_MAX_CODE + 1]; GifHashTableType *HashTable; + bool gif89; } GifFilePrivateType; -extern int _GifError; - #endif /* _GIF_LIB_PRIVATE_H */ + +/* end */ diff --git a/third_party/giflib/lib/gifalloc.c b/third_party/giflib/lib/gifalloc.c index 61e5f9adb..9fe3edf8c 100644 --- a/third_party/giflib/lib/gifalloc.c +++ b/third_party/giflib/lib/gifalloc.c @@ -1,34 +1,25 @@ /***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber Ver 0.1, Jun. 1989 - * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 - ***************************************************************************** - * GIF construction tools - ***************************************************************************** - * History: - * 15 Sep 92 - Version 1.0 by Eric Raymond. - ****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif + GIF construction tools + +****************************************************************************/ #include #include #include + #include "gif_lib.h" #define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** - * Miscellaneous utility functions - *****************************************************************************/ + Miscellaneous utility functions +******************************************************************************/ /* return smallest bitfield size n will fit in */ int -BitSize(int n) { - +GifBitSize(int n) +{ register int i; for (i = 1; i <= 8; i++) @@ -38,25 +29,24 @@ BitSize(int n) { } /****************************************************************************** - * Color map object functions - *****************************************************************************/ + Color map object functions +******************************************************************************/ /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ ColorMapObject * -MakeMapObject(int ColorCount, - const GifColorType * ColorMap) { - +GifMakeMapObject(int ColorCount, const GifColorType *ColorMap) +{ ColorMapObject *Object; /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to * make the user know that or should we automatically round up instead? */ - if (ColorCount != (1 << BitSize(ColorCount))) { + if (ColorCount != (1 << GifBitSize(ColorCount))) { return ((ColorMapObject *) NULL); } - + Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); if (Object == (ColorMapObject *) NULL) { return ((ColorMapObject *) NULL); @@ -64,13 +54,15 @@ MakeMapObject(int ColorCount, Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType)); if (Object->Colors == (GifColorType *) NULL) { + free(Object); return ((ColorMapObject *) NULL); } Object->ColorCount = ColorCount; - Object->BitsPerPixel = BitSize(ColorCount); + Object->BitsPerPixel = GifBitSize(ColorCount); + Object->SortFlag = false; - if (ColorMap) { + if (ColorMap != NULL) { memcpy((char *)Object->Colors, (char *)ColorMap, ColorCount * sizeof(GifColorType)); } @@ -78,77 +70,75 @@ MakeMapObject(int ColorCount, return (Object); } -/* - * Free a color map object - */ +/******************************************************************************* +Free a color map object +*******************************************************************************/ void -FreeMapObject(ColorMapObject * Object) { - +GifFreeMapObject(ColorMapObject *Object) +{ if (Object != NULL) { - free(Object->Colors); - free(Object); - /*** FIXME: - * When we are willing to break API we need to make this function - * FreeMapObject(ColorMapObject **Object) - * and do this assignment to NULL here: - * *Object = NULL; - */ + (void)free(Object->Colors); + (void)free(Object); } } #ifdef DEBUG void -DumpColorMap(ColorMapObject * Object, - FILE * fp) { - - if (Object) { +DumpColorMap(ColorMapObject *Object, + FILE * fp) +{ + if (Object != NULL) { int i, j, Len = Object->ColorCount; for (i = 0; i < Len; i += 4) { for (j = 0; j < 4 && j < Len; j++) { - fprintf(fp, "%3d: %02x %02x %02x ", i + j, - Object->Colors[i + j].Red, - Object->Colors[i + j].Green, - Object->Colors[i + j].Blue); + (void)fprintf(fp, "%3d: %02x %02x %02x ", i + j, + Object->Colors[i + j].Red, + Object->Colors[i + j].Green, + Object->Colors[i + j].Blue); } - fprintf(fp, "\n"); + (void)fprintf(fp, "\n"); } } } #endif /* DEBUG */ -/* - * Compute the union of two given color maps and return it. If result can't - * fit into 256 colors, NULL is returned, the allocated union otherwise. - * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are - * copied iff they didn't exist before. ColorTransIn2 maps the old - * ColorIn2 into ColorUnion color map table. - */ +/******************************************************************************* + Compute the union of two given color maps and return it. If result can't + fit into 256 colors, NULL is returned, the allocated union otherwise. + ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are + copied iff they didn't exist before. ColorTransIn2 maps the old + ColorIn2 into the ColorUnion color map table./ +*******************************************************************************/ ColorMapObject * -UnionColorMap(const ColorMapObject * ColorIn1, - const ColorMapObject * ColorIn2, - GifPixelType ColorTransIn2[]) { - - int i, j, CrntSlot, RoundUpTo, NewBitSize; +GifUnionColorMap(const ColorMapObject *ColorIn1, + const ColorMapObject *ColorIn2, + GifPixelType ColorTransIn2[]) +{ + int i, j, CrntSlot, RoundUpTo, NewGifBitSize; ColorMapObject *ColorUnion; /* - * Allocate table which will hold the result for sure. + * We don't worry about duplicates within either color map; if + * the caller wants to resolve those, he can perform unions + * with an empty color map. */ - ColorUnion = MakeMapObject(MAX(ColorIn1->ColorCount, + + /* Allocate table which will hold the result for sure. */ + ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount, ColorIn2->ColorCount) * 2, NULL); if (ColorUnion == NULL) return (NULL); - /* Copy ColorIn1 to ColorUnionSize; */ - /*** FIXME: What if there are duplicate entries into the colormap to begin - * with? */ + /* + * Copy ColorIn1 to ColorUnion. + */ for (i = 0; i < ColorIn1->ColorCount; i++) ColorUnion->Colors[i] = ColorIn1->Colors[i]; CrntSlot = ColorIn1->ColorCount; - /* + /* * Potentially obnoxious hack: * * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end @@ -160,15 +150,11 @@ UnionColorMap(const ColorMapObject * ColorIn1, && ColorIn1->Colors[CrntSlot - 1].Blue == 0) CrntSlot--; - /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */ + /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */ for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) { /* Let's see if this color already exists: */ - /*** FIXME: Will it ever occur that ColorIn2 will contain duplicate - * entries? So we should search from 0 to CrntSlot rather than - * ColorIn1->ColorCount? - */ for (j = 0; j < ColorIn1->ColorCount; j++) - if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], + if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0) break; @@ -182,17 +168,17 @@ UnionColorMap(const ColorMapObject * ColorIn1, } if (CrntSlot > 256) { - FreeMapObject(ColorUnion); + GifFreeMapObject(ColorUnion); return ((ColorMapObject *) NULL); } - NewBitSize = BitSize(CrntSlot); - RoundUpTo = (1 << NewBitSize); + NewGifBitSize = GifBitSize(CrntSlot); + RoundUpTo = (1 << NewGifBitSize); if (RoundUpTo != ColorUnion->ColorCount) { register GifColorType *Map = ColorUnion->Colors; - /* + /* * Zero out slots up to next power of 2. * We know these slots exist because of the way ColorUnion's * start dimension was computed. @@ -207,18 +193,17 @@ UnionColorMap(const ColorMapObject * ColorIn1, } ColorUnion->ColorCount = RoundUpTo; - ColorUnion->BitsPerPixel = NewBitSize; + ColorUnion->BitsPerPixel = NewGifBitSize; return (ColorUnion); } -/* - * Apply a given color translation to the raster bits of an image - */ +/******************************************************************************* + Apply a given color translation to the raster bits of an image +*******************************************************************************/ void -ApplyTranslation(SavedImage * Image, - GifPixelType Translation[]) { - +GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]) +{ register int i; register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; @@ -227,85 +212,72 @@ ApplyTranslation(SavedImage * Image, } /****************************************************************************** - * Extension record functions - *****************************************************************************/ - -void -MakeExtension(SavedImage * New, - int Function) { - - New->Function = Function; - /*** FIXME: - * Someday we might have to deal with multiple extensions. - * ??? Was this a note from Gershon or from me? Does the multiple - * extension blocks solve this or do we need multiple Functions? Or is - * this an obsolete function? (People should use AddExtensionBlock - * instead?) - * Looks like AddExtensionBlock needs to take the int Function argument - * then it can take the place of this function. Right now people have to - * use both. Fix AddExtensionBlock and add this to the deprecation list. - */ -} - + Extension record functions +******************************************************************************/ int -AddExtensionBlock(SavedImage * New, - int Len, - unsigned char ExtData[]) { - +GifAddExtensionBlock(int *ExtensionBlockCount, + ExtensionBlock **ExtensionBlocks, + int Function, + unsigned int Len, + unsigned char ExtData[]) +{ ExtensionBlock *ep; - if (New->ExtensionBlocks == NULL) - New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); + if (*ExtensionBlocks == NULL) + *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); else - New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks, + *ExtensionBlocks = (ExtensionBlock *)realloc(*ExtensionBlocks, sizeof(ExtensionBlock) * - (New->ExtensionBlockCount + 1)); + (*ExtensionBlockCount + 1)); - if (New->ExtensionBlocks == NULL) + if (*ExtensionBlocks == NULL) return (GIF_ERROR); - ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; + ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++]; + ep->Function = Function; ep->ByteCount=Len; - ep->Bytes = (char *)malloc(ep->ByteCount); + ep->Bytes = (GifByteType *)malloc(ep->ByteCount); if (ep->Bytes == NULL) return (GIF_ERROR); - if (ExtData) { + if (ExtData != NULL) { memcpy(ep->Bytes, ExtData, Len); - ep->Function = New->Function; } return (GIF_OK); } void -FreeExtension(SavedImage * Image) +GifFreeExtensions(int *ExtensionBlockCount, + ExtensionBlock **ExtensionBlocks) { ExtensionBlock *ep; - if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) { + if (*ExtensionBlocks == NULL) return; - } - for (ep = Image->ExtensionBlocks; - ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++) + + for (ep = *ExtensionBlocks; + ep < (*ExtensionBlocks + *ExtensionBlockCount); + ep++) (void)free((char *)ep->Bytes); - free((char *)Image->ExtensionBlocks); - Image->ExtensionBlocks = NULL; + (void)free((char *)*ExtensionBlocks); + *ExtensionBlocks = NULL; + *ExtensionBlockCount = 0; } /****************************************************************************** - * Image block allocation functions + Image block allocation functions ******************************************************************************/ /* Private Function: * Frees the last image in the GifFile->SavedImages array */ void -FreeLastSavedImage(GifFileType *GifFile) { - +FreeLastSavedImage(GifFileType *GifFile) +{ SavedImage *sp; - + if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) return; @@ -314,36 +286,32 @@ FreeLastSavedImage(GifFileType *GifFile) { sp = &GifFile->SavedImages[GifFile->ImageCount]; /* Deallocate its Colormap */ - if (sp->ImageDesc.ColorMap) { - FreeMapObject(sp->ImageDesc.ColorMap); + if (sp->ImageDesc.ColorMap != NULL) { + GifFreeMapObject(sp->ImageDesc.ColorMap); sp->ImageDesc.ColorMap = NULL; } /* Deallocate the image data */ - if (sp->RasterBits) + if (sp->RasterBits != NULL) free((char *)sp->RasterBits); /* Deallocate any extensions */ - if (sp->ExtensionBlocks) - FreeExtension(sp); + GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks); /*** FIXME: We could realloc the GifFile->SavedImages structure but is * there a point to it? Saves some memory but we'd have to do it every - * time. If this is used in FreeSavedImages then it would be inefficient + * time. If this is used in GifFreeSavedImages then it would be inefficient * (The whole array is going to be deallocated.) If we just use it when * we want to free the last Image it's convenient to do it here. */ } /* - * Append an image block to the SavedImages array + * Append an image block to the SavedImages array */ SavedImage * -MakeSavedImage(GifFileType * GifFile, - const SavedImage * CopyFrom) { - - SavedImage *sp; - +GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom) +{ if (GifFile->SavedImages == NULL) GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); else @@ -353,21 +321,21 @@ MakeSavedImage(GifFileType * GifFile, if (GifFile->SavedImages == NULL) return ((SavedImage *)NULL); else { - sp = &GifFile->SavedImages[GifFile->ImageCount++]; + SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++]; memset((char *)sp, '\0', sizeof(SavedImage)); - if (CopyFrom) { + if (CopyFrom != NULL) { memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); - /* + /* * Make our own allocated copies of the heap fields in the * copied record. This guards against potential aliasing * problems. */ /* first, the local color map */ - if (sp->ImageDesc.ColorMap) { - sp->ImageDesc.ColorMap = MakeMapObject( + if (sp->ImageDesc.ColorMap != NULL) { + sp->ImageDesc.ColorMap = GifMakeMapObject( CopyFrom->ImageDesc.ColorMap->ColorCount, CopyFrom->ImageDesc.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { @@ -389,7 +357,7 @@ MakeSavedImage(GifFileType * GifFile, CopyFrom->ImageDesc.Width); /* finally, the extension blocks */ - if (sp->ExtensionBlocks) { + if (sp->ExtensionBlocks != NULL) { sp->ExtensionBlocks = (ExtensionBlock *)malloc( sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); @@ -399,17 +367,6 @@ MakeSavedImage(GifFileType * GifFile, } memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); - - /* - * For the moment, the actual blocks can take their - * chances with free(). We'll fix this later. - *** FIXME: [Better check this out... Toshio] - * 2004 May 27: Looks like this was an ESR note. - * It means the blocks are shallow copied from InFile to - * OutFile. However, I don't see that in this code.... - * Did ESR fix it but never remove this note (And other notes - * in gifspnge?) - */ } } @@ -418,8 +375,8 @@ MakeSavedImage(GifFileType * GifFile, } void -FreeSavedImages(GifFileType * GifFile) { - +GifFreeSavedImages(GifFileType *GifFile) +{ SavedImage *sp; if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { @@ -427,17 +384,18 @@ FreeSavedImages(GifFileType * GifFile) { } for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { - if (sp->ImageDesc.ColorMap) { - FreeMapObject(sp->ImageDesc.ColorMap); + if (sp->ImageDesc.ColorMap != NULL) { + GifFreeMapObject(sp->ImageDesc.ColorMap); sp->ImageDesc.ColorMap = NULL; } - if (sp->RasterBits) + if (sp->RasterBits != NULL) free((char *)sp->RasterBits); - - if (sp->ExtensionBlocks) - FreeExtension(sp); + + GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks); } free((char *)GifFile->SavedImages); - GifFile->SavedImages=NULL; + GifFile->SavedImages = NULL; } + +/* end */ diff --git a/third_party/giflib/lib/qprintf.c b/third_party/giflib/lib/qprintf.c deleted file mode 100644 index 9d3dd58fd..000000000 --- a/third_party/giflib/lib/qprintf.c +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 - ****************************************************************************** - * Module to emulate a printf with a possible quiet (disable mode.) - * A global variable GifQuietPrint controls the printing of this routine - ****************************************************************************** - * History: - * 12 May 91 - Version 1.0 by Gershon Elber. - *****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef HAVE_STDARG_H -#include -#elif defined (HAVE_VARARGS_H) -#include -#endif /* HAVE_STDARG_H */ - -#include "gif_lib.h" - -#ifdef __MSDOS__ -int GifQuietPrint = FALSE; -#else -int GifQuietPrint = TRUE; -#endif /* __MSDOS__ */ - -/***************************************************************************** - * Same as fprintf to stderr but with optional print. - *****************************************************************************/ -#ifdef HAVE_STDARG_H -void -GifQprintf(char *Format, ...) { - char Line[128]; - va_list ArgPtr; - - va_start(ArgPtr, Format); -#else -# ifdef HAVE_VARARGS_H -void -GifQprintf(va_alist) - va_dcl -{ - char *Format, Line[128]; - va_list ArgPtr; - - va_start(ArgPtr); - Format = va_arg(ArgPtr, char *); -# endif /* HAVE_VARARGS_H */ -#endif /* HAVE_STDARG_H */ - if (GifQuietPrint) - return; - - vsprintf(Line, Format, ArgPtr); - va_end(ArgPtr); - - fputs(Line, stderr); -} diff --git a/third_party/giflib/lib/quantize.c b/third_party/giflib/lib/quantize.c index 4c0715e8a..e5d4a5906 100644 --- a/third_party/giflib/lib/quantize.c +++ b/third_party/giflib/lib/quantize.c @@ -1,26 +1,15 @@ /***************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 - ****************************************************************************** - * Module to quatize high resolution image into lower one. You may want to - * peek into the following article this code is based on: - * "Color Image Quantization for frame buffer Display", by Paul Heckbert - * SIGGRAPH 1982 page 297-307. - ****************************************************************************** - * History: - * 5 Jan 90 - Version 1.0 by Gershon Elber. - *****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include -#endif + quantize.c - quantize a high resolution image into lower one -#ifdef __MSDOS__ -#include -#include -#include -#endif /* __MSDOS__ */ + Based on: "Color Image Quantization for frame buffer Display", by + Paul Heckbert SIGGRAPH 1982 page 297-307. + + This doesn't really belong in the core library, was undocumented, + and was removed in 4.2. Then it turned out some client apps were + actually using it, so it was restored in 5.0. + +******************************************************************************/ #include #include @@ -29,18 +18,9 @@ #define ABS(x) ((x) > 0 ? (x) : (-(x))) -/* The colors are stripped to 5 bits per primary color if non MSDOS system - * or to 4 (not enough memory...) if MSDOS as first step. - */ -#ifdef __MSDOS__ -#define COLOR_ARRAY_SIZE 4096 -#define BITS_PER_PRIM_COLOR 4 -#define MAX_PRIM_COLOR 0x0f -#else #define COLOR_ARRAY_SIZE 32768 #define BITS_PER_PRIM_COLOR 5 #define MAX_PRIM_COLOR 0x1f -#endif /* __MSDOS__ */ static int SortRGBAxis; @@ -61,22 +41,22 @@ typedef struct NewColorMapType { static int SubdivColorMap(NewColorMapType * NewColorSubdiv, unsigned int ColorMapSize, unsigned int *NewColorMapSize); -static int SortCmpRtn(const VoidPtr Entry1, const VoidPtr Entry2); +static int SortCmpRtn(const void *Entry1, const void *Entry2); /****************************************************************************** - * Quantize high resolution image into lower one. Input image consists of a - * 2D array for each of the RGB colors with size Width by Height. There is no - * Color map for the input. Output is a quantized image with 2D array of - * indexes into the output color map. - * Note input image can be 24 bits at the most (8 for red/green/blue) and - * the output has 256 colors at the most (256 entries in the color map.). - * ColorMapSize specifies size of color map up to 256 and will be updated to - * real size before returning. - * Also non of the parameter are allocated by this routine. - * This function returns GIF_OK if succesfull, GIF_ERROR otherwise. - ******************************************************************************/ + Quantize high resolution image into lower one. Input image consists of a + 2D array for each of the RGB colors with size Width by Height. There is no + Color map for the input. Output is a quantized image with 2D array of + indexes into the output color map. + Note input image can be 24 bits at the most (8 for red/green/blue) and + the output has 256 colors at the most (256 entries in the color map.). + ColorMapSize specifies size of color map up to 256 and will be updated to + real size before returning. + Also non of the parameter are allocated by this routine. + This function returns GIF_OK if successful, GIF_ERROR otherwise. +******************************************************************************/ int -QuantizeBuffer(unsigned int Width, +GifQuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize, GifByteType * RedInput, @@ -95,7 +75,6 @@ QuantizeBuffer(unsigned int Width, ColorArrayEntries = (QuantizedColorType *)malloc( sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE); if (ColorArrayEntries == NULL) { - _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } @@ -173,10 +152,7 @@ QuantizeBuffer(unsigned int Width, OutputColorMap[i].Red = (Red << (8 - BITS_PER_PRIM_COLOR)) / j; OutputColorMap[i].Green = (Green << (8 - BITS_PER_PRIM_COLOR)) / j; OutputColorMap[i].Blue = (Blue << (8 - BITS_PER_PRIM_COLOR)) / j; - } else - fprintf(stderr, - "\n%s: Null entry in quantized color map - that's weird.\n", - PROGRAM_NAME); + } } /* Finally scan the input buffer again and put the mapped index in the @@ -212,11 +188,11 @@ QuantizeBuffer(unsigned int Width, } /****************************************************************************** - * Routine to subdivide the RGB space recursively using median cut in each - * axes alternatingly until ColorMapSize different cubes exists. - * The biggest cube in one dimension is subdivide unless it has only one entry. - * Returns GIF_ERROR if failed, otherwise GIF_OK. - ******************************************************************************/ + Routine to subdivide the RGB space recursively using median cut in each + axes alternatingly until ColorMapSize different cubes exists. + The biggest cube in one dimension is subdivide unless it has only one entry. + Returns GIF_ERROR if failed, otherwise GIF_OK. +*******************************************************************************/ static int SubdivColorMap(NewColorMapType * NewColorSubdiv, unsigned int ColorMapSize, @@ -249,7 +225,7 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv, /* Sort all elements in that entry along the given axis and split at * the median. */ SortArray = (QuantizedColorType **)malloc( - sizeof(QuantizedColorType *) * + sizeof(QuantizedColorType *) * NewColorSubdiv[Index].NumEntries); if (SortArray == NULL) return GIF_ERROR; @@ -258,6 +234,17 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv, j++, QuantizedColor = QuantizedColor->Pnext) SortArray[j] = QuantizedColor; + /* + * Because qsort isn't stable, this can produce differing + * results for the order of tuples depending on platform + * details of how qsort() is implemented. + * + * We mitigate this problem by sorting on all three axes rather + * than only the one specied by SortRGBAxis; that way the instability + * can only become an issue if there are multiple color indices + * referring to identical RGB tuples. Older versions of this + * sorted on only the one axis. + */ qsort(SortArray, NewColorSubdiv[Index].NumEntries, sizeof(QuantizedColorType *), SortCmpRtn); @@ -272,8 +259,8 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv, Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count; NumEntries = 1; Count = QuantizedColor->Count; - while ((Sum -= QuantizedColor->Pnext->Count) >= 0 && - QuantizedColor->Pnext != NULL && + while (QuantizedColor->Pnext != NULL && + (Sum -= QuantizedColor->Pnext->Count) >= 0 && QuantizedColor->Pnext->Pnext != NULL) { QuantizedColor = QuantizedColor->Pnext; NumEntries++; @@ -285,6 +272,7 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv, * they need to be rescaled. */ MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */ + /* coverity[var_deref_op] */ MinColor = QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */ MaxColor <<= (8 - BITS_PER_PRIM_COLOR); MinColor <<= (8 - BITS_PER_PRIM_COLOR); @@ -319,12 +307,24 @@ SubdivColorMap(NewColorMapType * NewColorSubdiv, } /**************************************************************************** - * Routine called by qsort to compare to entries. - ****************************************************************************/ -static int -SortCmpRtn(const VoidPtr Entry1, - const VoidPtr Entry2) { + Routine called by qsort to compare two entries. +*****************************************************************************/ - return (*((QuantizedColorType **) Entry1))->RGB[SortRGBAxis] - - (*((QuantizedColorType **) Entry2))->RGB[SortRGBAxis]; +static int +SortCmpRtn(const void *Entry1, + const void *Entry2) { + QuantizedColorType *entry1 = (*((QuantizedColorType **) Entry1)); + QuantizedColorType *entry2 = (*((QuantizedColorType **) Entry2)); + + /* sort on all axes of the color space! */ + int hash1 = entry1->RGB[SortRGBAxis] * 256 * 256 + + entry1->RGB[(SortRGBAxis+1) % 3] * 256 + + entry1->RGB[(SortRGBAxis+2) % 3]; + int hash2 = entry2->RGB[SortRGBAxis] * 256 * 256 + + entry2->RGB[(SortRGBAxis+1) % 3] * 256 + + entry2->RGB[(SortRGBAxis+2) % 3]; + + return hash1 - hash2; } + +/* end */