giflib-6.1.3/0000775000175000017500000000000015166751647011145 5ustar esresrgiflib-6.1.3/NEWS0000664000175000017500000011437715166751647011661 0ustar esresr GIFLIB NEWS Version 6.1.3 ============= Code fixes ---------- * Fix SF bugs #194, #195, #196, #197: these were in the gif_fiont.c code, which is a historical relic not affecting general library clients. * Fix SF bug #193, double free on malicious GIF when built with reallocarray. Version 6.1.2 ============= Code Fixes ---------- * Fix for low-severity CVE-2026-23868 affecting gifponge, giftool, and gifbuild, but not the core library - library clients need not be alarned. Version 6.1.1 ============= This release bumps the major version, but only one entry point - EGifSpew() - has changed signature and behavior (in order to be able to pass out a detailed error code). The internal error codes in the E_GIF_ERR series have changed value so none of them collides with GIF_ERROR. This code has been systematically audited and hardened wuth ChatGPT-5.2. The only library fixes reported by users or found by robot were for some memory leaks that could only triggered by severely malformed GIFs. Other bugs are edge-case failures in the CLI tools. The gif2rbg CLI tool has been moved to the "obsolete" bin, because its only deployment case in 2026 is as a piñata at fuzzer parties. Warning: the CLI tools in the obsolete category will soon be removed from the distribution entirely. The maintainer is tired of fielding junk bugs filed against them by would-be coup-counters who found yet another edge case, and the rest of the world doesn't need noisy CVEs that aren't actually DoS or security issues for giflib clients. Code Fixes ---------- * Fix for CVE-2021-40633. * Fix SF bug #165 EGifSpew leaks GifFileOut->SColorMap * Fix SF bug #171 ImageMagick required to build giflib on non-Darwin Platforms * Fix SF bug #172 Incorrect object files in shared libutil on darwin * Fix SF bug #173 installation of manual pages and html documentation * Fix SF bug #175 Memory leaks in gifecho.c's main() and in gifalloc.c's GifMakeMapObject * Fix SF bug #177 wrong pointer used in giftool getbool * Fix SF bug #179 Path Traversal vulnerability * Fix SF bug #180: -Wformat-truncation likely pointing out an actual bug * Fix SF bug #182 out‐of‐bounds writes in Icon2Gif * Fix SF bug #184 uninitialized buffer in DumpScreen2RGB * Fix SF bug #185 integer overflow in gifbg.c * Fix SF bug #186 integer overflow in Icon2Gif * Fix SF bug #187: CVE-2025-31344 * Fix SF bug #170 Tests failing on Ubuntu Noble, giftext buffer overflow * Fix SF bug #165 EGifSpew leaks GifFileOut->SColorMap * Fix SF bug #162 detected memory leaks in GifMakeSavedImage giflib/gifalloc.c * Fix SF bug #161 detected memory leaks in EGifOpenFileHandle giflib/egif_lib.c * Fix SF bug #142 ABI break public symbol GifQuantizeBuffer Other bugs that duplicate these have been addressesed by these fixes * SF bug #156 EGifSpew leaks SavedImages (and more); won't fix, caller might want to write a GIF, modify the in-memory data, then write again. Tests ----- Test suite now emits TAP (Test Anything Protocol). ============================================================================== Version 5.2.2 ============= This is a point release intended to clear up a couple of CVEs and apply point fixes that have been accumulating since 5.2.1 There are a few unresolved (but minor) memory leaks related to design issues in the API that still need to be resolved. Expect those fixes in the next release. Code Fixes ---------- * Fixes for CVE-2023-48161, CVE-2022-28506 * Address SF issue #138 Documentation for obsolete utilities still installed * Address SF issue #139: Typo in "LZW image data" page ("110_2 = 4_10") * Address SF issue #140: Typo in "LZW image data" page ("LWZ") * Address SF issue #141: Typo in "Bits and bytes" page ("filed") * Note as already fixed SF issue #143: cannot compile under mingw * Address SF issue #144: giflib-5.2.1 cannot be build on windows and other platforms using c89 * Address SF issue #145: Remove manual pages installation for binaries that are not installed too * Address SF issue #146: Limit installed man pages to binaries, move giflib to section 7 * Address SF issue #147: Fixes to doc/whatsinagif/ content * Address SF issue #148: heap Out of Bound Read in gif2rgb.c:298 DumpScreen2RGB * Declared no-info on SF issue #150: There is a denial of service vulnerability in GIFLIB 5.2.1 * Declared Won't-fix on SF issue 149: Out of source builds no longer possible * Address SF issue #151: A heap-buffer-overflow in gif2rgb.c:294:45 * Address SF issue #152: Fix some typos on the html documentation and man pages * Address SF issue #153: Fix segmentation faults due to non correct checking for args * Address SF issue #154: Recover the giffilter manual page * Address SF issue #155: Add gifsponge docs * Address SF issue #157: An OutofMemory-Exception or Memory Leak in gif2rgb * Address SF issue #158: There is a null pointer problem in gif2rgb * Address SF issue #159 A heap-buffer-overflow in GIFLIB5.2.1 DumpScreen2RGB() in gif2rgb.c:298:45 * Address SF issue #163: detected memory leaks in openbsd_reallocarray giflib/openbsd-reallocarray.c * Address SF issue #164: detected memory leaks in GifMakeMapObject giflib/gifalloc.c * Address SF issue #166: a read zero page leads segment fault in getarg.c and memory leaks in gif2rgb.c and gifmalloc.c * Address SF issue #167: Heap-Buffer Overflow during Image Saving in DumpScreen2RGB Function at Line 321 of gif2rgb.c ============================================================================== Version 5.2.1 ============== This is the "Maybe I shouldn't have done a release while in surgical recovery" release. * In gifbuild.c, avoid a core dump on no color map. * Restore inadvertently removed library version numbers in Makefile. ============================================================================== Version 5.2.0 ============= The undocumented and deprecated GifQuantizeBuffer() entry point has been moved to the util library to reduce libgif size and attack surface. Applications needing this function are couraged to link the util library or make their own copy. The following obsolete utility programs are no longer installed: gifecho, giffilter, gifinto, gifsponge. These were either installed in error or have been obsolesced by modern image-transformation tools like ImageMagick convert. They may be removed entirely in a future release. * Address SourceForge issue #136: Stack-buffer-overflow in gifcolor.c:84 * Address SF bug #134: Giflib fails to slurp significant number of gifs * Apply SPDX convention for license tagging. ============================================================================== Version 5.1.9 ============= The documentation directory now includes an HTMlified version of the GIF89 standard, and a more detailed description of how LZW compression is applied to GIFs. * Address SF bug #129: The latest version of giflib cannot be build on windows. * Address SF bug #126: Cannot compile giflib using c89 ============================================================================== Version 5.1.8 ============= * Address SF bug #119: MemorySanitizer: FPE on unknown address. This is CVE-2019-15133 * Address SF bug #125: 5.1.7: xmlto is still required for tarball * Address SF bug #124: 5.1.7: ar invocation is not crosscompile compatible * Address SF bug #122: 5.1.7 installs manpages to wrong directory * Address SF bug #121: make: getversion: Command not found * Address SF bug #120: 5.1.7 does not build a proper library - no ============================================================================== Version 5.1.7 ============= Correct a minor packaging error (superfluous symlinks) in the 5.1.6 tarballs. ============================================================================== Version 5.1.6 ============= Build Fixes ----------- Fix library installation in the Makefile. ============================================================================== Version 5.1.5 ============= Code Fixes ---------- * Fix SF bug #114: Null dereferences in main() of gifclrmp * Fix SF bug #113: Heap Buffer Overflow-2 in function DGifDecompressLine() in cgif.c. This had been assigned CVE-2018-11490. * Fix SF bug #111: segmentation fault in PrintCodeBlock * Fix SF bug #109: Segmentation fault of giftool reading a crafted file * Fix SF bug #107: Floating point exception in giftext utility * Fix SF bug #105: heap buffer overflow in DumpScreen2RGB in gif2rgb.c:317 * Fix SF bug #104: Ineffective bounds check in DGifSlurp ^ Fix SF bug #103: GIFLIB 5.1.4: DGifSlurp fails on empty comment * Fix SF bug #87: Heap buffer overflow in 5.1.2 (gif2rgb). Build Fixes ----------- The horrible old autoconf build system has been removed with extreme prejudice. You now build this simply by running "make" from the top-level directory. ============================================================================== Version 5.1.4 ============= Code Fixes ---------- * Fix SF bug #94: giflib 5 loves to fail to load images... a LOT. * Fix SF Bug #92: Fix buffer overread in gifbuild. * Fix SF Bug #93: Add bounds check in gifbuild netscape2.0 path * Fix SF Bug #89: Fix buffer overread in gifbuild. ============================================================================== Version 5.1.3 ============= As of this version the library and code has been seriously abused by fuzzers, smoking out crash bugs (now fixed) induced by various kinds of severely malformed GIF. Code Fixes ---------- * Prevent malloc randomess from causing the header output routine to emit a GIF89 version string even when no GIF89 features are present. Only breaks tests, not production code, but it's odd this wasn't caught sooner. * Prevent malloc randomess from producing sporadic failures by causing sanity checks added in 5.1.2 to misfire. * Bulletproof gif2rgb against 0-height images. Addressed SF bug #78: Heap overflow in gif2rgb with images of size 0, also SF bug #82. * Remove unnecessary duplicate EGifClose() in gifcolor.c. Fixes SF bug #83 introduced in 5.1.2. * Fix SF Bug #84: incorrect return of DGifSlurp(). ============================================================================== Version 5.1.2 ============= Code Fixes ---------- * Code hardening using reallocarray() from OpenBSD. * Sanity check in giffilter catches files with malformed extension records Fixes SourceForge bug #63: malformed gif causes segfault in giffilter. * Inexpensive sanity check in DGifSlurp() catches malformed files with no image descriptor. Fixes SourceForge bug #64: malformed gif causes crash in giftool. * Fix SourceForge bug #66: GifDrawBoxedText8x8() modifying constant input parameter. * Bail out of GIF read on invalid pixel width. Addresses Savannah bug #67: invalid shift in dgif_lib.c * Fix SourceForge bug #69: #69 Malformed: Gif file with no extension block after a GRAPHICS_EXT_FUNC_CODE extension causes segfault (in giftext). * Fix SourceForge bug #71: Buffer overwrite when giffixing a malformed gif. * Fix SourceForge bug #73: Null pointer deference in gifclrmap (only reachable with malformed GIF). * Fix SourceForge bug #74: Double free in gifsponge under 5.1.1, for any valid gif image. * Fix SourceForge bug #75: GAGetArgs overflows due to uncounted use of va_arg. * Sanity check in giffix catches some malformed files. Addresses SourceForge bug #77: dgif_lib.c: extension processing error ============================================================================== Version 5.1.1 ============= Code Fixes ---------- * Numerous minor fixes in getarg.c. Affects only the utilities, not the core library. * Fix SourceForge bug #59: DGifOpen can segfault if DGifGetScreenDesc fails. * SourceForge patch #20: In gifalloc, fix usage of realloc() in case of failure. * Fix SourceForge bug #61 Leak in gifsponge. Build Fixes ---------- * glibtoolize port fix for OS X. ============================================================================== 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 line" from the ImageMagick 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() and 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 prevent the library from building on some platforms. ============================================================================== Version 4.1.5 ============= This version has some important fixes for segfaults when working with corrupt files. All users are strongly encouraged to upgrade. Code Fixes ---------- * Fix segfault in utilities due to referencing ColorMaps in GifFiles that had no ColorMap present. * Fix gif2x11 to work on 24 bit displays. * Fix for giftext segfault when the GifFile does not store a global colormap. * Checks to fail gracefully when an image contains improper LZ codes. * Close file handles on failure in DGifOpenFileHandle() * Checks to operate on files in binary mode on WIN32 as well as MSDOS. Building -------- * Add checks to make building on Win32 easier. * Allow turning off gl_s, rle, and X11 support from the configure command line. * Fix for finding a 32 bit integer type on some platforms. * Only enable -Wall if we're using gcc. ============================================================================== Version 4.1.4 ============= This version fixes some bugs with deallocating ColorMaps. Fix building on several platforms. Fix x86_64 builds to not hang the encoder. * Fix several areas in decoding where we removed a ColorMap from our GifFile but didn't set the pointer to NULL. This could lead to double free's of the ColorMap. * Fix a bug in dev2gif.c where we redefined some gl types incorrectly. * Fix a bug in the gif LZW encoder that was triggered on modern 64 bit platforms. * Fix building on Windows. Note -- there has been one API changing event for Windows (renaming DrawText to DrawGifText.) This should have conflicted with Windows API and therefore caused the builds to fail previously. If you had it working with DrawText before, apologies, you'll need to change to DrawGifText in your code. This only affects Windows. * Add support for building on The Game Boy Advance. Note: Due to the GBA's limited memory, the API for the GBA uses short's in many places where the other platforms use ints. This shouldn't affect anyone unless you've been able to get an older version of the code to run on GBA and want to start using this version instead. A recompile of your dependent code will be necessary in this case. ============================================================================== Version 4.1.3 ============= This version fixes some bugs in the Extension writing code in EGifPutExtensionFirst, Next, and Last. Using these functions, it is possible to output extensions that contain multiple subblocks. Additionally, library code has been updated to use these functions, making it safe to output long Comments, and multi-block extensions read in from another file. * giflib is now hosted on sourceforge with libungif: http://sourceforge.net/projects/libungif * Make the EGifPutExtension{First,Next,Last} family of functions use WRITE so user defined WRITE methods will output them correctly. * Modify EGifSpew and EGifPutComment to use EGifPutExtension{First,Next,Last} so we won't output broken GIFs when dealing with GIFs with multiple subblocks. * More -Wall fixes revealed while testing on Solaris and FreeBSD. * Updated the gif_lib.html documentation to not use EGifPutExtension when dealing with multiple subblocks. Use EGifPutExtension{First,Next,Last} instead. * Some Windows code from the old CVS repository now available in the windows subdirectory. I don't have a Windows environment to test and maintain this 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 library. * 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 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.) ============================================================================== 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. * Old copyright notices in a few source files have been updated. All library copyrights should now reflect the copyright notice in the COPYING file. ============================================================================== Version 4.0.0 -- giflib ======================= This version of the giflib library merges Eric Raymond's giflib-3.0 release with the libungif-4.0 release to give people a binary compatible choice between the two libraries and gives me the chance to add bugfixes to giflib that have been incorporated in libungif. PLEASE READ THE FILE PATENT_PROBLEMS BEFORE USING THIS LIBRARY! ============================================================================== Version 4.0.0 ============= Major fixes have been made to the code that handles Extensions. Unfortunately, this causes binary incompatibility with giflib-3.0 and libungif-3.x. However, the API is still intact. I am, however, deprecating the use of saveImage[x].Function. Use saveImage[x].ExtensionBlocks[y].Function instead. ============================================================================== Version 3.1.1 ============= The following bugs which caused SegFaults have been fixed: * When reading gif files with extensions, DGifSlurp would violate memory. * When closing a gif that had a local colormap, DGifCloseFile would attempt to free the colormap twice. * Fix a potential memory leak in DGifSlurp. * New function DGifOpen to allow specifying a user definable gif reading function. ============================================================================== Version 3.1.0 ============= * Add a new function: GifFileType *DGifOpen(void * userData, InputFunc readFunc) to read the gif image from a user defined input function. * A few bugfixes. ============================================================================== 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. * 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. 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. ============================================================================== giflib-6.1.3/gifclrmp.c0000664000175000017500000002766015166751647013127 0ustar esresr/***************************************************************************** gifclrmap - extract colormaps from GIF images *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifclrmp" static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- s%- t%-TranslationFile!s l%-ColorMapFile!s g%-Gamma!F " "i%-Image#!d h%- GifFile!*s"; static bool SaveFlag = false, TranslateFlag = false, LoadFlag = false, GammaFlag = false; static double Gamma = 1.0; static FILE *ColorFile = NULL; FILE *TranslateFile = NULL; static GifPixelType Translation[256]; static ColorMapObject *ModifyColorMap(ColorMapObject *ColorMap); static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int NumFiles, ExtCode, CodeSize, ImageNum = 0, ImageN, HasGIFOutput, ErrorCode; bool Error, ImageNFlag = false, HelpFlag = false, GifNoisyPrint = false; GifRecordType RecordType; GifByteType *Extension, *CodeBlock; char **FileName = NULL, *ColorFileName, *TranslateFileName; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &SaveFlag, &TranslateFlag, &TranslateFileName, &LoadFlag, &ColorFileName, &GammaFlag, &Gamma, &ImageNFlag, &ImageN, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles > 1) { GIF_MESSAGE("Error in command line parsing - one GIF " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (SaveFlag + LoadFlag + GammaFlag + TranslateFlag > 1) { GIF_EXIT("Can not handle more than one of -s -l, -t, or -g at " "the same time."); } /* Default action is to dump colormaps */ if (!SaveFlag && !LoadFlag && !GammaFlag && !TranslateFlag) { SaveFlag = true; } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } else { /* Use stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } if (SaveFlag) { /* We are dumping out the color map as text file to stdout: */ ColorFile = stdout; } else { if (TranslateFlag) { /* We are loading new color map from specified file: */ if ((TranslateFile = fopen(TranslateFileName, "rt")) == NULL) { GIF_EXIT("Failed to open specified color " "translation file."); } } if (LoadFlag) { /* We are loading new color map from specified file: */ if ((ColorFile = fopen(ColorFileName, "rt")) == NULL) { GIF_EXIT( "Failed to open specified color map file."); } } } if ((HasGIFOutput = (LoadFlag || TranslateFlag || GammaFlag)) != 0) { /* Open stdout for GIF output file: */ if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } if (!ImageNFlag) { /* We are supposed to modify the screen color map, so do it: */ if (!GifFileIn->SColorMap) { GIF_EXIT("No colormap to modify"); } GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap); if (!HasGIFOutput) { /* We can quit here, as we have the color map: */ DGifCloseFile(GifFileIn, NULL); fclose(ColorFile); exit(EXIT_SUCCESS); } } /* And dump out its new possible repositioned screen information: */ if (HasGIFOutput) { if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if ((++ImageNum == ImageN) && ImageNFlag) { /* We are suppose to modify this image color * map, do it: */ GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap); if (!HasGIFOutput) { /* We can quit here, as we have the * color map: */ DGifCloseFile(GifFileIn, NULL); fclose(ColorFile); exit(EXIT_SUCCESS); } } if (HasGIFOutput) { if (EGifPutImageDesc( GifFileOut, GifFileIn->Image.Left, GifFileIn->Image.Top, GifFileIn->Image.Width, GifFileIn->Image.Height, GifFileIn->Image.Interlace, GifFileIn->Image.ColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } if (!TranslateFlag || (ImageNFlag && (ImageN != ImageNum))) { /* Now read image itself in decoded form as we * don't */ /* really care what we have there, and this is * much */ /* faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (HasGIFOutput) { if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (HasGIFOutput) { if (EGifPutCodeNext( GifFileOut, CodeBlock) == GIF_ERROR) { QuitGifError( GifFileIn, GifFileOut); } } } } else /* we need to mung pixels intices */ { int i; register GifPixelType *cp; GifPixelType *Line = (GifPixelType *)malloc( GifFileIn->Image.Width * sizeof(GifPixelType)); for (i = 0; i < GifFileIn->Image.Height; i++) { if (DGifGetLine( GifFileIn, Line, GifFileIn->Image.Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* translation step goes here */ for (cp = Line; cp < Line + GifFileIn->Image.Width; cp++) { *cp = Translation[*cp]; } if (EGifPutLine( GifFileOut, Line, GifFileIn->Image.Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } free((char *)Line); } break; case EXTENSION_RECORD_TYPE: assert(GifFileOut != NULL); /* might pacify Coverity */ /* pass through extension records */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (Extension == NULL) { break; } if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (EGifPutExtensionBlock(GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } while (Extension != NULL) { if (DGifGetExtensionNext( GifFileIn, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (Extension != NULL) { if (EGifPutExtensionBlock( GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } } if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (HasGIFOutput) { if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } return 0; } /****************************************************************************** Modify the given colormap according to global variables setting. ******************************************************************************/ static ColorMapObject *ModifyColorMap(ColorMapObject *ColorMap) { int i, Dummy, Red, Green, Blue; if (SaveFlag) { /* Save this color map to ColorFile: */ for (i = 0; i < ColorMap->ColorCount; i++) { fprintf(ColorFile, "%3d %3d %3d %3d\n", i, ColorMap->Colors[i].Red, ColorMap->Colors[i].Green, ColorMap->Colors[i].Blue); } return (ColorMap); } else if (LoadFlag) { /* Read the color map in ColorFile into this color map: */ for (i = 0; i < ColorMap->ColorCount; i++) { if (feof(ColorFile)) { GIF_EXIT("Color file to load color map from, " "too small."); } if (fscanf(ColorFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue) == 4) { ColorMap->Colors[i].Red = Red; ColorMap->Colors[i].Green = Green; ColorMap->Colors[i].Blue = Blue; } } return (ColorMap); } else if (GammaFlag) { /* Apply gamma correction to this color map: */ double Gamma1 = 1.0 / Gamma; for (i = 0; i < ColorMap->ColorCount; i++) { ColorMap->Colors[i].Red = ((int)(255 * pow(ColorMap->Colors[i].Red / 255.0, Gamma1))); ColorMap->Colors[i].Green = ((int)(255 * pow(ColorMap->Colors[i].Green / 255.0, Gamma1))); ColorMap->Colors[i].Blue = ((int)(255 * pow(ColorMap->Colors[i].Blue / 255.0, Gamma1))); } return (ColorMap); } else if (TranslateFlag) { ColorMapObject *NewMap; int Max = 0; /* Read the translation table in TranslateFile: */ for (i = 0; i < ColorMap->ColorCount; i++) { int tmp; if (feof(TranslateFile)) { GIF_EXIT("Color file to load color map from, " "too small."); } if (fscanf(TranslateFile, "%3d %3d\n", &Dummy, &tmp) == 2) { Translation[i] = tmp & 0xff; if (Translation[i] > Max) { Max = Translation[i]; } } } if ((NewMap = GifMakeMapObject(1 << GifBitSize(Max + 1), NULL)) == NULL) { GIF_EXIT("Out of memory while allocating color map!"); } /* Apply the translation; we'll do it to the pixels, too */ for (i = 0; i < ColorMap->ColorCount; i++) { if (Translation[i] >= ColorMap->ColorCount) { GIF_EXIT( "Color map translation index out of range."); } NewMap->Colors[i] = ColorMap->Colors[Translation[i]]; } return (NewMap); } else { GIF_EXIT("Nothing to do!"); return (ColorMap); } } /****************************************************************************** Close both input and output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) { if (GifFileIn != NULL) { PrintGifError(GifFileIn->Error); EGifCloseFile(GifFileIn, NULL); } if (GifFileOut != NULL) { PrintGifError(GifFileOut->Error); EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } /* end */ giflib-6.1.3/getarg.c0000664000175000017500000005506415166751647012574 0ustar esresr/*************************************************************************** getarg.c - routines to grab the parameters from the command line: Names of all the routines except the main one start with GA (Get Arguments) to prevent conflicts. The following routines are available in this module: 1. int GAGetArgs(argc, argv, CtrlStr, Variables...) where argc, argv are 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. This feature is very useful in case of an 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) Describe 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 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 required ('!')... 3. '-' must always be given. 4. Alphanumeric string, usually ignored, but used by GAPrintHowTo to print the meaning of this option. 5. Sequences starts with '!' or '%'. Again if '!' then this sequence must exist (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 non-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 be initialized with 0. If that option is given in the command line, it will be set. 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 required. The caller is responsible for freeing this memory, including the pointed to memory. 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: 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 exist, and that the order of the options is 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 *). **************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include #include #include "getarg.h" #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. */ #define ARG_OK false #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, const char **argv_end, const char ***argv, void *Parameters[MAX_PARAM], int *ParamCount); static int GAUpdateParameters(void *Parameters[], int *ParamCount, char *Option, char *CtrlStrCopy, char *CtrlStr, char **argv_end, char ***argv); static int GAGetParmeters(void *Parameters[], int *ParamCount, char *CtrlStrCopy, char *Option, char **argv_end, char ***argv); static int GAGetMultiParmeters(void *Parameters[], int *ParamCount, char *CtrlStrCopy, char **argv_end, char ***argv); static void GASetParamCount(const char *CtrlStr, const int Max, int *ParamCount); static bool GAOptionExists(const char **argv_end, const char **argv); /*************************************************************************** Allocate or die ***************************************************************************/ static void *xmalloc(unsigned size) { void *p; if ((p = malloc(size)) != NULL) { return p; } fprintf(stderr, "Not enough memory, exit.\n"); exit(2); return NULL; /* Makes warning silent. */ } /*************************************************************************** Routine to access the command line argument and interpret them: Return ARG_OK (0) is case of successful parsing, error code else... ***************************************************************************/ bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...) { int i, ParamCount = 0; void *Parameters[MAX_PARAM]; /* Save here parameter addresses. */ char CtrlStrCopy[CTRL_STR_MAX_LEN]; const char **argv_end = (const char **)argv + argc; va_list ap; strncpy(CtrlStrCopy, CtrlStr, sizeof(CtrlStrCopy) - 1); GASetParamCount(CtrlStr, strlen(CtrlStr), &ParamCount); va_start(ap, CtrlStr); for (i = 1; i <= ParamCount; i++) { Parameters[i - 1] = va_arg(ap, void *); } va_end(ap); argv++; /* Skip the program name (first in argv/c list). */ while (argv < (char **)argv_end) { bool Error = false; if (!GAOptionExists(argv_end, (const char **)argv)) { break; /* The loop. */ } char *Option = *argv++; if ((Error = GAUpdateParameters( Parameters, &ParamCount, Option, CtrlStrCopy, CtrlStr, (char **)argv_end, &argv)) != false) { return Error; } } /* Check for results and update trail of command line: */ return GATestAllSatis(CtrlStrCopy, CtrlStr, argv_end, (const char ***)&argv, Parameters, &ParamCount) != ARG_OK; } /*************************************************************************** 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, const char **argv_end, const char ***argv, void *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. */ *(int *)Parameters[(*ParamCount)++] = argv_end - *argv; *(char ***)Parameters[(*ParamCount)++] = *(char ***)argv; } 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(void *Parameters[], int *ParamCount, char *Option, char *CtrlStrCopy, char *CtrlStr, char **argv_end, char ***argv) { int i; bool 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. */ *(bool *)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, argv_end, argv); } /*************************************************************************** Routine to get parameters according to the CtrlStr given from argv/argc ***************************************************************************/ static int GAGetParmeters(void *Parameters[], int *ParamCount, char *CtrlStrCopy, char *Option, char **argv_end, char ***argv) { int i = 0, ScanRes; while (!(ISSPACE(CtrlStrCopy[i]))) { if ((*argv) == argv_end) { GAErrorToken = Option; return CMD_ERR_NumRead; } 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)++]); break; 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. */ *(char **)Parameters[(*ParamCount)++] = *((*argv)++); break; case '*': /* Get few parameters into one: */ ScanRes = GAGetMultiParmeters(Parameters, ParamCount, &CtrlStrCopy[i], argv_end, 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] != '*') { i += 2; /* Skip to next parameter (if any). */ } else { i += 3; /* Skip the '*' also! */ } } return ARG_OK; } /*************************************************************************** Routine to get a 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(void *Parameters[], int *ParamCount, char *CtrlStrCopy, char **argv_end, char ***argv) { int i = 0, ScanRes, NumOfPrm = 0; void **Pmain, **Ptemp; union TmpArray { /* Save here the temporary data before copying it to */ void *VoidArray[MAX_PARAM]; /* the returned pointer block. */ int *IntArray[MAX_PARAM]; 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] = xmalloc(sizeof(int)); ScanRes = sscanf(*((*argv)++), "%d", (int *)TmpArray.IntArray[NumOfPrm++]); break; case 'u': TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int)); ScanRes = sscanf( *((*argv)++), "%u", (unsigned int *)TmpArray.IntArray[NumOfPrm++]); break; case 'o': TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int)); ScanRes = sscanf( *((*argv)++), "%o", (unsigned int *)TmpArray.IntArray[NumOfPrm++]); break; case 'x': TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int)); ScanRes = sscanf( *((*argv)++), "%x", (unsigned int *)TmpArray.IntArray[NumOfPrm++]); break; case 'D': TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long)); ScanRes = sscanf(*((*argv)++), "%ld", (long *)TmpArray.IntArray[NumOfPrm++]); break; case 'U': TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long)); ScanRes = sscanf( *((*argv)++), "%lu", (unsigned long *)TmpArray.IntArray[NumOfPrm++]); break; case 'O': TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long)); ScanRes = sscanf( *((*argv)++), "%lo", (unsigned long *)TmpArray.IntArray[NumOfPrm++]); break; case 'X': TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long)); ScanRes = sscanf( *((*argv)++), "%lx", (unsigned long *)TmpArray.IntArray[NumOfPrm++]); break; case 'f': TmpArray.FltArray[NumOfPrm] = xmalloc(sizeof(float)); ScanRes = sscanf(*((*argv)++), "%f", // cppcheck-suppress invalidPointerCast (float *)TmpArray.LngArray[NumOfPrm++]); break; case 'F': TmpArray.DblArray[NumOfPrm] = xmalloc(sizeof(double)); ScanRes = sscanf(*((*argv)++), "%lf", // cppcheck-suppress invalidPointerCast (double *)TmpArray.LngArray[NumOfPrm++]); break; case 's': while ((*argv < argv_end) && ((**argv)[0] != '-')) { TmpArray.ChrArray[NumOfPrm++] = *((*argv)++); } ScanRes = 0; /* Force quit from do - loop. */ NumOfPrm++; /* Updated again immediately after loop! */ (*argv)++; /* "" */ break; default: ScanRes = 0; /* Make optimizer warning silent. */ } } while (ScanRes == 1); /* Exactly one parameter was read. */ (*argv)--; NumOfPrm--; /* Now allocate the block with the exact size, and set it: */ Ptemp = Pmain = xmalloc((unsigned)(NumOfPrm + 1) * sizeof(void *)); /* And here we use the assumption that all pointers are the same: */ for (i = 0; i < NumOfPrm; i++) { *Ptemp++ = TmpArray.VoidArray[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: */ *(int *)Parameters[(*ParamCount)++] = NumOfPrm; *(void ***)Parameters[(*ParamCount)++] = Pmain; /* free(Pmain); -- can not free here as caller needs to access memory */ return NumOfPrm; } /*************************************************************************** Routine to scan the CtrlStr, up to 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 const *CtrlStr, const 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 check if more option (i.e. first char == '-') exists in the given list argc, argv: ***************************************************************************/ static bool GAOptionExists(const char **argv_end, const char **argv) { while (argv < argv_end) { 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; bool 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)) { // cppcheck-suppress arrayIndexThenCheck 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"); } /* end */ giflib-6.1.3/control0000664000175000017500000000133415166751647012551 0ustar esresr# This is not a real Debian control file, though the syntax is compatible. # It's project metadata for the shipper tool Package: giflib XBS-Packaged-As: giflib Destinations: ~,sourceforge, vulns@meta.com Description: a library for rendering and generating GIF image files. This is the GIF service code in C used for over two decades by graphics applications, web browsers, game consoles, ATMs, and pretty much anything else that throws pixels on a display. Simple, stable, and bulletproof. XBS-Web-Directory: doc/staging XBS-Logo: doc/staging/giflib-logo.gif XBS-SourceForge-Folder: giflib-6.x XBS-Packaged-As: giflib XBS-VC-Tag-Template: %(version)s #XBS-Project-Tags: GIF, graphics XBS-Validate: make check spellcheck giflib-6.1.3/README.adoc0000664000175000017500000000266315166751647012741 0ustar esresr= GIFLIB = This is the README file of GIFLIB, a library for manipulating GIF files. Latest versions of GIFLIB are currently hosted at: http://sourceforge.net/projects/giflib == Overview == 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. 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.adoc You will find full documentation of the API in doc/ and on the project website. Please report bugs to the bug tracker on sourceforge: http://sourceforge.net/tracker/?group_id=102202 The project has a long and confusing history, described in history.adoc The project to-do list is in TODO. == Authors == Gershon Elber original giflib code Toshio Kuratomi uncompressed gif writing code former maintainer Eric Raymond current as well as long time former maintainer of giflib code There have been many other contributors; see the attributions in the version-control history to learn more. == Packages == This code is commonly packaged as "giflib". image:https://repology.org/badge/vertical-allrepos/giflib.svg[Repology package status] giflib-6.1.3/TODO0000664000175000017500000000060615166751647011637 0ustar esresr= GIFLIB TODO list = There is a list of GIF test suites here: https://stackoverflow.com/questions/4866093/test-suite-for-gif-containing-images-using-rarely-used-features These break the format in quite a number of interesting ways. GIFLIB doesn't do as well as it could; I haven't found one that causes a core dump, yet, but some malformations that could be worked around are not yet. giflib-6.1.3/gifwedge.c0000664000175000017500000001071415166751647013075 0ustar esresr/***************************************************************************** gifwedge - create a GIF test pattern *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifwedge" #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 350 #define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */ static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- l%-#Lvls!d s%-Width|Height!d!d h%-"; static int NumLevels = DEFAULT_NUM_LEVELS, ImageWidth = DEFAULT_WIDTH, ImageHeight = DEFAULT_HEIGHT; /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, l, c, LevelStep, LogNumLevels, ErrorCode, Count = 0; bool Error, LevelsFlag = false, SizeFlag = false, HelpFlag = false, GifNoisyPrint = false; GifRowType Line = NULL; ColorMapObject *ColorMap = NULL; GifFileType *GifFile; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &LevelsFlag, &NumLevels, &SizeFlag, &ImageWidth, &ImageHeight, &HelpFlag)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* Make sure the number of levels is power of 2 (up to 32 levels.). */ for (i = 1; i < 6; i++) { if (NumLevels == (1 << i)) { break; } } if (i == 6) { GIF_EXIT("#Lvls (-l option) is not power of 2 up to 32."); } LogNumLevels = i + 3; /* Multiple by 8 (see below). */ LevelStep = 256 / NumLevels; /* Make sure the image dimension is a multiple of NumLevels horizontally */ /* and 7 (White, Red, Green, Blue and Yellow Cyan Magenta) vertically. */ ImageWidth = (ImageWidth / NumLevels) * NumLevels; ImageHeight = (ImageHeight / 7) * 7; /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out screen description with given size and generated color map: */ /* The color map has 7 NumLevels colors for White, Red, Green and then */ /* The secondary colors Yellow Cyan and magenta. */ if ((ColorMap = GifMakeMapObject(8 * NumLevels, NULL)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } for (i = 0; i < 8; i++) { /* Set color map. */ for (j = 0; j < NumLevels; j++) { l = LevelStep * j; c = i * NumLevels + j; ColorMap->Colors[c].Red = (i == 0 || i == 1 || i == 4 || i == 6) * l; ColorMap->Colors[c].Green = (i == 0 || i == 2 || i == 4 || i == 5) * l; ColorMap->Colors[c].Blue = (i == 0 || i == 3 || i == 5 || i == 6) * l; } } if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap) == GIF_ERROR) { PrintGifError(GifFile->Error); } GifFreeMapObject(ColorMap); /* Dump out the image descriptor: */ if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); /* Allocate one scan line to be used for all image. */ if ((Line = (GifRowType)malloc(sizeof(GifPixelType) * ImageWidth)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } /* Dump the pixels: */ for (c = 0; c < 7; c++) { for (i = 0, l = 0; i < NumLevels; i++) { for (j = 0; j < ImageWidth / NumLevels; j++) { Line[l++] = i + NumLevels * c; } } for (i = 0; i < ImageHeight / 7; i++) { if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } GifQprintf("\b\b\b\b%-4d", Count++); } } free((char *)Line); if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; } /* end */ giflib-6.1.3/gifecho.c0000664000175000017500000001602515166751647012721 0ustar esresr/***************************************************************************** gifecho - generate a GIF from ASCII text *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifecho" #define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */ #define LINE_LEN 256 /* Maximum length of one text line. */ #define DEFAULT_FG_INDEX 1 /* Text foreground index. */ #define DEFAULT_COLOR_RED 255 /* Text foreground color. */ #define DEFAULT_COLOR_GREEN 255 #define DEFAULT_COLOR_BLUE 255 static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-"; static unsigned int RedColor = DEFAULT_COLOR_RED, GreenColor = DEFAULT_COLOR_GREEN, BlueColor = DEFAULT_COLOR_BLUE; static void QuitGifError(GifFileType *GifFile); static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, int BufferWidth, int ForeGroundIndex); /****************************************************************************** Interpret the command line and generate the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, l, ImageWidth, ImageHeight, NumOfLines, LogNumLevels, ErrorCode, NumLevels, ColorMapSize = 1, ForeGroundIndex = DEFAULT_FG_INDEX; bool Error, ClrMapSizeFlag = false, ForeGroundFlag = false, TextLineFlag = false, HelpFlag = false, ColorFlag = false, GifNoisyPrint = false; char *TextLines[MAX_NUM_TEXT_LINES]; GifRowType RasterBuffer[GIF_FONT_HEIGHT]; ColorMapObject *ColorMap; GifFileType *GifFile; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &ClrMapSizeFlag, &ColorMapSize, &ForeGroundFlag, &ForeGroundIndex, &ColorFlag, &RedColor, &GreenColor, &BlueColor, &TextLineFlag, &TextLines[0], &HelpFlag)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (ForeGroundIndex > 255 || ForeGroundIndex < 1) { GIF_EXIT( "Foregound (-f) should be in the range 1..255, aborted."); } if (ColorMapSize > 8 || ColorMapSize < 1) { GIF_EXIT( "ColorMapSize (-s) should be in the range 1..8, aborted."); } if (TextLineFlag) { NumOfLines = 1; ImageHeight = GIF_FONT_HEIGHT; ImageWidth = GIF_FONT_WIDTH * strlen(TextLines[0]); } else { char Line[LINE_LEN]; NumOfLines = l = 0; while (fgets(Line, LINE_LEN - 1, stdin)) { for (i = strlen(Line); i > 0 && Line[i - 1] <= ' '; i--) { ; } Line[i] = 0; if (l < i) { l = i; } TextLines[NumOfLines++] = strdup(Line); if (NumOfLines == MAX_NUM_TEXT_LINES) { GIF_EXIT( "Input file has too many lines, aborted."); } } if (NumOfLines == 0) { GIF_EXIT("No input text, aborted."); } ImageHeight = GIF_FONT_HEIGHT * NumOfLines; ImageWidth = GIF_FONT_WIDTH * l; } /* Allocate the raster buffer for GIF_FONT_HEIGHT scan lines (one text * line). */ for (i = 0; i < GIF_FONT_HEIGHT; i++) { if ((RasterBuffer[i] = (GifRowType)malloc( sizeof(GifPixelType) * ImageWidth)) == NULL) { while (--i >= 0) { free((char *)RasterBuffer[i]); } GIF_EXIT( "Failed to allocate memory required, aborted."); } } /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out screen description with given size and generated color map: */ for (LogNumLevels = 1, NumLevels = 2; NumLevels < ForeGroundIndex; LogNumLevels++, NumLevels <<= 1) { ; } if (NumLevels < (1 << ColorMapSize)) { NumLevels = (1 << ColorMapSize); LogNumLevels = ColorMapSize; } if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } for (i = 0; i < NumLevels; i++) { ColorMap->Colors[i].Red = ColorMap->Colors[i].Green = ColorMap->Colors[i].Blue = 0; } ColorMap->Colors[ForeGroundIndex].Red = RedColor; ColorMap->Colors[ForeGroundIndex].Green = GreenColor; ColorMap->Colors[ForeGroundIndex].Blue = BlueColor; if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap) == GIF_ERROR) { QuitGifError(GifFile); } /* Dump out the image descriptor: */ if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); for (i = l = 0; i < NumOfLines; i++) { GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth, ForeGroundIndex); for (j = 0; j < GIF_FONT_HEIGHT; j++) { if (EGifPutLine(GifFile, RasterBuffer[j], ImageWidth) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", l++); } } if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } for (i = 0; i < GIF_FONT_HEIGHT; i++) { free((char *)RasterBuffer[i]); } if (!TextLineFlag) { for (i = 0; i < NumOfLines; i++) { free(TextLines[i]); } } GifFreeMapObject(ColorMap); return 0; } /****************************************************************************** Generate raster bits corresponding to given text ******************************************************************************/ static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, int BufferWidth, int ForeGroundIndex) { unsigned char Byte, Mask; int i, j, k, CharPosX, Len = strlen(TextLine); for (i = 0; i < BufferWidth; i++) { for (j = 0; j < GIF_FONT_HEIGHT; j++) { RasterBuffer[j][i] = 0; } } for (i = CharPosX = 0; i < Len; i++, CharPosX += GIF_FONT_WIDTH) { unsigned char c = TextLine[i]; for (j = 0; j < GIF_FONT_HEIGHT; j++) { Byte = GifAsciiTable8x8[(unsigned short)c][j]; for (k = 0, Mask = 128; k < GIF_FONT_WIDTH; k++, Mask >>= 1) { if (Byte & Mask) { RasterBuffer[j][CharPosX + k] = ForeGroundIndex; } } } } } /****************************************************************************** * Close output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFile) { if (GifFile != NULL) { PrintGifError(GifFile->Error); EGifCloseFile(GifFile, NULL); } exit(EXIT_FAILURE); } /* end */ giflib-6.1.3/giffix.c0000664000175000017500000001574415166751647012600 0ustar esresr/***************************************************************************** giffix - attempt to fix a truncated GIF *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "giffix" static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- h%- GifFile!*s"; static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, NumFiles, ExtCode, Row, Col, Width, Height, ErrorCode, DarkestColor = 0, ColorIntens = 10000; bool Error, HelpFlag = false, GifNoisyPrint = false; GifRecordType RecordType; GifByteType *Extension; char **FileName = NULL; GifRowType LineBuffer; ColorMapObject *ColorMap; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; int ImageNum = 0; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles > 1) { GIF_MESSAGE("Error in command line parsing - one GIF " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } else { /* Use stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } /* Open stdout for the output file: */ if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out exactly same screen information: */ /* coverity[var_deref_op] */ if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if ((LineBuffer = (GifRowType)malloc(GifFileIn->SWidth)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (GifFileIn->Image.Interlace) { GIF_EXIT("Cannot fix interlaced images."); } Row = GifFileIn->Image .Top; /* Image Position relative to Screen. */ Col = GifFileIn->Image.Left; Width = GifFileIn->Image.Width; Height = GifFileIn->Image.Height; GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); if (Width > GifFileIn->SWidth) { GIF_EXIT("Image is wider than total"); } /* Put the image descriptor to out file: */ if (EGifPutImageDesc( GifFileOut, Col, Row, Width, Height, false, GifFileIn->Image.ColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Find the darkest color in color map to use as a * filler. */ ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap : GifFileIn->SColorMap); for (i = 0; i < ColorMap->ColorCount; i++) { j = ((int)ColorMap->Colors[i].Red) * 30 + ((int)ColorMap->Colors[i].Green) * 59 + ((int)ColorMap->Colors[i].Blue) * 11; if (j < ColorIntens) { ColorIntens = j; DarkestColor = i; } } /* Load the image, and dump it. */ for (i = 0; i < Height; i++) { GifQprintf("\b\b\b\b%-4d", i); if (DGifGetLine(GifFileIn, LineBuffer, Width) == GIF_ERROR) { break; } if (EGifPutLine(GifFileOut, LineBuffer, Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } if (i < Height) { fprintf(stderr, "\nFollowing error occurred " "(and ignored):"); PrintGifError(GifFileIn->Error); /* Fill in with the darkest color in color map. */ for (j = 0; j < Width; j++) { LineBuffer[j] = DarkestColor; } for (; i < Height; i++) { if (EGifPutLine(GifFileOut, LineBuffer, Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } } break; case EXTENSION_RECORD_TYPE: /* pass through extension records */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (Extension != NULL) { if (EGifPutExtensionBlock( GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } while (Extension != NULL) { if (DGifGetExtensionNext( GifFileIn, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (Extension != NULL) { if (EGifPutExtensionBlock( GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } } if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; } /****************************************************************************** Close both input and output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) { fprintf(stderr, "\nFollowing unrecoverable error occurred:"); if (GifFileIn != NULL) { PrintGifError(GifFileIn->Error); EGifCloseFile(GifFileIn, NULL); } if (GifFileOut != NULL) { PrintGifError(GifFileOut->Error); EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } /* end */ giflib-6.1.3/ChangeLog0000664000175000017500000007307015166751647012726 0ustar esresrshipper: ignore this. It's retained for archival purposes only. 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. 2007-11-10 13:16 abadger1999 * configure.ac: Bump release version in configure.ac. 2007-11-10 13:15 abadger1999 * 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. 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. 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. 2007-11-10 09:22 abadger1999 * 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. 2007-11-09 20:13 abadger1999 * 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. 2007-11-09 13:24 abadger1999 * 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. 2007-11-09 12:36 abadger1999 * 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. 2007-11-09 11:48 abadger1999 * 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. 2007-11-09 11:25 abadger1999 * 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. 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. 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. 2005-11-06 08:32 abadger1999 * 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 * Sync with libungif r93. * ChangeLog: Update to r92. * NEWS: Update with combined libungif/giflib changes. 2005-10-09 Toshio Kuratomi - r92 * lib/gif_lib.h: Change GifPrefixType to unsigned. 2005-10-09 Toshio Kuratomi - r91 * ChangeLog: Update to r90. * NEWS: Update on GBA and Windows fixes. 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: - When Compiling for Game Boy Advance, file functions are not needed so exclude DGifOpenFileName(), DGifOpenFileHandle(), DGifSlurp(), and PrintGifError(). - On Game Boy Advance we need to reduce memory usage. Change values to short int where appropriate. * lib/gif_lib.h: - Handle te GBA changes by defining GifPrefixType and GifWord to int unless compiling on GBA. Then use unsigned short and short 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 * Sync with libungif r85. 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. * doc/lzgif.txt: Change dos line encoding to UNIX. * lib/dgif_lib.c: (eisenbud) - Set GifFile's ColorMaps to NULL when we free a colormap object. - Detect some cases of corrupted GIFs which were crashing the library. * lib/egif_lib.c: Set ColorMaps to NULL when we free a colormap object. * lib/gifalloc.c: Set ColorMaps to NULL when we free a colormap object. * 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 * 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 * Sync with libungif-4.1.3. 2004-05-29 Toshio Kuratomi - r74 * ChangeLog, prop=lastlog: Sync with the subversion logs. 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 * 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 * ChangeLog, prop=lastlog: Sync the ChangeLog for the release. 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. * README: Redundancy fix. * doc/gif_lib.html: Add EGifPutExtension{First,Next,Last} to the documentation 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 * 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. * lib/egif_lib.c: - EGifPutComment(): reimplemented using EGifPutExtensionFirst, Next, and 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. - 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 EGifPutExtension{First,Next,Last} instead. - EGifSpew: Reimplement to use EGifPutExtension{First,Next,Last} so we don't output broken GIFs when there are multiple sub-blocks on an extension. * lib/Makefile.am: Bump version to 4.1.3. * 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 * Clean up some typos. 2004-05-25 Toshio Kuratomi - r66 * Sync with libungif-4.1.2. 2004-03-03 Toshio Kuratomi - r64 Last minute updates to the release notes in various files. 2004-03-03 Toshio Kuratomi - r63 * Set property lastlog to remind me when I last synced the ChangeLog 2004-03-03 Toshio Kuratomi - r62 * ChangeLog: Update 2004-03-03 Toshio Kuratomi - r61 * configure.ac: Bump version to 4.1.2 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 * TODO: Take out -Wall as that's all ready now. 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 indentation of the code. * lib/getarg.h: indent changes * lib/dgif_lib.c: indent changes - Move stdlib.h out of #ifdef's as it's included on all platforms. - Add checks to be sure malloc and MakeMapObject succeed. * lib/quantize.c: indent changes - Move stdlib.h out of #ifdef's as it's included on all platforms. - _GifError already pulled in through gif_lib_private.h. Remove decl. - Make Count in NewColorMapType be unsigned. - Separated mallocs from conditionals in a few places. Easier reading. * lib/gifalloc.c: indent changes - Added four FIXME's where I think the code might not be doing what we want. Need to do more research to figure out. - Add note to MakeExtension that I think it needs to be deprecated. - Separated mallocs from conditionals in a few places. Easier reading. - FreeLastSavedImage: New private function to free the last image in a GifFile structure. Used to back out when unable to completely allocate a new SavedImage structure. - check for NULL values before deallocating in Free* functions and make sure all Free* functions set the pointer to NULL after they deallocate 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) * lib/gif_lib.h: indent changes - Condense the #else #if VARARGS to #elif VARARGS check. * lib/qprintf.c: indent changes - Condense the #else #if VARARGS to #elif VARARGS check. * lib/dev2gif.c: indent changes * lib/getarg.c: indent changes * 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 * 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 * 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 * README: add varargs to the deprecation list 2004-02-20 Toshio Kuratomi - r44 * test-unx: Quote the program names. * lib/dgif_lib.c: - Make sure memory was allocated for the colormap - Some reformatting of code but no syntactic changes. * lib/gif_lib.h: - C++ extern "C" fix - Fix typo with EGifOpen * 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 * 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 * 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 Merge -Wall fixes from branches/Wall-audit r29 * configure.ac: - Make the stdarg vs varargs check simpler by relying on AC_CHECK_HEADERS() magic. - Check for unistd.h * dgif_lib.c, gif_lib.h, egif_lib.c, gifalloc.c, quantize.c, dev2gif.c, getarg.c, gif_lib_private.h, gif_font.c gif_err.c, gifinto.c, icon2gif.c, raw2gif.c, gifcolor.c, gifasm.c, gif2epsn.c, gif2iris.c, gifrotat.c, gifovly.c, gif2x11.c, rle2gif.c, gif2rle.c, text2gif.c, gifspnge.c, gifclrmp.c, giffiltr.c, giftext.c, gifinfo.c, rgb2gif.c, gif2rgb.c, gif2ps.c - Changes to get rid of -Wall compile warnings. + Casting of types + New header includes for unistd.h and fcntl.h + Explicit declaration of many types to unsigned + Removed unused variables and functions + Removed VerStr from every library file. Instead include it via gif_lib_private.h * gif_lib.h, gif_lib_private.h: Moved the VerStr into gif_lib_private.h and made it a #define instead of a static char *. 2004-02-19 Toshio Kuratomi - r37 Deprecation notes 2004-02-19 Toshio Kuratomi - r36 Add notes about security things to do and giflib syncing 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 Add config.h include to gif_hash.c 2004-02-17 Toshio Kuratomi - r30 Sync up with libungif 4.1.1 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 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. 2004-02-16 Toshio Kuratomi * 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. 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. 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 2004-02-15 Toshio Kuratomi 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 2004-02-15 Toshio Kuratomi * 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 2004-02-15 Toshio Kuratomi Import of version 4.1.0b1 2004-02-15 Toshio Kuratomi - r10 Import giflib 4.1.0 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 Release 4.1.0 2004-02-15 Toshio Kuratomi - r6 Import of version 4.1.0 2004-02-15 Toshio Kuratomi - r5 Set ignore patterns on the project directories. 2004-02-15 Toshio Kuratomi - r3 Remove a Makefile.in that was left in in the first commit. 2004-02-14 Toshio Kuratomi - r2 Commit revision 3.1.0 to subversion 2004-02-14 Toshio Kuratomi - r1 Initial SVN Repository Layout 2000 6 Feb Toshio Kuratomi * configure.in: Change to using config.h - Every .c file: Change to using config.h. * configure.in: added check for varargs header. * lib/getarg.c: Changed the ifdef USE_VARARGS to ifdef HAVE_VARARGS_H. - lib/getarg.h: Ditto. - lib/gif_lib.h: Ditto. - lib/qprintf.h: Ditto. 2000 6 Feb Toshio Kuratomi * lib/getarg.h: Prepend an underscore to the header file define. * lib/gif_lib.h: Ditto * lib/gif_lib_private.h: Ditto * lib/getarg.c: ifdef'd MyMalloc so it actually won't define if it already is. 2000 3 Feb Toshio Kuratomi * A new cvs repository based my private tree from home. It now goes back to giflib-3.0. * Updated the cvs repository to make multiple developers possible. * Merge all of Michael's patches into the distribution. * DEVELOPER: Updated to reflect the new versions of autoconf/automake/libtool we're using. * libungif.spec: Updated a few things from the latest redhat spec file. 1999 5 Dec Toshio Kuratomi * Update links to the web pages as I have reorganized them somewhat. * Add the welcome2.gif to the pic directory and a test that utilizes it to test-unx. 1999 17 Nov Toshio Kuratomi * New cvs Repository. Hopefully I've got everything that was in the old one. This one is available on anonymous cvs. * Update to libtool 1.3.3, automake 1.4, and autoconf 2.13 1999 23 May Michael R Brown * Lots of 'const' qualifiers added, thanks Alexis Wilke for finding these. 1999 22 Mar Michael R Brown * util/gif2x11.c: Patch by (who?) to fix lots of memory leeks. * util/*.c: lib/dgif_lib.c: Makefile.in: Patch by David Kaelbling to compile on IRIX 6.x. Basically fixing lots of bad/missing parameter passing to printf, scanf and similar. * Added pics/welcome2.gif, from Peter Merz which provokes a bug prior to patch 19990224 to do with colour map management. There is still a problem with util/gifspnge processing this image, so it will not be added to test-unx yet. 1999 05 Mar Michael R Brown * lib/getarg.c: Lines 107 and 189 Added ifdef's to use stdarg when available. On dec-alpha the default code was causing programs to crash, probably because it assumes a stack that grows-up. 1999 24 Feb Michael R Brown * lib/dgif_lib.c: Lines 363 and 367 Bug reported by Steve Sanders, where &'s where causing the memcpy to overwrite the pointers. Fixed by removing the &'s so that memcpy overwrote the memory pointed to. 1999 09 Feb Toshio Kuratomi * Release 4.1.0 1999 09 Feb Toshio Kuratomi * Merge libungif changes into the giflib tree: - upgrade to libtool 1.2b - util/Makefile.am: Minor change to allow compilation outside the source_dir. - lib/egif_lib.c: FILE_STATE_WRITE, FILE_STATE_SCREEN, FILE_STATE_IMAGE, IS_WRITEABLE are now in gif_lib_private.h - lib/dgif_lib.c: FILE_STATE_READ and IS_READABLE are now in gif_lib_private.h - lib/gif_lib_private.h: Above mentioned constants and macros are now here. FILE_STATE_READ is now 0x08 instead of 0x00. - configure.in: Update version to 4.1.0 - lib/Makefile.am: Update libtool version to 5:0:1 (libtool) - giflib.spec: Update for version 4.1.0 (Add libungif-4.1 compatibility stuff and change version.) - giflib.lsm: Update for version 4.1.0 - lib/egif_lib.c: (WRITE) change from a function to a macro. - lib/dgif_lib.c: (DGifOpenFileName) close FileHandle on error. - lib/dgif_lib.c: (DGifOpenFileHandle) make sure the FILE stream is closed if we hit an error. - lib/dev2gif.c, lib/quantize.c, lib/gif_err.c, lib/gif_lib_private.h: Reflect Eric's copyright notice rather than Gershon's 1999 14 Jan Michael R Brown * lib/gif_lib.h: Add OutputFunc type * lib/gif_lib.h: Add EGifOpen for user supplied output function * lib/egif_lib.c: (EGifOpenFileName) Fixed wasted memory when an error occurs in EGifOpenFileHandle * lib/egif_lib.c: Add EGifOpen, WRITE, and lots of changes to support user supplied output function. Basically changing all fwrite's to WRITE, and then all of the knock on effects. 1998 17 Dec Toshio Kuratomi * configure.in: Change references to libungif to giflib. * libungif.lsm: Rename to giflib.lsm and change to reflect giflib rather than libungif. * 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. * Makefile.am: Replace libungif with giflib. * README: Adapted language to giflib. * lib/Makefile.am: Changed references to libungif to libgif. * util/Makefile.am: Changed references to libungif to libgif. 1998 17 Dec Toshio Kuratomi * lib/egif_lib.c: Merge LZW stuff into this branch of the library. This includes numerous changes to initialize the hash table as well as the code forthe encoder. * lib/gif_hash.c: Functions needed for the LZW encoder. * lib/gif_hash.h: Functions needed for the LZW encoder. * lib/Makefile.am: Add gif_hash.c gif_hash.h to the list of sources. 1998 15 Dec Toshio Kuratomi * lib/dgif_lib.c: (DGifSlurp) Fix a Seg Fault when an image contains no extension blocks. 1998 14 Dec Toshio Kuratomi * configure.in: Update version to 4.0 * lib/Makefile.am: Update libtool version to 4:0:0 (libtool) * libungif.spec: Update for version 4.0 (not binary compatible with giflib, change version.) * lib/gif_lib_private.h: (PrivateType) New header for common stuff private to the library. Currently, this is only the Private struct. * lib/dgif_lib.c: (PrivateType) Extract the Private struct to gif_lib_private.h * lib/egif_lib.c: (PrivateType) Extract the Private struct to gif_lib_private.h * lib/Makefile.am: Add gif_lib_private.h to the list of source files. * lib/gif_lib.h: (ExtensionBlock) Add a Function entry to the ExtensionBlock record. Note that this is not entirely correct: the GifLib ExtensionBlock structure is actually a data sub-block record. By adding the function entry here, we are pushing the ExtensionBlockType in with the DataSubBlock. Sometime in the future, we need to change the API to have true ExtensionBlocks which have DataSubBlocks belonging to them. * lib/gif_lib.h: (ExtensionBlock) Deprecate the use of Function in the SavedImage struct. Use ExtensionBlock's Function instead. * lib/egif_lib.c: (EGifSpew) Changes to use the new Function variable. * lib/dgif_lib.c: (DGifSlurp) Changes to put data into the new Function variable. 1998 3 Dec Toshio Kuratomi * lib/dgif_lib.c: (DGifSlurp) Three changes: - No longer allocate SaveImage in this function. All allocations of SaveImage take place in DGifGetImageDesc. - Extension blocks are now associated with the Image Block that is read in subsequent to them, not before. This should now be conformant to the gif89a specification. - Fix an off-by-one error when copying extension data from structure to structure. * lib/dgif_lib.c: (DGifGetImageDesc) Change the function to do its own allocation of space for the SavedImage structure no matter what. * lib/egif_lib.c: (EGifSpew) The function now spits out ExtensionBlocks before the associated Image Block to conform with the gif89a specification. * lib/egif_lib.c: (EGifOpenFileHandle) Move the write of the GifVersion (gif87a or gif89a) from this function into EGifPutScreenDesc so that it can be controlled by EGifSpew. Note that this is still a hack as the GifVersion write doesn't really belong in either of these functions. * lib/egif_lib.c: (EGifPutScreenDesc) Moved writing the version (gif87a or gif89a) into the file into this function from EGifOpenFileHandle. * test-unx: Now test the extension code. * pic/x-trans.gif: New image with Comments and transparency to test the extension code with. 1998 29 Nov Toshio Kuratomi * lib/dgif_lib.c: (DGifSlurp) Fix a few of the minor bugs plaguing this function. At this point, the function should no longer cause a Seg Fault. It is now losing all extension data however. I know how to hack a fix in, but I need to commit these changes first. * lib/dgif_lib.c: (DGifGetImageDesc) Fix my bug fix: the colormap is now only copied if it exists :-). 1998 10 Nov Toshio Kuratomi * test-unx: Add a test for DGifSlurp and EGifSpew 1998 14 Oct Toshio Kuratomi * lib/dgif_lib.c: (DGifGetImageDesc) Fix a bug where the Colormap for the image description and the SaveImage were pointers to the same structure, causing a SegV when DGifClosing the file. 1998 9 Oct Toshio Kuratomi * lib/dgif_lib.c: (DGifSlurp) memory for the extensions was not being allocated. Now I call AddExtensionBlock when I add an extension to the structure. Additionally, fix a memory leak here. * configure.in, NEWS, lib/Makefile.am: Update to version 3.1.1 * ltmain.sh, ltconfig: removed from the cvs repository * BUGS: add the BUGS file to list unresolved BUGS. 1998 9 Sep Toshio Kuratomi * libungif.spec: Fix wrong version in %files and %install section. 1998 8 Sep Toshio Kuratomi * lib/gif_hash.c, lib/gif_hash.h: Removed these because a hash table is not needed to create uncompressed gifs. * 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). 1998 6 Sep Toshio Kuratomi * util/*.{gif.rle}: removed files that were left by my testing process and shouldn't have been in the distribution. * UNCOMPRESSED_GIF: add section on why software that can decode LZW compressed gifs (but not write them) is legal. * .cvsignore: added .cvsignore files to ignore Makefiles and other generated files in my cvs repository. * Makefile.am's: Fixes to allow the dist* family of targets to work correctly. Preliminary support for make check as well. * configure.in: Update version to 3.1.0 * lib/Makefile.am: Update libtool version to 4:0:1 libtool) * libungif-3.0.spec: Update from Marc Ewing. * Add int/pointer Alpha fixes from Dick Porter to many source files. giflib-6.1.3/tests/0000775000175000017500000000000015166751647012307 5ustar esresrgiflib-6.1.3/tests/tapview0000775000175000017500000001475315166751647013726 0ustar esresr#! /bin/sh # tapview - a TAP (Test Anything Protocol) viewer in pure POSIX shell # # This code is intended to be embedded in your project. The author # grants permission for it to be distributed under the prevailing # license of your project if you choose, provided that license is # OSD-compliant; otherwise the following SPDX tag incorporates the # MIT No Attribution license by reference. # # SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: MIT-0 # # This version shipped on 2024-02-05. # # A newer version may be available at https://gitlab.com/esr/tapview; # check the ship date oagainst the commit list there to see if it # might be a good idea to update. OK="." FAIL="F" SKIP="s" TODO_NOT_OK="x" TODO_OK="u" LF=' ' ship_char() { # shellcheck disable=SC2039 printf '%s' "$1" # https://www.etalabs.net/sh_tricks.html } ship_line() { report="${report}${1}$LF" } ship_error() { # Terminate dot display and bail out with error if [ "${testcount}" -gt 0 ] then echo "" fi report="${report}${1}$LF" echo "${report}" exit 1 } testcount=0 failcount=0 skipcount=0 todocount=0 status=0 report="" ln=0 state=plaintext # shellcheck disable=SC2086 context_get () { printenv "ctx_${1}${depth}"; } context_set () { export "ctx_${1}${depth}=${2}"; } context_push () { context_set plan "" context_set count 0 context_set test_before_plan no context_set test_after_plan no context_set expect "" context_set bail no context_set strict no } context_pop () { if [ "$(context_get count)" -gt 0 ] && [ -z "$(context_get plan)" ] then ship_line "Missing a plan at line ${ln}." status=1 elif [ "$(context_get test_before_plan)" = "yes" ] && [ "$(context_get test_after_plan)" = "yes" ] then ship_line "A plan line may only be placed before or after all tests." status=1 elif [ "$(context_get plan)" != "" ] && [ "$(context_get expect)" -gt "$(context_get count)" ] then ship_line "Expected $(context_get expect) tests but only ${testcount} ran." status=1 elif [ "$(context_get plan)" != "" ] && [ "$(context_get expect)" -lt "$(context_get count)" ] then ship_line "${testcount} ran but $(context_get expect) expected." status=1 fi } directive () { case "$1" in *[[:space:]]#[[:space:]]*$2*) return 0;; *) return 1;; esac } depth=0 context_push while read -r line do ln=$((ln + 1)) IFS=" " # shellcheck disable=SC2086 set -- $line tok1="$1" tok2="$2" tok3="$3" IFS="" # Ignore blank lines and comments if [ -z "$tok1" ] || [ "$tok1" = '#' ] then continue fi # Process bailout if [ "$tok1" = "Bail" ] && [ "$tok2" = "out!" ] then ship_line "$line" status=2 break fi # Use the current indent to choose a scope level leading_spaces="${line%%[! ]*}" indent=${#leading_spaces} if [ "${indent}" -lt "${depth}" ] then context_pop depth="${indent}" elif [ "${indent}" -gt "${depth}" ] then depth="${indent}" context_push fi # Process a plan line case "$tok1" in [0123456789]*) case "$tok1" in 1[.][.]*) if [ "$(context_get plan)" != "" ] then ship_error "tapview: cannot have more than one plan line." fi if directive "$line" [Ss][Kk][Ii][Pp] then ship_line "$line" echo "${report}" exit 1 # Not specified in the standard whether this should exit 1 or 0 fi context_set plan "${line}" context_set expect "${tok1##[1][.][.]}" continue ;; *) echo "Ill-formed plan line at ${ln}" exit 1 ;; esac ;; esac # Check for test point numbers out-of-order with the sequence (TAP 14) testpoint="" case "$tok1" in ok) testpoint="$tok2";; not) testpoint="$tok3";; esac case "$testpoint" in *[0123456789]*) if [ "${testpoint}" != "" ] && [ "$(context_get expect)" != "" ] && [ "${testpoint}" -gt "$(context_get expect)" ] then ship_error "tapview: testpoint number ${testpoint} is out of range for plan $(context_get plan)." fi ;; esac # Process an ok line if [ "$tok1" = "ok" ] then context_set count $(($(context_get count) + 1)) testcount=$((testcount + 1)) if [ "$(context_get plan)" = "" ] then context_set test_before_plan yes else context_set test_after_plan yes fi if directive "$line" [Tt][Oo][Dd][Oo] then ship_char ${TODO_OK} ship_line "$line" todocount=$((todocount + 1)) elif directive "$line" [Ss][Kk][Ii][Pp] then ship_char ${SKIP} ship_line "$line" skipcount=$((skipcount + 1)) else ship_char ${OK} fi state=plaintext continue fi # Process a not-ok line if [ "$tok1" = "not" ] && [ "$tok2" = "ok" ] then context_set count $(($(context_get count) + 1)) testcount=$((testcount + 1)) if [ "$(context_get plan)" = "" ] then context_set test_before_plan yes else context_set test_after_plan yes fi if directive "$line" [Ss][Kk][Ii][Pp] then ship_char "${SKIP}" state=plaintext skipcount=$((skipcount + 1)) continue fi if directive "$line" [Tt][Oo][Dd][Oo] then ship_char ${TODO_NOT_OK} state=plaintext todocount=$((todocount + 1)) continue fi ship_char "${FAIL}" ship_line "$line" state=plaintext failcount=$((failcount + 1)) status=1 if [ "$(context_get bail)" = yes ] then ship_line "Bailing out on line ${ln} due to +bail pragma." break fi continue fi # Process a TAP 14 pragma case "$line" in pragma*) case "$line" in *+bail*) context_set bail yes;; *-bail*) context_set bail yes;; *+strict*) context_set strict yes;; *-strict*) context_set strict yes;; *) ship_line "Pragma '$line' ignored";; esac continue ;; esac # shellcheck disable=SC2166 if [ "${state}" = "yaml" ] then ship_line "$line" if [ "$tok1" = "..." ] then state=plaintext else continue fi elif [ "$tok1" = "---" ] then ship_line "$line" state=yaml continue fi # Any line that is not a valid plan, test result, pragma, # or comment lands here. if [ "$(context_get strict)" = yes ] then ship_line "Bailing out on line ${ln} due to +strict pragma" status=1 break fi done /bin/echo "" depth=0 context_pop report="${report}${testcount} tests, ${failcount} failures" if [ "$todocount" != 0 ] then report="${report}, ${todocount} TODOs" fi if [ "$skipcount" != 0 ] then report="${report}, ${skipcount} SKIPs" fi echo "${report}." exit "${status}" # end giflib-6.1.3/tests/porsche.rgb0000664000175000017500000056700015166751647014456 0ustar esresr"3DU"f""w""w""33333333333333333333333333333w""w""w""w""w""w""f""f""f""U"DD3"DU"33DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D33333333w""f""U"DD3""""DDD"""U"3DDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D33333w""w""f""U"DD3"DDDDDDDDD""""""3DDU333U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"f""w""333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D333w""f""U"DD3"wffDDD333""""""D3f""f""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDfD3fD3DDU"U"U"U"U"U"U"U"U"U"U"U"f""w""33333D3D3D3D3D3D3D3D333f""U"DD3""""wffDDD""""""D3f""DDD"""""""""333333333DDD333DDDDDDDDDDDDDDDDDDfD3fD3f""f""f""f""f""U"U"U"U"U"f""333333D3D3D3D3D3D33333f""f""DUUUUUUDDD"""D3DDD"""333333333DDDfD3fD3fD3fD3f""f""f""f""f""f""U"U"f""333333D3D3D3D3D3D3D3DDDDDD"""UUUUUU333"""f""3""""""DDDDDD""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333"""""""""""""""""""""""""""333333DDDDDDfD3fD3fD3U"f""w""f""U"U"f""w""333D3D3D3D3DDDDDDDDDDUUUUUUDDD333"""f""3"""""""""wffwff333"""333wffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUUUUDDDUUUDDDDDD333333"""""""""""""""333DDDfD3fD3U"f""f""3w""f""U"U"333D3D"""DDDwffwffDDD""""""UUUUUUDDD333"""f""3"""""""""DDDwffwff""""""DDDwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUDDDDDD333"""""""""""""""333DDDDDDfD3fD3U"w""33f""U"U"33"""333DDDwffwffDDD"""333UUUUUUDDD333"""f""3""""""UUUUUUUUU333"""333UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU333333"""333DDDfD3fD3U"w""33w""U"U"w""D"""333DDDwffwffDDD""""""DDDUUUUUUDDD333"""f""3""""""333DDDDDDDDD""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333DDD333333"""""""""333333fD3fD33333w""U"U"w""D"""333DDDwffwffDDD"""DDDDDDUUUDDDDDD333"""f""3""""""333DDDDDDDDD333"""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333""""""DDDDDDDDDDDD333333"""""""""333DDDDDDfD3333D33U"U"U"w""D"""333DDDwffwffDDD""""""DDDUUUUUUDDDDDD""""""f""3""""""333DDDDDDDDDDDD""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""333DDDDDDDDDDDDDDDDDDDDD333333"""""""""333DDDDDDfD33333D33U"U"U"w""D"""333DDDwffwffwff333333UUUUUUDDDDDD333"""f""3""""""333DDDDDDDDDDDD333"""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333"""""""""333DDDfD3333D3D33U"U"U"w""D"""333DDDwffwffwffDDD"""DDDUUUDDDDDDDDD333"""3f""""""""333DDDDDDDDDDDDDDD""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333""""""""""""DDDfD33333D3D33U"U"w""D333333DDDwffwffwffDDD""""""333DDDUUUDDDDDD333333"""fD33f""""""""333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333"""""""""DDDfD3333333D33U"U"U"f""D"""333DDDwffwffDDDDDD"""333UUUUUUDDDDDD333333"""fD33f""""""""DDDDDDDDDDDDDDDDDDDDD""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""""""""DDDDDD3333333D3D33U"U"U"D333333DDDDDDwffDDDDDD"""DDDUUUUUUDDD333333333"""fD33f""""""""333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333"""""""""DDDDDD333333D3D3Dw""U"U"U"D"""333DDDDDDDDDDDD""""""333DDDUUUDDDDDD333333333"""f""3f""""""""333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333"""333DDD33333333D3D3D3Dw""U"U"w""D"""333DDDDDD333333333UUUUUUDDD333333333"""f""3f""""""""333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDD3333333333D3D3D3Dw""U"U"U"D"""DDDw""DUUUUUUUUUUUUUUU3333333DDUDUDDDDDDDDD3f""""""""333333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""DDD333333333D3D3D3D3D3Dw""U"U"U""""f""33333w""DUUU333UUU3333D3D3D3DDUDDD""""""f""""""""333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDD""""""333333333333D3D3D3D3D3D3Dw""U"U"w""3D3D3D3333DD"""333DDDwffwffwffDDDwffDDDDDD333DDD333333333333333333333333333333333333333"3DD33333UUU"""3DDUDUDU3DDDD""""""""""""333333333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333"""333""""""""""""""""""fD333333333333333D3D3D3D3D3D3D3U"U"w""w""3D3DD33w""f""DUDU33DDDDDD333333333333333333333"""""""""""""""""""""""""""""""""""""""""""""""""DDU"w""w""w""w""w""w""DD33D3D3D3D3DDDD""""""""""""333333333333333333333333333333333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""""""333333333333333333333333333333333333333333333333333333333333333"""333"""""""""""""""""""""333U"fD3f""33333333333333333333333D3D3D3D3D3w""U"w""w""D3D3D3Dw""w""w""w""w""3DDD333333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""3DDf""f""f""f""f""f""f""f""f""f""f""f""DDDDD3D3D3D3D3D333""""""U"U"U"U"U"DDf""f""f""w""333333333333333333333333333333333333333D3D3D3D3D333U"U"w""3D3D3DD3D3D3D333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDU"U"f""f""f""w""w""w""w""w""w""333333333333D3D3D3D3DDDD333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDDf""f""f""333333333333333333333333333333333333333333333333333333333333D3D3D3D333U"w""3D3D3D3D333333333"""""""""""""""""""""""""""""""""""""""""""3DDU"f""333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3U"U"DD3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Df""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D333D3D3333333333333333333333333333333333333333333333333333333333333D3D3D3D33U"w""3D3D"D"3DDU"f""333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDU333DDUDU33U"U"U"D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUf""DUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D333333333333333333333333333333333333333333333333333333333333333333333D3D3D333U"w""3DD""""""""""33333D"3DU"333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3Dw""33D3D3D3DU""""DD3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Df""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D33333333333333333333333333333333333333333333333333333D3D3D3U"U"f""DD"33333333333D"3DU"w""33333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUw""DUDUDUDUDUDUw""U"U"U"w""w""DUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUf""DUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D33333333333333333333333333333333333333333D3D333U"U"U"D""3DDDDDDD"3DU"w""333D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Dw""3D3D3D3D3D3D3Dw""w""w""w""w""w""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Df""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3333333333333333333333333333333333333D3U"U"U"D3"3DDDD3DDf"""33333D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Dw""3D3D3D3D3D3D3D3D33333333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Df""DDDDU"33DDDDDDwff3D33f""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D333D3D3D3D3D333D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3DDU3D3D3D3D3D3D3333333333333333333333333333333333333D3DU"U"U"D"33DDf""w""3D33U"3D3D3D3D3D3D3D3D3D3DDU3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3Dw""333D3D3D3D3D3D3D33333333333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDDD"""""""""3Dw""33D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D33333D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333333333333333333333333333DU"U"U"D333f""333D3DD3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333w""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333D"""f""f""f""w""3DDU"""wff3Df""3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D33333333333333333333333333333D3DU"U"D33333DUw""w""DUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333333w""333333333333333333333333333333333333333333333333333333333333333333333333DDUDUDU333333333333f""3D333333333333333333333333333333333D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333333333333333333D3DU"U"DU"33DDUU"DU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D33333333333333w""3333333333333333333333333333333333333333333333333333333333333333333333333333333333f""3333333333333333333333D3D3D3D3D3D3DDUDUDUDUDUDUDU̻DUDUDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3333333333333333333D3D3DU"U"3333Dw""w""3D3D333333333333333333333333333D3D3DDUDUDUDUDUDUDUDUDUDUDU̻DUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D33333333333w""333333333333333333333333333333333333333333333333333333333333333333333333333333333f""333333333333f""f""3333D3D3D3D3D3D3DDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3DDUDUDUDUDUDUDUDUDUDU3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D33333333333333333D333D33D3DU"33333333333333333333333333333333333D3DDUDUDUDUDUDUDUDU3D3D33333333333333D3D3DDUDUDUDUDUDU3D3D3D3D3D333333333333w""w""w""f""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""3333333f""f""f""3333D3D3D3D3D3DDUDUDUDUDUDU3D3D3f""U"U"U"U"U"U"U"f""f""f""w""33D3DDUDUDUDUDUDUDU3D3D3D3D3D3D3D3333333D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D333333333333333D33U"D333Dw""w""333333333333333333333333333333333D3DDUDUDUDUDU3D33DD33""""DU"333D3DDUDUDUDUDU3D3D33333333333w""w""w""w""w""w""w""f""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""w""f""f""w""w""w""w""w""w""w""w""f""f""f""f""333D3D3D3D3D3D3DDUDUDU3D3D3f""f""DD3""33Df""333D3DDUDUDUDU3D3D3D3D3D3D333333333333333333333333333D3D3D3D3D3D3D33333333333333U"3333DU"333333333333333333333333333333333D3DDUDU3D3D3Dw""DD3"3U"w""333DDUDUDUDU3D3D3333w""w""w""w""w""w""w""w""w""w""w""w""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""333D3D3D3D3D3DDUDUDUDU3Dw""f""D3""Df""33DDUDUDUDU3D3D3D3D3D33333333333333333333333333D3D3D3D3D3D33333333U"33w""w""3333333333333333333333333333333DDUDU3D3D3D3D3"D3333DDUDUDU3D3D33w""w""w""w""w""w""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""w""w""3D3D3D3D3D3DDUDUDU3D3Df""D""Df""33DDUDUDU3D3D3D3D333333333333333333333333333333D3D3D3D333U"Dw""w""U"333333333333333333333333333333DDUDU3D3D3D""""""""""333333333333333333333333333"""""""""D33D3DDU3D3D3D3w""w""w""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""w""w""3D3D333""""""""""""""""""3D3DD""""""""""""333333333333333333""""""""""""3D33DDUDU3D3D3D3D33333333333333333333333333333333333DU"Dw""w""333333333333333333333333333DDU3D3D3D""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333"""""""D333DDU3D3D3w""f""f""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""w""w""3DDD"""""""""""""""""""""3D3D"""""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""""""""Dw""3DDUDU3D333D33333333333333333333333333""""""""""""""""""""""""""""""3DDw""3333333333333333333333D3D3D3D3"""333333DDDDDDDDDDDDDDD333333333333333333333DDDDDDDDDDDD333333333"""D33D3D3D33w""w""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""w""w""3DDD""""""""""""""""""D3D3"""""""333DDDDDDDDDDDDDDD333333333333333333DDDDDDDDDDDDDDDDDD333333""""w""3DDUDU3D333333333333333333333333"""fUfUUUfffU3Dw""DD33333333333333333333D3D3D33333DDDDDDDDD333333333"""""""""""""""""""""""""""""""""333333DDDDDDDDD333333"""Dw""3D3D3D3f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""w""3DDD""""""""""""""""""D3D3"333333DDDDDD333333333"""""""""""""""""""""""""""""""""333333DDDDDDDDD333333""""w""3DDUDU33333333333333333333333333333ffffUUfݙDfU3D33333333333333333333333333D3D33333DDD333333333"""""""""""""""""""""""""""""""""""""""""""""""""""333333DDD333333333D33D3D3w""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""3DDD"""""""""""""""""""""33"333333333333333"""""""""""""""""""""""""""""""""""""""""""""""""""333333DDDDDD333333"w""33DU33333333333333333333333"""ffݙDfUffݙDfUDDDDDDDDDDDDDDDDDDDDDDU"f""w""333D3D33333333333333""""""""""""""""""""""""""""""333333333333333D33D3Dw""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""3DDD"""""""""""""""""""""f""3"333333333333""""""""""""""""""""""""""""""333DDD333333333333333333333333333333333333333333fݙDݙDfffݙDݙDݙDfUDUDUDUDUDUDUDUDUDUDUDUDUDUDUDUUUU"""UUU"""UUU"""UUU"""UUU"""UUU""""""""""""""""""333333333""""""""""""""""""""""""333333333333D3D3D3f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""w""DDD"""""""""""""""""""""D3D333333333""""""""""""""""""""""""333DDD333333Dw""333333333333333333333"""ffݙDݙDݙDfݙDݙDݙDݙDfUw""w""33333333333333DDDDDDDDDDDDDDDDDDD""""""333333333"""""""""DDDUUUUUUwffwffwffwffwffUUUUUUDDD"""""""""333333333333f""33Dw""f""f""f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""DDD"""""""""""""""""""""f""f""333333333"""""""""DDDUUUUUUwffwffwffwffwffUUUUUUDDD"""""""""333333333333"D33333333333333333333333333""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDD333DDDDDDDDD"""""""""""""""""""""DDDDDDDDDDDDDDD""""""""""""""""""""""""""""""333333333"""""""""333UUUwffwffwffUUUUUUUUUUUUUUUUUUUUUwffwffwffUUU333"""""""""333333333333"f""33f""f""f""f""f""f""f""f""U"U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""f""U"f""f""f""DDD""""""""""""""""""Df""333333333"""""""""333UUUwffwffwffUUUUUUUUUUUUUUUUUUUUUwffwffwffUUU333"""""""""333333333333DDDDDDD"""""""""""DD333"""333"""333"""333"""333"""U"U"U"U"U"U"U"U"U"DDDDDDDD333""""""fff"""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333"""""""""UUUUUUwffUUUUUU333333333333333333333333333UUUUUUwffwffUUU"""""""""3333333333333w""3f""U"U"f""f""f""f""f""f""U"f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""U"U"f""f""DDD"""""""""""""""f""D333333333"""""""""UUUUUUwffUUUUUU333333333333333333333333333UUUUUUwffwffUUU"""""""""333333333333U"33f""f""f""f""w""33D3D3D3D3D3D3D3D3DDUDUDUwff"""wff"""wff"""wff"""wff"""DUDUDUDUDUDUDUDUDUDU3D3"""DDD333333""""""ff3D"""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333"""""""""UUUwffUUUDDD333DDDUUUUUUUUUUUUUUUUUUUUUUUUUUUDDD333DDDwffwffwff"""""""""333333333"""f""f""f""U"U"f""f""f""f""f""f""Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""f""f""U"U"U"U"DDD"""""""""DU"333333333"""""""""UUUwffUUUDDD333DDDUUUUUUUUUUUUUUUUUUUUUUUUUUUDDD333DDDwffwffwff"""""""""333333333""""w""f""f""f""f""w""w""333333333333""""""""""""""""""""""""w""w""3333333333""""""333333333UU33"""""""""""""""""""""333333333"""""""""UUUwffUUU333UUUwffUUUDDD"""U"U"U"U"DDDUUUwffUUUDDDUUUwffwff"""""""""3333333333f""f""U"U"U"U"U"U"U"U"Df""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""U"U"U"U"U"f""""""""f""D333333333"""""""""UUUwffUUU333UUUwffUUUDDD"""U"U"U"U"DDDUUUwffUUUDDDUUUwffwff"""""""""333333333"""Dw""f""f""f""f""w""333333333333"""""""""""""""333333333333333333333DDD333DDDDDDDDDDDD""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333""""""UUUwffUUU333wffwffDDD"""UfffD3U"U"DDDwffwffUUUUUUwffwff""""""333333333"""f""f""f""U"U"U"U"U"U"U"DU"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"Df""U"U"U"U"U"U"f"""""DU"333333333""""""UUUwffUUU333wffwffDDD"""UfffD3U"U"DDDwffwffUUUUUUwffwff""""""333333333""""w""f""f""f""f""f""w""33333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDDDDDDDD""""""333333"""""""""UUUwffUUUUUUwffUUU"""UfffUfD3"""UUUwffUUUUUUwffwff"""""""""3333333333f""f""U"U"f""f""f""f""f""DDf""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""f""Df""f""U"U"U"U"U"U"""""""DU""""333333"""""""""UUUwffUUUUUUwffUUU"""UfffUfD3"""UUUwffUUUUUUwffwff"""""""""333333333w""f""f""f""f""f""w""33333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333333D""""""333333"""""""""DDDwffwffUUUwffUUUU"UUfffU"""UUUwffUUUUUUwff333"""""""""333333""""f""U"U"U"U"U"U"U"U"DDU"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"DU"U"U"U"U"U"U"f""""""""U"D"""333333"""""""""DDDwffwffUUUwffUUUU"UUfffU"""UUUwffUUUUUUwff333"""""""""333333"""Df""f""f""f""f""w""33333333333"""""""""""""""""""""""""""""""""333333"""""""""UUUwffUUUwffUUUU"fUUwffUݙDfU"""wffUUUUUUwffwff333"""""""""333333"""3f""U"U"U"U"U"U"U"U"3U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"DU"U"U"U"U"U"U"U""""DU"""""333333"""""""""UUUwffUUUwffUUUU"fUUwffUݙDfU"""wffUUUUUUwffwff333"""""""""333333""""w""f""f""f""f""f""w""3333333333"""""""""""""""DU"U"U"U"U"U"U"DDDD"""""""333DDDDDDDDDDDDD""""333333333""""""DDDwffUUUwffUUUU"UUffUUUUDDDfݙDffD3""""""wffUUUUUUwffDDD""""""333333"""f""U"U"U"U"U"U"U"U"3U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"U"DU"U"U"U"U"U"U"D""""""DU"333333333""""""DDDwffUUUwffUUUU"UUffUUUUDDDfݙDffD3""""""wffUUUUUUwff333""""""333333"""w""f""f""f""f""f""w""33w""w""w""w""w""w""w""w"""""DDDDDDDDDDDD"""""""""3DDDDDDDDU"U"U"f""f""f""""""""""""333333"""""""""UUUwffUUUwffUUUU"UfݙDݙDfUffU"""""""""wffUUUUUUwffUUU"""""""""333"""DDDDDDDDDD33333333333333333333333333333333333333333333333333333333333333333333DDDDDDDD"""DU"333333"""""""""UUUwffUUUwffUUUU"UfݙDݙDfUffU"""""""""wffUUUUUUwffUUU""""""""""""333"""w""w""U"U"U"U"U"U"U"U"U"DDDDDD"""""""""""""""""""""33DDDDDDU"U"U"f""f""f"""""""""""333333"""""""""wffwffwffUUUU"fD3fD3UfݙDݙDݙDU""""""DDD"""fD3fD3UUUwffUUUwffwff333"""""""""333""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDD"""333333"""""""""wffwffwffUUUU"fD3fD3UfݙDݙDݙDU""""""DDD"""fD3fD3UUUwffUUUwffwff333"""""""""333"""Df""U"U"DDDDDDDDD3333"""""""""""""""""333DDDDDDU"U"f""f""U""""""""""333333"""""""""wffwffwffUUUfD3fD3Uff333333fD3UfffffD3wffUUUwff"""333""""""333"""""""""333333"""""""""wffwffwffUUUfD3fD3Uff333333fD3UfffffD3wffUUUwff"""333""""""333"""Df""U"DDDDDDDDDDDDD33333333333""""""""""""""""""""""333DDDDU"U"f""f""U"""""""333333"""""""""wffwffUUU333wffwfffݙDݙDݙDݙDݙDݙDݙDfD3wffwffwff333333""""""333""""""333333"""""""""wffwffUUU333wffwfffݙDݙDݙDݙDݙDݙDݙDfD3wffwffwff333333""""""333"""3f""DDDDDDDDDDDD3333333333"""333DDDDU"Df""""""""333333"""""""""wffwff333DDD333333fffffffffD3wffwffwffDDD333""""""333"""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDDD"""333333"""""""""wffwff333DDD333333fffffffffD3wffwffwffDDD333""""""333"""f""DDDDDDDD33333333333""333333333"""""""""333333"""""""""wffwff"""DDDDDDݙDUU"U"333U"fD3fD3UfD3wffwffDDD333""""""""""""333333333333333333333333333333333333333333333333333333333333333333333"""""""""""""""3333333333333333333333DDU"U""""333333"""""""""wffwff"""DDDDDDݙDUU"U"333U"fD3fD3UfD3wffwffDDD333""""""""""""3DD33333333333"""""""""""""333333"""""""""wffDDDfݙDfUUU333333U"fD3wffDDD"""333""""""""""33DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333DDU"U"U""""333333"""""""""wffDDDfݙDfUUU333333U"fD3wffDDD"""333""""""""""333333""""""""""""""""""""""""""""""""""""""""""""""""""""333333"""""""""wffwffUݙDݙDfU"""ffUDDDDDD"""wffDDD"""333""""""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""DDDDDDDDDDDDD333333333DDU""""333333"""""""""wffwffUݙDݙDfU"""ffUDDDDDD"""wffDDD"""333"""""""""""""""""""""""""""""""""""""""333333"""""""""DDDwff"""UfݙDݙDfffD3333333UݙDf"""UUUwffwff"""333"""""""""""33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""""333333"""""""""DDDwff"""UfݙDݙDfffD3333333UݙDf"""UUUwffwff""""""333"""""""""333""""""""""""DDDfD3ݙDݙDfffD3DDDDDD"""UݙDff"""wffDDD"""333""""""""""""333""""""""""""DDDfD3ݙDݙDfffD3DDDDDD"""UݙDff"""wffDDD"""333"""""""""""""""333"""""""""wffDDDfD3fffD3UݙDff"""wffwff333333333""""""""""""333"""""""""wffDDDfD3fffD3UݙDff"""wffwff333333333"""""""""""""""""""""333"""wfffD3UfD3UݙDfff"""wff̻DDD"""333""""""""""""""""""""""""333"""wfffD3UfD3UݙDfff"""wff̻DDD"""333""""""""""""""""""""""""333333"""DDDUUUU"UݙDݙDfD3̻333"""333333"""""""""""""""""""""333333"""DDDUUUU"UݙDݙDfD3̻333"""333333""""""""""""""""""333333"""333UUUU"UUUUUU̻333333333333"""""""""""""""""""""333333"""333UUUU"UUUUUU̻333333333333"""""""""""""""""""""333333333333̻̻333333333333"""""""""""""""""""""333333333333̻̻333333333333""""""""""""""""""333333333333̻̻333333333333""""""""""""""""""333333333333̻̻333333333333"""""""""""""""""""""333333333333333̻333333333333333"""""""""""""""""""""333333333333333̻333333333333333"""""""""""""""""""""333333333333333333̙333333333333333333""""""""""""""""""""""""333333333333333333̙333333333333333333""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""333333333333333333333333333333333333333333333333333333333""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""333333333333333333333333333333333333333333333333333333333""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333333333333333333333333333333333333333""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""333333333333333333333333333333333333333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333"""""""""""""""""""""""""""""""""333333333333333333333333333"""""""""""""""""""""""""""""""""333333333333333333333333333"""""""""""""""""""""333333333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDDDDDD333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333DDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDDDDDD333333333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333DDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUDDDDDDDDDDDDDDD333333333333333333333333333333333333333333333333333333333333333333""""""""""""""""""""""""""""""""""""""""""""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"""""""""""""""""""""""""""""""""""""""""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333DDDDDDDDDDDDDDDDDDUUUUUUUUUwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333333333333"""""""""333333333333333333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333333333""""""333333333333333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffwffUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""UUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333333"""333"""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""333"""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""333""""""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDD"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""DDD"""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDD""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""DDD""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""""""""""""""""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333"""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""333"""""""""""""""DDDUUUDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDD""""""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333""""""""""""DDD"""""""""""""""""""""333"""""""""""""""333"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333"""""""""""""""333""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDD""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD333""""""""""""""""""DDDDDDDDD""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDD""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""""""""""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD""""""""""""DDDDDDDDD""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""DDDDDDDDD""""""""""""DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333giflib-6.1.3/tests/treescap-interlaced.dmp0000664000175000017500000000043515166751647016731 0ustar esresr Stdin: Screen Size - Width = 40, Height = 40. ColorResolution = 7, BitsPerPixel = 4, BackGround = 0, Aspect = 0. Has Global Color Map. Image #1: Image Size - Left = 0, Top = 0, Width = 40, Height = 40. Image is Interlaced. No Image Color Map. GIF file terminated normally. giflib-6.1.3/tests/porsche.map0000664000175000017500000000100015166751647014440 0ustar esresr 0 0 0 0 1 102 68 51 2 17 17 17 3 85 85 85 4 17 0 0 5 34 0 0 6 51 17 17 7 68 17 17 8 68 17 17 9 85 17 34 10 102 34 34 11 119 34 34 12 136 0 51 13 153 51 51 14 170 51 68 15 170 51 68 16 187 51 68 17 204 68 85 18 221 68 85 19 119 102 102 20 136 136 136 21 153 153 153 22 221 153 68 23 170 102 0 24 153 85 0 25 85 34 0 26 255 255 238 27 221 221 204 28 187 187 187 29 68 68 68 30 51 51 51 31 34 34 34 giflib-6.1.3/tests/gifgrid.rgb0000664000175000017500000007246015166751647014427 0ustar esresrgiflib-6.1.3/tests/treescap-interlaced.map0000664000175000017500000000040015166751647016716 0ustar esresr 0 46 140 93 1 0 255 255 2 0 157 0 3 81 200 86 4 190 190 190 5 110 110 110 6 255 255 0 7 136 115 95 8 231 231 231 9 0 153 102 10 0 0 0 11 0 0 0 12 0 0 0 13 0 0 0 14 0 0 0 15 0 0 0 giflib-6.1.3/tests/gifgrid.ico0000664000175000017500000002450215166751647014421 0ustar esresrscreen width 100 screen height 100 screen colors 8 screen background 0 pixel aspect byte 0 screen map sort flag on rgb 000 000 248 is 0 rgb 248 000 000 is 1 rgb 000 016 160 is 2 rgb 160 016 000 is 3 rgb 160 176 160 is 4 rgb 248 248 248 is 5 rgb 000 000 000 is 6 rgb 000 000 000 is 7 end image # 1 image left 0 image top 0 image bits 100 by 100 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3111111113311111111331111111133111111113311111111320000000022000000002200000000220000000022000000002 3333333333333333333333333333333333333333333333333322222222222222222222222222222222222222222222222222 3333333333333333333333333333334444444444444444444444444444444444444444222222222222222222222222222222 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3333333333333333333333333333334444444444444444444444444444444444444444222222222222222222222222222222 3333333333333333333333333333334444444444444444444444444444444444444444222222222222222222222222222222 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3111111113311111111331111111134555555554455555555445555555544555555554200000000220000000022000000002 3333333333333333333333333333334444444444444444444444444444444444444444222222222222222222222222222222 2222222222222222222222222222224444444444444444444444444444444444444444333333333333333333333333333333 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2222222222222222222222222222224444444444444444444444444444444444444444333333333333333333333333333333 2222222222222222222222222222224444444444444444444444444444444444444444333333333333333333333333333333 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2000000002200000000220000000024555555554455555555445555555544555555554311111111331111111133111111113 2222222222222222222222222222224444444444444444444444444444444444444444333333333333333333333333333333 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2000000002200000000220000000022000000002200000000231111111133111111113311111111331111111133111111113 2222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333 # The following sets edit modes for GNU EMACS # Local Variables: # mode:picture # truncate-lines:t # End: giflib-6.1.3/tests/gifgrid.dmp0000664000175000017500000000066315166751647014431 0ustar esresr Stdin: Screen Size - Width = 100, Height = 100. ColorResolution = 3, BitsPerPixel = 3, BackGround = 0, Aspect = 0. Has Global Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 0 User Input Flag: 0 Transparency on: no DelayTime: 0 Transparent Index: -1 Image #1: Image Size - Left = 0, Top = 0, Width = 100, Height = 100. Image is Non Interlaced. No Image Color Map. GIF file terminated normally. giflib-6.1.3/tests/treescap.dmp0000664000175000017500000000044115166751647014616 0ustar esresr Stdin: Screen Size - Width = 40, Height = 40. ColorResolution = 7, BitsPerPixel = 4, BackGround = 0, Aspect = 0. Has Global Color Map. Image #1: Image Size - Left = 0, Top = 0, Width = 40, Height = 40. Image is Non Interlaced. No Image Color Map. GIF file terminated normally. giflib-6.1.3/tests/makefile0000664000175000017500000001256715166751647014022 0ustar esresr# Regression-test suite for the giflib library and tools # All utilities have tests except gifbg, gifcolor, and gifhisto. .SUFFIXES: .gif .rgb # This is what to do by default test: @$(MAKE) --quiet tap | ./tapview tap: @$(MAKE) --quiet tapstream | tee taplog$$$$; echo "1..$$(grep ok taplog$$$$ | wc -l)"; rm taplog$$$$ tapstream: render-regress \ gif2rgb-regress \ gifbuild-regress \ gifclrmp-regress \ gifecho-regress \ giffilter-regress \ giffix-regress \ gifinto-regress \ gifsponge-regress \ giftext-regress \ giftool-regress \ gifwedge-regress rebuild: render-rebuild \ gif2rgb-rebuild \ gifclrmp-rebuild \ gifecho-rebuild \ giffix-rebuild \ gifinto-rebuild \ giftext-rebuild \ gifwedge-rebuild UTILS = .. PICS = ../pic GIF2RGB = ../gif2rgb $(GIF2RGB): @$(MAKE) -C .. gif2rgb GIFS := $(shell ls ../pic/*.gif) # Test decompression and rendering by unpacking images, # converting them to RGB, and comparing that result to a check file. render-regress: $(GIF2RGB) @for test in $(GIFS); \ do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ $(UTILS)/gif2rgb -1 <$${test} | ./cmpdiffer "gif2rgb: test of $${test}" $${stem}.rgb; \ done render-rebuild: $(GIF2RGB) @for test in $(GIFS); do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ echo "Remaking $${stem}.rgb"; \ $(UTILS)/gif2rgb -1 -o $${stem}.rgb $${test}; \ done gif2rgb-regress: $(GIF2RGB) @$(UTILS)/gif2rgb -c 3 -s 100 100 gifgrid.ico gifbuild-regress: @$(UTILS)/gifbuild -d <$(PICS)/treescap.gif | ./tapdiffer "gifbuild: basic sanity check" treescap.ico @$(UTILS)/gifbuild <$(PICS)/sample.ico | $(UTILS)/gifbuild -d > $@.sample-1.ico; $(UTILS)/gifbuild < $@.sample-1.ico | $(UTILS)/gifbuild -d > $@.sample-2.ico; @./tapdiffer <$@.sample-1.ico "gifbuild: Checking idempotency on an icon file." $@.sample-2.ico; rm $@.sample-?.ico @$(UTILS)/gifbuild -d <$(PICS)/fire.gif > $@.fire1.ico @$(UTILS)/gifbuild < $@.fire1.ico > $@.fire2.gif @$(UTILS)/gifbuild -d < $@.fire2.gif > $@.fire2.ico @./tapdiffer <$@.fire1.ico "gifbuild: Checking idempotency on an animation." $@.fire2.ico @rm -f $@.fire1.ico $@.fire2.ico $@.fire2.gif gifclrmp-regress: @for test in $(GIFS); \ do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ if ! $(UTILS)/gifclrmp <$${test} > $@.$${stem}.regress 2>&1; \ then \ echo "not ok - gifclrmap: crashed on $${test}"; \ else \ ./tapdiffer <$@.$${stem}.regress "gifclrmap: Checking colormap of $${test}" $${stem}.map; \ fi \ done @rm -f $@.*.regress gifclrmp-rebuild: @for test in $(GIFS); do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ echo "Remaking $${stem}.map"; \ $(UTILS)/gifclrmp <$${test} >$${stem}.map; \ done gifecho-rebuild: @echo "Rebuilding gifecho test." @$(UTILS)/gifecho -t "foobar" | $(UTILS)/gifbuild -d >foobar.ico gifecho-regress: @$(UTILS)/gifecho -t "foobar" | $(UTILS)/gifbuild -d | ./tapdiffer "gifecho: Testing gifecho behavior" foobar.ico giffilter-regress: $(GIF2RGB) @for test in $(GIFS); \ do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ $(UTILS)/giffilter <$${test} | $(UTILS)/gif2rgb | ./cmpdiffer "giffiltr: copy of $${test}" "$${stem}.rgb"; \ done giffix-rebuild: @echo "Rebuilding giffix test." @head --bytes=-20 <$(PICS)/treescap.gif | $(UTILS)/giffix 2>/dev/null | $(UTILS)/gifbuild -d >giffixed.ico giffix-regress: @head --bytes=-20 <$(PICS)/treescap.gif | $(UTILS)/giffix 2>/dev/null | $(UTILS)/gifbuild -d | ./tapdiffer "giffix: Testing giffix behavior" giffixed.ico gifinto-regress: @rm -f $@.giflib.tmp @$(UTILS)/gifinto <$(PICS)/porsche.gif $@.giflib.tmp @if test ! -f $@.giflib.tmp; then echo "not ok - gifinto failed to create a file when it should have."; fi @rm -f $@.giflib.tmp @echo "0123456789" | $(UTILS)/gifinto $@.giflib.tmp 2>/dev/null @if test -f $@.giflib.tmp; \ then \ echo "not ok - gifinto created a file when it shouldn't have."; \ else \ echo "ok - gifinto correctly refrained from file creation."; \ fi @rm -f $@.giflib.tmp gifsponge-regress: $(GIF2RGB) @for test in $(GIFS); \ do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ $(UTILS)/gifsponge <$${test} | $(UTILS)/gif2rgb | ./cmpdiffer "gifsponge: sink of $${test}" $${stem}.rgb; \ done giftext-regress: @for test in $(GIFS); \ do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ $(UTILS)/giftext <$${test} | ./cmpdiffer "text dump of $${test}" $${stem}.dmp; \ done giftext-rebuild: @for test in $(GIFS); do \ stem=`basename $${test} | sed -e "s/.gif$$//"`; \ echo "Remaking $${stem}.dmp"; \ $(UTILS)/giftext <$${test} >$${stem}.dmp; \ done giftool-regress: $(GIF2RGB) @$(UTILS)/giftool <$(PICS)/gifgrid.gif | $(UTILS)/gif2rgb | ./cmpdiffer "giftool: expensive copy via giftool" gifgrid.rgb @$(UTILS)/giftool -i on <$(PICS)/treescap-interlaced.gif | $(UTILS)/gif2rgb | ./cmpdiffer "giftool: deinterlace" treescap.rgb @$(UTILS)/giftool -i off <$(PICS)/treescap.gif | $(UTILS)/gif2rgb | ./cmpdiffer "giftool: interlace" treescap-interlaced.rgb gifwedge-rebuild: @echo "Remaking the gifwedge test." @$(UTILS)/gifwedge >wedge.gif gifwedge-regress: @$(UTILS)/gifwedge | ./cmpdiffer "gifwedge: wedge generation." wedge.gif giflib-6.1.3/tests/fire.map0000664000175000017500000001000015166751647013722 0ustar esresr 0 247 222 132 1 123 99 66 2 165 123 74 3 82 58 41 4 206 173 66 5 197 165 99 6 58 25 25 7 181 132 25 8 132 99 16 9 214 181 82 10 90 49 8 11 33 25 16 12 115 58 25 13 230 197 90 14 148 123 66 15 115 90 49 16 132 99 33 17 181 132 33 18 82 41 16 19 181 148 66 20 173 148 99 21 148 107 33 22 25 0 0 23 230 197 107 24 82 58 25 25 197 148 66 26 115 82 16 27 132 74 8 28 74 41 8 29 156 107 41 30 156 115 41 31 99 74 49 32 181 148 41 33 156 99 8 34 132 99 41 35 156 123 74 36 181 123 49 37 74 49 33 38 82 58 33 39 206 165 58 40 181 148 99 41 197 165 74 42 58 16 8 43 58 33 0 44 156 123 33 45 214 173 74 46 90 41 0 47 41 0 0 48 90 58 25 49 115 58 8 50 115 82 33 51 132 82 33 52 165 123 41 53 66 33 25 54 165 132 90 55 181 140 74 56 181 148 74 57 8 0 8 58 197 148 49 59 115 74 8 60 74 25 0 61 132 99 58 62 107 66 25 63 165 123 49 64 189 156 74 65 197 156 74 66 165 115 16 67 99 58 0 68 230 206 115 69 123 99 49 70 165 123 58 71 66 49 58 72 197 156 66 73 181 156 99 74 197 165 82 75 49 25 16 76 58 33 8 77 165 132 25 78 165 132 33 79 132 82 8 80 206 165 99 81 82 49 0 82 33 16 0 83 99 58 25 84 99 66 16 85 214 189 82 86 140 107 66 87 115 74 41 88 173 132 33 89 66 41 25 90 66 49 16 91 165 132 58 92 181 132 58 93 181 148 49 94 140 90 25 95 140 107 16 96 8 0 0 97 66 41 25 98 99 66 16 99 115 66 16 100 123 66 0 101 140 99 49 102 140 107 58 103 99 66 33 104 173 132 41 105 181 140 33 106 140 90 8 107 140 90 16 108 123 82 41 109 156 123 58 110 189 156 49 111 197 156 41 112 189 148 82 113 41 8 0 114 41 25 8 115 156 107 25 116 206 165 74 117 82 25 0 118 25 8 0 119 90 49 8 120 99 58 8 121 107 74 25 122 156 140 74 123 58 33 16 124 140 90 41 125 90 58 33 126 189 140 74 127 99 41 0 128 165 115 25 129 173 115 25 130 206 173 82 131 148 115 41 132 165 132 49 133 140 90 0 134 66 16 0 135 247 222 123 136 123 90 58 137 123 99 58 138 165 123 66 139 197 165 66 140 206 165 66 141 49 33 25 142 173 132 25 143 181 123 25 144 123 90 16 145 132 90 16 146 206 173 90 147 214 173 82 148 82 49 8 149 90 49 0 150 25 16 16 151 33 16 8 152 115 58 16 153 222 189 82 154 222 189 90 155 148 115 58 156 148 115 66 157 107 82 49 158 115 82 41 159 123 90 25 160 132 90 33 161 132 99 25 162 173 132 41 163 181 123 33 164 74 49 16 165 181 140 66 166 173 140 90 167 140 107 33 168 148 107 25 169 16 0 8 170 16 8 8 171 222 189 99 172 74 49 25 173 82 49 25 174 189 140 58 175 189 148 66 176 197 148 58 177 115 74 16 178 123 74 8 179 123 82 8 180 66 33 0 181 74 33 0 182 74 41 0 183 148 99 41 184 148 107 41 185 148 107 49 186 148 115 49 187 99 66 41 188 99 74 41 189 181 140 41 190 181 140 49 191 148 99 8 192 148 99 16 193 123 90 49 194 132 90 41 195 156 123 66 196 173 123 49 197 66 49 33 198 197 165 49 199 197 156 82 200 49 16 0 201 49 25 0 202 58 16 0 203 58 25 0 204 58 25 8 205 156 115 25 206 156 115 33 207 206 173 74 208 206 181 74 209 82 41 0 210 82 41 8 211 33 0 0 212 33 0 8 213 90 49 16 214 90 58 16 215 107 58 0 216 107 58 8 217 107 74 41 218 115 74 33 219 123 74 25 220 123 82 33 221 132 82 25 222 156 115 41 223 156 123 49 224 165 115 41 225 58 41 16 226 66 33 16 227 165 132 82 228 173 140 74 229 0 0 0 230 8 0 0 231 189 140 41 232 189 148 49 233 107 66 0 234 115 66 8 235 66 25 0 236 132 99 49 237 99 66 33 238 156 115 58 239 156 107 8 240 156 115 16 241 90 58 0 242 115 99 58 243 189 156 66 244 41 25 16 245 165 123 25 246 165 123 33 247 123 82 16 248 74 49 0 249 33 8 0 250 99 58 16 251 214 181 90 252 132 107 74 253 107 82 41 254 165 132 41 255 66 41 16 giflib-6.1.3/tests/welcome2.dmp0000664000175000017500000000623715166751647014536 0ustar esresr Stdin: Screen Size - Width = 290, Height = 48. ColorResolution = 8, BitsPerPixel = 8, BackGround = 0, Aspect = 0. Has Global Color Map. GIF89 application block (Ext Code = 255 [ ]): GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 0 Image #1: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 210 Image #2: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced, BitsPerPixel = 8. Image Has Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 0 Image #3: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 210 Image #4: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced, BitsPerPixel = 8. Image Has Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 0 Image #5: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 2 User Input Flag: 0 Transparency on: yes DelayTime: 100 Transparent Index: 210 Image #6: Image Size - Left = 0, Top = 0, Width = 290, Height = 48. Image is Non Interlaced, BitsPerPixel = 8. Image Has Color Map. GIF89 comment (Ext Code = 254 [ ]): 00000: 54 68 69 73 20 61 6e 69 6d 61 74 65 64 20 47 49 This animated GI 00010: 46 20 69 73 20 63 72 65 61 74 65 64 20 62 79 20 F is created by 00020: 46 61 69 72 79 20 53 75 72 79 61 6e 61 0d 0a 68 Fairy Suryana h 00030: 74 74 70 3a 2f 2f 6d 65 6d 62 65 72 73 2e 61 6f ttp://members.ao 00040: 6c 2e 63 6f 6d 2f 42 65 61 74 46 61 63 74 6f 2f l.com/BeatFacto/ 00050: 0d 0a 68 74 74 70 3a 2f 2f 77 77 77 2e 64 65 77 http://www.dew 00060: 61 2e 63 6f 6d 2f 0d 0a 0d 0a 46 61 69 72 79 20 a.com/ Fairy 00070: 53 75 72 79 61 6e 61 20 44 4a 20 70 61 6c 69 6e Suryana DJ palin 00080: 67 20 6a 61 67 6f 20 73 65 20 64 75 6e 69 61 21 g jago se dunia! GIF89 application block (Ext Code = 255 [ ]): 00000: 47 49 46 43 4f 4e 6e 62 31 2e 30 05 00 0a 00 02 GIFCONnb1.0 00010: 00 05 00 00 00 00 00 00 00 00 00 6e 65 77 2d 36 new-6 00020: 2e 67 69 66 00 0a 00 02 00 07 00 00 00 00 00 00 .gif 00030: 00 00 00 4e 65 77 2d 35 2e 67 69 66 00 0a 00 02 New-5.gif 00040: 00 09 00 00 00 00 00 00 00 00 00 6e 65 77 2d 36 new-6 00050: 2e 67 69 66 00 0a 00 02 00 0b 00 00 00 00 00 00 .gif 00060: 00 00 00 4e 65 77 2d 35 2e 67 69 66 00 0a 00 02 New-5.gif 00070: 00 0d 00 00 00 00 00 00 00 00 00 6e 65 77 2d 36 new-6 GIF file terminated normally. giflib-6.1.3/tests/wedge.gif0000664000175000017500000003572515166751647014105 0ustar esresrGIF87a^ 000@@@PPP```ppp 0@P`p 0@P`p 0@P`p 00@@PP``pp 00@@PP``pp 00@@PP``pp,^  HA*\ȰÇ I(Qŋ7iܨǏ[)Җɓ&\˗.ɜ)S͛6ܩϟ> *ԟѣF*]ӧN)J ի8j*ׯHKٳX]k۷hʝݻ xݫ߿  *^JN$7LVhCbK誎6͎zsc ' /d/q^T*M}Vko溻x~ ˯j~]οvng`]%ނ}yބU|7\}ᇜ~ H] 2FhބZj8y!ˉ8"љx"ש"ݹ"8#x##A EII*M: QJiUZYjI]z9&y&&&9'y''X'` J*::J:Zj*z*hz*o*w*:+z++V+^ ;,f*K:JKZj;z;嚻n.8.@;/H{/P// <0'|0/)< ;?I<[Oi\y! )l19,AɌIQ= A E I+ M;QK=U[]Ykmחy5أ ٣}6Ǩ ۯ6Mݻ}7}ߑ7>6~8(688H>7X~9 i7x 袈 饛nꩫ׸.  )/ 9OIoYi?{O )W>}S2>q~;W?}U  PH v) 9"! b0.*D 002 c 02: #z?C,QD%NaH*Z:!C qQ%NO,x7^1!qb{Xǰzc@<)ZM^29M>DWPcT& AgR >9UJLԂєPIZN)x ?*YUӀTNR ~1՟,ZO* =R+ZT+ ;, <^YUVSAXZYS, 9R,( :y^9U~a`I[[Ӓ hS-X 7 x-h 8byWd[] HS.Ә 5R X.Ϩ 6jX>l[_ (S/ 3 8'L [p6{ q%@(NM<0gb 8αwcW@L"HN&;YL*[Sƀ.{`rL2hNs56pݼ:xγ|gπMh@wЈNF''MJ[Zȴ7N{ӛΰG-jԦ^Wjծg-k#ֶ~wk,׾-l5ƞl>;.-mG[־mP{& T`-XM\ൾm` d`h;'l[7p{ 3(_1WNczM'X&Ì𞫙@3ćgO9K+l{8X?1˷{=2kN%T޹ڻ9p3=JϻICmgze|N[n|7p{Gw oxc]oyɓ򕿼3yGOzWYou׿[ivgyvswWorї˩_}׾ι}'~FG~g~L~~~~,'G1g7=C'HIgO Ȁ&Fhǁ !(G%h)Ƃ-1(Ff7;ȃ?'CHgGKȄO&SHfYƅ]a(Feh܆iƆm膫q(Fuh{ȇ&HfঈȈ戏&HfƉ&Fh݆ߦƊ*&0Gf6<NjB&HGfNᦌƌ)(;FhM٨_ƍq(Fh騎Ǝ'3&FcgPibƕotu'F{gƖm$q)6FuiHyZƗ}l)~Fiǘ%5&I@fIYədm}&Ifɚb9o9ypypyq)zęqyzrɚ֜xY։٩ٝ )Y扜ʹɞ 9?&ecYg9iٜo JzZi  Iiơ.Y3:Yy㙢繢٢iשٝ9Y?*IU*06ʤ< ,J "$ʥ&( **SJiG*yZ{}ꣁsjWYKʧMO Q*cJEjwʨꨟ *Je*gi[ʪm_ q*ꘕjɦ饤 )JpiNJɪ]ꩿja*Jujtx|ɬ鬄 )lIjjIʩ*o BJjTX\ɮ`d h)LIj48<ɰ@D H),IPi犭骯ʯ *J%kɱ $ () I0i ˲ *KEkȳ )Hi˴  +#KekԈبȵ(Hh79; !+CKkȷ;[{K!ۺ+[{k#л;K{țʻ̋%;[k؛ڻ۽ޫ';[{껾۾˾)0[{ۿ+P| < -p "<$\&,/*,.+2<2,6|6::L>>ܼB@߻B?DF?HJLNPR/TVXZac_fiLnq/T_vZ_a?+go_?w‘=ȗO_doJlROto:y_?k_oswz~oDg_/\O/./ !"#$%&'()*+, HA-*\ȰÇ I(Qŋ7iܨǏ[)Җɓ&\˗.ɜ)S͛6ܩϟ> *ԟѣF*]ӧN)Jի/8j ׯ!H+ٳ#X]K۷%hʝkݻ'x݋߿) +*^-JN$7LVhCbK誎6͎zsc ' /d/q^T*M}Vko溻x~ ˯j~]οvng`]%ނ}yބU|7\}ᇜ~ H] 2FhބZj8y!ˉ8"љx"ש"ݹ"8#x##A EII*M: QJiUZYjI]z9&y&&&9'y''X'` J*::J:Zj*z*hz*o*w*:+z++V+^ ;,f*K:JKZj;z;嚻n.8.@;/H{/P// <0'|0/)< ;?I<[Oi\y! )l19,AɌIQ= A E I+ M;QK=U[]Ykmחy5أ ٣}6Ǩ ۯ6Mݻ}7}ߑ7>6~8(688H>7X~9 i7/'7 G/Wo3dw o_߾ o篿7 ?L@'H FP̠7zP;GH# W0dafH8a }@ }"HLx9Nt(YVy^(f$רn(vD~ԡ )!d"H(:0$',Z2&790z4 (GY46`*Wy88,g<:.w@< 0D>`2H:x0Iq6Gn+I@XLq(VzP~ X:QUZQ%\Rk5Wj,8 [XÚU,;X,>)[YB,&9M~hI;NӞTjYN׾liOnyI߂)[\U-\ѕ1[]:ծ%]zxɻJTzٻKÔ|L~I) \` V0`0")\a ?9a!IJtTYGƄiHSyEc򐉼F#IVrG'Qr"H+GUԲ5E/se8F3uT;G7΅>H;ysg?Ёt]hC/щVthGґt)]iK 9=OI=@S3TY}BWiD[y=_@cT]Bg8Dk6=oD]nscT7mBwJ]o{7P8^Q;U8R'8)R88q!9H^r)W9Yr19i^syx>z^@TzB?4zD_Z9׳b)[ivjO*{v½r*ݛiw#/5{u 7<x7pn{{>?I3Tzg=io^/ixߞf={ƻ)ouW_~>?[>'`|gxyxuGWxxWy\}GgЇҧǀ<'}%~'H~)x~+~-~u'Hhǂ'#HEhGIKȃM/sHh OsA(@GDgHLPǁT瀯'sHuhgt k(u !( G$g(,0LJ4(3(tgwitȄmhs1(Gg lj(Ff膋즋Ƌ&Hhy{Ȋ}舟(FfȆ̦ƌ挸&Hhȍ荿(FfƎ掘&HhLjȏ)FfƐx&Hh爑ɨȑ1)`FdfhlpƒtNPR9T ApXZ\ٕY)`b9dYf)CjlٖnkIr9tYvyxIE|ٗ~}iYyiGИ9yI9YٚK9YyٛɛM0YyșٜOPyؙڹY9yy 깞ꙗ)9yIٙi:z ::zʝ @@":A&zB*C.D@2:E6zF:G>H@B:IFzJJKNL@R:MVzNZO^Z$^dz,zp j4ڦp<: vڙD|L TZʉ:\bZY:hzlZnک~zt:yz٧9ڛZƙ:)ƺڬ9JzZzI :YʫJjǚꬠ :Z֊ڭ*Jj_ʮ *Jjʯ *Kjbeʰ j +pJkv|ʱ뱂 !+J%k )(ʲh/ m*3Ksj7y;˳? *CKjG$K˴,0 Q+7JUk?YGʵ]O a+WJeki&ʶm. 4*sK;jwC{˷K S*K[j"˸*긏 2*6Jkʹ +Jk߉ɺ +I:j˻ 껿 *KjNj㩼˼ )Ki٫ ʽ  +Jjቾ婾fʾl )rJix~ʿ 꿄 *JjT e w ,Il !,I%lRc+ox o*3LÓiÜ{;÷ ć*CLiS]Km/ ŀ)SLői7Ť[ŵ? )cLiG[dnv q,ǢJulǨǣǬǶǾ ȁ,ȺJȅlVȓhșz ɟ*ɌIɥjɞɫɰɱ ʷ*IʽjOʩ`ʭr ˱,˄I˵l˖˹˨˽˺ ,IlWaq |)ͅI͕i׌ͩ͠͹ )Ii윖\ܣL\ܤ]=ݥXź Mm"M}Ȍ {ݘ1}џI7é#]=mAݢCMF}ILO R=Um@+M-GMM -SMl%j-o=]#}&*-m3u9{ ؑlM0]r6x<]h \M^m`bdfڏ ,ۃֵ׷M׹}׻׽ׯY-ܓMەmۇۉۋۍ۟ ݁-ڳMm׍٭ܿ ޡ̣Mݥmޗީޛޭ߭-Ll،ܬ? ܬ,Nn͙-Ν߱-Llฌ༬ !.-ͅmͫm~ -Ll☌✬ .pLtlx|h ,#N%n' /a.PLTlX\`dH l,CNEnG)+-O.0L4l8<@D( L,SNUnWIKM_.Ll $ ,,sNunwY[].Kk >Qp.>^.SN?_OU  o_oW "?&(*,Y02?4_18:<>[B?D_FCJLNP]0T_VXU\^`b_Pfhjg_nnr?rvvzz~~/?Oo???P@?QRST@?UVʿWX@?YZڿ[\@?]^__VWXYZ[\]^_PQRST HAU*\ȰÇ I(Qŋ7iܨǏ[)Җɓ&\˗.ɜ)S͛6ܩϟ> *ԟѣF*]ӧN)JjիW8j݊ׯYHٳ[X]۷]hʝݻ_x ߿Q ,S*^LUJN$7LVhCbK誎6͎zsc ' /d/q^T*M}Vko溻x~ ˯j~]οvng`]%ނ}yބU|7\}ᇜ~ H] 2FhބZj8y!ˉ8"љx"ש"ݹ"8#x##A EII*M: QJiUZYjI]z9&y&&&9'y''X'` J*::J:Zj*z*hz*o*w*:+z++V+^ ;,f*K:JKZj;z;嚻n.8.@;/H{/P// <0'|0/)< ;?I<[Oi\y! )l19,AɌIQ= A E I+ M;QK=U[]Ykmחy5أ ٣}6Ǩ ۯ6Mݻ}7}ߑ7>6~8(688H>7X~9 i7x 袈 饛nꩫ׸.  )/ 9OIoYi?{O )W>}S2>q~;W?}U  PH v) 9"! b0.*D 002 c 02: #z?C,QD%NaH*Z:!C qQ%NO,x7^1!qb{Xǰzc@<)ZM^29M>DWPcT& AgR >9UJLԂєPIZN)x ?*YUӀTNR ~1՟,ZO* =R+ZT+ ;, <^YUVSAXZYS, 9R,( :y^9U~a`I[[ hS-X 7 x-h 8-z xMz{^1|K_ͯ~ LXeH; 6'L [6{ q@(NM0gb58αwc@L" HN&;YmL*[Sv.{`L2hNs6p3K:ٿx3>€43LBZĈN4WF3Ɛ4{LJSȘ4Nsˠ5LRZͨN5VAΰuLZAϸ^Av MbANfAЎv,MjA ac;MK4{'es[<θ蝷k7(0W N#0^s 9@_2ŇNO;W#MN[,˷~l{`6Ǿ_hڿMVܛC]"zկk.N:G{Fny{w| _xW|x|)_y9oIOpӟ WYq׿ijֽy{~_|W~Ù|Oї~Ʃ_}׾k&~G~f~~զ~~~&Gf(Fhц ƀ (FhƁ&#Hf'+Ȃ/&3Hmf7u;ȃ}?&FEhIƄM脢Q(FUhqYyƅ]腁a(FfgƆo&Fofs{Ƈ'Fg ƈ爣'Fe󥉛ȉ扟&H)f;ȊM抯_&He񆋹ŋ(!F*f ɨEƌN(iFe녍٨ō(Fh2騎CƎV(gFh酏ŏ0'I6g1:DƐL H'Ie!'Ǒ-&3G,f9>?ǒPEb&KGe7;ɓ? &CI$fG6KɔHO Z&SINg兕凌ŕ] &#Fei.7GƖmR[&kFuixzy_|ٗ~9lul)v9myvmv9nwniuSu)Iyɚ)YViٙ ƛaY-&cٚQ9fIwyϹk)Y׉ڹI) )۩靮 )tIfٞ9Yy ~Iy ʡʗ)9jĹ9z)IiɣZ ʟCE*GZIK= !*#Jjʤ- A*cJejgikʥM/ʕ1*3J%j7);ʧm_ ^)bIfijnr: *J' +ʦ? >)BIFiJNRɩ6顯 Q Jjʖ9J O )"I&i*.2ɫ鬟 (Ii ɭ *Jjʪ (HhꈮȮ*Jjʯ (HhʈΨȰ*Jj׊٪ʱ/ (Hh:Ȳ貺+Kk犳骳ʳ O ~(Hh;giflib-6.1.3/tests/giffixed.ico0000664000175000017500000000434515166751647014576 0ustar esresrscreen width 40 screen height 40 screen colors 128 screen background 0 pixel aspect byte 0 screen map sort flag off rgb 046 140 093 is 0 rgb 000 255 255 is 1 rgb 000 157 000 is 2 rgb 081 200 086 is 3 rgb 190 190 190 is 4 rgb 110 110 110 is 5 rgb 255 255 000 is 6 rgb 136 115 095 is 7 rgb 231 231 231 is 8 rgb 000 153 102 is 9 rgb 000 000 000 is a rgb 000 000 000 is b rgb 000 000 000 is c rgb 000 000 000 is d rgb 000 000 000 is e rgb 000 000 000 is f end image # 1 image left 0 image top 0 image bits 40 by 40 8888888888888888888888888888888888888885 8888888888888888888888888888888888888855 8844444444444444444444444444444444444455 8845555555555555555555555555555555558455 8845666661111111111111111111111111118455 8845666661111111133333311111111111118455 8845666611111133333333333311111111118455 8845666611113333333333323391111111118455 8845661111113333223333322231111111118455 8845111111113333322333733291111111118455 8845111111333333323337223239111111118455 8845111113333337723373232222111111118455 8845111113373333773332222229211111118455 8845111113777733332333772229911111118455 8845111113333732232223222229211111118455 8845111111139392372337223779111111118455 8845111111111929277372222222111111118455 8845111111111111117733222122111111118455 8845111111111111117772231111111111118455 8845111111111111117711211111111111118455 8845111111111111117711111111111111118455 8845111111111111117711111111111111118455 8845111111111111117711111111111111118455 8845111111112222227722111111111111118455 8845292912222222227722221111111111118455 8845999922222222227722222222211111118455 8845292222222222277722222222222111118455 8845999222222227777772222222222291118455 8845292222222227227077722222222229298455 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # The following sets edit modes for GNU EMACS # Local Variables: # mode:picture # truncate-lines:t # End: giflib-6.1.3/tests/solid2.map0000664000175000017500000000400015166751647014174 0ustar esresr 0 0 0 255 1 255 255 0 2 253 253 0 3 251 251 0 4 249 249 0 5 247 247 0 6 245 245 0 7 244 244 0 8 242 242 0 9 240 240 0 10 238 238 0 11 236 236 0 12 235 235 0 13 233 233 0 14 231 231 0 15 229 229 0 16 227 227 0 17 226 226 0 18 224 224 0 19 222 222 0 20 220 220 0 21 218 218 0 22 217 217 0 23 215 215 0 24 213 213 0 25 211 211 0 26 209 209 0 27 208 208 0 28 206 206 0 29 204 204 0 30 202 202 0 31 200 200 0 32 198 198 0 33 197 197 0 34 195 195 0 35 193 193 0 36 191 191 0 37 189 189 0 38 188 188 0 39 186 186 0 40 184 184 0 41 182 182 0 42 180 180 0 43 179 179 0 44 177 177 0 45 175 175 0 46 173 173 0 47 171 171 0 48 170 170 0 49 168 168 0 50 166 166 0 51 164 164 0 52 162 162 0 53 161 161 0 54 159 159 0 55 157 157 0 56 155 155 0 57 153 153 0 58 151 151 0 59 150 150 0 60 148 148 0 61 146 146 0 62 144 144 0 63 142 142 0 64 141 141 0 65 139 139 0 66 137 137 0 67 135 135 0 68 133 133 0 69 132 132 0 70 130 130 0 71 128 128 0 72 126 126 0 73 124 124 0 74 123 123 0 75 121 121 0 76 119 119 0 77 117 117 0 78 115 115 0 79 114 114 0 80 112 112 0 81 110 110 0 82 108 108 0 83 106 106 0 84 105 105 0 85 103 103 0 86 101 101 0 87 99 99 0 88 97 97 0 89 95 95 0 90 94 94 0 91 92 92 0 92 90 90 0 93 88 88 0 94 86 86 0 95 85 85 0 96 83 83 0 97 81 81 0 98 79 79 0 99 77 77 0 100 76 76 0 101 74 74 0 102 72 72 0 103 70 70 0 104 68 68 0 105 67 67 0 106 65 65 0 107 63 63 0 108 61 61 0 109 59 59 0 110 58 58 0 111 56 56 0 112 54 54 0 113 52 52 0 114 50 50 0 115 48 48 0 116 47 47 0 117 45 45 0 118 43 43 0 119 41 41 0 120 39 39 0 121 38 38 0 122 36 36 0 123 34 34 0 124 32 32 0 125 30 30 0 126 29 29 0 127 27 27 0 giflib-6.1.3/tests/treescap.map0000664000175000017500000000040015166751647014606 0ustar esresr 0 46 140 93 1 0 255 255 2 0 157 0 3 81 200 86 4 190 190 190 5 110 110 110 6 255 255 0 7 136 115 95 8 231 231 231 9 0 153 102 10 0 0 0 11 0 0 0 12 0 0 0 13 0 0 0 14 0 0 0 15 0 0 0 giflib-6.1.3/tests/fire.dmp0000664000175000017500000002151415166751647013741 0ustar esresr Stdin: Screen Size - Width = 30, Height = 60. ColorResolution = 8, BitsPerPixel = 8, BackGround = 0, Aspect = 0. Has Global Color Map. GIF89 application block (Ext Code = 255 [ ]): GIF89 comment (Ext Code = 254 [ ]): 00000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #1: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #2: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #3: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #4: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #5: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #6: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #7: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #8: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #9: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #10: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #11: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #12: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #13: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #14: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #15: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #16: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #17: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #18: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #19: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #20: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #21: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #22: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #23: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #24: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #25: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #26: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #27: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #28: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #29: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #30: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #31: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #32: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 1 User Input Flag: 0 Transparency on: no DelayTime: 5 Transparent Index: -1 Image #33: Image Size - Left = 0, Top = 0, Width = 30, Height = 60. Image is Interlaced. No Image Color Map. GIF89 comment (Ext Code = 254 [ ]): 00000: 44 6f 6e 27 74 20 66 6c 61 6d 65 20 6d 65 21 20 Don't flame me! 00010: 70 6f 6c 64 65 72 40 78 73 34 61 6c 6c 2e 6e 6c polder@xs4all.nl 00020: 0a 28 63 29 20 31 39 39 36 20 44 65 6d 6f 6e 20 (c) 1996 Demon GIF file terminated normally. giflib-6.1.3/tests/treescap.ico0000664000175000017500000000434515166751647014617 0ustar esresrscreen width 40 screen height 40 screen colors 128 screen background 0 pixel aspect byte 0 screen map sort flag off rgb 046 140 093 is 0 rgb 000 255 255 is 1 rgb 000 157 000 is 2 rgb 081 200 086 is 3 rgb 190 190 190 is 4 rgb 110 110 110 is 5 rgb 255 255 000 is 6 rgb 136 115 095 is 7 rgb 231 231 231 is 8 rgb 000 153 102 is 9 rgb 000 000 000 is a rgb 000 000 000 is b rgb 000 000 000 is c rgb 000 000 000 is d rgb 000 000 000 is e rgb 000 000 000 is f end image # 1 image left 0 image top 0 image bits 40 by 40 8888888888888888888888888888888888888885 8888888888888888888888888888888888888855 8844444444444444444444444444444444444455 8845555555555555555555555555555555558455 8845666661111111111111111111111111118455 8845666661111111133333311111111111118455 8845666611111133333333333311111111118455 8845666611113333333333323391111111118455 8845661111113333223333322231111111118455 8845111111113333322333733291111111118455 8845111111333333323337223239111111118455 8845111113333337723373232222111111118455 8845111113373333773332222229211111118455 8845111113777733332333772229911111118455 8845111113333732232223222229211111118455 8845111111139392372337223779111111118455 8845111111111929277372222222111111118455 8845111111111111117733222122111111118455 8845111111111111117772231111111111118455 8845111111111111117711211111111111118455 8845111111111111117711111111111111118455 8845111111111111117711111111111111118455 8845111111111111117711111111111111118455 8845111111112222227722111111111111118455 8845292912222222227722221111111111118455 8845999922222222227722222222211111118455 8845292222222222277722222222222111118455 8845999222222227777772222222222291118455 8845292222222227227077722222222229298455 8845999222222222227007772222222229998455 8845292222222222222200020002222229298455 8845999222222222222222000000022229998455 8845292222222222222222200000000229298455 8845999999999999999999990000000009998455 8845292929292929292929292000000000098455 8845999999999999999999999000900000098455 8848888888888888888888888888888888888455 8844444444444444444444444444444444444455 8555555555555555555555555555555555555555 5555555555555555555555555555555555555555 # The following sets edit modes for GNU EMACS # Local Variables: # mode:picture # truncate-lines:t # End: giflib-6.1.3/tests/solid2.dmp0000664000175000017500000000044515166751647014210 0ustar esresr Stdin: Screen Size - Width = 640, Height = 400. ColorResolution = 7, BitsPerPixel = 7, BackGround = 0, Aspect = 0. Has Global Color Map. Image #1: Image Size - Left = 0, Top = 0, Width = 640, Height = 400. Image is Non Interlaced. No Image Color Map. GIF file terminated normally. giflib-6.1.3/tests/treescap-interlaced.rgb0000664000175000017500000001130015166751647016714 0ustar esresrnnnnnnnnn羾nnnnnn羾nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn羾nnnnnn羾nnn羾nnnnnn羾nnnQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVQVQVQVf羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVs_QVQVf羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVs_QVQVf羾nnnnnn羾nnnQVQVQVQVQVQVs_s_QVQVs_QVQV羾nnnnnn羾nnnQVQVs_QVQVQVQVs_s_QVQVQVf羾nnnnnn羾nnnQVs_s_s_s_QVQVQVQVQVQVQVs_s_ff羾nnnnnn羾nnnQVQVQVQVs_QVQVQVf羾nnnnnn羾nnnQVfQVfQVs_QVQVs_QVs_s_f羾nnnnnn羾nnnffs_s_QVs_羾nnnnnn羾nnns_s_QVQV羾nnnnnn羾nnns_s_s_QV羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnnffs_s_羾nnnnnn羾nnnffffs_s_羾nnnnnn羾nnnfs_s_s_羾nnnnnn羾nnnfffs_s_s_s_s_s_f羾nnnnnn羾nnnfs_s_.]s_s_s_ff羾nnnnnn羾nnnfffs_.].]s_s_s_fff羾nnnnnn羾nnnf.].].].].].]ff羾nnnnnn羾nnnfff.].].].].].].]fff羾nnnnnn羾nnnf.].].].].].].].]ff羾nnnnnn羾nnnffffffffffffffffffff.].].].].].].].].]fff羾nnnnnn羾nnnffffffffff.].].].].].].].].].]f羾nnnnnn羾nnnfffffffffffffffffffff.].].]f.].].].].].]f羾nnnnnn羾羾nnnnnn羾nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnngiflib-6.1.3/tests/tapdiffer0000775000175000017500000000257515166751647014212 0ustar esresr#! /bin/sh # # tapdiffer - Render diff between input and checkfile as a TAP report # # Usage: tapdiffer LEGEND CHECKFILE # # Output is a TAP report, ok if the diff is empty and not ok otherwise. # A nonempty diff is shipped as a TAP YAML block following "not ok" # unless QUIET=1 in the environment. # # This code is intended to be embedded in your project. The author # grants permission for it to be distributed under the prevailing # license of your project if you choose, provided that license is # OSD-compliant; otherwise the following SPDX tag incorporates the # MIT No Attribution license by reference. # # SPDX-FileCopyrightText: (C) Eric S. Raymond # SPDX-License-Identifier: MIT-0 # # A newer version may be available at https://gitlab.com/esr/tapview # Check your last commit dqte for this file against the commit list # there to see if it might be a good idea to update. # diffopts=-u while getopts bn opt do case $opt in b) diffopts=-ub;; *) echo "tapdiffer: unknown option ${opt}."; exit 1;; esac done # shellcheck disable=SC2004 shift $(($OPTIND - 1)) legend=$1 checkfile=$2 trap 'rm /tmp/tapdiff$$' EXIT HUP INT QUIT TERM if diff --text "${diffopts}" "${checkfile}" - >/tmp/tapdiff$$ then echo "ok - ${legend}" else echo "not ok - ${legend}" if [ ! "${QUIET}" = 1 ] then echo " --- |" sed # SPDX-License-Identifier: MIT-0 # # A newer version may be available at https://gitlab.com/esr/tapview # Check your last commit dqte for this file against the commit list # there to see if it might be a good idea to update. # legend=$1 checkfile=$2 if cmp "${checkfile}" - then echo "ok - ${legend}" else echo "not ok - ${legend}" fi # end giflib-6.1.3/tests/welcome2.map0000664000175000017500000001000015166751647014512 0ustar esresr 0 0 0 0 1 74 74 74 2 222 0 0 3 255 255 255 4 172 0 0 5 180 0 0 6 82 82 82 7 189 0 0 8 213 0 0 9 205 0 0 10 32 32 32 11 98 98 98 12 115 115 115 13 123 123 123 14 90 90 90 15 197 0 0 16 131 131 131 17 57 57 57 18 41 41 41 19 106 106 106 20 205 205 205 21 139 139 139 22 197 197 197 23 180 180 180 24 213 213 213 25 172 172 172 26 148 148 148 27 230 0 0 28 246 246 246 29 156 156 156 30 238 238 238 31 189 189 189 32 164 164 164 33 222 222 222 34 24 24 24 35 65 65 65 36 164 0 0 37 49 49 49 38 230 230 230 39 172 16 16 40 148 16 16 41 106 49 49 42 164 16 16 43 123 49 49 44 238 82 82 45 8 8 8 46 180 16 16 47 189 41 41 48 156 16 16 49 238 172 172 50 16 16 16 51 131 0 0 52 115 49 49 53 139 24 24 54 82 65 65 55 230 82 82 56 246 172 172 57 131 57 57 58 164 8 8 59 156 41 41 60 172 8 8 61 205 8 8 62 156 24 24 63 139 65 65 64 123 90 90 65 197 65 65 66 197 49 49 67 98 0 0 68 189 16 16 69 148 90 90 70 164 49 49 71 222 16 16 72 205 74 74 73 189 57 57 74 222 172 172 75 255 230 230 76 156 98 98 77 213 164 164 78 222 82 82 79 189 65 65 80 205 156 156 81 148 24 24 82 164 24 24 83 197 24 24 84 164 41 41 85 139 82 82 86 123 82 82 87 148 41 41 88 197 41 41 89 197 131 131 90 246 230 230 91 148 49 49 92 205 57 57 93 189 49 49 94 123 98 98 95 180 32 32 96 98 49 49 97 205 139 139 98 230 24 24 99 180 65 65 100 189 24 24 101 197 123 123 102 213 82 82 103 213 148 148 104 139 0 0 105 115 74 74 106 148 32 32 107 197 148 148 108 172 74 74 109 189 123 123 110 222 74 74 111 180 115 115 112 205 24 24 113 189 74 74 114 148 0 0 115 205 32 32 116 164 139 139 117 180 57 57 118 213 115 115 119 156 57 57 120 123 57 57 121 156 0 0 122 106 82 82 123 238 197 197 124 230 205 205 125 205 82 82 126 180 8 8 127 197 57 57 128 180 24 24 129 205 131 131 130 164 90 90 131 115 41 41 132 238 115 115 133 222 156 156 134 230 57 57 135 246 139 139 136 139 57 57 137 115 90 90 138 213 41 41 139 172 57 57 140 172 49 49 141 172 24 24 142 213 172 172 143 180 74 74 144 180 123 123 145 123 41 41 146 156 82 82 147 213 8 8 148 255 197 197 149 222 24 24 150 230 164 164 151 197 74 74 152 213 139 139 153 90 57 57 154 238 139 139 155 156 90 90 156 189 8 8 157 148 82 82 158 90 65 65 159 189 139 139 160 213 57 57 161 180 82 82 162 139 123 123 163 238 189 189 164 164 32 32 165 213 16 16 166 148 57 57 167 115 82 82 168 123 0 0 169 156 49 49 170 238 213 213 171 139 41 41 172 106 74 74 173 164 98 98 174 197 98 98 175 123 106 106 176 156 123 123 177 230 156 156 178 222 164 164 179 172 123 123 180 189 115 115 181 139 16 16 182 238 164 164 183 197 32 32 184 213 74 74 185 106 90 90 186 180 41 41 187 156 106 106 188 172 106 106 189 197 164 164 190 139 115 115 191 172 65 65 192 164 74 74 193 131 41 41 194 205 65 65 195 222 148 148 196 205 180 180 197 106 0 0 198 205 49 49 199 156 8 8 200 213 189 189 201 222 65 65 202 123 32 32 203 164 65 65 204 164 57 57 205 123 74 74 206 180 131 131 207 180 90 90 208 213 65 65 209 197 16 16 210 213 24 24 211 164 82 82 212 123 65 65 213 131 49 49 214 205 16 16 215 148 115 115 216 148 98 98 217 156 131 131 218 222 98 98 219 115 98 98 220 197 82 82 221 106 65 65 222 205 115 115 223 180 49 49 224 115 0 0 225 246 197 197 226 230 172 172 227 222 115 115 228 197 139 139 229 230 180 180 230 172 98 98 231 148 65 65 232 106 57 57 233 222 123 123 234 139 32 32 235 164 148 148 236 148 123 123 237 230 148 148 238 156 32 32 239 98 57 57 240 222 139 139 241 148 106 106 242 172 115 115 243 213 156 156 244 230 74 74 245 98 74 74 246 189 148 148 247 156 139 139 248 172 41 41 249 131 82 82 250 131 98 98 251 115 57 57 252 172 32 32 253 131 90 90 254 197 8 8 255 180 148 148 giflib-6.1.3/tests/welcome2.rgb0000664000175000017500000012144015166751647014522 0ustar esresrZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR   ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR  ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR  ZJR      ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR  ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR    ZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))1191111)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))11999111))ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)11111111))ZJRZJRZJRZJRZJR))1111111999991111111111111111111111))ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))11199111999999991119111))ZJRZJRZJRZJRZJR)))11111111111111111199111))ZJRZJRZJRZJRZJRZJRZJRZJRZJR))1119111)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111111))ZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111911111999999111911)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19AJJRJJJJA91ZJRZJRZJRZJRZJRZJRZJR)19AJRRRRRJJA91)ZJRZJRZJRZJRZJRZJR)19AJRRRRJJAA911119AAJRRRRRRRRRRRRRRRRRRRRJJJRJRRJRJJAA91ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19AJJRRRRRRRRRRRRRRRRRRRJJA9911119AAJJRRRRRRRRRRRRRRRRRRRJJA911)ZJRZJRZJR))19AJJRRJJAA11ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19AJJRRRJAA91))ZJRZJRZJR))19AJJRRRRRRRRRRRRRRRRRJJJA11)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)1ARZZjjjjjZZRA1)ZJRZJRZJR)19JRbbjjss jjZZRA9)ZJR )19JRbbjjsjjZbZRJJJRRZbjjssss s s s s s s s s s s s js s jjjjjjjjjs s jZZRA1)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19JRZbjjssss s s s s s s s s s s s s s jjZZRRJJJJRZbbjjjs s s s s s s s s s s s s s s s jjbbZRA91119AJRZbjjjjjbZRA1)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR19JRZbjjjjjbZRA991119AJRZbjjjjjjs s s s s s s s s s s sjjZZJA1)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1ARbss       {jZJ91)11ARbj{   s jZJ91)19ARbs{     {sjjbjjs{ )))))) ) ) ) ) ) ) ) )    ) ) )   s jRA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9ARbs{ ))))))))))))))))   {sjbbbjjs )))))))))))  {sjbRJJJRZbj{sjZJ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)1ARbs{{jbRJJAJRZbs{))))))))))))) {jRA1)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Jb{  ) ) ) sZJ999ARb{  ) ) )  sbJA99ARj{  ) ) ) )   ) ) ) ) ) ))) 1 1 1 1 1 1)))))))))))))))))))))) 1)))))))) 1 ){jZA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9JZs  ) 1 ) 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) {  ) ) 1 1 1 1 1 1 1 ) ) ) ) ) 1 ) )  {sjbbjss{ŔŔjj99sbJ9)ZJRZJRZJRZJRZJRZJRZJRZJR)1AZb{jj{{{{ZZ99{sjbbbj{   ) ) ) ) ) ) ) 1 1 1 1 1 1 ) ) ) ) {jR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9RjjjsZJAARb{AAլsZJJJRj{AAŽZZ jjŽ99))))))Ž{{{bJ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR9JbsޜŽŽ{{jj欬ŽŽŽŽjj s{Ž{{99{bR9)ZJRZJRZJRZJRZJRZJRZJR1AZjޜŽ{ss99 ދլ{{{{{{{ss{sssjjj11bJ1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)AZs ՜jZRRbs͜jbRZb{ͬ)) AAŽ99)1)1)1ʹ{{sZA)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZs99ŽjjŽ{JJ潋{{{{99{bJ9)ZJRZJRZJRZJRZJR1ARjͬ{{{{{{{{{ss99ދͽ{{{{{ss{ssjssjjbZZj11jR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rs ޜjj99RRRRjjsbbsjjRRRRRRRRRRދޤZZ{jbjsRRRRRRRRŽ{{   AAދRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR999A9A9ARRRRRRs{{{bA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9RjAAދRRRRRRRRRRRRRRRRRRRRRRAAAAAA9999999999))JJ{ssZZ     s{RRRRRRRRRRRRRRRRRRRRAAAAAAAAAAAAAAAAAAAA99JJ{JJRRJJ{sssjj99{ZJ1)ZJRZJRZJR)9RjRR11sjjjbb99ދլRR99111111111111111111)))))))))))))))))){JJRJJj11sR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rs AAŽլs{潋{{{jjլRR99{{{{AA9A9A9A99{{ jJ1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jb{AA99 jbbZZ 99{{{ss{JJ99Ž11sjjjbbsZA1)ZJR)9Jb{ދ bZZbRR )    s{j11RJJ{))sZ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jjޜ JJjjޜJJ洬jj)1))))99999999999999999999999999999999JJjs{ssAA9A9A9A99{{ jR1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR9Rj )1)1)1)1)19999999999999999999999{99bZZZZ ) ) )jj{99{99{99{99{99{99{99999999999999)1 sbbsbb ދ99sbbsZZjRA119JZs99 )1ZJJ{99jj99 j11j11j11j11j11j11j11j11j11j11j11j11j11j11j11j11j11bAARJJ{)){Z9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)AZ{ jjRRRRŔ99 jjŽ))ŔjjRR))bRRbRRbRRbRRbRRbRRbZZbZZbZZbZZbZZbZZbZZbZZbZZjbbsbbsbbsbbsbbsbb99199A1999{{ sR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)AZs99bAAZJJZJJZRRZRRZRRZRRZRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRR{JJ ) ) ))1ZJJZJJZJJZJJZRRZRRZRRZRRbRRbRRbRRbRRbRRbRRbRRbZZsbb{ss))))bZZ99ŴsZZjbb99bRAAJZjRRZJJbAA99 bAAZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJRJJRJJRJJ sZ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rsս))JJ))99ͬjjދ))ޜAA11bZZbRR99  ) ) ) ) ) ) ) )))))))))1919191919)){{sR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)Ab{jjbAAZJJ9911           ) ) ) )RRj11ZJJbAA11       99JJ{ssJJbZZbRR  ޜ jbbsZZ {bZZZjjjŬZJJ{99 )ŬZJJbAA11   ) ) ) ) ) ) )sR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jbs{AAjj{{99ޜ{{ZZŽRRjj{{Ŕ99sjjsbb     ) ) )))))111119191919))jj jR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jbs{ދbAAZJJ))  ) ){99ZJJbAA )1 {99ZJJ   ŔbAAZJJsjjjj 11sbb{JJ{sjs )bAAbRRsbb))ZJJ{99 )ޜbAAZJJ      )   sR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)AZs{{潴ދRR ޜŬ))9A99Ŕ99)){{{ss     ) )))))))1111191919))jjsR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR 1Jbs{ދ ZJJ{99  ) )ZJJbAA  jj{{{99ZJJ11  ދj11ZJJ99ZZZZsbb )s{ZJJbAAZZZJJ{99 ) )JJZJJbAA          sR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jj{{99ދRRޜ)1JJ))RRŽJJޜs{ {{ Ŕ99))欬欬欬欬19191911)){{jjsR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jjs{ދ99bRZ11   )ZJJbAA jjŽ{99ZJJ11 )սZJJZJJ  Ŕ99)1sjjsbb99bAAZJJ AAZJJ{99 )JJZJJsbb{{{{{{{{{{{{{{{{{{{{{{{{{{JJsR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZ{))ZZ99޽լ{{ZZŽ{{ jjZZ9999Ž19191919欬)){{jjsZ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR 9Rjjjދ99bZZ11{{sssssssss{  )սZJJbAA  {ssss{{s{լ{99ZJJ11  欬սZJJZJJ ) )RRZZsjj99)){))ZJJ11AAZJJ{99  JJbRRsjj{ss{ss{ss{ss{ss{ss{ss{ss{ss{ss{ss{ss{sssjjsjjsjjsjjsbbsbbjbbbRRsR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR9Rj{{ Ž)1RRսs{ {{)){{RRޜ))9999ŔŔŔޜޜޜޜլޜޜ欬欬欬欬欬欬欬欬ޜ19191911欬)){{ZZ{bA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rsjjͽ99bZZ11{jbbZZZZZZZbjs  սZJRbAA {sjbZZZbj{s{լ{99ZJJ11  欬ͽ{{ZJJZJJ ) ) ){{ZZ11sjj{ssދޜZJJbAAʹ99ZJJ{99 )JJ{JJ{JJ{JJ{JJZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZsbbZJJsR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZ{JJJJRRͽ{{ޜ9999{ssjj))RR99ޜRR99{ss99{{19191919欬ս)){ssZZjR91)ZJRZJRZJRZJRZJRZJR)19AZ{jjŽ99bZZ11sbZRRRRRRRRZbj{ սZRRbAA sbZRRRRZbss{լ{99ZJJ11 欬Ž{{ZJJZJJ ))) )99 ZZ{ssZZ9AŴj11ZJJ))9AŴ99ZJJ{99  )޴JJZRRbAAsR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rsսʹ)1 լZZJJ RRJJZZZZ{{JJ99{ss{ss19191919լŽ {ssZZsbRA99919999AJZjjjŽ99bZZ99sbZZRRRRRRRZbj{ ͽZRR{JJ  sjZZRRRZbss{欬{99ZJJ11 欬Ž{{ZJJZJJ)) ) ) )jjjj{ss)1RRZJJ{99 9AŽ99ZJJ{99  )AAbbbbbbbbjjs{{RJJbAAsR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1JbZZ99s{ŽjjRR99  {{jjޜ {{{ss 99sbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsbbsjj9A191919ޜ)) {ssZZ sjZZRRRRRRZZbsjjŽ{{99jbb99{sjbbbbbbbbjj{  ͽbRR{JJ sjbbbjjs{s{Ŕ{99ZJJ11  欬jjZJJZJJ ) ) 9999{{jjjjŔbAAZJJ   9AŽ11ZJJ{99  )AAZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJRJJRJJbAA{Z9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)AZs{{{{Žs{RR99{ss   jj))RR)1լAA99{sssbb99{sssjjZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ9A1919))ޜ {sssjj   {{sssssss{jjս{{99sbb99  {{{{{{{{{   ŽbZZ{JJ   {{{{欬{99ZJJ))  欬jjZJJbJJ   AA{{jjAAսͽ{))ZJJ11 jjŴ11ZJJ{99  )AAZJJbJJ{99{99{99{99{99{JJ{JJ{JJ{JJ{JJ{JJ{JJ{JJ{JJ{JJ{JJ{JJbAAbAAbAA{99{ZA)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR9JbZZ{{))ދսZZ{{ZZRRJJ սլjj{ss1199{{{ss)1))))199A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A1919))Ŕ JJ     jjŽ{{99sjjsbb         )ŽZZsjj99   9Aދ{99ZJJ))  ޜjjZJJbJJ     {{JJ11s{ŽJJZJJbAAjjŽ11 ZJJ{99   ʹ99ZJJ{99 )))))199A9A9A9A9A9A9A9A9A9A9A9A9A19)1)1 ) bA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZ{)){{ZZދ{{{{99{{ދRR{sssjjRR))jj))))1919999A9A9A9A9A9A9A9A9A9A9A9A9A9A191919))))Ŕ jjjj             jjs{ {{ZZ99                 )11{ss{{jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjs{{99ZJJ  )լZZZJJZJJ    ))jjj11ZJJ )jjŽ)) ZJJ{99)Ŵ99ZJJbAA )))191919999A9A9A9A9A9A9A9A9A9A1919)1)1)) jJ1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1Jjjj{ss99ދ )){{{ss jj)) ދjjZZ{ss{JJ{ssJJZZ欬欬欬欬欬լދ)))1 )))欬欬լլլլޜŔŔŔŔŔ{{JJ欬欬լլլլޜŔŔŔŔŔjj  )Ŕ))JJսRRZJJbAA ) )ŔZZZJJZJJ   ZZZZ ZJJ{99jj)) ZJJbAAZZjJJsbb{ss{{{{{{{{{{{{{{{{{{{{{{{{{{{{jj)1sR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZs99{ss99ZZ{{ZZJJJJsjjsjj ){jbbsս{{ ) jjZZŔŽjjŽZZ  jj{{99ŔŽ欬99ZJJ{99  )))ZJJZJJ {{11JJZZbAARJJ s{ ZJJ{99s{sbb{{{{{ss{ss{sssjjsjjjbb99sR9ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Jb{sbbsjj{ss{ss11{{{{99sjj{JJjZRRbsJJ{{jjRRޜޜլ{ss    {{1199欬ޜޜޜދދ{{{{{ss  AA{{s{ޜ欬ޜޜŔދ{{{{{{{{{{jj{{{{ZZ  99))))))))))))))))))))))))bAAZJJ  )))RJJbAA  ZZsbb{{{))ZJJ11s{ ZJJ{99    {{ZZ))ZZjjjjZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZbRR11{Z9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9Rj11sbbZZ99sjjZZJJ{ss99sbbsbb)1sZJAAJbsZZ{ssZZ)){{sjj    )){ss{ss99{sssjjZZ{{jj ))sbbZZ)){{{{11bAAZJJ11 ))RJJbAA{{{{ss99RJJbAAs{ RJJ{99  ))ZZ RJJ)1{ZA)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR1AZs99bZZbZZ 99jbbsZZ ZZsjj99{JJbZZ99{bJ9119Jb{ZZsbbbZZ11 99sjjsbb )jssjj{JJ jbbsbb99jssbbsZZ 11bRZ{JJ)){ssjsZZ)1)1ZJJRJJ)1   {{11RJJbAA sjs{ ){{sjjj11RJJ s{{{ {))RJJ)1)){{{sssbb)1j11RJJ)1{bA)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9JZs)1bRRbRRbAA)1)1)1ZRRbRR{JJ {ss{{JJbZZbRR{99)1)1)1bAAZJJZRR99jRA1))19Jb{11sZZbRRZRRZJJZJJZJJZJJZJRZRRbRRbRRbRRbRRbRRbRRbRZbZZbZZbZZbZZbZZbZZbZZjbbbZZZZjbbbRRZJRZJJZJJZJJZJRZJRZRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRZbZZ ){JJsZZbRZbRRZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJRZJRZJRZJRZRRZRRZRRbAA )ZZsZZbZZbRRZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJRJJbAA {{{sssjjjbbbRRZJJbAA{bZZbsZZ{sssjjbZZbRRZJJZJJRJJj11{{{{{{{sssbbbZZZJRRJJ)1ZZsbbbZZbRRZJRZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJZJJRJJRJJRJJRJJ)1{ZA)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9AZs99bAAZJJZJJZJJbAA11sbZZZj{))bAAbJJZJJZJJZJJbAA{99 sZA1)ZJRZJRZJR)9Jb{))11)1)1)1)1)1)1)1)1)1)1)1))))))))111111111111)1{ 11)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)11111)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1)1 )1111)1)1)1)1)1)1)1)1)1)1)))))))))1)1)1)))))1)1 99JJJJ99999911)1jZJJRbs99999911)1)1)1sjbbs11JJ9999991111)1{1111)1)1)1)1)))1)1)1)))))))))))))1)1)1)1)1)1)1sR9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9JZssZJAAJRbs{bJ9)ZJRZJRZJRZJRZJR)9Jbs{jbjs{sss{{sjj{sZJA9AJZj{jZRJRZj{{jbjs{{bJ1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9JZj{sZJ9119ARbs{bR91ZJRZJRZJRZJRZJRZJRZJR)9JZj{{sbZRRZbssjZZZbj{sbZRRZjs{sjjjs{sbJ91119ARj{{bRJ999ARbs{sbZRRZbs{{jRA1ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)9ARbj{{sbZA91) )19JZbs{{sbJA1ZJRZJRZJRZJRZJRZJRZJRZJRZJR)1ARbjs{{sjZJA99ARZbs{{jZRJAAJRbjs{sjZRJA9ARZjs{{sjbZRJRZbjs{{sjZJ91)ZJRZJR)1ARbj{{{jbRA9)))1AJZjs{{{sbZJA9AAJZbs{sbRA9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR19JRZbjjbbZJA1)ZJRZJRZJRZJRZJR)9AJZbjjjjbZRJ9)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19ARZbbjjjssssssssssjjjjbZJA91))19AJRZbjjsjjjjjjjjjjsjjjbZRJ991199JRZZbjjjsjjjjsssssjjjjbZRA911)19AJZbbjjjjjsssjjjjjjjjjjjbbRRJA9999AJRZbZZRJ9)ZJRZJRZJRZJRZJRZJR19JRZbbbZRJ91) ZJRZJRZJR)9ARZbbbZRA91))199JRZbjjjjjjssssssssjjjjbZRA1)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19AJJJJAA91 ZJRZJRZJRZJRZJRZJRZJRZJR)99AJRRJJA91) ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)19AAJJRRJRRRRRRRRRRRJJJA91)ZJR ZJRZJR)199AJJRRRRRRRRRRRRRRJJJA91))ZJRZJR))199AJJRRRRRRRRRRRRRRJJJA91) ZJRZJRZJR)199AJJJRRRRRRRRRRRRRRRRJJAA91))ZJR))199AAAA91)ZJRZJRZJRZJRZJRZJRZJRZJR)19AAJAA91)ZJRZJRZJRZJRZJRZJRZJR)19AAAAA91)ZJRZJRZJRZJRZJR)19AJJJRRRRRRRRRRRRRRRJJA91)ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111)) ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)111111)) ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111119999999911111))ZJRZJRZJRZJRZJRZJRZJR )))111119911999911111))ZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111111999999991111))ZJRZJRZJRZJRZJRZJRZJRZJRZJR))1111199991111111111111))ZJRZJRZJRZJRZJRZJRZJRZJR))))))ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR))111))ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR)))1)))ZJRZJRZJRZJRZJRZJRZJRZJRZJR))11111111999999991111))ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJR ZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJR ZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRZJRgiflib-6.1.3/tests/x-trans.dmp0000664000175000017500000000072515166751647014411 0ustar esresr Stdin: Screen Size - Width = 100, Height = 100. ColorResolution = 7, BitsPerPixel = 8, BackGround = 0, Aspect = 0. Has Global Color Map. GIF89 comment (Ext Code = 254 [ ]): GIF89 graphics control (Ext Code = 249 [ ]): Disposal Mode: 0 User Input Flag: 0 Transparency on: yes DelayTime: 10 Transparent Index: 0 Image #1: Image Size - Left = 0, Top = 0, Width = 100, Height = 100. Image is Interlaced. No Image Color Map. GIF file terminated normally. giflib-6.1.3/tests/solid2.rgb0000664000175000017500000273400015166751647014205 0ustar esresr??JJJJJJJJJJaayyyyyyyyVVJJJJJJJJJJ''22''JJJJJJJJyyyyyyyyyyyyyyyyyyyyyynnJJJJJJ??JJ22''JJVVyyyyyyJJJJ??22''iiii22''JJVVyyyyyyJJJJ2222FFrr;;''JJVVyyyyyyJJJJ''yy??FF{{gg0022aaVV22yyVV''&&ZZgg&&''JJyyyyJJ''aaJJ))&&CCaa\\&&JJnnnnJJJJrrggUU??++&&AAiiQQ22aauuiiZZZZ\\\\^^DD====aaaaaaFF''JJyy||;;JJnnii22??SSVVss22''VV^^''aa2222nn__''??nn==??jj''VV22VVHH''nn__22uu''JJ22aaHH22yy__??jj''aauu''''nnrrssuuppuu''22ppaajjuu||uu''JJ{{{{||||~~iiOOaalluu||uu''JJVVccnnww||__''ssccnnww||__nnnnww||||||__JJ~~||wwpp__22||wwppiigg__yy||wwppiiaaXXHHVV~~{{uunngg__XXLL2222~~{{uunngg__UUHHCCuu''yy~~{{uunngg__UUHH::HHaa~~yyssllee^^UUFF88cc22??~~yyssllee^^QQDD66||uu''''~~yyssllee^^QQDDXX^^VV||yyrrjjcc\\ppHHyyyy22''yyyyyyyyyyyyss??yyyyyyyyyyyyyyyyyyFFaayyyyyyyyyyyyyyyyyyyyyyyyyy||&&yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyFF''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||&&??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQVVyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&&yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&&??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyggVVyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy00yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy""yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{||~~yyyynnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||~~yyyyyyssaayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{||yyyyyyyyyyyyaa??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{||yyyyyyyyyyyyyyyyyyaa??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{~~~~yyyyyyyyyyyyyyyyyyyyyyyyJJ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||ssssuuuuwwwwssnnjjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy22yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy--nnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa??yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVVyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyDD''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy22yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy2222yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaaaa||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\yy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJyy{{wwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ''ssuuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy22uuppssuuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy2222llnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy''nniillnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaaaaee__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaaaa\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ^^XX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJJJZZUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy??yy__QQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn''MMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ''QQMMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''VV{{HHMMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDDCCHHMMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\""ccCCHHMMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyrryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn::22==CCHHMMQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy^^yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""aa__==CCHHLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy^^==yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii2266;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ==yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO;;yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''??66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO;;\\yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDDnnuu66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO;;00yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\""UU66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO;;00yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22''66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO;;00ssyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""JJ&&66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyFF;;00QQyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii--JJ&&66;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyAA88--OOyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssJJJJSS44;;AAFFLLQQUUXX\\__ccggiijjnnpprruuwwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyAA88--OOyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''JJ~~22;;AAFFLLQQUUXX\\__cceeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyAA88--rryyyyyyyyyyyyyyyyyyyyyyyyyyss??JJ22;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyAA88--||yyyyyyyyyyyyyyyyyyyyyyyy\\""JJ22;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyAA88--||yyyyyyyyyyyyyyyyyyyynn22JJ22;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyywwAA88--yyyyyyyyyyyyyyyyyyQQ""JJ22;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyll??66++yyyyyyyyyyyyyyii--JJgg;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa==??66++yyyyyyyyyyssDDJJ;;AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss??&&??66llyyyyyyyyaa''JJVVAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""&&??66yyyyss::JJ\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa--&&??__yyVV""JJyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn??&&??22JJyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ""--QQyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''//yyyyyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn::AAyyyyyyyyyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssJJ''yyyyyyyyyyyyyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\''yyyyyyyyyyyyyyyyyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22yyyyyyyyyyyyyyyyyyyyyyyyyyyy\\AAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssJJaayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""JJppyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii22??VVCCyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD22//--yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""VV----yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa--''--SSyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZAAFFLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss????ii''&&66yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZ??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""aaCC$$&&44yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZ??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa--''88""&&44jjyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZ??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyyynn::??88""&&44CCyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZ??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyyyyyJJ""??uu66 4488yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy^^??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyyyyyyaa''JJOO66 44::yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyyyyynn::JJ==66 4488OOyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyyyyssJJJJ;;// 4488==yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyyyyyy\\''JJ;;//2288==yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyyyyynn22VV^^;;++2266;;eeyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyyyssJJ''aaAA::''2288;;AAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~||||||||ee\\\\\\UU;;==^^^^^^^^ww~~~~~~yyVV""''aaAA::''2266;;AAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~ss\\DD44;;LLeeii22JJnn??88$$--66::??MMyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~yyaaJJ;;??VVyyOO??88""--66::??DD||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeiijjllpprrsswwyy{{||||~~ggJJ$$''yyyyJJ22''JJyyFF??88""--66::??DDFFyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||||~~^^AAaayyyyyyyyJJJJJJJJJJJJnnyyyyyyQQDD==66--66::==CCFFZZyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||||~~ww\\00JJ~~HHDD==66&&44::==CCFFHHyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||~~ssLL))''JJHHDD==44&&44::==CCFFHHSSyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||~~ll66yyJJHHCC;;//&&44::==CCFFHHJJyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||~~cc66JJMMJJHHCC;;//&&44::==CCFFHHJJLLyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{||~~ZZ''22ppLLJJHHAA::++ 2288==AADDHHSSyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDLLOOSSVVZZ^^aaeeggjjllnnrrssuuyy{{XX''''yyOOMMJJFFAA::'' 2288==AADDyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDJJOOSSVVZZ^^aaeeggjjllpprrsswwUU''aarrOOLLJJFFAA::'' 2288==yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDJJOOSSVVZZ^^aaeeiijjllpprrnn88??QQMMLLJJFF??88"" 22__yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj??DDJJOOSSVVZZ^^aaeeiijjllpp\\ ''ccQQMMLLHHFF??88""22yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj==DDJJOOSSVVZZ^^aaeeiijjllAAnnSSOOMMLLHHFF??88 ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj==DDJJOOSSVVZZ^^aaeeii\\++JJ^^SSQQMMLLHHDD==66''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj==DDJJOOSSVVZZ^^aaeeFF22UUSSOOMMJJHHDD==66aayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj==DDJJOOSSVVZZ^^aa88''yy__UUSSOOMMJJHHDD;;22VVyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj==DDJJOOSSVVZZ^^66VVVVUUQQOOMMJJHHCC;;//''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy==DDJJOOSSVVZZ44??XXVVSSQQOOLLJJHHCC;;//yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy==DDJJOOSSXX88''rrXXVVSSQQOOLLJJHHAA::))MMyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy==DDJJOOSSAAnnZZXXUUSSQQMMLLJJFFAA::''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy==DDJJOO==JJ\\ZZXXUUSSQQMMLLJJFFAA::&&yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy==DDJJ;;22^^\\ZZXXUUSSQQMMLLJJFF??88""OOyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy??DDHHyy^^^^\\ZZVVUUSSOOMMLLHHFF??88""))yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy??DD22VV__^^\\\\ZZVVUUSSOOMMLLHHDD==66yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy????22ii__^^\\ZZZZVVUUSSOOMMLLHHDD==66OOyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy??++''pp____^^\\ZZXXVVUUQQOOMMJJHHDD==66))yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy::aawwaa____^^\\ZZXXVVUUQQOOMMJJHHCC;;00yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&&JJccaa____^^\\ZZXXVVSSQQOOLLJJHHCC;;//\\yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy''ccccaa__^^^^\\ZZXXVVSSQQOOLLJJHHCC;;//))yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyeeccccaa__^^^^\\ZZXXVVSSQQOOLLJJHHAA::''yyyyyyyyyyyyyyyyyyyyyyyyyyyyeeeeccaaaa__^^\\\\ZZXXUUSSQQMMLLJJFFAA::''\\yyyyyyyyyyyyyyyyyyyyggggeeccaaaa__^^\\\\ZZXXUUSSQQMMLLJJFFAA::&&))yyyyyyyyyyyyyynnggeeeeccaa____^^\\\\ZZXXUUSSQQMMLLJJFF??88""yyyyyyyywwiiggeeeeccaa____^^\\ZZZZVVUUSSOOMMLLHHFF??88""~~iiggggeeccccaa____^^\\ZZZZVVUUSSOOMMLLHHDD==66\\~~iiiiggeeeeccaaaa__^^^^\\ZZZZVVUUQQOOMMJJHHDD==6666rrjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHDD==66lllljjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHCC;;//nnlljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVSSQQOOLLJJHHCC;;//\\nnnnlljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHCC;;--66wwppnnnnlljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHAA::''ppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFFAA::''rrrrppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFF??88$$jjyyssrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFF??88""CCssssrrrrppppnnnnlllljjjjiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMLLHHFF??88""))uussssrrrrppppnnnnlljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMLLHHDD==66uuuussssrrrrppppnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMJJHHDD==66~~wwuuuussssrrrrppppnnnnlljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHDD==44wwwwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHCC;;//jjyyyywwwwuuuussssrrrrppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVSSQQOOLLJJHHCC;;//CCyyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHAA::++)){{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHAA::''))||{{{{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFFAA::''||||{{{{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFF??88$$~~||||||{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFF??88""jj~~~~~~||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggeeccccaa____^^\\\\ZZVVUUSSOOMMLLHHFF??88""CC~~~~~~||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMLLHHFF??88CC~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMJJHHDD==22CC~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHDD==++CC~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHHDD==$$))~~~~~~||||{{{{{{yyyywwwwuuuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOLLJJHHCC;;))~~~~~~||||||{{{{{{yyyywwwwuuuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHCC88))~~~~~~||||||{{{{{{yyyywwwwuuuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHHAA00~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFFAA))~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLJJFFAA""~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLHHFF==~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggeeccccaa____^^\\\\ZZVVUUSSOOMMLLHHFF88~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMLLHHFF//~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOMMJJHHDD&&~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUQQOOMMJJHHDD~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOMMJJHH==~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUQQOOLLJJHH22~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHH++))~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJHH ))~~~~~~~~||||||{{{{{{yyyywwwwuuuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQMMLLJJAA))~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLLJJ44))~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXUUSSQQMMLLFF))~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVSSQQOOLL22CC~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZXXUUSSQQMMHHOO~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZXXUUSSQQMM44ii~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOOLLyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSOO44yyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZZZVVUUSSMM))yyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccaaaa__^^^^\\ZZXXVVUUSS66CCyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVUUOOCCyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVUU00iiyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVVMMyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXVV00))yyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa____^^\\\\ZZXXOOCCyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeccccaa__^^^^\\ZZZZXX22ssyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZQQ''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZZZ22AAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggeeeeccaaaa__^^^^\\ZZQQZZyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggggeeccccaa____^^\\\\//yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa____^^\\AA''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa____^^HHZZ||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa____SS ''||wwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa__\\$$MM||uunnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa__))ZZ||wwppggyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggeeeeccccaa66;;||wwppgg__yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeeeccaaCC;;~~||wwppgg__yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrrrppppnnnnlllljjjjiiggggeeeeccMM00^^||wwppgg__ppyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggeeeeVV ++^^__||~~yyrrii__SSyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggee__$$''^^__jjuu{{~~~~yyrrii__UUyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjjjiiggggee))^^__aajjnnww{{~~~~yyrriiaaVVllyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiigggg88^^__aacc{{ggppww{{~~~~yyrriiaaVVnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiggFFQQ__aaaacccciippww{{~~~~{{ssjjaaVVnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiiiQQLL__aaaacccc^^eejjppww{{~~~~{{ssjjaaVVnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjiiZZ HH__aaaaaaccccjj^^ccjjppww{{~~~~{{ssllccZZppyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjjjee&&;;^^aaaacccceeeeVV^^ccjjppuu{{~~~~{{ssllccZZyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnlllljjee++;;^^aaaacccccceeeerrUU\\cciinnuuyy||{{ssllccZZyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssssrrrrppppnnnnllgg4400^^aaaaaacccceeeennHHSS\\aaiinnuuyy||||uullccZZyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuuuussssrrrrppppnnnnnncc++++^^__aaaacccceeeeggnniiHHSS\\aaiinnuuyy||||uunnee^^yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyyyywwwwuuuussssssrrrrppppnnZZ ++^^__aaaacccceeeegggg~~;;FFSSZZaaggnnssyy||||uunneeyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyyyywwwwuuuussssssrrrrppppOO^^__aaaacccccceeeegggg::DDQQZZaaggllssyy||||uunneeyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{yyyyyywwwwuuuussssrrrrrrpp;;^^__aaaacccccceeeegggggg88DDQQZZaaggllssyy||||wwnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwwwuuuussssssrrll++UU__aaaaaacccceeeeeeggggggee88DDQQZZaaggllssyy||||wwppyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwwwuuuussssrraa&&LL__aaaaaacccccceeeeggggggiiZZ88CCMMXX__eellrrww{{~~||wwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||||{{{{{{yyyywwwwwwuuuussssSS LL__aaaaaacccccceeeeggggggiijjOO44AAMMXX__eellrrww{{~~||wwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwwwuuuussHH;;^^aaaaaacccccceeeeeeggggiiiijj0066AAMMXX__eellrrww{{~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwwwuupp==;;^^aaaaaacccccceeeeeeggggiiiijjll==66AALLVV^^ccjjppww{{~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyywwwwuujj--44^^aaaaaacccccceeeeeeggggiiiijjllnnuu44??JJVV^^ccjjppww{{~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{{{yyyyyywwgg""++^^__aaaacccccceeeeeeggggggiijjjjllnnuuUU??JJVV^^ccjjppww{{~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyyyyUU++^^__aaaacccccceeeeeeggggggiijjjjllllnnpp==JJUU\\cciippuu{{~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{yyyy??^^__aaaaaacccceeeeeeggggggiiiijjjjllllnnpp;;HHSS\\aaiinnuuyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||||{{{{{{{{ss22^^__aaaaaacccceeeeeeggggggiiiijjjjllllnnnnppHHSS\\aaiinnuuyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||{{{{{{ii''UU__aaaaaacccceeeeeeggggggiiiijjjjllllnnnnpprrSS\\aaiinnuuyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~~~||||||SS""LL__aaaaaacccccceeeeggggggiiiijjjjllllllnnnnppppZZaaggllssyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~~~||||ee''LL__aaaaaacccccceeeeggggggiiiiiijjjjllllnnnnppppppaaggllssyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~~~rr::;;^^aaaaaacccccceeeeggggggiiiiiijjjjllllllnnnnppppppllssyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy~~yyMM;;^^aaaaaacccccceeeeeeggggiiiiiijjjjjjllllllnnnnppppppyy||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyZZ''44^^aaaaaacccccceeeeeeggggiiiiiijjjjjjllllllnnnnpppppprr~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn44++^^__aaaacccccceeeeeeggggggiiiijjjjjjllllllnnnnpppppprrrrrryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||CC++^^__aaaacccccceeeeeeggggggiiiijjjjjjllllllnnnnnnpppprrrrssssyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO""^^__aaaacccccceeeeeeggggggiiiijjjjjjllllllnnnnnnpppprrrrrrssssyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjj))^^__aaaaaacccceeeeeeggggggiiiiiijjjjllllllnnnnnnpppprrrrrrssssss{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyww66UU__aaaaaacccceeeeeeggggggiiiiiijjjjllllllnnnnnnpppprrrrrrssssssuuuuyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQDD__aaaaaacccccceeeeggggggiiiiiijjjjllllllnnnnnnpppprrrrrrssssssuuuuuuyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy^^"" \\aaaaaacccccceeeeggggggiiiiiijjjjjjllllnnnnnnpppppprrrrrrssssssuuuuuu||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyll66--aaaaaacccccceeeeggggggiiiiiijjjjjjllllnnnnnnpppppprrrrrrssssssuuuuuuwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyDDDDcccccceeeeeeeeggggggiiiiiijjjjjjllllnnnnnnpppppprrrrrrssssssuuuuuuwwwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||LL""HHcccceeeeeeeeggggggiiiiiijjjjjjllllllnnnnpppppprrrrrrssssssssuuuuuuwwwwww~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa88 VVcccceeeeeeggggggiiiiiijjjjjjllllllnnnnpppppprrrrrrrrssssssuuuuuuuuwwwwwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||SS)) VVcccceeeeeeggggggiiiijjjjjjllllllnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii??&&aaeeeeeeggggggggiiiijjjjjjllllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\))))aaeeeeggggggggiiiijjjjjjllllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyrrFF22eeeeeeggggggiiiiiijjjjllllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyy{{{{{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyycc))88ggggggggggiiiiiijjjjllllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyy{{{{{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy{{FF""FFggggggggiiiiiijjjjjjllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyee::LLggggggiiiiiijjjjjjllllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyy{{{{{{||||||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyOO$$UUggggiiiiiijjjjjjllllnnnnnnpppppprrrrrrrrssssssssuuuuuuwwwwwwwwyyyyyyyy{{{{{{||||||||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyll:: ZZiiiiiiiijjjjjjllllnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyyyy{{{{{{{{||||||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy||VV++ eeiiiiiijjjjjjllllllnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyy{{{{{{||||||||~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyggJJ++++eeiiiijjjjjjllllllnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyy{{{{{{{{||||||||~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyywwQQ22++eejjjjllllllllnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaaCC++ggjjjjllllllnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyjjJJ++++ggjjllllllnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaaFFppyySS22++ggllllnnnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss??22ZZyyccCC$$++^^llllnnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""$$CCccssLL++ ^^llllnnnnnnpppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22++LLjj{{ZZ44 __nnnnnnpppppprrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ""44CC\\ll{{||\\LL;;$$ __nnnnpppppppprrrrrrrrssssssssuuuuuuwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii--$$;;UUcc||||uu\\DD44 OOnnnnpppppprrrrrrrrssssssssuuuuuuwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD;;DD\\ss||||ee\\;;++QQpppppppprrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''++;;\\ee||||\\LL;;QQpppppprrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss::;;LL\\||||ll\\DD44QQrrrrrrrrrrrrssssssssuuuuuuuuwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""44;;^^^^^^^^^^~~~~~~~~~~~~~~~~~~ww^^^^^^^^MM;;++;;rrrrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22$$========DD^^^^^^^^nn~~~~~~~~~~~~~~~~gg^^^^^^^^==========;;rrrrrrrrssssssssuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ""==nnssssssssuuuuuuuuuuwwwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa----ccssssssuuuuuuuuuuwwwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD""XXssssssuuuuuuuuuuwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\''HHuuuuuuuuuuwwwwwwwwwwwwyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss::22ppuuuuuuuuwwwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""''eeuuuuuuwwwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22""UUuuuuuuwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ??wwwwwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa----llwwwwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD""aawwwwwwyyyyyyyyyy{{{{{{{{||||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\''OOyyyyyyyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn::::ssyyyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""--iiyyyyyyyy{{{{{{{{{{||||||||~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii22""QQ{{{{{{{{{{||||||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ44pp{{{{{{{{||||||||||~~~~~~~~~~||yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''""QQ{{{{{{{{||||||||||~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD44pp||||||||||~~~~~~~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\""""SS||||||||||~~~~~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn::44rr||||||~~~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""""SS~~~~~~~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii2244ss~~~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssJJMM~~~~~~~~~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''//llyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss??MMyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\\""//nnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22OO{{yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyQQ""))\\yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii--//iiyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssJJ66uuyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''CC~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss::""OO~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""))^^yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22//jj~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJ""66yy~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyii--DD~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyssDD""QQ~~yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyaa''))^^yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyss::))__yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyVV""""QQyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyynn22""SSyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyJJDD||yyyyyyyyyyyyyyyyyyyyyyyyyyaa--DDuuyyyyyyyyyyyyyyyyyyyyyyssDD88ppyyyyyyyyyyyyyyyyyyyy\\''88aayyyyyyyyyyyyyyyyss::))aayyyyyyyyyyyyyyQQ""))UUyyyyyyyyyynn22""UUyyyyyyyyJJFFrryyyyaa--))\\ssDD""giflib-6.1.3/tests/treescap.rgb0000664000175000017500000001130015166751647014604 0ustar esresrnnnnnnnnn羾nnnnnn羾nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn羾nnnnnn羾nnn羾nnnnnn羾nnnQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVQVQVQVf羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQV羾nnnnnn羾nnnQVQVQVQVQVQVQVQVs_QVQVf羾nnnnnn羾nnnQVQVQVQVQVQVQVQVQVQVs_QVQVf羾nnnnnn羾nnnQVQVQVQVQVQVs_s_QVQVs_QVQV羾nnnnnn羾nnnQVQVs_QVQVQVQVs_s_QVQVQVf羾nnnnnn羾nnnQVs_s_s_s_QVQVQVQVQVQVQVs_s_ff羾nnnnnn羾nnnQVQVQVQVs_QVQVQVf羾nnnnnn羾nnnQVfQVfQVs_QVQVs_QVs_s_f羾nnnnnn羾nnnffs_s_QVs_羾nnnnnn羾nnns_s_QVQV羾nnnnnn羾nnns_s_s_QV羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnns_s_羾nnnnnn羾nnnffs_s_羾nnnnnn羾nnnffffs_s_羾nnnnnn羾nnnfs_s_s_羾nnnnnn羾nnnfffs_s_s_s_s_s_f羾nnnnnn羾nnnfs_s_.]s_s_s_ff羾nnnnnn羾nnnfffs_.].]s_s_s_fff羾nnnnnn羾nnnf.].].].].].]ff羾nnnnnn羾nnnfff.].].].].].].]fff羾nnnnnn羾nnnf.].].].].].].].]ff羾nnnnnn羾nnnffffffffffffffffffff.].].].].].].].].]fff羾nnnnnn羾nnnffffffffff.].].].].].].].].].]f羾nnnnnn羾nnnfffffffffffffffffffff.].].]f.].].].].].]f羾nnnnnn羾羾nnnnnn羾nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnngiflib-6.1.3/COPYING0000664000175000017500000000201715166751647012200 0ustar esresr= MIT LICENSE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. giflib-6.1.3/build.adoc0000664000175000017500000000341615166751647013100 0ustar esresr= Build instructions = == Building == Building this package from a distribution tarball should be as simple as running make. Install with "make install" as root. You will need xmlto to build the derived forms of the documentation from the DocBook-XML sources. If you are going no modify the website, you will also need to have asciidoc and the ImageMagick convert(1) utility installed. == Testing == You can run "make check" after the library and utilities have been built to see a regression test of the codebase. No output (other than the test header lines) is good news. == Portability note == This codebase now assumes your compiler is C99-conformant. If it isn't, the most likely trouble spot is "#include "; your compiler may be looking for "inttypes.h" instead. By test, the code is backward-conformant to C89 except that it uses bool/true/false. One (minimal but sufficient) concession to Windows portability has been make; inclusion of is conditional on _WIN32 not being defined by the compiler (if it is is included instead). Requests to go any further out of the way to accommodate Microsoft's toolchains are unlikely be looked on favorably. == Release Procedure == 1. Check the SourceForge tracker for bugs and patches. 2. Bump the version number in gif_lib.h. Do "make version" to confirm that it looks sane when extracted to the Makefile. 3. Version-stamp the top entry in the NEWS file. 4. If you are changing major versions, crearte a new folder in the Files section of the project ad sync the XBS-SourceForge-Folder attribute in the control file. 5. 'make dist' to make a tarball. 6. Tag the release in the repo. 7. Ship the release tarball. The last three steps can be done with "make release" if you have shipper installed. giflib-6.1.3/getversion0000775000175000017500000000060715166751647013263 0ustar esresr#!/bin/sh # # getversion - get the librarty version by analyzing its header # # Done this way so there's a single point of truth about the version. # MAJOR=`sed #include #include #include "gif_lib.h" #include "gif_lib_private.h" #define ABS(x) ((x) > 0 ? (x) : (-(x))) #define COLOR_ARRAY_SIZE 32768 #define BITS_PER_PRIM_COLOR 5 #define MAX_PRIM_COLOR 0x1f static int SortRGBAxis; typedef struct QuantizedColorType { GifByteType RGB[3]; GifByteType NewColorIndex; long Count; struct QuantizedColorType *Pnext; } QuantizedColorType; typedef struct NewColorMapType { GifByteType RGBMin[3], RGBWidth[3]; unsigned int NumEntries; /* # of QuantizedColorType in linked list below */ unsigned long Count; /* Total number of pixels in all the entries */ QuantizedColorType *QuantizedColors; } NewColorMapType; static int SubdivColorMap(NewColorMapType *NewColorSubdiv, unsigned int ColorMapSize, unsigned int *NewColorMapSize); 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 successful, GIF_ERROR otherwise. ******************************************************************************/ int GifQuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize, const GifByteType *RedInput, const GifByteType *GreenInput, const GifByteType *BlueInput, GifByteType *OutputBuffer, GifColorType *OutputColorMap) { unsigned int Index, NumOfEntries; int i, j, MaxRGBError[3]; unsigned int NewColorMapSize; long Red, Green, Blue; NewColorMapType NewColorSubdiv[256]; QuantizedColorType *ColorArrayEntries, *QuantizedColor; ColorArrayEntries = (QuantizedColorType *)malloc( sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE); if (ColorArrayEntries == NULL) { return GIF_ERROR; } for (i = 0; i < COLOR_ARRAY_SIZE; i++) { ColorArrayEntries[i].RGB[0] = i >> (2 * BITS_PER_PRIM_COLOR); ColorArrayEntries[i].RGB[1] = (i >> BITS_PER_PRIM_COLOR) & MAX_PRIM_COLOR; ColorArrayEntries[i].RGB[2] = i & MAX_PRIM_COLOR; ColorArrayEntries[i].Count = 0; } /* Sample the colors and their distribution: */ for (i = 0; i < (int)(Width * Height); i++) { Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) << (2 * BITS_PER_PRIM_COLOR)) + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) << BITS_PER_PRIM_COLOR) + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR)); ColorArrayEntries[Index].Count++; } /* Put all the colors in the first entry of the color map, and call the * recursive subdivision process. */ for (i = 0; i < 256; i++) { NewColorSubdiv[i].QuantizedColors = NULL; NewColorSubdiv[i].Count = NewColorSubdiv[i].NumEntries = 0; for (j = 0; j < 3; j++) { NewColorSubdiv[i].RGBMin[j] = 0; NewColorSubdiv[i].RGBWidth[j] = 255; } } /* Find the non empty entries in the color table and chain them: */ for (i = 0; i < COLOR_ARRAY_SIZE; i++) { if (ColorArrayEntries[i].Count > 0) { break; } } QuantizedColor = NewColorSubdiv[0].QuantizedColors = &ColorArrayEntries[i]; NumOfEntries = 1; while (++i < COLOR_ARRAY_SIZE) { if (ColorArrayEntries[i].Count > 0) { QuantizedColor->Pnext = &ColorArrayEntries[i]; QuantizedColor = &ColorArrayEntries[i]; NumOfEntries++; } } QuantizedColor->Pnext = NULL; NewColorSubdiv[0].NumEntries = NumOfEntries; /* Different sampled colors */ NewColorSubdiv[0].Count = ((long)Width) * Height; /* Pixels */ NewColorMapSize = 1; if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) != GIF_OK) { free((char *)ColorArrayEntries); return GIF_ERROR; } if (NewColorMapSize < *ColorMapSize) { /* And clear rest of color map: */ for (i = NewColorMapSize; i < *ColorMapSize; i++) { OutputColorMap[i].Red = OutputColorMap[i].Green = OutputColorMap[i].Blue = 0; } } /* Average the colors in each entry to be the color to be used in the * output color map, and plug it into the output color map itself. */ for (i = 0; i < NewColorMapSize; i++) { if ((j = NewColorSubdiv[i].NumEntries) > 0) { QuantizedColor = NewColorSubdiv[i].QuantizedColors; Red = Green = Blue = 0; while (QuantizedColor) { QuantizedColor->NewColorIndex = i; Red += QuantizedColor->RGB[0]; Green += QuantizedColor->RGB[1]; Blue += QuantizedColor->RGB[2]; QuantizedColor = QuantizedColor->Pnext; } 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; } } /* Finally scan the input buffer again and put the mapped index in the * output buffer. */ MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0; for (i = 0; i < (int)(Width * Height); i++) { Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) << (2 * BITS_PER_PRIM_COLOR)) + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) << BITS_PER_PRIM_COLOR) + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR)); Index = ColorArrayEntries[Index].NewColorIndex; OutputBuffer[i] = Index; if (MaxRGBError[0] < ABS(OutputColorMap[Index].Red - RedInput[i])) { MaxRGBError[0] = ABS(OutputColorMap[Index].Red - RedInput[i]); } if (MaxRGBError[1] < ABS(OutputColorMap[Index].Green - GreenInput[i])) { MaxRGBError[1] = ABS(OutputColorMap[Index].Green - GreenInput[i]); } if (MaxRGBError[2] < ABS(OutputColorMap[Index].Blue - BlueInput[i])) { MaxRGBError[2] = ABS(OutputColorMap[Index].Blue - BlueInput[i]); } } #ifdef DEBUG fprintf(stderr, "Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n", MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]); #endif /* DEBUG */ free((char *)ColorArrayEntries); *ColorMapSize = NewColorMapSize; return 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, unsigned int *NewColorMapSize) { unsigned int i, j, Index = 0; QuantizedColorType *QuantizedColor, **SortArray; while (ColorMapSize > *NewColorMapSize) { /* Find candidate for subdivision: */ long Sum, Count; int MaxSize = -1; unsigned int NumEntries, MinColor, MaxColor; for (i = 0; i < *NewColorMapSize; i++) { for (j = 0; j < 3; j++) { if ((((int)NewColorSubdiv[i].RGBWidth[j]) > MaxSize) && (NewColorSubdiv[i].NumEntries > 1)) { MaxSize = NewColorSubdiv[i].RGBWidth[j]; Index = i; SortRGBAxis = j; } } } if (MaxSize == -1) { return GIF_OK; } /* Split the entry Index into two along the axis SortRGBAxis: */ /* Sort all elements in that entry along the given axis and * split at the median. */ SortArray = (QuantizedColorType **)malloc( sizeof(QuantizedColorType *) * NewColorSubdiv[Index].NumEntries); if (SortArray == NULL) { return GIF_ERROR; } for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors; j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL; 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); /* Relink the sorted list into one: */ for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++) { SortArray[j]->Pnext = SortArray[j + 1]; } SortArray[NewColorSubdiv[Index].NumEntries - 1]->Pnext = NULL; NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0]; free((char *)SortArray); /* Now simply add the Counts until we have half of the Count: */ Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count; NumEntries = 1; Count = QuantizedColor->Count; while (QuantizedColor->Pnext != NULL && (Sum -= QuantizedColor->Pnext->Count) >= 0 && QuantizedColor->Pnext->Pnext != NULL) { QuantizedColor = QuantizedColor->Pnext; NumEntries++; Count += QuantizedColor->Count; } /* Save the values of the last color of the first half, and * first of the second half so we can update the Bounding Boxes * later. Also as the colors are quantized and the BBoxes are * full 0..255, they need to be rescaled. */ MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */ /* coverity[var_deref_op] */ MinColor = // cppcheck-suppress nullPointerRedundantCheck QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */ MaxColor <<= (8 - BITS_PER_PRIM_COLOR); MinColor <<= (8 - BITS_PER_PRIM_COLOR); /* Partition right here: */ NewColorSubdiv[*NewColorMapSize].QuantizedColors = QuantizedColor->Pnext; QuantizedColor->Pnext = NULL; NewColorSubdiv[*NewColorMapSize].Count = Count; NewColorSubdiv[Index].Count -= Count; NewColorSubdiv[*NewColorMapSize].NumEntries = NewColorSubdiv[Index].NumEntries - NumEntries; NewColorSubdiv[Index].NumEntries = NumEntries; for (j = 0; j < 3; j++) { NewColorSubdiv[*NewColorMapSize].RGBMin[j] = NewColorSubdiv[Index].RGBMin[j]; NewColorSubdiv[*NewColorMapSize].RGBWidth[j] = NewColorSubdiv[Index].RGBWidth[j]; } NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] = NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] + NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - MinColor; NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor; NewColorSubdiv[Index].RGBWidth[SortRGBAxis] = MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis]; (*NewColorMapSize)++; } return GIF_OK; } /**************************************************************************** Routine called by qsort to compare two entries. *****************************************************************************/ 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 */ giflib-6.1.3/openbsd-reallocarray.c0000664000175000017500000000427615166751647015432 0ustar esresr/* * SPDX-FileCopyrightText: Copyright (C) 2008 Otto Moerbeek * SPDX-License-Identifier: MIT */ #include #include #include #include #ifndef SIZE_MAX #define SIZE_MAX UINTPTR_MAX #endif /* * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW */ #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size) { if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) { errno = ENOMEM; return NULL; } /* * Head off variations in realloc behavior on different * platforms (reported by MarkR ) * * The behaviour of reallocarray is implementation-defined if * nmemb or size is zero. It can return NULL or non-NULL * depending on the platform. * https://www.securecoding.cert.org/confluence/display/c/MEM04-C.Beware+of+zero-lengthallocations * * Here are some extracts from realloc man pages on different platforms. * * void realloc( void memblock, size_t size ); * * Windows: * * If there is not enough available memory to expand the block * to the given size, the original block is left unchanged, * and NULL is returned. If size is zero, then the block * pointed to by memblock is freed; the return value is NULL, * and memblock is left pointing at a freed block. * * OpenBSD: * * If size or nmemb is equal to 0, a unique pointer to an * access protected, zero sized object is returned. Access via * this pointer will generate a SIGSEGV exception. * * Linux: * * If size was equal to 0, either NULL or a pointer suitable * to be passed to free() is returned. * * OS X: * * If size is zero and ptr is not NULL, a new, minimum sized * object is allocated and the original object is freed. * * It looks like images with zero width or height can trigger * this, and fuzzing behaviour will differ by platform, so * fuzzing on one platform may not detect zero-size allocation * problems on other platforms. */ if (size == 0 || nmemb == 0) { return NULL; } return realloc(optr, size * nmemb); } giflib-6.1.3/gif_lib.h0000664000175000017500000003061615166751647012717 0ustar esresr/****************************************************************************** gif_lib.h - service library for decoding and encoding GIF images SPDX-License-Identifier: MIT *****************************************************************************/ #ifndef _GIF_LIB_H_ #define _GIF_LIB_H_ 1 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define GIFLIB_MAJOR 6 #define GIFLIB_MINOR 1 #define GIFLIB_RELEASE 3 #define GIF_ERROR 0 #define GIF_OK 1 #include #include #define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ #define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 #define GIF_VERSION_POS 3 /* Version first character in stamp. */ #define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */ #define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */ typedef unsigned char GifPixelType; typedef unsigned char *GifRowType; typedef unsigned char GifByteType; typedef unsigned int GifPrefixType; typedef int GifWord; typedef struct GifColorType { GifByteType Red, Green, Blue; } 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. */ 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 (GIF89) */ } 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; /* 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, IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */ EXTENSION_RECORD_TYPE, /* Begin with '!' */ TERMINATE_RECORD_TYPE /* Begin with ';' */ } GifRecordType; /* func type to read gif data from arbitrary sources (TVT) */ typedef int (*InputFunc)(GifFileType *, GifByteType *, int); /* func type to write gif data to arbitrary targets. * Returns count of bytes written. (MRB) */ typedef int (*OutputFunc)(GifFileType *, const GifByteType *, int); /****************************************************************************** GIF89 structures ******************************************************************************/ 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; /****************************************************************************** GIF encoding routines ******************************************************************************/ /* Main entry points */ GifFileType *EGifOpenFileName(const char *GifFileName, const bool GifTestExistence, int *Error); GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error); GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error); int EGifSpew(GifFileType *GifFile, int *ErrorCode); 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 201 /* And EGif possible errors. */ #define E_GIF_ERR_WRITE_FAILED 202 #define E_GIF_ERR_HAS_SCRN_DSCR 203 #define E_GIF_ERR_HAS_IMAG_DSCR 204 #define E_GIF_ERR_NO_COLOR_MAP 205 #define E_GIF_ERR_DATA_TOO_BIG 206 #define E_GIF_ERR_NOT_ENOUGH_MEM 207 #define E_GIF_ERR_DISK_IS_FULL 208 #define E_GIF_ERR_CLOSE_FAILED 209 #define E_GIF_ERR_NOT_WRITEABLE 210 /* 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 #define D_GIF_ERR_NO_SCRN_DSCR 104 #define D_GIF_ERR_NO_IMAG_DSCR 105 #define D_GIF_ERR_NO_COLOR_MAP 106 #define D_GIF_ERR_WRONG_RECORD 107 #define D_GIF_ERR_DATA_TOO_BIG 108 #define D_GIF_ERR_NOT_ENOUGH_MEM 109 #define D_GIF_ERR_CLOSE_FAILED 110 #define D_GIF_ERR_NOT_READABLE 111 #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 DGifGetImageHeader(GifFileType *GifFile); int DGifGetImageDesc(GifFileType *GifFile); int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen); int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel); 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); const char *DGifGetGifVersion(GifFileType *GifFile); /****************************************************************************** Error handling and reporting. ******************************************************************************/ 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. ******************************************************************************/ /****************************************************************************** Color map handling from gif_alloc.c ******************************************************************************/ 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 GifBitSize(int n); /****************************************************************************** Support for the in-core structures allocation (slurp mode). ******************************************************************************/ extern void GifApplyTranslation(SavedImage *Image, const 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); /****************************************************************************** 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 const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH]; extern void GifDrawText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int color); extern void GifDrawBox(SavedImage *Image, const int x, const int y, const int w, const int d, const int color); extern void GifDrawRectangle(SavedImage *Image, const int x, const int y, const int w, const int d, const int color); extern void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int border, const int bg, const int fg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _GIF_LIB_H */ /* end */ giflib-6.1.3/gif_err.c0000664000175000017500000000512515166751647012731 0ustar esresr/***************************************************************************** gif_err.c - handle error reporting for the GIF library. ****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include "gif_lib.h" #include "gif_lib_private.h" /***************************************************************************** Return a string description of the last GIF error *****************************************************************************/ const char *GifErrorString(int ErrorCode) { const char *Err; 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"; break; case E_GIF_ERR_HAS_SCRN_DSCR: Err = "Screen descriptor has already been set"; break; case E_GIF_ERR_HAS_IMAG_DSCR: Err = "Image descriptor is still active"; break; case E_GIF_ERR_NO_COLOR_MAP: Err = "Neither global nor local color map"; break; case E_GIF_ERR_DATA_TOO_BIG: Err = "Number of pixels bigger than width * height"; break; case E_GIF_ERR_NOT_ENOUGH_MEM: Err = "Failed to allocate required memory"; break; case E_GIF_ERR_DISK_IS_FULL: Err = "Write failed (disk full?)"; break; case E_GIF_ERR_CLOSE_FAILED: Err = "Failed to close given file"; break; case E_GIF_ERR_NOT_WRITEABLE: Err = "Given file was not opened for write"; break; case D_GIF_ERR_OPEN_FAILED: Err = "Failed to open given file"; break; case D_GIF_ERR_READ_FAILED: Err = "Failed to read from given file"; break; case D_GIF_ERR_NOT_GIF_FILE: Err = "Data is not in GIF format"; break; case D_GIF_ERR_NO_SCRN_DSCR: 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"; break; case D_GIF_ERR_WRONG_RECORD: Err = "Wrong record type detected"; break; case D_GIF_ERR_DATA_TOO_BIG: Err = "Number of pixels bigger than width * height"; break; case D_GIF_ERR_NOT_ENOUGH_MEM: Err = "Failed to allocate required memory"; break; case D_GIF_ERR_CLOSE_FAILED: Err = "Failed to close given file"; break; case D_GIF_ERR_NOT_READABLE: Err = "Given file was not opened for read"; break; case D_GIF_ERR_IMAGE_DEFECT: Err = "Image is defective, decoding aborted"; break; case D_GIF_ERR_EOF_TOO_SOON: Err = "Image EOF detected before image complete"; break; default: Err = NULL; break; } return Err; } /* end */ giflib-6.1.3/gif_hash.c0000664000175000017500000001066515166751647013071 0ustar esresr/***************************************************************************** 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. *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include "gif_hash.h" #include "gif_lib.h" #include "gif_lib_private.h" /* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */ #ifdef DEBUG_HIT_RATE static long NumberOfTests = 0, NumberOfMisses = 0; #endif /* DEBUG_HIT_RATE */ static int KeyItem(uint32_t Item); /****************************************************************************** Initialize HashTable - allocate the memory needed and clear it. * ******************************************************************************/ GifHashTableType *_InitHashTable(void) { GifHashTableType *HashTable; if ((HashTable = (GifHashTableType *)malloc( sizeof(GifHashTableType))) == NULL) { return NULL; } _ClearHashTable(HashTable); return HashTable; } /****************************************************************************** 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_t)); } /****************************************************************************** Routine to insert a new Item into the HashTable. The data is assumed to be * new one. * ******************************************************************************/ void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code) { int HKey = KeyItem(Key); uint32_t *HTable = HashTable->HTable; #ifdef DEBUG_HIT_RATE NumberOfTests++; NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ 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. * ******************************************************************************/ int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key) { int HKey = KeyItem(Key); uint32_t *HTable = HashTable->HTable, HTKey; #ifdef DEBUG_HIT_RATE NumberOfTests++; NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ 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! * ******************************************************************************/ static int KeyItem(uint32_t Item) { return ((Item >> 12) ^ Item) & HT_KEY_MASK; } #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 * ******************************************************************************/ void HashTablePrintHitRatio(void) { printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", NumberOfMisses, NumberOfTests, NumberOfMisses * 100 / NumberOfTests); } #endif /* DEBUG_HIT_RATE */ /* end */ giflib-6.1.3/gif_font.c0000664000175000017500000004127615166751647013116 0ustar esresr/**************************************************************************** gif_font.c - utility font handling and simple drawing for the GIF library ****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Eric S. Raymond #include #include #include #include #include "gif_lib.h" /**************************************************************************** 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. */ /*@+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 */ {0x00, 0xee, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 3 */ {0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 4 */ {0x00, 0x3c, 0x18, 0xff, 0xff, 0x08, 0x18, 0x00}, /* Ascii 5 */ {0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x10, 0x38, 0x00}, /* Ascii 6 */ {0x00, 0x00, 0x18, 0x3c, 0x18, 0x00, 0x00, 0x00}, /* Ascii 7 */ {0xff, 0xff, 0xe7, 0xc3, 0xe7, 0xff, 0xff, 0xff}, /* Ascii 8 */ {0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00}, /* Ascii 9 */ {0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0xbd, 0xc3, 0xff}, /* Ascii 10 */ {0x1f, 0x07, 0x0d, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* Ascii 11 */ {0x00, 0x7e, 0xc3, 0xc3, 0x7e, 0x18, 0x7e, 0x18}, /* Ascii 12 */ {0x04, 0x06, 0x07, 0x04, 0x04, 0xfc, 0xf8, 0x00}, /* Ascii 13 */ {0x0c, 0x0a, 0x0d, 0x0b, 0xf9, 0xf9, 0x1f, 0x1f}, /* Ascii 14 */ {0x00, 0x92, 0x7c, 0x44, 0xc6, 0x7c, 0x92, 0x00}, /* Ascii 15 */ {0x00, 0x00, 0x60, 0x78, 0x7e, 0x78, 0x60, 0x00}, /* Ascii 16 */ {0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00}, /* Ascii 17 */ {0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18}, /* Ascii 18 */ {0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00}, /* Ascii 19 */ {0xff, 0xb6, 0x76, 0x36, 0x36, 0x36, 0x36, 0x00}, /* Ascii 20 */ {0x7e, 0xc1, 0xdc, 0x22, 0x22, 0x1f, 0x83, 0x7e}, /* Ascii 21 */ {0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00}, /* Ascii 22 */ {0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x00, 0xff}, /* Ascii 23 */ {0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, /* Ascii 24 */ {0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x00}, /* Ascii 25 */ {0x00, 0x04, 0x06, 0xff, 0x06, 0x04, 0x00, 0x00}, /* Ascii 26 */ {0x00, 0x20, 0x60, 0xff, 0x60, 0x20, 0x00, 0x00}, /* Ascii 27 */ {0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0x00}, /* Ascii 28 */ {0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00}, /* Ascii 29 */ {0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00}, /* Ascii 30 */ {0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 31 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* */ {0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x00}, /* ! */ {0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */ {0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00}, /* # */ {0x10, 0x7c, 0xd2, 0x7c, 0x86, 0x7c, 0x10, 0x00}, /* $ */ {0xf0, 0x96, 0xfc, 0x18, 0x3e, 0x72, 0xde, 0x00}, /* % */ {0x30, 0x48, 0x30, 0x78, 0xce, 0xcc, 0x78, 0x00}, /* & */ {0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */ {0x10, 0x60, 0xc0, 0xc0, 0xc0, 0x60, 0x10, 0x00}, /* ( */ {0x10, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x10, 0x00}, /* ) */ {0x00, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x00, 0x00}, /* * */ {0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00}, /* + */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70}, /* , */ {0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}, /* - */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00}, /* . */ {0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00}, /* / */ {0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* 0 */ {0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* 1 */ {0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x60, 0xfe, 0x00}, /* 2 */ {0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00}, /* 3 */ {0x0e, 0x1e, 0x36, 0x66, 0xfe, 0x06, 0x06, 0x00}, /* 4 */ {0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xfc, 0x00}, /* 5 */ {0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00}, /* 6 */ {0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x00}, /* 7 */ {0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* 8 */ {0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00}, /* 9 */ {0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00}, /* : */ {0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x20, 0x00}, /* }, */ {0x00, 0x1c, 0x30, 0x60, 0x30, 0x1c, 0x00, 0x00}, /* < */ {0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00}, /* = */ {0x00, 0x70, 0x18, 0x0c, 0x18, 0x70, 0x00, 0x00}, /* > */ {0x7c, 0xc6, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00}, /* ? */ {0x7c, 0x82, 0x9a, 0xaa, 0xaa, 0x9e, 0x7c, 0x00}, /* @ */ {0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00}, /* A */ {0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x00}, /* B */ {0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00}, /* C */ {0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00}, /* D */ {0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xfe, 0x00}, /* E */ {0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* F */ {0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7e, 0x00}, /* G */ {0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00}, /* H */ {0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, /* I */ {0x1e, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00}, /* J */ {0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00}, /* K */ {0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00}, /* L */ {0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00}, /* M */ {0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00}, /* N */ {0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* O */ {0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* P */ {0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x06}, /* Q */ {0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0x00}, /* R */ {0x78, 0xcc, 0x60, 0x30, 0x18, 0xcc, 0x78, 0x00}, /* S */ {0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00}, /* T */ {0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* U */ {0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* V */ {0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00}, /* W */ {0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00}, /* X */ {0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00}, /* Y */ {0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00}, /* Z */ {0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00}, /* [ */ {0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x00}, /* \ */ {0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00}, /* ] */ {0x00, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00}, /* ^ */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, /* _ */ {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */ {0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00}, /* a */ {0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0x00}, /* b */ {0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7e, 0x00}, /* c */ {0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x00}, /* d */ {0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7e, 0x00}, /* e */ {0x1e, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x00}, /* f */ {0x00, 0x00, 0x7e, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* g */ {0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* */ {0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* i */ {0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0xf0}, /* j */ {0xc0, 0xc0, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0x00}, /* k */ {0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* l */ {0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xc6, 0xc6, 0x00}, /* m */ {0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* n */ {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* o */ {0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0}, /* p */ {0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x06}, /* q */ {0x00, 0x00, 0x6e, 0x70, 0x60, 0x60, 0x60, 0x00}, /* r */ {0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0xfc, 0x00}, /* s */ {0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00}, /* t */ {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00}, /* u */ {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* v */ {0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00}, /* w */ {0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00}, /* x */ {0x00, 0x00, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* y */ {0x00, 0x00, 0xfc, 0x18, 0x30, 0x60, 0xfc, 0x00}, /* z */ {0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00}, /* { */ {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, /* | */ {0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00}, /* } */ {0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00}, /* ~ */ {0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00} /* Ascii 127 */ }; /*@=charint@*/ static bool GifImageGetGeometry(const SavedImage *Image, size_t *width, size_t *height, size_t *pixels) { size_t w, h; if (Image == NULL || Image->RasterBits == NULL) { return false; } if (Image->ImageDesc.Width <= 0 || Image->ImageDesc.Height <= 0) { return false; } w = (size_t)Image->ImageDesc.Width; h = (size_t)Image->ImageDesc.Height; if (w > SIZE_MAX / h) { return false; } if (width != NULL) { *width = w; } if (height != NULL) { *height = h; } if (pixels != NULL) { *pixels = w * h; } return true; } static void GifPutPixelClipped(SavedImage *Image, int x, int y, GifPixelType color) { size_t width, height; if (!GifImageGetGeometry(Image, &width, &height, NULL)) { return; } if (x < 0 || y < 0) { return; } if ((size_t)x >= width || (size_t)y >= height) { return; } Image->RasterBits[(size_t)y * width + (size_t)x] = color; } void GifDrawText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int color) { int i; const unsigned char *cp; if (legend == NULL) { return; } for (i = 0; i < GIF_FONT_HEIGHT; i++) { int row_y = y + i; if (row_y < 0 || row_y > INT_MAX) { continue; } for (cp = (const unsigned char *)legend; *cp != '\0'; cp++) { size_t char_index = (size_t)(cp - (const unsigned char *)legend); size_t j; int glyph_x; unsigned int glyph; if (*cp >= 128) { continue; } if (char_index > (size_t)(INT_MAX / GIF_FONT_WIDTH)) { break; } glyph_x = x + (int)(char_index * GIF_FONT_WIDTH); glyph = GifAsciiTable8x8[*cp][i]; for (j = 0; j < GIF_FONT_WIDTH; j++) { if ((glyph & (1U << (GIF_FONT_WIDTH - 1 - j))) != 0U) { if (glyph_x <= INT_MAX - (int)j) { GifPutPixelClipped(Image, glyph_x + (int)j, row_y, (GifPixelType)color); } } } } } } void GifDrawBox(SavedImage *Image, const int x, const int y, const int w, const int d, const int color) { int j; if (w < 0 || d < 0) { return; } for (j = 0; j <= w; j++) { if (x <= INT_MAX - j) { GifPutPixelClipped(Image, x + j, y, (GifPixelType)color); if (y <= INT_MAX - d) { GifPutPixelClipped(Image, x + j, y + d, (GifPixelType)color); } } } for (j = 0; j <= d; j++) { if (y <= INT_MAX - j) { GifPutPixelClipped(Image, x, y + j, (GifPixelType)color); if (x <= INT_MAX - w) { GifPutPixelClipped(Image, x + w, y + j, (GifPixelType)color); } } } } void GifDrawRectangle(SavedImage *Image, const int x, const int y, const int w, const int d, const int color) { size_t width, height; size_t row; size_t x0, y0, x1, y1; if (!GifImageGetGeometry(Image, &width, &height, NULL)) { return; } if (w <= 0 || d <= 0) { return; } x0 = (x <= 0) ? 0U : (size_t)x; y0 = (y <= 0) ? 0U : (size_t)y; if (x >= 0 && (size_t)x < width) { size_t rw = (size_t)w; x1 = rw > width - (size_t)x ? width : (size_t)x + rw; } else if (x < 0) { size_t rw = (size_t)w; size_t start = (size_t)(-x); if (rw <= start) { return; } x1 = rw - start; if (x1 > width) { x1 = width; } } else { return; } if (y >= 0 && (size_t)y < height) { size_t rh = (size_t)d; y1 = rh > height - (size_t)y ? height : (size_t)y + rh; } else if (y < 0) { size_t rh = (size_t)d; size_t start = (size_t)(-y); if (rh <= start) { return; } y1 = rh - start; if (y1 > height) { y1 = height; } } else { return; } if (x0 >= x1 || y0 >= y1) { return; } for (row = y0; row < y1; row++) { memset(Image->RasterBits + row * width + x0, (GifPixelType)color, x1 - x0); } } void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int border, const int bg, const int fg) { size_t j = 0, LineCount = 0, TextWidth = 0; const char *cp; char *dup; size_t legend_len; if (legend == NULL || border < 0) { return; } /* compute size of text to box */ for (cp = legend; *cp != '\0'; cp++) { if (*cp == '\r' || *cp == '\n') { if (j > TextWidth) { TextWidth = j; } j = 0; LineCount++; } else if (*cp != '\t') { ++j; } } LineCount++; /* count last line */ if (j > TextWidth) { /* last line might be longer than any previous */ TextWidth = j; } legend_len = strlen(legend); dup = malloc(legend_len + 1); /* FIXME: should return bad status, but that would require API change */ if (dup != NULL) { size_t fill_w = 0, fill_h = 0, box_w = 0, box_h = 0; int i = 0; char *line, *next; if (TextWidth <= (SIZE_MAX - (size_t)(2 * border)) / GIF_FONT_WIDTH) { box_w = (size_t)(2 * border) + TextWidth * GIF_FONT_WIDTH; if (box_w > 0) { fill_w = box_w - 1; } } if (LineCount <= (SIZE_MAX - (size_t)(2 * border)) / GIF_FONT_HEIGHT) { box_h = (size_t)(2 * border) + LineCount * GIF_FONT_HEIGHT; if (box_h > 0) { fill_h = box_h - 1; } } if (fill_w > (size_t)INT_MAX) { fill_w = (size_t)INT_MAX; } if (fill_h > (size_t)INT_MAX) { fill_h = (size_t)INT_MAX; } if (box_w > (size_t)INT_MAX) { box_w = (size_t)INT_MAX; } if (box_h > (size_t)INT_MAX) { box_h = (size_t)INT_MAX; } /* fill the box */ GifDrawRectangle(Image, x + 1, y + 1, (int)fill_w, (int)fill_h, bg); memcpy(dup, legend, legend_len + 1); for (line = dup; line != NULL; line = next) { size_t leadspace = 0; char *eol = strpbrk(line, "\r\n"); next = NULL; if (eol != NULL) { next = eol + 1; if ((*eol == '\r' && *next == '\n') || (*eol == '\n' && *next == '\r')) { ++next; } *eol = '\0'; } if (line[0] == '\t') { size_t linelen = strlen(line + 1); if (linelen < TextWidth) { leadspace = (TextWidth - linelen) / 2; } ++line; } if ((size_t)i <= (size_t)(INT_MAX / GIF_FONT_HEIGHT)) { int text_x = x + border; int text_y = y + border + (GIF_FONT_HEIGHT * i++); if (leadspace <= (size_t)(INT_MAX / GIF_FONT_WIDTH) && text_x <= INT_MAX - (int)(leadspace * GIF_FONT_WIDTH)) { text_x += (int)(leadspace * GIF_FONT_WIDTH); } GifDrawText8x8(Image, text_x, text_y, line, fg); } } free(dup); /* outline the box */ GifDrawBox(Image, x, y, (int)box_w, (int)box_h, fg); } } /* end */ giflib-6.1.3/giftext.c0000664000175000017500000003556415166751647013000 0ustar esresr/***************************************************************************** giftext - dump GIF pixels and metadata as text *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #ifdef _WIN32 #include #endif /* _WIN32 */ #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "giftext" #define MAKE_PRINTABLE(c) (isprint(c) ? (c) : ' ') static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- c%- e%- z%- p%- r%- h%- GifFile!*s"; static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, bool Reset); static void PrintPixelBlock(GifByteType *PixelBlock, int Len, bool Reset); static void PrintExtBlock(GifByteType *Extension, bool Reset); static void PrintLZCodes(GifFileType *GifFile); /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, ExtCode, ErrorCode, CodeSize, NumFiles, Len, ImageNum = 1; bool Error, ColorMapFlag = false, EncodedFlag = false, LZCodesFlag = false, PixelFlag = false, HelpFlag = false, RawFlag = false, GifNoisyPrint; char *GifFileName, **FileName = NULL; GifPixelType *Line; GifRecordType RecordType; GifByteType *CodeBlock, *Extension; GifFileType *GifFile; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &ColorMapFlag, &EncodedFlag, &LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles > 1) { GIF_MESSAGE("Error in command line parsing - one GIF " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (NumFiles == 1) { GifFileName = *FileName; if ((GifFile = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } else { /* Use stdin instead: */ GifFileName = "Stdin"; if ((GifFile = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } /* Because we write binary data - make sure no text will be written. */ if (RawFlag) { ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = false; #ifdef _WIN32 _setmode(1, O_BINARY); /* Make sure it is in binary mode. */ #endif /* _WIN32 */ } else { printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n", GifFileName, GifFile->SWidth, GifFile->SHeight); printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround " "= %d, Aspect = %d.\n", GifFile->SColorResolution, GifFile->SColorMap ? GifFile->SColorMap->BitsPerPixel : 0, GifFile->SBackGroundColor, GifFile->AspectByte); if (GifFile->SColorMap) { printf("\tHas Global Color Map.\n\n"); } else { printf("\tNo Global Color Map.\n\n"); } if (ColorMapFlag && GifFile->SColorMap) { printf("\tGlobal Color Map:\n"); Len = GifFile->SColorMap->ColorCount; printf("\tSort Flag: %s\n", GifFile->SColorMap->SortFlag ? "on" : "off"); for (i = 0; i < Len; i += 4) { for (j = 0; j < 4 && i + j < Len; j++) { printf("%3d: %02xh %02xh %02xh ", i + j, GifFile->SColorMap->Colors[i + j] .Red, GifFile->SColorMap->Colors[i + j] .Green, GifFile->SColorMap->Colors[i + j] .Blue); } printf("\n"); } } } do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } if (!RawFlag) { printf( "\nImage #%d:\n\n\tImage Size - Left = %d, " "Top = %d, Width = %d, Height = %d.\n", ImageNum++, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); printf("\tImage is %s", GifFile->Image.Interlace ? "Interlaced" : "Non Interlaced"); if (GifFile->Image.ColorMap != NULL) { printf(", BitsPerPixel = %d.\n", GifFile->Image.ColorMap ->BitsPerPixel); } else { printf(".\n"); } if (GifFile->Image.ColorMap) { printf("\tImage Has Color Map.\n"); } else { printf("\tNo Image Color Map.\n"); } if (ColorMapFlag && GifFile->Image.ColorMap) { printf("\tSort Flag: %s\n", GifFile->Image.ColorMap->SortFlag ? "on" : "off"); Len = 1 << GifFile->Image.ColorMap ->BitsPerPixel; for (i = 0; i < Len; i += 4) { for (j = 0; j < 4 && j < Len; j++) { printf( "%3d: %02xh %02xh " "%02xh ", i + j, GifFile->Image .ColorMap ->Colors[i + j] .Red, GifFile->Image .ColorMap ->Colors[i + j] .Green, GifFile->Image .ColorMap ->Colors[i + j] .Blue); } printf("\n"); } } } if (EncodedFlag) { if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } printf("\nImage LZ compressed Codes (Code Size " "= %d):\n", CodeSize); PrintCodeBlock(GifFile, CodeBlock, true); while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } PrintCodeBlock(GifFile, CodeBlock, false); } } else if (LZCodesFlag) { PrintLZCodes(GifFile); } else if (PixelFlag) { Line = (GifPixelType *)malloc( GifFile->Image.Width * sizeof(GifPixelType)); for (i = 0; i < GifFile->Image.Height; i++) { if (DGifGetLine(GifFile, Line, GifFile->Image.Width) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } PrintPixelBlock( Line, GifFile->Image.Width, i == 0); } PrintPixelBlock(NULL, GifFile->Image.Width, false); free((char *)Line); } else if (RawFlag) { Line = (GifPixelType *)malloc( GifFile->Image.Width * sizeof(GifPixelType)); for (i = 0; i < GifFile->Image.Height; i++) { if (DGifGetLine(GifFile, Line, GifFile->Image.Width) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } fwrite(Line, 1, GifFile->Image.Width, stdout); } free((char *)Line); } else { /* Skip the image: */ if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } } } break; case EXTENSION_RECORD_TYPE: if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } if (!RawFlag) { putchar('\n'); switch (ExtCode) { case COMMENT_EXT_FUNC_CODE: printf("GIF89 comment"); break; case GRAPHICS_EXT_FUNC_CODE: printf("GIF89 graphics control"); break; case PLAINTEXT_EXT_FUNC_CODE: printf("GIF89 plaintext"); break; case APPLICATION_EXT_FUNC_CODE: printf("GIF89 application block"); break; default: printf( "Extension record of unknown type"); break; } printf(" (Ext Code = %d [%c]):\n", ExtCode, MAKE_PRINTABLE(ExtCode)); PrintExtBlock(Extension, true); if (ExtCode == GRAPHICS_EXT_FUNC_CODE) { GraphicsControlBlock gcb; if (Extension == NULL) { printf("Invalid extension " "block\n"); GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } if (DGifExtensionToGCB( Extension[0], Extension + 1, &gcb) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } printf("\tDisposal Mode: %d\n", gcb.DisposalMode); printf("\tUser Input Flag: %d\n", gcb.UserInputFlag); printf("\tTransparency on: %s\n", gcb.TransparentColor != -1 ? "yes" : "no"); printf("\tDelayTime: %d\n", gcb.DelayTime); printf("\tTransparent Index: %d\n", gcb.TransparentColor); } } for (;;) { if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } if (Extension == NULL) { break; } PrintExtBlock(Extension, false); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (!RawFlag) { printf("\nGIF file terminated normally.\n"); } return 0; } /****************************************************************************** Print the given CodeBlock - a string in pascal notation (size in first place). Save local information so printing can be performed continuously, or reset to start state if Reset. If CodeBlock is NULL, output is flushed ******************************************************************************/ static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, bool Reset) { static int CrntPlace = 0; static long CodeCount = 0; int i, Len; if (Reset || CodeBlock == NULL) { if (CodeBlock == NULL) { long NumBytes = 0; if (CrntPlace > 0) { printf("\n"); CodeCount += CrntPlace - 16; } if (GifFile->Image.ColorMap) { NumBytes = ((((long)GifFile->Image.Width) * GifFile->Image.Height) * GifFile->Image.ColorMap->BitsPerPixel) / 8; } else if (GifFile->SColorMap != NULL) { NumBytes = ((((long)GifFile->Image.Width) * GifFile->Image.Height) * GifFile->SColorMap->BitsPerPixel) / 8; } /* FIXME: What should the compression ratio be if no * color table? */ if (NumBytes > 0) { int Percent = 100 * CodeCount / NumBytes; printf("\nCompression ratio: %ld/%ld (%d%%).\n", CodeCount, NumBytes, Percent); } return; } CrntPlace = 0; CodeCount = 0; } // cppcheck-suppress nullPointerRedundantCheck Len = CodeBlock[0]; for (i = 1; i <= Len; i++) { if (CrntPlace == 0) { printf("\n%05lxh: ", CodeCount); CodeCount += 16; } (void)printf(" %02xh", CodeBlock[i]); if (++CrntPlace >= 16) { CrntPlace = 0; } } } /****************************************************************************** Print the given Extension - a string in pascal notation (size in first place). Save local information so printing can be performed continuously, or reset to start state if Reset. If Extension is NULL, output is flushed ******************************************************************************/ static void PrintExtBlock(GifByteType *Extension, bool Reset) { static int CrntPlace = 0; static long ExtCount = 0; static char HexForm[49], AsciiForm[17]; if (Reset || Extension == NULL) { if (Extension == NULL) { if (CrntPlace > 0) { HexForm[CrntPlace * 3] = 0; AsciiForm[CrntPlace] = 0; printf("\n%05lx: %-49s %-17s\n", ExtCount, HexForm, AsciiForm); return; } else { printf("\n"); } } CrntPlace = 0; ExtCount = 0; } if (Extension != NULL) { int i, Len; Len = Extension[0]; for (i = 1; i <= Len; i++) { (void)snprintf(&HexForm[CrntPlace * 3], 4, " %02x", Extension[i]); (void)snprintf(&AsciiForm[CrntPlace], 2, "%c", MAKE_PRINTABLE(Extension[i])); if (++CrntPlace == 16) { HexForm[CrntPlace * 3] = 0; AsciiForm[CrntPlace] = 0; printf("\n%05lx: %-49s %-17s", ExtCount, HexForm, AsciiForm); ExtCount += 16; CrntPlace = 0; } } } } /****************************************************************************** Print the given PixelBlock of length Len. Save local information so printing can be performed continuously, or reset to start state if Reset. If PixelBlock is NULL, output is flushed ******************************************************************************/ static void PrintPixelBlock(GifByteType *PixelBlock, int Len, bool Reset) { static int CrntPlace = 0; static long ExtCount = 0; static char HexForm[49], AsciiForm[17]; int i; if (Reset || PixelBlock == NULL) { if (PixelBlock == NULL) { if (CrntPlace > 0) { HexForm[CrntPlace * 3] = 0; AsciiForm[CrntPlace] = 0; printf("\n%05lx: %-49s %-17s\n", ExtCount, HexForm, AsciiForm); } else { printf("\n"); } } CrntPlace = 0; ExtCount = 0; if (PixelBlock == NULL) { return; } } for (i = 0; i < Len; i++) { (void)snprintf(&HexForm[CrntPlace * 3], 4, " %02x", PixelBlock[i]); (void)snprintf(&AsciiForm[CrntPlace], 2, "%c", MAKE_PRINTABLE(PixelBlock[i])); if (++CrntPlace == 16) { HexForm[CrntPlace * 3] = 0; AsciiForm[CrntPlace] = 0; printf("\n%05lx: %-49s %-17s", ExtCount, HexForm, AsciiForm); ExtCount += 16; CrntPlace = 0; } } } /****************************************************************************** Print the image as LZ codes (each 12bits), until EOF marker is reached. ******************************************************************************/ static void PrintLZCodes(GifFileType *GifFile) { int Code, CrntPlace = 0; long CodeCount = 0; do { if (CrntPlace == 0) { printf("\n%05lx:", CodeCount); } if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } if (Code >= 0) { printf(" %03x", Code); /* EOF Code is returned as -1. */ } CodeCount++; if (++CrntPlace >= 16) { CrntPlace = 0; } } while (Code >= 0); } /* end */ giflib-6.1.3/qprintf.c0000664000175000017500000000227415166751647013001 0ustar esresr/***************************************************************************** qprintf.c - module to emulate a printf with a possible quiet (disable mode.) A global variable GifNoisyPrint controls the printing of this routine *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include "gif_lib.h" bool GifNoisyPrint = false; /***************************************************************************** Same as fprintf to stderr but with optional print. ******************************************************************************/ void GifQprintf(char *Format, ...) { va_list ArgPtr; va_start(ArgPtr, Format); if (GifNoisyPrint) { char Line[128]; (void)vsnprintf(Line, sizeof(Line), Format, ArgPtr); (void)fputs(Line, stderr); } va_end(ArgPtr); } void PrintGifError(int ErrorCode) { const char *Err = GifErrorString(ErrorCode); if (Err != NULL) { fprintf(stderr, "GIF-LIB error: %s.\n", Err); } else { fprintf(stderr, "GIF-LIB undefined error %d.\n", ErrorCode); } } /* end */ giflib-6.1.3/gifbg.c0000664000175000017500000002517715166751647012403 0ustar esresr/***************************************************************************** gifbg - generate a test-pattern GIF *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifbg" #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 350 #define DEFAULT_COLOR_RED 0 #define DEFAULT_COLOR_GREEN 0 #define DEFAULT_COLOR_BLUE 255 #define DEFAULT_MIN_INTENSITY 10 /* In percent. */ #define DEFAULT_MAX_INTENSITY 100 #define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen in image. */ #define DIR_NONE 0 /* Direction the levels can be changed: */ #define DIR_TOP 1 #define DIR_TOP_RIGHT 2 #define DIR_RIGHT 3 #define DIR_BOT_RIGHT 4 #define DIR_BOT 5 #define DIR_BOT_LEFT 6 #define DIR_LEFT 7 #define DIR_TOP_LEFT 8 #define DEFAULT_DIR "T" /* TOP (North) direction. */ static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d " "m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-"; static int MaximumIntensity = DEFAULT_MAX_INTENSITY, /* In percent. */ MinimumIntensity = DEFAULT_MIN_INTENSITY, NumLevels = DEFAULT_NUM_LEVELS, ImageWidth = DEFAULT_WIDTH, ImageHeight = DEFAULT_HEIGHT, Direction; static unsigned int RedColor = DEFAULT_COLOR_RED, GreenColor = DEFAULT_COLOR_GREEN, BlueColor = DEFAULT_COLOR_BLUE; static void QuitGifError(GifFileType *GifFile); /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, l, LevelWidth, LogNumLevels, ErrorCode, Count = 0; bool Error, FlipDir, DoAllMaximum = false, DirectionFlag = false, LevelsFlag = false, ColorFlag = false, MinFlag = false, MaxFlag = false, SizeFlag = false, HelpFlag = false, GifNoisyPrint; GifPixelType Color; char *DirectionStr = DEFAULT_DIR; GifRowType Line; ColorMapObject *ColorMap; GifFileType *GifFile; if ((Error = GAGetArgs( argc, argv, CtrlStr, &GifNoisyPrint, &DirectionFlag, &DirectionStr, &LevelsFlag, &NumLevels, &ColorFlag, &RedColor, &GreenColor, &BlueColor, &MinFlag, &MinimumIntensity, &MaxFlag, &MaximumIntensity, &SizeFlag, &ImageWidth, &ImageHeight, &HelpFlag)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* Validate image dimensions early to avoid overflow/negative values. */ if (ImageWidth <= 0 || ImageHeight <= 0) { GIF_EXIT("Image size must be positive."); } if (ImageWidth > INT_MAX / 2) { GIF_EXIT("Image width too large."); } /* Make sure intensities are in the right range: */ if (MinimumIntensity < 0 || MinimumIntensity > 100 || MaximumIntensity < 0 || MaximumIntensity > 100) { GIF_EXIT("Intensities (-m or -M options) are not in [0..100] " "range (percent)."); } /* Convert DirectionStr to our local representation: */ Direction = DIR_NONE; FlipDir = false; /* Make sure it's upper case. */ for (i = 0; i < (int)strlen(DirectionStr); i++) { if (islower(DirectionStr[i])) { DirectionStr[i] = toupper(DirectionStr[i]); } } switch (DirectionStr[0]) { case 'T': /* Top or North */ case 'N': if (strlen(DirectionStr) < 2) { Direction = DIR_TOP; } else { switch (DirectionStr[1]) { case 'R': case 'E': Direction = DIR_TOP_RIGHT; break; case 'L': case 'W': Direction = DIR_TOP_LEFT; FlipDir = true; break; } } break; case 'R': /* Right or East */ case 'E': Direction = DIR_RIGHT; break; case 'B': /* Bottom or South */ case 'S': if (strlen(DirectionStr) < 2) { Direction = DIR_BOT; FlipDir = true; } else { switch (DirectionStr[1]) { case 'R': case 'E': Direction = DIR_BOT_RIGHT; break; case 'L': case 'W': Direction = DIR_BOT_LEFT; FlipDir = true; break; } } break; case 'L': /* Left or West */ case 'W': Direction = DIR_LEFT; FlipDir = true; break; } if (Direction == DIR_NONE) { GIF_EXIT("Direction requested (-d option) is weird!"); } /* We are going to handle only TOP, TOP_RIGHT, RIGHT, BOT_RIGHT so flip */ /* the complement cases (TOP <-> BOT for example) by flipping the */ /* Color i with color (NumLevels - i - 1). */ if (FlipDir) { switch (Direction) { case DIR_BOT: Direction = DIR_TOP; break; case DIR_BOT_LEFT: Direction = DIR_TOP_RIGHT; break; case DIR_LEFT: Direction = DIR_RIGHT; break; case DIR_TOP_LEFT: Direction = DIR_BOT_RIGHT; break; } } /* If binary mask is requested (special case): */ if (MinimumIntensity == 100 && MaximumIntensity == 100 && NumLevels == 2) { MinimumIntensity = 0; DoAllMaximum = true; Direction = DIR_RIGHT; } /* Make sure colors are in the right range: */ if (RedColor > 255 || GreenColor > 255 || BlueColor > 255) { GIF_EXIT("Colors are not in the ragne [0..255]."); } /* Make sure number of levels is power of 2 (up to 8 bits per pixel). */ for (i = 1; i < 8; i++) { if (NumLevels == (1 << i)) { break; } } if (i == 8) { GIF_EXIT("#Lvls (-l option) is not power of 2."); } LogNumLevels = i; /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out screen description with given size and generated color map: */ if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } for (i = 1; i <= NumLevels; i++) { /* Ratio will be in the range of 0..100 for required intensity: */ unsigned int Ratio = (MaximumIntensity * (i * (256 / NumLevels)) + MinimumIntensity * ((NumLevels - i) * (256 / NumLevels))) / 256; ColorMap->Colors[i - 1].Red = (RedColor * Ratio) / 100; ColorMap->Colors[i - 1].Green = (GreenColor * Ratio) / 100; ColorMap->Colors[i - 1].Blue = (BlueColor * Ratio) / 100; } if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap) == GIF_ERROR) { QuitGifError(GifFile); } /* Dump out the image descriptor: */ if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); /* Allocate one scan line twice as big as image is, as we are going to */ /* shift along it, while we dump the scan lines: */ if ((Line = (GifRowType)malloc(sizeof(GifPixelType) * ImageWidth * 2)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } if (Direction == DIR_TOP) { int LevelHeight; /* We must evaluate the line each time level is changing: */ LevelHeight = ImageHeight / NumLevels; for (Color = NumLevels, i = l = 0; i < ImageHeight; i++) { if (i == l) { int j; /* Time to update the line to next color level: */ if (Color != 0) { Color--; } for (j = 0; j < ImageWidth; j++) { Line[j] = (FlipDir ? NumLevels - Color - 1 : Color); } l += LevelHeight; } if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", Count++); } } else if (Direction == DIR_RIGHT) { /* We pre-prepare the scan lines as going from color zero to * maximum */ /* color and dump the same scan line Height times: */ /* Note this case should handle the Boolean Mask special case. */ LevelWidth = ImageWidth / NumLevels; if (DoAllMaximum) { /* Special case - do all in maximum color: */ for (i = 0; i < ImageWidth; i++) { Line[i] = 1; } } else { for (Color = i = 0, l = LevelWidth; i < ImageWidth; i++, l--) { if (l == 0) { l = LevelWidth; if (Color < NumLevels - 1) { Color++; } } Line[i] = (FlipDir ? NumLevels - Color - 1 : Color); } } for (i = 0; i < ImageHeight; i++) { /* coverity[uninit_use_in_call] */ if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", Count++); } } else { int Accumulator, StartX, StepX; /* We are in one of the TOP_RIGHT, BOT_RIGHT cases: we will */ /* initialize the Line with its double ImageWidth length from * the */ /* minimum intensity to the maximum intensity and shift along it */ /* while we go along the image height. */ LevelWidth = ImageWidth * 2 / NumLevels; for (Color = i = 0, l = LevelWidth; i < ImageWidth * 2; i++, l--) { if (l == 0) { l = LevelWidth; if (Color < NumLevels - 1) { Color++; } } Line[i] = (FlipDir ? NumLevels - Color - 1 : Color); } /* We need to implement a DDA to know how much to shift Line * while */ /* we go down along image height. we set the parameters for it * now: */ Accumulator = 0; switch (Direction) { case DIR_TOP_RIGHT: StartX = ImageWidth; StepX = -1; break; case DIR_BOT_RIGHT: default: StartX = 0; StepX = 1; break; } /* Time to dump information out: */ for (i = 0; i < ImageHeight; i++) { if (EGifPutLine(GifFile, &Line[StartX], ImageWidth) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", Count++); if ((Accumulator += ImageWidth) > ImageHeight) { while (Accumulator > ImageHeight) { Accumulator -= ImageHeight; StartX += StepX; } if (Direction < 0) { Direction = 0; } if (Direction > ImageWidth) { Direction = ImageWidth; } } } } if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; } /****************************************************************************** Close output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFile) { if (GifFile != NULL) { PrintGifError(GifFile->Error); EGifCloseFile(GifFile, NULL); } exit(EXIT_FAILURE); } /* end */ giflib-6.1.3/gif_hash.h0000664000175000017500000000264515166751647013075 0ustar esresr/****************************************************************************** gif_hash.h - magfic constants and declarations for GIF LZW ******************************************************************************/ // SPDX-License-Identifier: MIT #ifndef _GIF_HASH_H_ #define _GIF_HASH_H_ #ifndef _WIN32 #include #endif /* _WIN32 */ #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. */ /* 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. */ /* 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) typedef struct GifHashTableType { uint32_t HTable[HT_SIZE]; } GifHashTableType; GifHashTableType *_InitHashTable(void); void _ClearHashTable(GifHashTableType *HashTable); void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code); int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key); #endif /* _GIF_HASH_H_ */ /* end */ giflib-6.1.3/gifbuild.c0000664000175000017500000006757115166751647013116 0ustar esresr/***************************************************************************** gifbuild - dump GIF data in a textual format, or undump it to a GIF *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include #include #include #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifbuild" static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- d%- t%-Characters!s h%- GifFile(s)!*s"; static char KeyLetters[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO" "PQRSTUVWXYZ!\"#$%&'()*+,-./:<=>?@[\\]^_`{|}~"; #define PRINTABLES (sizeof(KeyLetters) - 1) static void Icon2Gif(char *FileName, FILE *txtin, bool, int fdout); static void Gif2Icon(char *FileName, int fdin, int fdout, char NameTable[]); static int EscapeString(char *cp, char *tp); /****************************************************************************** Main sequence ******************************************************************************/ int main(int argc, char **argv) { int NumFiles; bool Error, DisasmFlag = false, HelpFlag = false, TextLineFlag = false, GifNoisyPrint = false; char **FileNames = NULL; char *TextLines[1]; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &DisasmFlag, &TextLineFlag, &TextLines[0], &HelpFlag, &NumFiles, &FileNames)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (!DisasmFlag && NumFiles > 1) { GIF_MESSAGE( "Error in command line parsing - one text input please."); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (!DisasmFlag && TextLineFlag) { GIF_MESSAGE( "Error in command line parsing - -t invalid without -d."); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (NumFiles == 0) { if (DisasmFlag) Gif2Icon("Stdin", 0, 1, TextLineFlag ? TextLines[0] : KeyLetters); else Icon2Gif("Stdin", stdin, GifNoisyPrint, 1); } else { int i; for (i = 0; i < NumFiles; i++) { FILE *fp; if ((fp = fopen(FileNames[i], "r")) == (FILE *)NULL) { (void)fprintf(stderr, "Can't open %s\n", FileNames[i]); exit(EXIT_FAILURE); } if (DisasmFlag) { printf("#\n# GIF information from %s\n", FileNames[i]); Gif2Icon(FileNames[i], -1, 1, TextLineFlag ? TextLines[0] : KeyLetters); } else { Icon2Gif(FileNames[i], fp, GifNoisyPrint, 1); } (void)fclose(fp); } } return 0; } /****************************************************************************** Parse image directives ******************************************************************************/ #define PARSE_ERROR(str) \ (void)fprintf(stderr, "%s:%d: %s\n", FileName, LineNum, str); static void Icon2Gif(char *FileName, FILE *txtin, bool GifNoisyPrint, int fdout) { unsigned int ColorMapSize = 0; GifColorType GlobalColorMap[256], LocalColorMap[256], *ColorMap = GlobalColorMap; char GlobalColorKeys[PRINTABLES], LocalColorKeys[PRINTABLES], *KeyTable = GlobalColorKeys; bool SortFlag = false; unsigned int ExtCode, intval; int red, green, blue, n; char buf[BUFSIZ * 2], InclusionFile[64]; GifFileType *GifFileOut; SavedImage *NewImage = NULL; int LeadingExtensionBlockCount = 0; ExtensionBlock *LeadingExtensionBlocks = NULL; int ErrorCode, LineNum = 0; if ((GifFileOut = EGifOpenFileHandle(fdout, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* OK, interpret directives */ /* coverity[tainted_data_transitive] */ while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) { char *cp; ++LineNum; /* * Skip lines consisting only of whitespace and comments */ for (cp = buf; isspace((int)(*cp)); cp++) { continue; } if (*cp == '#' || *cp == '\0') { continue; } /* * If there's a trailing comment, nuke it and all preceding * whitespace. But preserve the EOL. */ if ((cp = strchr(buf, '#')) && (cp == strrchr(cp, '#'))) { while (isspace((int)(*--cp))) { continue; } *++cp = '\n'; *++cp = '\0'; } /* * Explicit header declarations */ if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == 1) { if (GifFileOut->SWidth <= 0) { PARSE_ERROR("Invalid screen width."); exit(EXIT_FAILURE); } continue; } else if (sscanf(buf, "screen height %d\n", &GifFileOut->SHeight) == 1) { if (GifFileOut->SHeight <= 0) { PARSE_ERROR("Invalid screen height."); exit(EXIT_FAILURE); } continue; } else if (sscanf(buf, "screen colors %d\n", &n) == 1) { int ResBits = GifBitSize(n); if (n > 256 || n < 0 || n != (1 << ResBits)) { PARSE_ERROR("Invalid color resolution value."); exit(EXIT_FAILURE); } GifFileOut->SColorResolution = ResBits; continue; } else if (sscanf(buf, "screen background %d\n", &GifFileOut->SBackGroundColor) == 1) { continue; } else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) { GifFileOut->AspectByte = (GifByteType)(intval & 0xff); continue; } /* * Color table parsing */ else if (strcmp(buf, "screen map\n") == 0) { if (GifFileOut->SColorMap != NULL) { PARSE_ERROR("You've already declared a global " "color map."); exit(EXIT_FAILURE); } ColorMapSize = 0; ColorMap = GlobalColorMap; SortFlag = false; KeyTable = GlobalColorKeys; memset(GlobalColorKeys, '\0', sizeof(GlobalColorKeys)); } else if (strcmp(buf, "image map\n") == 0) { if (NewImage == NULL) { PARSE_ERROR("No previous image declaration."); exit(EXIT_FAILURE); } ColorMapSize = 0; ColorMap = LocalColorMap; KeyTable = LocalColorKeys; memset(LocalColorKeys, '\0', sizeof(LocalColorKeys)); } else if (sscanf(buf, " rgb %d %d %d is %c", &red, &green, &blue, &KeyTable[ColorMapSize]) == 4) { if (ColorMapSize >= 256) { PARSE_ERROR("Too many color entries."); exit(EXIT_FAILURE); } if (ColorMapSize >= PRINTABLES) { PARSE_ERROR("Too many color entries for keyed " "color map."); exit(EXIT_FAILURE); } ColorMap[ColorMapSize].Red = red; ColorMap[ColorMapSize].Green = green; ColorMap[ColorMapSize].Blue = blue; ColorMapSize++; } else if (sscanf(buf, " rgb %d %d %d", &red, &green, &blue) == 3) { if (ColorMapSize >= 256) { PARSE_ERROR("Too many color entries."); exit(EXIT_FAILURE); } ColorMap[ColorMapSize].Red = red; ColorMap[ColorMapSize].Green = green; ColorMap[ColorMapSize].Blue = blue; ColorMapSize++; } else if (strcmp(buf, " sort flag on\n") == 0) { SortFlag = true; } else if (strcmp(buf, " sort flag off\n") == 0) { SortFlag = false; } else if (strcmp(buf, "end\n") == 0) { ColorMapObject *NewMap; NewMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ColorMap); if (NewMap == (ColorMapObject *)NULL) { PARSE_ERROR("Out of memory while allocating " "new color map."); exit(EXIT_FAILURE); } NewMap->SortFlag = SortFlag; if (NewImage) { NewImage->ImageDesc.ColorMap = NewMap; } else { GifFileOut->SColorMap = NewMap; } } /* GIF inclusion */ /* ugly magic number is because scanf has no */ else if (sscanf(buf, "include %63s", InclusionFile) == 1) { bool DoTranslation; GifPixelType Translation[256]; GifFileType *Inclusion; SavedImage *CopyFrom; if ((Inclusion = DGifOpenFileName( InclusionFile, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (DGifSlurp(Inclusion) == GIF_ERROR) { PARSE_ERROR("Inclusion read failed."); // cppcheck-suppress knownConditionTrueFalse if (Inclusion != NULL) { PrintGifError(Inclusion->Error); DGifCloseFile(Inclusion, NULL); } if (GifFileOut != NULL) { EGifCloseFile(GifFileOut, NULL); }; exit(EXIT_FAILURE); } // cppcheck-suppress nullPointerRedundantCheck if ((DoTranslation = (GifFileOut->SColorMap != (ColorMapObject *)NULL))) { ColorMapObject *UnionMap; UnionMap = GifUnionColorMap( // cppcheck-suppress nullPointerRedundantCheck GifFileOut->SColorMap, Inclusion->SColorMap, Translation); if (UnionMap == NULL) { PARSE_ERROR("Inclusion failed --- " "global map conflict."); // cppcheck-suppress nullPointerRedundantCheck PrintGifError(GifFileOut->Error); // cppcheck-suppress knownConditionTrueFalse if (Inclusion != NULL) { DGifCloseFile(Inclusion, NULL); } if (GifFileOut != NULL) { EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } GifFreeMapObject(GifFileOut->SColorMap); GifFileOut->SColorMap = UnionMap; } for (CopyFrom = Inclusion->SavedImages; CopyFrom < Inclusion->SavedImages + Inclusion->ImageCount; CopyFrom++) { if ((NewImage = GifMakeSavedImage( GifFileOut, CopyFrom)) == NULL) { PARSE_ERROR("Inclusion failed --- out " "of memory."); // cppcheck-suppress nullPointerRedundantCheck PrintGifError(GifFileOut->Error); // cppcheck-suppress knownConditionTrueFalse if (Inclusion != NULL) { DGifCloseFile(Inclusion, NULL); } if (GifFileOut != NULL) { EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } else if (DoTranslation) { GifApplyTranslation(NewImage, Translation); } GifQprintf("%s: Image %d at (%d, %d) [%dx%d]: " "from %s\n", PROGRAM_NAME, GifFileOut->ImageCount, NewImage->ImageDesc.Left, NewImage->ImageDesc.Top, NewImage->ImageDesc.Width, NewImage->ImageDesc.Height, InclusionFile); } (void)DGifCloseFile(Inclusion, NULL); } /* * Extension blocks. */ else if (strcmp(buf, "comment\n") == 0) { int bc = 0; while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) { if (strcmp(buf, "end\n") == 0) { break; } else { int Len; buf[strlen(buf) - 1] = '\0'; Len = EscapeString(buf, buf); if (GifAddExtensionBlock( &LeadingExtensionBlockCount, &LeadingExtensionBlocks, bc++ == CONTINUE_EXT_FUNC_CODE ? COMMENT_EXT_FUNC_CODE : 0, Len, (unsigned char *)buf) == GIF_ERROR) { PARSE_ERROR( "out of memory while " "adding comment block."); exit(EXIT_FAILURE); } } } } else if (strcmp(buf, "plaintext\n") == 0) { int bc = 0; while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) { if (strcmp(buf, "end\n") == 0) { break; } else { int Len; buf[strlen(buf) - 1] = '\0'; Len = EscapeString(buf, buf); if (GifAddExtensionBlock( &LeadingExtensionBlockCount, &LeadingExtensionBlocks, bc++ == CONTINUE_EXT_FUNC_CODE ? PLAINTEXT_EXT_FUNC_CODE : 0, Len, (unsigned char *)buf) == GIF_ERROR) { PARSE_ERROR( "out of memory while " "adding plaintext block."); exit(EXIT_FAILURE); } } } } else if (strcmp(buf, "graphics control\n") == 0) { GraphicsControlBlock gcb; size_t Len; memset(&gcb, '\0', sizeof(gcb)); gcb.TransparentColor = NO_TRANSPARENT_COLOR; while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) { if (strcmp(buf, "end\n") == 0) { break; } else { char *tp = buf; while (isspace(*tp)) { tp++; } if (sscanf(tp, "disposal mode %d\n", &gcb.DisposalMode)) { continue; } if (strcmp(tp, "user input flag on\n") == 0) { gcb.UserInputFlag = true; continue; } if (strcmp(tp, "user input flag off\n") == 0) { gcb.UserInputFlag = false; continue; } if (sscanf(tp, "delay %d\n", &gcb.DelayTime)) { continue; } if (sscanf(tp, "transparent index %d\n", &gcb.TransparentColor)) { continue; } (void)fputs(tp, stderr); PARSE_ERROR("unrecognized directive in " "GCB block."); exit(EXIT_FAILURE); } } Len = EGifGCBToExtension(&gcb, (GifByteType *)buf); if (GifAddExtensionBlock( &LeadingExtensionBlockCount, &LeadingExtensionBlocks, GRAPHICS_EXT_FUNC_CODE, Len, (unsigned char *)buf) == GIF_ERROR) { PARSE_ERROR("out of memory while adding GCB."); exit(EXIT_FAILURE); } } else if (sscanf(buf, "netscape loop %u", &intval)) { unsigned char params[3] = {1, 0, 0}; /* Create a Netscape 2.0 loop block */ if (GifAddExtensionBlock( &LeadingExtensionBlockCount, &LeadingExtensionBlocks, APPLICATION_EXT_FUNC_CODE, 11, (unsigned char *)"NETSCAPE2.0") == GIF_ERROR) { PARSE_ERROR( "out of memory while adding loop block."); exit(EXIT_FAILURE); } params[1] = (intval & 0xff); params[2] = (intval >> 8) & 0xff; if (GifAddExtensionBlock(&LeadingExtensionBlockCount, &LeadingExtensionBlocks, 0, sizeof(params), params) == GIF_ERROR) { PARSE_ERROR("out of memory while adding loop " "continuation."); exit(EXIT_FAILURE); } } else if (sscanf(buf, "extension %x", &ExtCode)) { int bc = 0; while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) { if (strcmp(buf, "end\n") == 0) { break; } else { int Len; buf[strlen(buf) - 1] = '\0'; Len = EscapeString(buf, buf); if (GifAddExtensionBlock( &LeadingExtensionBlockCount, &LeadingExtensionBlocks, bc++ == CONTINUE_EXT_FUNC_CODE ? ExtCode : 0, Len, (unsigned char *)buf) == GIF_ERROR) { PARSE_ERROR( "out of memory while " "adding extension block."); exit(EXIT_FAILURE); } } } } /* * Explicit image declarations */ else if (strcmp(buf, "image\n") == 0) { if ((NewImage = GifMakeSavedImage(GifFileOut, NULL)) == (SavedImage *)NULL) { PARSE_ERROR("Out of memory while allocating " "image block."); exit(EXIT_FAILURE); } /* use global table unless user specifies a local one */ ColorMap = GlobalColorMap; KeyTable = GlobalColorKeys; /* connect leading extension blocks */ NewImage->ExtensionBlockCount = LeadingExtensionBlockCount; NewImage->ExtensionBlocks = LeadingExtensionBlocks; LeadingExtensionBlockCount = 0; LeadingExtensionBlocks = NULL; } /* * Nothing past this point is valid unless we've seen a previous * image declaration. */ else if (NewImage == (SavedImage *)NULL) { (void)fputs(buf, stderr); PARSE_ERROR("Syntax error in header block."); exit(EXIT_FAILURE); } /* * Accept image attributes */ else if (sscanf(buf, "image top %d\n", &NewImage->ImageDesc.Top) == 1) { continue; } else if (sscanf(buf, "image left %d\n", &NewImage->ImageDesc.Left) == 1) { continue; } else if (strcmp(buf, "image interlaced\n") == 0) { NewImage->ImageDesc.Interlace = true; continue; } else if (sscanf(buf, "image bits %d by %d", &NewImage->ImageDesc.Width, &NewImage->ImageDesc.Height) == 2) { int i, j; static GifPixelType *Raster; int c; bool hex = (strstr(buf, "hex") != NULL); size_t pixel_count; if (NewImage->ImageDesc.Width <= 0 || NewImage->ImageDesc.Height <= 0 || NewImage->ImageDesc.Width > INT_MAX / NewImage->ImageDesc.Height) { PARSE_ERROR("Invalid image dimensions."); exit(EXIT_FAILURE); } pixel_count = (size_t)NewImage->ImageDesc.Width * (size_t)NewImage->ImageDesc.Height; if (pixel_count > SIZE_MAX / sizeof(GifPixelType)) { PARSE_ERROR("Image dimensions overflow."); exit(EXIT_FAILURE); } /* coverity[overflow_sink] */ if ((Raster = (GifPixelType *)malloc( sizeof(GifPixelType) * pixel_count)) == NULL) { PARSE_ERROR("Failed to allocate raster block, " "aborted."); exit(EXIT_FAILURE); } GifQprintf("%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFileOut->ImageCount, NewImage->ImageDesc.Left, NewImage->ImageDesc.Top, NewImage->ImageDesc.Width, NewImage->ImageDesc.Height); GifByteType *tp = Raster; for (i = 0; i < NewImage->ImageDesc.Height; i++) { char *dp; for (j = 0; j < NewImage->ImageDesc.Width; j++) { if ((c = fgetc(txtin)) == EOF) { PARSE_ERROR("input file ended " "prematurely."); exit(EXIT_FAILURE); } else if (c == '\n') { --j; ++LineNum; } else if (isspace(c)) { --j; } else if (hex) { const static char *hexdigits = "0123456789ABCDEF"; unsigned char hi, lo; dp = strchr(hexdigits, toupper(c)); if (dp == NULL) { PARSE_ERROR( "Invalid hex high " "byte."); exit(EXIT_FAILURE); } hi = (dp - hexdigits); if ((c = fgetc(txtin)) == EOF) { PARSE_ERROR( "input file ended " "prematurely."); exit(EXIT_FAILURE); } dp = strchr(hexdigits, toupper(c)); if (dp == NULL) { PARSE_ERROR( "Invalid hex low " "byte."); exit(EXIT_FAILURE); } lo = (dp - hexdigits); *tp++ = (hi << 4) | lo; } else if ((dp = strchr(KeyTable, c))) { *tp++ = (dp - KeyTable); } else { PARSE_ERROR( "Invalid ASCII pixel key."); exit(EXIT_FAILURE); } } if (GifNoisyPrint) { fprintf(stderr, "\b\b\b\b%-4d", i); } } if (GifNoisyPrint) { putc('\n', stderr); } NewImage->RasterBits = (unsigned char *)Raster; } else { (void)fputs(buf, stderr); PARSE_ERROR("Syntax error in image description."); exit(EXIT_FAILURE); } } /* connect trailing extension blocks */ GifFileOut->ExtensionBlockCount = LeadingExtensionBlockCount; GifFileOut->ExtensionBlocks = LeadingExtensionBlocks; // LeadingExtensionBlockCount = 0; LeadingExtensionBlocks = NULL; if (EGifSpew(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } static void VisibleDumpBuffer(GifByteType *buf, int len) /* Visibilize a given string */ { GifByteType *cp; for (cp = buf; cp < buf + len; cp++) { if (isprint((int)(*cp)) || *cp == ' ') { putchar(*cp); } else if (*cp == '\n') { putchar('\\'); putchar('n'); } else if (*cp == '\r') { putchar('\\'); putchar('r'); } else if (*cp == '\b') { putchar('\\'); putchar('b'); } else if (*cp < ' ') { putchar('\\'); putchar('^'); putchar('@' + *cp); } else { printf("\\0x%02x", *cp); } } } static void DumpExtensions(GifFileType *GifFileOut, int ExtensionBlockCount, ExtensionBlock *ExtensionBlocks) { ExtensionBlock *ep; for (ep = ExtensionBlocks; ep < ExtensionBlocks + ExtensionBlockCount; ep++) { bool last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1)); if (ep->Function == COMMENT_EXT_FUNC_CODE) { printf("comment\n"); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); putchar('\n'); while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) { ++ep; last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1)); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); putchar('\n'); } printf("end\n\n"); } else if (ep->Function == PLAINTEXT_EXT_FUNC_CODE) { printf("plaintext\n"); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); putchar('\n'); while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) { ++ep; last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1)); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); putchar('\n'); } printf("end\n\n"); } else if (ep->Function == GRAPHICS_EXT_FUNC_CODE) { GraphicsControlBlock gcb; printf("graphics control\n"); if (DGifExtensionToGCB(ep->ByteCount, ep->Bytes, &gcb) == GIF_ERROR) { GIF_MESSAGE("invalid graphics control block"); exit(EXIT_FAILURE); } printf("\tdisposal mode %d\n", gcb.DisposalMode); printf("\tuser input flag %s\n", gcb.UserInputFlag ? "on" : "off"); printf("\tdelay %d\n", gcb.DelayTime); printf("\ttransparent index %d\n", gcb.TransparentColor); printf("end\n\n"); } else if (!last && ep->Function == APPLICATION_EXT_FUNC_CODE && ep->ByteCount >= 11 && (ep + 1)->ByteCount >= 3 && memcmp(ep->Bytes, "NETSCAPE2.0", 11) == 0) { unsigned char *params = (++ep)->Bytes; unsigned int loopcount = params[1] | (params[2] << 8); printf("netscape loop %u\n\n", loopcount); } else { printf("extension 0x%02x\n", ep->Function); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) { ++ep; last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1)); VisibleDumpBuffer(ep->Bytes, ep->ByteCount); putchar('\n'); } printf("end\n\n"); } } } static void Gif2Icon(char *FileName, int fdin, int fdout, char NameTable[]) { int ErrorCode, im, i, j, ColorCount = 0; GifFileType *GifFile; size_t name_len = strlen(NameTable); if (fdin == -1) { if ((GifFile = DGifOpenFileName(FileName, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } else { /* Use stdin instead: */ if ((GifFile = DGifOpenFileHandle(fdin, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } if (DGifSlurp(GifFile) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } printf("screen width %d\nscreen height %d\n", GifFile->SWidth, GifFile->SHeight); printf( "screen colors %d\nscreen background %d\npixel aspect byte %u\n\n", 1 << GifFile->SColorResolution, GifFile->SBackGroundColor, (unsigned)GifFile->AspectByte); if (GifFile->SColorMap) { printf("screen map\n"); printf("\tsort flag %s\n", GifFile->SColorMap->SortFlag ? "on" : "off"); for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { if (GifFile->SColorMap->ColorCount < PRINTABLES) { if ((size_t)i >= name_len) { GIF_EXIT("Name table too short."); } printf("\trgb %03d %03d %03d is %c\n", GifFile->SColorMap->Colors[i].Red, GifFile->SColorMap->Colors[i].Green, GifFile->SColorMap->Colors[i].Blue, NameTable[i]); } else { printf("\trgb %03d %03d %03d\n", GifFile->SColorMap->Colors[i].Red, GifFile->SColorMap->Colors[i].Green, GifFile->SColorMap->Colors[i].Blue); } } printf("end\n\n"); } for (im = 0; im < GifFile->ImageCount; im++) { SavedImage *image = &GifFile->SavedImages[im]; DumpExtensions(GifFile, image->ExtensionBlockCount, image->ExtensionBlocks); printf("image # %d\nimage left %d\nimage top %d\n", im + 1, image->ImageDesc.Left, image->ImageDesc.Top); if (image->ImageDesc.Interlace) { printf("image interlaced\n"); } if (image->ImageDesc.ColorMap) { printf("image map\n"); printf("\tsort flag %s\n", image->ImageDesc.ColorMap->SortFlag ? "on" : "off"); if (image->ImageDesc.ColorMap->ColorCount < PRINTABLES) { for (i = 0; i < image->ImageDesc.ColorMap->ColorCount; i++) { if ((size_t)i >= name_len) { GIF_EXIT( "Name table too short."); } printf( "\trgb %03d %03d %03d is %c\n", image->ImageDesc.ColorMap->Colors[i] .Red, image->ImageDesc.ColorMap->Colors[i] .Green, image->ImageDesc.ColorMap->Colors[i] .Blue, NameTable[i]); } } else { for (i = 0; i < image->ImageDesc.ColorMap->ColorCount; i++) { printf( "\trgb %03d %03d %03d\n", image->ImageDesc.ColorMap->Colors[i] .Red, image->ImageDesc.ColorMap->Colors[i] .Green, image->ImageDesc.ColorMap->Colors[i] .Blue); } } printf("end\n\n"); } /* one of these conditions has to be true */ if (image->ImageDesc.ColorMap) { ColorCount = image->ImageDesc.ColorMap->ColorCount; } else if (GifFile->SColorMap) { ColorCount = GifFile->SColorMap->ColorCount; } if (ColorCount < PRINTABLES) { printf("image bits %d by %d\n", image->ImageDesc.Width, image->ImageDesc.Height); } else { printf("image bits %d by %d hex\n", image->ImageDesc.Width, image->ImageDesc.Height); } for (i = 0; i < image->ImageDesc.Height; i++) { for (j = 0; j < image->ImageDesc.Width; j++) { GifByteType ch = image->RasterBits [i * image->ImageDesc.Width + j]; if (ColorCount < PRINTABLES && ch < PRINTABLES) { putchar(NameTable[ch]); } else { printf("%02x", ch); } } putchar('\n'); } putchar('\n'); } DumpExtensions(GifFile, GifFile->ExtensionBlockCount, GifFile->ExtensionBlocks); /* Tell EMACS this is a picture... */ printf("# The following sets edit modes for GNU EMACS\n"); printf("# Local "); /* ...break this up, so that EMACS doesn't */ printf("Variables:\n"); /* get confused when visiting *this* file! */ printf("# mode:picture\n"); printf("# truncate-lines:t\n"); printf("# End:\n"); if (fdin == -1) { (void)printf("# End of %s dump\n", FileName); } /* * Sanity checks. */ /* check that the background color isn't garbage (SF bug #87) */ if (GifFile->SBackGroundColor < 0 || (GifFile->SColorMap && GifFile->SBackGroundColor >= GifFile->SColorMap->ColorCount)) { fprintf(stderr, "gifbuild: background color invalid for screen " "colormap.\n"); } if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } static int EscapeString(char *cp, char *tp) /* process standard C-style escape sequences in a string */ { char *StartAddr = tp; while (*cp) { int cval = 0; if (*cp == '\\' && strchr("0123456789xX", cp[1])) { int dcount = 0; if (*++cp == 'x' || *cp == 'X') { char *dp, *hex = "00112233445566778899aAbBcCdDeEfF"; for (++cp; (dp = strchr(hex, *cp)) && (dcount++ < 2); cp++) { cval = (cval * 16) + (dp - hex) / 2; } } else if (*cp == '0') { while (strchr("01234567", *cp) != (char *)NULL && (dcount++ < 3)) { cval = (cval * 8) + (*cp++ - '0'); } } else { while ((strchr("0123456789", *cp) != (char *)NULL) && (dcount++ < 3)) { cval = (cval * 10) + (*cp++ - '0'); } } } else if (*cp == '\\') /* C-style character escapes */ { switch (*++cp) { case '\\': cval = '\\'; break; case 'n': cval = '\n'; break; case 't': cval = '\t'; break; case 'b': cval = '\b'; break; case 'r': cval = '\r'; break; default: cval = *cp; } cp++; } else if (*cp == '^') /* expand control-character syntax */ { cval = (*++cp & 0x1f); cp++; } else { cval = *cp++; } *tp++ = cval; } return (tp - StartAddr); } /* end */ giflib-6.1.3/dgif_lib.c0000664000175000017500000012050515166751647013053 0ustar esresr/****************************************************************************** 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! *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include #include #include #ifdef _WIN32 #include #else #include #endif /* _WIN32 */ #include "gif_lib.h" #include "gif_lib_private.h" /* compose unsigned little endian value */ #define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8)) /* avoid extra function call in case we use fread (TVT) */ static int InternalRead(GifFileType *gif, GifByteType *buf, int len) { // fprintf(stderr, "### Read: %d\n", len); return (((GifFilePrivateType *)gif->Private)->Read ? ((GifFilePrivateType *)gif->Private)->Read(gif, buf, len) : fread(buf, 1, len, ((GifFilePrivateType *)gif->Private)->File)); } static int DGifGetWord(GifFileType *GifFile, GifWord *Word); static int DGifSetupDecompress(GifFileType *GifFile); static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen); static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode); static int DGifDecompressInput(GifFileType *GifFile, int *Code); static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte); /****************************************************************************** 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, int *Error) { int FileHandle; GifFileType *GifFile; if ((FileHandle = open(FileName, O_RDONLY)) == -1) { if (Error != NULL) { *Error = D_GIF_ERR_OPEN_FAILED; } return NULL; } GifFile = DGifOpenFileHandle(FileHandle, Error); return GifFile; } /****************************************************************************** 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, int *Error) { char Buf[GIF_STAMP_LEN + 1]; GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { if (Error != NULL) { *Error = D_GIF_ERR_NOT_ENOUGH_MEM; } (void)close(FileHandle); return NULL; } /*@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 *)calloc(1, sizeof(GifFilePrivateType)); if (Private == NULL) { if (Error != NULL) { *Error = D_GIF_ERR_NOT_ENOUGH_MEM; } (void)close(FileHandle); free((char *)GifFile); return NULL; } /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType)); #ifdef _WIN32 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ #endif /* _WIN32 */ f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ /*@-mustfreeonly@*/ GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_READ; Private->Read = NULL; /* don't use alternate input method (TVT) */ GifFile->UserData = NULL; /* TVT */ /*@=mustfreeonly@*/ /* Let's see if this is a GIF file: */ /* coverity[check_return] */ if (InternalRead(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; } /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = 0; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { 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) { (void)fclose(f); free((char *)Private); free((char *)GifFile); return NULL; } GifFile->Error = 0; /* What version of GIF? */ Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9'); return GifFile; } /****************************************************************************** GifFileType constructor with user supplied input function (TVT) ******************************************************************************/ GifFileType *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) { 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 *)calloc(1, sizeof(GifFilePrivateType)); if (!Private) { if (Error != NULL) { *Error = D_GIF_ERR_NOT_ENOUGH_MEM; } free((char *)GifFile); return NULL; } /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType)); GifFile->Private = (void *)Private; Private->FileHandle = 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: */ /* coverity[check_return] */ if (InternalRead(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; } /* Check for GIF prefix at start of file */ Buf[GIF_STAMP_LEN] = '\0'; if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { if (Error != NULL) { *Error = D_GIF_ERR_NOT_GIF_FILE; } free((char *)Private); free((char *)GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { free((char *)Private); free((char *)GifFile); if (Error != NULL) { *Error = D_GIF_ERR_NO_SCRN_DSCR; } return NULL; } GifFile->Error = 0; /* What version of GIF? */ Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '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. ******************************************************************************/ int 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: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } /* Put the screen descriptor into the file: */ if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) { return GIF_ERROR; } if (InternalRead(GifFile, Buf, 3) != 3) { 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 = GifMakeMapObject(1 << BitsPerPixel, NULL); if (GifFile->SColorMap == NULL) { 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++) { /* coverity[check_return] */ if (InternalRead(GifFile, Buf, 3) != 3) { GifFreeMapObject(GifFile->SColorMap); GifFile->SColorMap = NULL; GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } GifFile->SColorMap->Colors[i].Red = Buf[0]; GifFile->SColorMap->Colors[i].Green = Buf[1]; GifFile->SColorMap->Colors[i].Blue = Buf[2]; } } else { GifFile->SColorMap = NULL; } /* * No check here for whether the background color is in range for the * screen color map. Possibly there should be. */ return GIF_OK; } const char *DGifGetGifVersion(GifFileType *GifFile) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (Private->gif89) { return GIF89_STAMP; } else { return GIF87_STAMP; } } /****************************************************************************** This routine should be called before any attempt to read an image. ******************************************************************************/ int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } /* coverity[check_return] */ if (InternalRead(GifFile, &Buf, 1) != 1) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } // fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf); switch (Buf) { case DESCRIPTOR_INTRODUCER: *Type = IMAGE_DESC_RECORD_TYPE; break; case EXTENSION_INTRODUCER: *Type = EXTENSION_RECORD_TYPE; break; case TERMINATOR_INTRODUCER: *Type = TERMINATE_RECORD_TYPE; break; default: *Type = UNDEFINED_RECORD_TYPE; GifFile->Error = D_GIF_ERR_WRONG_RECORD; return GIF_ERROR; } return GIF_OK; } int DGifGetImageHeader(GifFileType *GifFile) { unsigned int BitsPerPixel; GifByteType Buf[3]; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR || DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) { return GIF_ERROR; } if (InternalRead(GifFile, Buf, 1) != 1) { 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) ? true : false; /* 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 = GifMakeMapObject(1 << BitsPerPixel, NULL); if (GifFile->Image.ColorMap == NULL) { 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++) { /* coverity[check_return] */ if (InternalRead(GifFile, Buf, 3) != 3) { GifFreeMapObject(GifFile->Image.ColorMap); GifFile->Error = D_GIF_ERR_READ_FAILED; GifFile->Image.ColorMap = NULL; return GIF_ERROR; } GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; } } Private->PixelCount = (long)GifFile->Image.Width * (long)GifFile->Image.Height; /* Reset decompress algorithm parameters. */ return DGifSetupDecompress(GifFile); } /****************************************************************************** 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) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; SavedImage *sp; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (DGifGetImageHeader(GifFile) == GIF_ERROR) { return GIF_ERROR; } if (GifFile->SavedImages) { SavedImage *new_saved_images = (SavedImage *)reallocarray( GifFile->SavedImages, (GifFile->ImageCount + 1), sizeof(SavedImage)); if (new_saved_images == NULL) { GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } GifFile->SavedImages = new_saved_images; } else { if ((GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage))) == NULL) { GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } sp = &GifFile->SavedImages[GifFile->ImageCount]; memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc)); if (GifFile->Image.ColorMap != NULL) { sp->ImageDesc.ColorMap = GifMakeMapObject(GifFile->Image.ColorMap->ColorCount, GifFile->Image.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } sp->RasterBits = (unsigned char *)NULL; sp->ExtensionBlockCount = 0; sp->ExtensionBlocks = (ExtensionBlock *)NULL; GifFile->ImageCount++; return GIF_OK; } /****************************************************************************** Get one full scanned line (Line) of length LineLen from GIF file. ******************************************************************************/ int 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: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (!LineLen) { LineLen = GifFile->Image.Width; } if (LineLen < 0 || Private->PixelCount < (unsigned long)LineLen) { GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } Private->PixelCount -= LineLen; if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { if (Private->PixelCount == 0) { /* 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; } } while (Dummy != NULL); } return GIF_OK; } else { return GIF_ERROR; } } /****************************************************************************** Put one pixel (Pixel) into GIF file. ******************************************************************************/ int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel) { GifByteType *Dummy; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (Private->PixelCount == 0) { GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } Private->PixelCount --; if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) { if (Private->PixelCount == 0) { /* 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; } } while (Dummy != NULL); } return GIF_OK; } else { return GIF_ERROR; } } /****************************************************************************** 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) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; // fprintf(stderr, "### -> DGifGetExtension:\n"); if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } /* coverity[check_return] */ if (InternalRead(GifFile, &Buf, 1) != 1) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *ExtCode = Buf; // fprintf(stderr, "### <- DGifGetExtension: %02x, about to call // next\n", Buf); return DGifGetExtensionNext(GifFile, Extension); } /****************************************************************************** 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) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; // fprintf(stderr, "### -> DGifGetExtensionNext\n"); if (InternalRead(GifFile, &Buf, 1) != 1) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } // fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf); if (Buf > 0) { *Extension = Private->Buf; /* Use private unused buffer. */ (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ /* coverity[tainted_data,check_return] */ if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else { *Extension = NULL; } // fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension); return GIF_OK; } /****************************************************************************** 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, int *ErrorCode) { GifFilePrivateType *Private; 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: */ if (ErrorCode != NULL) { *ErrorCode = D_GIF_ERR_NOT_READABLE; } free((char *)GifFile->Private); free(GifFile); return GIF_ERROR; } 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 (ErrorCode != NULL) { *ErrorCode = D_GIF_SUCCEEDED; } return GIF_OK; } /****************************************************************************** Get 2 bytes (word) from the given file: ******************************************************************************/ static int DGifGetWord(GifFileType *GifFile, GifWord *Word) { unsigned char c[2]; /* coverity[check_return] */ if (InternalRead(GifFile, c, 2) != 2) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *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). ******************************************************************************/ int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } *CodeSize = Private->BitsPerPixel; return DGifGetCodeNext(GifFile, CodeBlock); } /****************************************************************************** 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) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; /* coverity[tainted_data_argument] */ /* coverity[check_return] */ if (InternalRead(GifFile, &Buf, 1) != 1) { 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 (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } } else { *CodeBlock = NULL; Private->Buf[0] = 0; /* Make sure the buffer is empty! */ Private->PixelCount = 0; /* And local info. indicate image read. */ } return GIF_OK; } /****************************************************************************** Setup the LZ decompression for this image: ******************************************************************************/ static int DGifSetupDecompress(GifFileType *GifFile) { int i, BitsPerPixel; GifByteType CodeSize; GifPrefixType *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; /* coverity[check_return] */ if (InternalRead(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */ GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; /* Failed to read Code size. */ } BitsPerPixel = CodeSize; /* this can only happen on a severely malformed GIF */ if (BitsPerPixel > 8) { GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */ return GIF_ERROR; /* Failed to read Code size. */ } Private->Buf[0] = 0; /* Input Buffer empty. */ Private->BitsPerPixel = BitsPerPixel; Private->ClearCode = (1 << BitsPerPixel); Private->EOFCode = Private->ClearCode + 1; Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ Private->StackPtr = 0; /* No pixels on the pixel stack. */ Private->LastCode = NO_SUCH_CODE; Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ Private->CrntShiftDWord = 0; Prefix = Private->Prefix; for (i = 0; i <= LZ_MAX_CODE; i++) { Prefix[i] = NO_SUCH_CODE; } return GIF_OK; } /****************************************************************************** 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) { int i = 0; int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; GifByteType *Stack, *Suffix; GifPrefixType *Prefix; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; StackPtr = Private->StackPtr; Prefix = Private->Prefix; Suffix = Private->Suffix; Stack = Private->Stack; EOFCode = Private->EOFCode; ClearCode = Private->ClearCode; LastCode = Private->LastCode; if (StackPtr > LZ_MAX_CODE) { return GIF_ERROR; } if (StackPtr != 0) { /* Let pop the stack off before continueing to read the GIF * file: */ while (StackPtr != 0 && i < LineLen) { Line[i++] = Stack[--StackPtr]; } } while (i < LineLen) { /* Decode LineLen items. */ if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) { return GIF_ERROR; } if (CrntCode == EOFCode) { /* 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. */ 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++) { Prefix[j] = NO_SUCH_CODE; } Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = Private->BitsPerPixel + 1; Private->MaxCode1 = 1 << Private->RunningBits; LastCode = Private->LastCode = NO_SUCH_CODE; } else { /* Its regular code - if in pixel range simply add it to * output stream, otherwise trace to codes linked list * until the prefix is in pixel range: */ if (CrntCode < ClearCode) { /* This is simple - its pixel scalar, so add it * to output: */ Line[i++] = CrntCode; } else { /* Its a code to needed to be traced: trace the * linked list until the prefix is a pixel, * while pushing the suffix 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) { Suffix[Private->RunningCode - 2] = Stack[StackPtr++] = DGifGetPrefixChar( Prefix, LastCode, ClearCode); } else { Suffix[Private->RunningCode - 2] = Stack[StackPtr++] = DGifGetPrefixChar( Prefix, CrntCode, ClearCode); } } else { CrntPrefix = CrntCode; } /* 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 (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } /* Push the last character on stack: */ Stack[StackPtr++] = CrntPrefix; /* Now lets pop all the stack into output: */ while (StackPtr != 0 && i < LineLen) { Line[i++] = Stack[--StackPtr]; } } if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < (LZ_MAX_CODE + 1) && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) { Prefix[Private->RunningCode - 2] = LastCode; if (CrntCode == Private->RunningCode - 2) { /* 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! */ Suffix[Private->RunningCode - 2] = DGifGetPrefixChar(Prefix, LastCode, ClearCode); } else { Suffix[Private->RunningCode - 2] = DGifGetPrefixChar(Prefix, CrntCode, ClearCode); } } LastCode = CrntCode; } } Private->LastCode = LastCode; Private->StackPtr = StackPtr; return GIF_OK; } /****************************************************************************** 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(const GifPrefixType *Prefix, int Code, int ClearCode) { int i = 0; while (Code > ClearCode && i++ <= LZ_MAX_CODE) { if (Code > LZ_MAX_CODE) { return NO_SUCH_CODE; } Code = Prefix[Code]; } return Code; } /****************************************************************************** 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) { GifByteType *CodeBlock; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_READABLE(Private)) { /* This file was NOT open for reading: */ GifFile->Error = D_GIF_ERR_NOT_READABLE; return GIF_ERROR; } if (DGifDecompressInput(GifFile, Code) == GIF_ERROR) { return GIF_ERROR; } if (*Code == Private->EOFCode) { /* Skip rest of codes (hopefully only NULL terminating block): */ do { if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) { return GIF_ERROR; } } while (CodeBlock != NULL); *Code = -1; } else if (*Code == Private->ClearCode) { /* We need to start over again: */ Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = Private->BitsPerPixel + 1; Private->MaxCode1 = 1 << Private->RunningBits; } return GIF_OK; } /****************************************************************************** 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) { 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; /* The image can't contain more than LZ_BITS per code. */ if (Private->RunningBits > LZ_BITS) { 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; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; /* If code cannot fit into RunningBits bits, must raise its size. Note * however that codes above 4095 are used for special signaling. * If we're using LZ_BITS bits already and we're at the max code, just * 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->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; } /****************************************************************************** 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) { if (Buf[0] == 0) { /* Needs to read the next buffer - this one is empty: */ /* coverity[check_return] */ if (InternalRead(GifFile, Buf, 1) != 1) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } /* There shouldn't be any empty data blocks here as the LZW spec * says the LZW termination code should come first. Therefore * we shouldn't be inside this routine at that point. */ if (Buf[0] == 0) { GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } if (InternalRead(GifFile, &Buf[1], Buf[0]) != Buf[0]) { GifFile->Error = D_GIF_ERR_READ_FAILED; return GIF_ERROR; } *NextByte = Buf[1]; Buf[1] = 2; /* We use now the second place as last char read! */ Buf[0]--; } else { *NextByte = Buf[Buf[1]++]; Buf[0]--; } return GIF_OK; } /****************************************************************************** This routine is called in case of error during parsing image. We need to decrease image counter and reallocate memory for saved images. Not decreasing ImageCount may lead to null pointer dereference, because the last element in SavedImages may point to the spoilt image and null pointer buffers. *******************************************************************************/ void DGifDecreaseImageCounter(GifFileType *GifFile) { GifFile->ImageCount--; if (GifFile->SavedImages[GifFile->ImageCount].RasterBits != NULL) { free(GifFile->SavedImages[GifFile->ImageCount].RasterBits); } if (GifFile->SavedImages[GifFile->ImageCount].ImageDesc.ColorMap != NULL) { GifFreeMapObject(GifFile->SavedImages[GifFile->ImageCount].ImageDesc.ColorMap); } // Avoid a dodgy edge casse in reallocarray() */ if (GifFile->ImageCount <= 0) { free(GifFile->SavedImages); GifFile->SavedImages = NULL; GifFile->ImageCount = 0; return; } /* Realloc array according to the new image counter. */ SavedImage *correct_saved_images = (SavedImage *)reallocarray( GifFile->SavedImages, GifFile->ImageCount, sizeof(SavedImage)); if (correct_saved_images != NULL) { GifFile->SavedImages = correct_saved_images; } } /****************************************************************************** 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) { size_t ImageSize; GifRecordType RecordType; SavedImage *sp; GifByteType *ExtData; int ExtFunction; GifFile->ExtensionBlocks = NULL; GifFile->ExtensionBlockCount = 0; do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { return (GIF_ERROR); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) { 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)) { DGifDecreaseImageCounter(GifFile); return GIF_ERROR; } ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) { DGifDecreaseImageCounter(GifFile); return GIF_ERROR; } sp->RasterBits = (unsigned char *)reallocarray( NULL, ImageSize, sizeof(GifPixelType)); if (sp->RasterBits == NULL) { DGifDecreaseImageCounter(GifFile); return GIF_ERROR; } if (sp->ImageDesc.Interlace) { int i, j; /* * The way an interlaced image should be read - * offsets and jumps... */ static const int InterlacedOffset[] = {0, 4, 2, 1}; static const 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) { DGifDecreaseImageCounter( GifFile); return GIF_ERROR; } } } } else { if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == GIF_ERROR) { DGifDecreaseImageCounter(GifFile); return GIF_ERROR; } } 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, &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); } } for (;;) { if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) { return (GIF_ERROR); } if (ExtData == NULL) { break; } /* Continue the extension block */ if (GifAddExtensionBlock( &GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks, CONTINUE_EXT_FUNC_CODE, ExtData[0], &ExtData[1]) == GIF_ERROR) { return (GIF_ERROR); } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Sanity check for corrupted file */ if (GifFile->ImageCount == 0) { GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR; return (GIF_ERROR); } return (GIF_OK); } /* end */ giflib-6.1.3/gifalloc.c0000664000175000017500000003132415166751647013074 0ustar esresr/***************************************************************************** GIF construction tools ****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include "gif_lib.h" #include "gif_lib_private.h" #define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** Miscellaneous utility functions ******************************************************************************/ /* return smallest bitfield size n will fit in */ int GifBitSize(int n) { register int i; for (i = 1; i <= 8; i++) { if ((1 << i) >= n) { break; } } return (i); } /****************************************************************************** Color map object functions ******************************************************************************/ /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ ColorMapObject *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 << GifBitSize(ColorCount))) { return ((ColorMapObject *)NULL); } Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); if (Object == (ColorMapObject *)NULL) { return ((ColorMapObject *)NULL); } Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType)); if (Object->Colors == (GifColorType *)NULL) { free(Object); return ((ColorMapObject *)NULL); } Object->ColorCount = ColorCount; Object->BitsPerPixel = GifBitSize(ColorCount); Object->SortFlag = false; if (ColorMap != NULL) { memcpy((char *)Object->Colors, (char *)ColorMap, ColorCount * sizeof(GifColorType)); } return (Object); } /******************************************************************************* Free a color map object *******************************************************************************/ void GifFreeMapObject(ColorMapObject *Object) { if (Object != NULL) { (void)free(Object->Colors); (void)free(Object); } } #ifdef DEBUG void 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++) { (void)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, "\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 the ColorUnion color map table./ *******************************************************************************/ ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1, const ColorMapObject *ColorIn2, GifPixelType ColorTransIn2[]) { int i, j, CrntSlot, RoundUpTo, NewGifBitSize; ColorMapObject *ColorUnion; /* * 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. */ /* 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 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 * of table 1. This is very useful if your display is limited to * 16 colors. */ while (CrntSlot > 0 && (ColorIn1->Colors[CrntSlot - 1].Red == 0 && ColorIn1->Colors[CrntSlot - 1].Green == 0 && ColorIn1->Colors[CrntSlot - 1].Blue == 0)) { CrntSlot--; } /* 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: */ for (j = 0; j < ColorIn1->ColorCount; j++) { if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0) { break; } } if (j < ColorIn1->ColorCount) { ColorTransIn2[i] = j; /* color exists in Color1 */ } else { /* Color is new - copy it to a new slot: */ ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i]; ColorTransIn2[i] = CrntSlot++; } } if (CrntSlot > 256) { GifFreeMapObject(ColorUnion); return ((ColorMapObject *)NULL); } 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. */ for (j = CrntSlot; j < RoundUpTo; j++) { Map[j].Red = Map[j].Green = Map[j].Blue = 0; } /* perhaps we can shrink the map? */ if (RoundUpTo < ColorUnion->ColorCount) { GifColorType *new_map = (GifColorType *)reallocarray( Map, RoundUpTo, sizeof(GifColorType)); if (new_map == NULL) { GifFreeMapObject(ColorUnion); return ((ColorMapObject *)NULL); } ColorUnion->Colors = new_map; } } ColorUnion->ColorCount = RoundUpTo; ColorUnion->BitsPerPixel = NewGifBitSize; return (ColorUnion); } /******************************************************************************* Apply a given color translation to the raster bits of an image *******************************************************************************/ void GifApplyTranslation(SavedImage *Image, const GifPixelType Translation[]) { register int i; register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; for (i = 0; i < RasterSize; i++) { Image->RasterBits[i] = Translation[Image->RasterBits[i]]; } } /****************************************************************************** Extension record functions ******************************************************************************/ int GifAddExtensionBlock(int *ExtensionBlockCount, ExtensionBlock **ExtensionBlocks, int Function, unsigned int Len, unsigned char ExtData[]) { ExtensionBlock *ep; if (*ExtensionBlocks == NULL) { *ExtensionBlocks = (ExtensionBlock *)malloc(sizeof(ExtensionBlock)); } else { ExtensionBlock *ep_new = (ExtensionBlock *)reallocarray( *ExtensionBlocks, (*ExtensionBlockCount + 1), sizeof(ExtensionBlock)); if (ep_new == NULL) { return (GIF_ERROR); } *ExtensionBlocks = ep_new; } if (*ExtensionBlocks == NULL) { return (GIF_ERROR); } ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++]; ep->Function = Function; ep->ByteCount = Len; ep->Bytes = (GifByteType *)malloc(ep->ByteCount); if (ep->Bytes == NULL) { return (GIF_ERROR); } if (ExtData != NULL) { memcpy(ep->Bytes, ExtData, Len); } return (GIF_OK); } void GifFreeExtensions(int *ExtensionBlockCount, ExtensionBlock **ExtensionBlocks) { ExtensionBlock *ep; if (*ExtensionBlocks == NULL) { return; } for (ep = *ExtensionBlocks; ep < (*ExtensionBlocks + *ExtensionBlockCount); ep++) { (void)free((char *)ep->Bytes); } (void)free((char *)*ExtensionBlocks); *ExtensionBlocks = NULL; *ExtensionBlockCount = 0; } /****************************************************************************** Image block allocation functions ******************************************************************************/ /* Private Function: * Frees the last image in the GifFile->SavedImages array */ void FreeLastSavedImage(GifFileType *GifFile) { SavedImage *sp; if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { return; } /* Remove one SavedImage from the GifFile */ GifFile->ImageCount--; sp = &GifFile->SavedImages[GifFile->ImageCount]; /* Deallocate its Colormap */ if (sp->ImageDesc.ColorMap != NULL) { GifFreeMapObject(sp->ImageDesc.ColorMap); sp->ImageDesc.ColorMap = NULL; } /* Deallocate the image data */ if (sp->RasterBits != NULL) { free((char *)sp->RasterBits); } /* Deallocate any extensions */ 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 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 */ SavedImage *GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom) { // cppcheck-suppress ctunullpointer if (GifFile->SavedImages == NULL) { GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); } else { SavedImage *newSavedImages = (SavedImage *)reallocarray( GifFile->SavedImages, (GifFile->ImageCount + 1), sizeof(SavedImage)); if (newSavedImages == NULL) { return ((SavedImage *)NULL); } GifFile->SavedImages = newSavedImages; } if (GifFile->SavedImages == NULL) { return ((SavedImage *)NULL); } else { SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++]; 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. */ /* Null out aliased pointers before any allocations * so that FreeLastSavedImage won't free CopyFrom's * data if an allocation fails partway through. */ sp->ImageDesc.ColorMap = NULL; sp->RasterBits = NULL; sp->ExtensionBlocks = NULL; sp->ExtensionBlockCount = 0; /* first, the local color map */ if (CopyFrom->ImageDesc.ColorMap != NULL) { sp->ImageDesc.ColorMap = GifMakeMapObject( CopyFrom->ImageDesc.ColorMap->ColorCount, CopyFrom->ImageDesc.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); } } /* next, the raster */ sp->RasterBits = (unsigned char *)reallocarray( NULL, (CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width), sizeof(GifPixelType)); if (sp->RasterBits == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); } memcpy(sp->RasterBits, CopyFrom->RasterBits, sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width); /* finally, the extension blocks */ if (CopyFrom->ExtensionBlocks != NULL) { int k; sp->ExtensionBlocks = (ExtensionBlock *)calloc( CopyFrom->ExtensionBlockCount, sizeof(ExtensionBlock)); if (sp->ExtensionBlocks == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); } for (k = 0; k < CopyFrom->ExtensionBlockCount; k++) { ExtensionBlock *dst = &sp->ExtensionBlocks[k]; ExtensionBlock *src = &CopyFrom->ExtensionBlocks[k]; dst->Function = src->Function; dst->ByteCount = src->ByteCount; if (src->ByteCount > 0) { dst->Bytes = (GifByteType *)malloc( src->ByteCount); if (dst->Bytes == NULL) { FreeLastSavedImage( GifFile); return (SavedImage *)(NULL); } memcpy(dst->Bytes, src->Bytes, src->ByteCount); } } } } else { memset((char *)sp, '\0', sizeof(SavedImage)); } return (sp); } } void GifFreeSavedImages(GifFileType *GifFile) { SavedImage *sp; if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { return; } for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { if (sp->ImageDesc.ColorMap != NULL) { GifFreeMapObject(sp->ImageDesc.ColorMap); sp->ImageDesc.ColorMap = NULL; } if (sp->RasterBits != NULL) { free((char *)sp->RasterBits); } GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks); } free((char *)GifFile->SavedImages); GifFile->SavedImages = NULL; } /* end */ giflib-6.1.3/getarg.h0000664000175000017500000000416515166751647012575 0ustar esresr/*************************************************************************** getarg.h - Support routines for the giflib utilities **************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #ifndef _GETARG_H #define _GETARG_H #include #include "gif_lib.h" #define VERSION_COOKIE " Version %d.%d, " /*************************************************************************** Error numbers as returned by GAGetArg routine: ***************************************************************************/ #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. */ bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...); void GAPrintErrMsg(int Error); void GAPrintHowTo(char *CtrlStr); /****************************************************************************** From qprintf.c ******************************************************************************/ extern void GifQprintf(char *Format, ...); extern void PrintGifError(int ErrorCode); /****************************************************************************** Color table quantization ******************************************************************************/ int GifQuantizeBuffer(unsigned int, unsigned int, int *, const GifByteType *, const GifByteType *, const GifByteType *, GifByteType *, GifColorType *); /* These used to live in the library header */ #define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg) #define GIF_EXIT(Msg) \ { \ GIF_MESSAGE(Msg); \ exit(-3); \ } #endif /* _GETARG_H */ /* end */ giflib-6.1.3/giffilter.c0000664000175000017500000001257515166751647013276 0ustar esresr/****************************************************************************** giffilter.c - skeleton file for generic GIF `filter' program Sequentially read GIF records from stdin, process them, send them out. Most of the junk above `int main' isn't needed for the skeleton, but is likely to be for what you'll do with it. If you compile this, it will turn into an expensive GIF copying routine; stdin to stdout with no changes and minimal validation. Well, it's a decent test of the low-level routines, anyway. Note: due to the vicissitudes of Lempel-Ziv compression, the output of this copier may not be bitwise identical to its input. This can happen if you copy an image from a much more (or much *less*) memory-limited system; your compression may use more (or fewer) bits. The uncompressed rasters should, however, be identical (you can check this with gifbuild -d). ******************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "giffilter" /****************************************************************************** Close both input and output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) { if (GifFileIn != NULL) { PrintGifError(GifFileIn->Error); EGifCloseFile(GifFileIn, NULL); } if (GifFileOut != NULL) { PrintGifError(GifFileOut->Error); EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } /****************************************************************************** Main sequence ******************************************************************************/ int main(int argc, char **argv) { GifFileType *GifFileIn = NULL, *GifFileOut = NULL; GifRecordType RecordType; int CodeSize, ExtCode, ErrorCode; GifByteType *CodeBlock, *Extension; /* * Command-line processing goes here. */ /* Use stdin as input (note this also read screen descriptor in: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Use the stdout as output: */ if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* And dump out its screen information: */ if (EGifPutScreenDesc(GifFileOut, GifFileIn->SWidth, GifFileIn->SHeight, GifFileIn->SColorResolution, GifFileIn->SBackGroundColor, GifFileIn->SColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Scan the content of the input GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Put image descriptor to out file: */ if (EGifPutImageDesc( GifFileOut, GifFileIn->Image.Left, GifFileIn->Image.Top, GifFileIn->Image.Width, GifFileIn->Image.Height, GifFileIn->Image.Interlace, GifFileIn->Image.ColorMap) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Now read image itself in decoded form as we dont * really */ /* care what we have there, and this is much faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } break; case EXTENSION_RECORD_TYPE: /* pass through extension records */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR || Extension == NULL) { QuitGifError(GifFileIn, GifFileOut); } if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (EGifPutExtensionBlock(GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } while (Extension != NULL) { if (DGifGetExtensionNext( GifFileIn, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (Extension != NULL) { if (EGifPutExtensionBlock( GifFileOut, Extension[0], Extension + 1) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } } if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; } /* end */ giflib-6.1.3/gif_lib_private.h0000664000175000017500000000511715166751647014447 0ustar esresr/**************************************************************************** gif_lib_private.h - internal giflib routines and structures SPDX-License-Identifier: MIT ****************************************************************************/ #ifndef _GIF_LIB_PRIVATE_H #define _GIF_LIB_PRIVATE_H #include "gif_hash.h" #include "gif_lib.h" #ifndef SIZE_MAX #define SIZE_MAX UINTPTR_MAX #endif #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 #define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */ #define FIRST_CODE 4097 /* Impossible code, to signal first. */ #define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */ #define FILE_STATE_WRITE 0x01 #define FILE_STATE_SCREEN 0x02 #define FILE_STATE_IMAGE 0x04 #define FILE_STATE_READ 0x08 #define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ) #define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE) typedef struct GifFilePrivateType { GifWord FileState, FileHandle, /* Where all this data goes to! */ BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */ ClearCode, /* The CLEAR LZ code. */ EOFCode, /* The EOF LZ code. */ RunningCode, /* The next code algorithm can generate. */ RunningBits, /* The number of bits required to represent RunningCode. */ MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */ LastCode, /* The code before the current code. */ CrntCode, /* Current algorithm code. */ StackPtr, /* For character stack (see below). */ CrntShiftState; /* Number of bits in CrntShiftDWord. */ unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */ unsigned long PixelCount; /* Number of pixels in image. */ FILE *File; /* File as stream. */ InputFunc Read; /* function to read gif input (TVT) */ OutputFunc Write; /* function to write gif output (MRB) */ GifByteType Buf[256]; /* Compressed input is buffered here. */ GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */ GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */ GifPrefixType Prefix[LZ_MAX_CODE + 1]; GifHashTableType *HashTable; bool gif89; } GifFilePrivateType; #ifndef HAVE_REALLOCARRAY extern void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size); #define reallocarray openbsd_reallocarray #endif #endif /* _GIF_LIB_PRIVATE_H */ /* end */ giflib-6.1.3/gifsponge.c0000664000175000017500000000540615166751647013277 0ustar esresr/**************************************************************************** gifsponge.c - skeleton file for generic GIF `sponge' program Slurp a GIF into core, operate on it, spew it out again. Most of the junk above `int main' isn't needed for the skeleton, but is likely to be for what you'll do with it. If you compile this, it will turn into an expensive GIF copying routine; stdin to stdout with no changes and minimal validation. Well, it's a decent test of DGifSlurp() and EGifSpew(), anyway. Note: due to the vicissitudes of Lempel-Ziv compression, the output of this copier may not be bitwise identical to its input. This can happen if you copy an image from a much more (or much *less*) memory-limited system; your compression may use more (or fewer) bits. The uncompressed rasters should, however, be identical (you can check this with gifbuild -d). ****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifsponge" int main(int argc, char **argv) { int i, ErrorCode; GifFileType *GifFileIn, *GifFileOut = (GifFileType *)NULL; if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (DGifSlurp(GifFileIn) == GIF_ERROR) { PrintGifError(GifFileIn->Error); exit(EXIT_FAILURE); } if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* * Your operations on in-core structures go here. * This code just copies the header and each image from the incoming * file. */ GifFileOut->SWidth = GifFileIn->SWidth; GifFileOut->SHeight = GifFileIn->SHeight; GifFileOut->SColorResolution = GifFileIn->SColorResolution; GifFileOut->SBackGroundColor = GifFileIn->SBackGroundColor; if (GifFileIn->SColorMap) { GifFileOut->SColorMap = GifMakeMapObject(GifFileIn->SColorMap->ColorCount, GifFileIn->SColorMap->Colors); } else { GifFileOut->SColorMap = NULL; } for (i = 0; i < GifFileIn->ImageCount; i++) { (void)GifMakeSavedImage(GifFileOut, &GifFileIn->SavedImages[i]); } /* * Note: don't do DGifCloseFile early, as this will * deallocate all the memory containing the GIF data! * * Further note: EGifSpew() doesn't try to validity-check any of this * data; it's *your* responsibility to keep your changes consistent. * Caveat hacker! */ if (EGifSpew(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); } if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); } return 0; } /* end */ giflib-6.1.3/egif_lib.c0000664000175000017500000011214615166751647013056 0ustar esresr/****************************************************************************** egif_lib.c - GIF encoding 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! *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond #include #include #include #include #include #ifdef _WIN32 #include #else #include #include #endif /* _WIN32 */ #include #include "gif_lib.h" #include "gif_lib_private.h" /* Masks given codes to BitsPerPixel, to make sure all codes are in range: */ /*@+charint@*/ static const GifPixelType CodeMask[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; /*@-charint@*/ static int EGifPutWord(int Word, GifFileType *GifFile); static int EGifSetupCompress(GifFileType *GifFile); static int EGifCompressLine(GifFileType *GifFile, const GifPixelType *Line, const int LineLen); 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) #ifndef S_IREAD #define S_IREAD S_IRUSR #endif #ifndef S_IWRITE #define S_IWRITE S_IWUSR #endif /****************************************************************************** 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, const bool TestExistence, int *Error) { int FileHandle; GifFileType *GifFile; 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, S_IREAD | S_IWRITE); } if (FileHandle == -1) { if (Error != NULL) { *Error = E_GIF_ERR_OPEN_FAILED; } return NULL; } GifFile = EGifOpenFileHandle(FileHandle, Error); if (GifFile == (GifFileType *)NULL) { (void)close(FileHandle); } return GifFile; } /****************************************************************************** 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(const int FileHandle, int *Error) { GifFileType *GifFile; GifFilePrivateType *Private; FILE *f; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { free(GifFile); if (Error != NULL) { *Error = E_GIF_ERR_NOT_ENOUGH_MEM; } return NULL; } /*@i1@*/ memset(Private, '\0', sizeof(GifFilePrivateType)); if ((Private->HashTable = _InitHashTable()) == NULL) { free(GifFile); free(Private); if (Error != NULL) { *Error = E_GIF_ERR_NOT_ENOUGH_MEM; } return NULL; } #ifdef _WIN32 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ #endif /* _WIN32 */ f = fdopen(FileHandle, "wb"); /* Make it into a stream: */ GifFile->Private = (void *)Private; Private->FileHandle = FileHandle; Private->File = f; Private->FileState = FILE_STATE_WRITE; Private->gif89 = false; Private->Write = (OutputFunc)0; /* No user write routine (MRB) */ GifFile->UserData = (void *)NULL; /* No user write handle (MRB) */ GifFile->Error = 0; return GifFile; } /****************************************************************************** Output constructor that takes user supplied output function. Basically just a copy of EGifOpenFileHandle. (MRB) ******************************************************************************/ GifFileType *EGifOpen(void *userData, OutputFunc writeFunc, int *Error) { GifFileType *GifFile; GifFilePrivateType *Private; GifFile = (GifFileType *)malloc(sizeof(GifFileType)); if (GifFile == NULL) { if (Error != NULL) { *Error = E_GIF_ERR_NOT_ENOUGH_MEM; } return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType)); if (Private == NULL) { free(GifFile); if (Error != NULL) { *Error = E_GIF_ERR_NOT_ENOUGH_MEM; } return NULL; } memset(Private, '\0', sizeof(GifFilePrivateType)); Private->HashTable = _InitHashTable(); if (Private->HashTable == NULL) { free(GifFile); free(Private); if (Error != NULL) { *Error = E_GIF_ERR_NOT_ENOUGH_MEM; } return NULL; } GifFile->Private = (void *)Private; Private->FileHandle = 0; Private->File = (FILE *)0; Private->FileState = FILE_STATE_WRITE; Private->Write = writeFunc; /* User write routine (MRB) */ GifFile->UserData = userData; /* User write handle (MRB) */ Private->gif89 = false; /* initially, write GIF87 */ GifFile->Error = 0; return GifFile; } /****************************************************************************** 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; } } /****************************************************************************** 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; 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; ColorMapObject *old_map = GifFile->SColorMap; if (Private->FileState & FILE_STATE_SCREEN) { /* If already has screen descriptor - something is wrong! */ GifFile->Error = E_GIF_ERR_HAS_SCRN_DSCR; return GIF_ERROR; } if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } 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; } GifFile->SWidth = Width; GifFile->SHeight = Height; GifFile->SColorResolution = ColorRes; GifFile->SBackGroundColor = BackGround; if (ColorMap == NULL) { if (old_map != NULL) { GifFreeMapObject(old_map); } GifFile->SColorMap = NULL; } else if (ColorMap == old_map) { /* Reuse existing map to avoid a redundant copy. */ GifFile->SColorMap = old_map; } else { if (old_map != NULL) { GifFreeMapObject(old_map); } GifFile->SColorMap = GifMakeMapObject(ColorMap->ColorCount, ColorMap->Colors); if (GifFile->SColorMap == NULL) { GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } /* * Put the logical screen descriptor into the file: */ /* Logical Screen Descriptor: Dimensions */ (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 * possible size (7+1 == 8 bits) because the decoder can use it to * decide how to display the files. */ Buf[0] = (ColorMap ? 0x80 : 0x00) | /* Yes/no global colormap */ ((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] = GifFile->AspectByte; /* Pixel Aspect Ratio */ InternalWrite(GifFile, Buf, 3); /* If we have Global color map - dump it also: */ 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 (InternalWrite(GifFile, Buf, 3) != 3) { GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } } /* Mark this file as has screen descriptor, and no pixel written yet: */ Private->FileState |= FILE_STATE_SCREEN; return GIF_OK; } /****************************************************************************** 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, 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 && Private->PixelCount > 0xffff0000UL) { /* If already has active image descriptor - something is wrong! */ GifFile->Error = E_GIF_ERR_HAS_IMAG_DSCR; return GIF_ERROR; } if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } GifFile->Image.Left = Left; GifFile->Image.Top = Top; GifFile->Image.Width = Width; GifFile->Image.Height = Height; GifFile->Image.Interlace = Interlace; if (ColorMap != GifFile->Image.ColorMap) { if (ColorMap) { 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) { GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; return GIF_ERROR; } } else { if (GifFile->Image.ColorMap != NULL) { GifFreeMapObject(GifFile->Image.ColorMap); } GifFile->Image.ColorMap = NULL; } } /* Put the image descriptor into the file: */ 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); InternalWrite(GifFile, Buf, 1); /* If we have Global color map - dump it also: */ 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 (InternalWrite(GifFile, Buf, 3) != 3) { GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } } if (GifFile->SColorMap == NULL && GifFile->Image.ColorMap == NULL) { GifFile->Error = E_GIF_ERR_NO_COLOR_MAP; return GIF_ERROR; } /* Mark this file as has screen descriptor: */ Private->FileState |= FILE_STATE_IMAGE; Private->PixelCount = (long)Width * (long)Height; /* Reset compress algorithm parameters. */ (void)EGifSetupCompress(GifFile); return GIF_OK; } /****************************************************************************** Put one full scanned line (Line) of length LineLen into GIF file. ******************************************************************************/ int 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: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (!LineLen) { LineLen = GifFile->Image.Width; } if (Private->PixelCount < (unsigned)LineLen) { GifFile->Error = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } Private->PixelCount -= LineLen; /* Make sure the codes are not out of bit range, as we might generate * wrong code (because of overflow when we combine them) in this case: */ Mask = CodeMask[Private->BitsPerPixel]; for (i = 0; i < LineLen; i++) { Line[i] &= Mask; } return EGifCompressLine(GifFile, Line, LineLen); } /****************************************************************************** Put one pixel (Pixel) into GIF file. ******************************************************************************/ int EGifPutPixel(GifFileType *GifFile, GifPixelType Pixel) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (Private->PixelCount == 0) { GifFile->Error = E_GIF_ERR_DATA_TOO_BIG; return GIF_ERROR; } --Private->PixelCount; /* Make sure the code is not out of bit range, as we might generate * wrong code (because of overflow when we combine them) in this case: */ Pixel &= CodeMask[Private->BitsPerPixel]; return EGifCompressLine(GifFile, &Pixel, 1); } /****************************************************************************** Put a comment into GIF file using the GIF89 comment extension block. ******************************************************************************/ int EGifPutComment(GifFileType *GifFile, const char *Comment) { unsigned int length; char *buf; length = strlen(Comment); if (length <= 255) { return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE, length, Comment); } else { buf = (char *)Comment; if (EGifPutExtensionLeader(GifFile, COMMENT_EXT_FUNC_CODE) == GIF_ERROR) { return GIF_ERROR; } /* Break the comment into 255 byte sub blocks */ while (length > 255) { if (EGifPutExtensionBlock(GifFile, 255, buf) == GIF_ERROR) { return GIF_ERROR; } buf = buf + 255; length -= 255; } /* Output any partial block and the clear code. */ if (length > 0) { if (EGifPutExtensionBlock(GifFile, length, buf) == GIF_ERROR) { return GIF_ERROR; } } if (EGifPutExtensionTrailer(GifFile) == GIF_ERROR) { return GIF_ERROR; } } return GIF_OK; } /****************************************************************************** Begin an extension block (see GIF manual). More extensions can be dumped using EGifPutExtensionBlock until EGifPutExtensionTrailer is invoked. ******************************************************************************/ int 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: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } Buf[0] = EXTENSION_INTRODUCER; Buf[1] = ExtCode; InternalWrite(GifFile, Buf, 2); return GIF_OK; } /****************************************************************************** Put extension block data (see GIF manual) into a GIF file. ******************************************************************************/ int 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: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } Buf = ExtLen; InternalWrite(GifFile, &Buf, 1); InternalWrite(GifFile, Extension, ExtLen); return GIF_OK; } /****************************************************************************** Put a terminating block (see GIF manual) into a GIF file. ******************************************************************************/ int EGifPutExtensionTrailer(GifFileType *GifFile) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } /* Write the block terminator */ Buf = 0; InternalWrite(GifFile, &Buf, 1); return GIF_OK; } /****************************************************************************** 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, 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: */ GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; return GIF_ERROR; } if (ExtCode == 0) { InternalWrite(GifFile, (GifByteType *)&ExtLen, 1); } else { Buf[0] = EXTENSION_INTRODUCER; Buf[1] = ExtCode; /* Extension Label */ Buf[2] = ExtLen; /* Extension length */ InternalWrite(GifFile, Buf, 3); } InternalWrite(GifFile, Extension, ExtLen); Buf[0] = 0; InternalWrite(GifFile, Buf, 1); return GIF_OK; } /****************************************************************************** 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: */ 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 (InternalWrite(GifFile, &Buf, 1) != 1) { * GifFile->Error = E_GIF_ERR_WRITE_FAILED; * return GIF_ERROR; * } */ return EGifPutCodeNext(GifFile, CodeBlock); } /****************************************************************************** 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) { GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; if (CodeBlock != NULL) { if (InternalWrite(GifFile, CodeBlock, CodeBlock[0] + 1) != (unsigned)(CodeBlock[0] + 1)) { GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } } else { Buf = 0; 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. */ } return GIF_OK; } /****************************************************************************** This routine should be called last, to close the GIF file. ******************************************************************************/ int EGifCloseFile(GifFileType *GifFile, int *ErrorCode) { GifByteType Buf; GifFilePrivateType *Private; FILE *File; if (GifFile == NULL) { return GIF_ERROR; } Private = (GifFilePrivateType *)GifFile->Private; if (Private == NULL) { return GIF_ERROR; } else if (!IS_WRITEABLE(Private)) { /* This file was NOT open for writing: */ if (ErrorCode != NULL) { *ErrorCode = E_GIF_ERR_NOT_WRITEABLE; } free(GifFile); return GIF_ERROR; } else { File = Private->File; Buf = TERMINATOR_INTRODUCER; InternalWrite(GifFile, &Buf, 1); if (GifFile->Image.ColorMap) { GifFreeMapObject(GifFile->Image.ColorMap); GifFile->Image.ColorMap = NULL; } if (GifFile->SColorMap) { GifFreeMapObject(GifFile->SColorMap); GifFile->SColorMap = NULL; } if (Private->HashTable) { free((char *)Private->HashTable); } free((char *)Private); if (File && fclose(File) != 0) { 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 (a word) into the given file in little-endian order: ******************************************************************************/ static int EGifPutWord(int Word, GifFileType *GifFile) { unsigned char c[2]; c[0] = LOBYTE(Word); c[1] = HIBYTE(Word); if (InternalWrite(GifFile, c, 2) == 2) { return GIF_OK; } else { return GIF_ERROR; } } /****************************************************************************** Setup the LZ compression for this image: ******************************************************************************/ static int EGifSetupCompress(GifFileType *GifFile) { int BitsPerPixel; GifByteType Buf; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; /* Test and see what color map to use, and from it # bits per pixel: */ if (GifFile->Image.ColorMap) { BitsPerPixel = GifFile->Image.ColorMap->BitsPerPixel; } else if (GifFile->SColorMap) { BitsPerPixel = GifFile->SColorMap->BitsPerPixel; } else { GifFile->Error = E_GIF_ERR_NO_COLOR_MAP; return GIF_ERROR; } Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel); InternalWrite(GifFile, &Buf, 1); /* Write the Code size to file. */ Private->Buf[0] = 0; /* Nothing was output yet. */ Private->BitsPerPixel = BitsPerPixel; Private->ClearCode = (1 << BitsPerPixel); Private->EOFCode = Private->ClearCode + 1; Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ Private->CrntCode = FIRST_CODE; /* Signal that this is first one! */ Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ Private->CrntShiftDWord = 0; /* Clear hash table and send Clear to make sure the decoder do the same. */ _ClearHashTable(Private->HashTable); if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { 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. ******************************************************************************/ static int EGifCompressLine(GifFileType *GifFile, const GifPixelType *Line, const int LineLen) { int i = 0, CrntCode; GifHashTableType *HashTable; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; HashTable = Private->HashTable; if (Private->CrntCode == FIRST_CODE) { /* Its first time! */ CrntCode = Line[i++]; } else { CrntCode = Private->CrntCode; /* Get last code in compression. */ } while (i < LineLen) { /* Decode LineLen items. */ GifPixelType Pixel = Line[i++]; /* Get next pixel from stream. */ /* Form a new unique key to search hash table for the code * combines CrntCode as Prefix string with Pixel as postfix * char. */ int NewCode; unsigned long 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: */ CrntCode = NewCode; } else { /* Put it in hash table, output the prefix code, and * make our CrntCode equal to Pixel. */ if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } CrntCode = Pixel; /* If however the HashTable if full, we send a clear * first and Clear the hash table. */ if (Private->RunningCode >= LZ_MAX_CODE) { /* Time to do some clearance: */ if (EGifCompressOutput(GifFile, Private->ClearCode) == GIF_ERROR) { GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } Private->RunningCode = Private->EOFCode + 1; Private->RunningBits = Private->BitsPerPixel + 1; Private->MaxCode1 = 1 << Private->RunningBits; _ClearHashTable(HashTable); } else { /* Put this unique key with its relative Code in * hash table: */ _InsertHashTable(HashTable, NewKey, Private->RunningCode++); } } } /* Preserve the current state of the compression algorithm: */ Private->CrntCode = CrntCode; if (Private->PixelCount == 0) { /* We are done - output last Code and flush output buffers: */ if (EGifCompressOutput(GifFile, CrntCode) == GIF_ERROR) { GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } if (EGifCompressOutput(GifFile, Private->EOFCode) == GIF_ERROR) { GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } if (EGifCompressOutput(GifFile, FLUSH_OUTPUT) == GIF_ERROR) { GifFile->Error = E_GIF_ERR_DISK_IS_FULL; return GIF_ERROR; } } return GIF_OK; } /****************************************************************************** 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, const int Code) { GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; int retval = GIF_OK; if (Code == FLUSH_OUTPUT) { while (Private->CrntShiftState > 0) { /* Get Rid of what is left in DWord, and flush it. */ if (EGifBufferedOutput(GifFile, Private->Buf, Private->CrntShiftDWord & 0xff) == GIF_ERROR) { retval = GIF_ERROR; } Private->CrntShiftDWord >>= 8; Private->CrntShiftState -= 8; } Private->CrntShiftState = 0; /* For next time. */ if (EGifBufferedOutput(GifFile, Private->Buf, FLUSH_OUTPUT) == GIF_ERROR) { retval = GIF_ERROR; } } else { Private->CrntShiftDWord |= ((long)Code) << Private->CrntShiftState; Private->CrntShiftState += Private->RunningBits; while (Private->CrntShiftState >= 8) { /* Dump out full bytes: */ if (EGifBufferedOutput(GifFile, Private->Buf, Private->CrntShiftDWord & 0xff) == GIF_ERROR) { retval = GIF_ERROR; } Private->CrntShiftDWord >>= 8; Private->CrntShiftState -= 8; } } /* If code cannt fit into RunningBits bits, must raise its size. Note */ /* however that codes above 4095 are used for special signaling. */ if (Private->RunningCode >= Private->MaxCode1 && Code <= 4095) { Private->MaxCode1 = 1 << ++Private->RunningBits; } return retval; } /****************************************************************************** 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) { if (c == FLUSH_OUTPUT) { /* Flush everything out. */ if (Buf[0] != 0 && 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 (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 (InternalWrite(GifFile, Buf, Buf[0] + 1) != (unsigned)(Buf[0] + 1)) { GifFile->Error = E_GIF_ERR_WRITE_FAILED; return GIF_ERROR; } Buf[0] = 0; } Buf[++Buf[0]] = c; } return GIF_OK; } /****************************************************************************** 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) { int j; for (j = 0; j < ExtensionBlockCount; j++) { ExtensionBlock *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, int *ErrorCode) { int i, j; int status = GIF_OK; int err = E_GIF_SUCCEEDED; if (EGifPutScreenDesc(GifFileOut, GifFileOut->SWidth, GifFileOut->SHeight, GifFileOut->SColorResolution, GifFileOut->SBackGroundColor, GifFileOut->SColorMap) == GIF_ERROR) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } for (i = 0; i < GifFileOut->ImageCount; i++) { SavedImage *sp = &GifFileOut->SavedImages[i]; int SavedHeight = sp->ImageDesc.Height; int SavedWidth = sp->ImageDesc.Width; /* this allows us to delete images by nuking their rasters */ if (sp->RasterBits == NULL) { continue; } if (EGifWriteExtensions(GifFileOut, sp->ExtensionBlocks, sp->ExtensionBlockCount) == GIF_ERROR) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } if (EGifPutImageDesc(GifFileOut, sp->ImageDesc.Left, sp->ImageDesc.Top, SavedWidth, SavedHeight, sp->ImageDesc.Interlace, sp->ImageDesc.ColorMap) == GIF_ERROR) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } if (sp->ImageDesc.Interlace) { /* * The way an interlaced image should be written - * offsets and jumps... */ static const int InterlacedOffset[] = {0, 4, 2, 1}; static const 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) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } } } } else { for (j = 0; j < SavedHeight; j++) { if (EGifPutLine(GifFileOut, sp->RasterBits + j * SavedWidth, SavedWidth) == GIF_ERROR) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } } } } if (EGifWriteExtensions(GifFileOut, GifFileOut->ExtensionBlocks, GifFileOut->ExtensionBlockCount) == GIF_ERROR) { status = GIF_ERROR; err = GifFileOut->Error; goto cleanup; } cleanup: GifFreeSavedImages(GifFileOut); GifFreeExtensions(&GifFileOut->ExtensionBlockCount, &GifFileOut->ExtensionBlocks); { int close_error = E_GIF_SUCCEEDED; if (EGifCloseFile(GifFileOut, &close_error) == GIF_ERROR) { status = GIF_ERROR; if (err == E_GIF_SUCCEEDED) { err = close_error; } } } if (ErrorCode != NULL) { *ErrorCode = (status == GIF_OK) ? E_GIF_SUCCEEDED : err; } return status; } /* end */ giflib-6.1.3/doc/0000775000175000017500000000000015166751647011712 5ustar esresrgiflib-6.1.3/doc/gifclrmp.html0000664000175000017500000000564315166751647014413 0ustar esresr gifclrmp

Name

gifclrmp — extract colormaps from GIF images

Synopsis

gifclrmp [-v] [-s] [-l mapfile] [-t trans] [-g gamma] [-i image] [-h] [gif-file]

Description

A program to modify GIF image colormaps. Any local colormap in a GIF file can be modified at a time, or the global screen one.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-s

Select the global screen color map.

-l mapfile

Load color map from this file instead of selected color map.

-t trans

Change color index values. The change is made to both the selected color table and the raster bits of the selected image. A translation file is a list of pairs of `before' and `after' index values. At present, the `before' index values must be in ascending order starting from 0.

-g gamma

Apply gamma correction to selected color map.

-i image

Select the color map of the numbered image.

-h

Print one command line help, similar to Usage above.

If no GIF file is given, gifclip will try to read a GIF file from stdin.

Notes

  • The default operation is to dump out the selected color map in text format.

  • The file to load/dump is simply one color map entry per line. Each such entry line has four integers: "ColorIndex Red Green Blue", where color index is in ascending order starting from 1.

Author

Gershon Elber.

giflib-6.1.3/doc/giftool.html0000664000175000017500000001317515166751647014252 0ustar esresr giftool

Name

giftool — GIF transformation tool

Synopsis

giftool [-a aspect] [-b bgcolor] [-d delaytime] [-i interlacing] [-n imagelist] [-p left,top] [-s width,height] [-t transcolor] [-u sort-flag] [-x disposal] [-z sort-flag]

Description

A filter for transforming GIFS. With no options, it's an expensive copy of a GIF in standard input to standard output. Options specify filtering operations and are performed in the order specified on the command line.

The -n option selects images, allowing the tool to act on a subset of images in a multi-image GIF. This option takes a comma-separated list of decimal integers which are interpreted as 1-origin image indices; these are the images that will be acted on. If no -n option is specified, the tool will select and transform all images.

The -b option takes a decimal integer argument and uses it to set the (0-origin) screen background color index.

The -f option accepts a printf-style format string and substitutes into it the values of image-descriptor and graphics-control fields. The string is formatted and output once for each selected image. Normal C-style escapes \b, \f, \n, \r, \t. \v, and \xNN are interpreted; also \e produces ESC (ASCII 0x1b). The following format cookies are substituted:

%a

Pixel aspect byte.

%b

Screen background color.

%d

Image delay time

%h

Image height (y dimension)

%n

Image index

%p

Image position (as an x,y pair)

%s

Screen size (as an x,y pair)

%t

Image transparent-color index

%u

Image user-input flag (boolean)

%v

GIF version string

%w

Image width (x dimension)

%x

Image GIF89 disposal mode

%z

Image's color table sort flag (boolean, false if no local color map)

Boolean substitutions may take a prefix to modify how they are displayed:

1

"1" or "0"

o

"on" or "off"

t

"t" or "f"

y

"yes" or "no"

Thus, for example, "%oz" displays image sort flags using the strings "on" and "off". The default with no prefix is numeric.

The -a option takes an unsigned decimal integer argument and uses it to set the aspect-ratio bye in the logical screen descriptor block.

The -b option takes an unsigned decimal integer argument and uses it to set the background color index in the logical screen descriptor block.

The -d option takes a decimal integer argument and uses it to set a delay time, in hundredths of a second, on selected images.

The -i option sets or clears interlacing in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f"

The -p option takes a (0-origin) x,y coordinate-pair and sets it as the preferred upper-left-corner coordinates of selected images.

The -s option takes a (0-origin) x,y coordinate-pair and sets it as the expected display screen size.

The -t option takes a decimal integer argument and uses it to set the (0-origin) index of the transparency color in selected images.

The -u option sets or clears the user-input flag in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f".

The -x option takes a decimal integer argument and uses it to set the GIF89 disposal mode in selected images.

The -z option sets or clears the color-table sort flag in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f".

Note that the -a, -b, -p, -s, and -z options are included to complete the ability to modify all fields defined in the GIF standard, but should have no effect on how an image renders on browsers or modern viewers.

Author

Eric S. Raymond.

giflib-6.1.3/doc/gifhisto.xml0000664000175000017500000000611115166751647014247 0ustar esresr 2 May 2012 gifhisto 1 GIFLIB GIFLIB Documentation gifhisto make a color histogram from GIF color frequencies gifhisto -v -t -s width height -n image-number -b -h gif-file Description A program to create histogram of number of pixels using each color. The output can be formatted into a GIF histogram file, or as text file - both go to stdout. If no GIF file is given, gifhisto will try to read a GIF file from stdin. Options -v Verbose mode (show progress). Enables printout of running scan lines. -t Force output to be text file of the following form: (colormap size) lines each containing two integers: number of times color appeared, and color index. Lines are in increasing color index order. This output can be fed directly to a sort program if ordering by color frequency is desired. The colormap picked is the one to be used for the image to generate histogram for, as defined in GIF format. -s width height Size of GIF histogram file. The height of the histogram should be power of 2 divisible by number of colors in colormap. Width sets the resolution (accuracy if you like) of the histogram as the maximum histogram bar is scaled to fit it. -n image-number Image number to test. Default is one. -b Zeros the background color count. As only linear scale bars are supported and usually the background appears much more often then other colors, deleting the background count will improve the scaling of other colors. -h Print one line of command line help, similar to Usage above. Author Gershon Elber giflib-6.1.3/doc/intro.xml0000664000175000017500000001546215166751647013577 0ustar esresr ]>
Introduction to GIFLIB Eric Steven Raymond Thyrsus Enterprises
&email;
2012 Eric S. Raymond
GIFLIB is a package of portable tools and library routines for working with GIF images. The Graphics Interchange Format(c) specification is the copyrighted property of CompuServe Incorporated. GIF(sm) is a service mark property of CompuServe Incorporated. This package has been released under an X Consortium-like open-source license. Use and copy as you see fit. If you make useful changes, add new tools, or find and fix bugs, please send your mods to the maintainers for general distribution. The util directory includes programs to clip, rotate, scale, and position GIF images. These are no replacement for an interactive graphics editor, but they can be very useful for scripted image generation or transformation. The library includes program-callable entry points for reading and writing GIF files, an 8x8 utility font for embedding text in GIFs, and an error handler. GIF manipulation can be done at a relatively low level by sequential I/O (which automatically does/undoes image compression) or at a higher level by slurping an entire GIF into allocated core. This library speaks both GIF87a and GIF89. The differences between GIF87 and GIF89 are minor: in the latter, the interpretation of some extension block types is defined. The library never needs to actually interpret these, but giftext notices them and there are functions in the API to read and modify them. Utilities Here is a summary of the utilities in this package. If you're looking at this page through a web browser, each utility name should be a hotlink to HTML documentation. Most utilities have a -v (verbose) option that will cause them to print the current input scan line number (counting up) whenever they read image input, and will print output image line number (counting down) when they dump output. Utilities that only read or write always print in increasing order. Image Manipulation Components gifclrmp modify GIF image colormaps giffix clumsily attempts to fix truncated GIF images Report Generators giftext print (text only) general information about a GIF GIF Composition Tools gifbuild converter/deconverter to/from an editable text format giftool GIF transformation tool Obsolete utilities These are used for testing by the GFLIB developers and no longer installed by a normal build. gif2rgb convert images saved as GIF to 24-bit RGB image(s) or vice-versa gifbg generate a single-color test pattern GIF gifcolor generate color test patterns gifwedge create a test GIF image resembling a color monitor test pattern gifhisto generate color-frequency histogram from a GIF gifecho generate GIF images out of regular text in 8x8 font gifinto end-of-pipe fitting for GIF-processing pipelines Library Functions The library contains two groups of C functions. One group does sequential I/O on the stream-oriented GIF format. The other supports grabbing an entire GIF into allocated core, operating on it in core, and then writing the modified in-core GIF out to disk. Unless you are on extremely memory-limited machine, you probably want to use the second group. Detailed documentation on the library entry points is in gif_lib.html. The GIF Standard The doc subdirectory includes an HTML presentation of the GIF standard; an explanation of Lempel-Ziv compression, and the original flat-ASCII description of GIF89 format . For historical completeness, we also include a copy of the GIF87 standard. You can also read a detailed narrative description of how GIFs are laid out. It clarifies some points on which the standard is obscure. Package Status GIFLIB's current maintainer is Eric S. Raymond. You can find his home page at &homepage;. GIFLIB is not under active development, but bug fixes are being accepted.
giflib-6.1.3/doc/gif2rgb.10000664000175000017500000000541115166751647013317 0ustar esresr'\" t .\" Title: gif2rgb .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIF2RGB" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gif2rgb \- convert images saved as GIF to 24\-bit RGB triplets .SH "SYNOPSIS" .HP \w'\fBgif2rgb\fR\ 'u \fBgif2rgb\fR [\-v] [\-1] [\-c\ \fIcolors\fR] [\-s\ \fIwidth\fR\ \fIheight\fR] [\-o\ \fIoutfile\fR] [\-h] [\fIgif\-file\fR] .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-1 .RS 4 Only one file in the format of RGBRGB\&.\&.\&. triplets (Each of R, G,B is a byte) is being read or written\&. This file size is 3 * Width * Height\&. If stdin is used for input or stdout for output, this option is implicitly applied\&. The default (if not `\-1\*(Aq) is 3 files with the names OutFileName\&.R, OutFileName\&.G, OutFileName\&.B, each of which is Width * Height bytes\&. .RE .PP \-c colors .RS 4 Specifies number of colors to use in RGB\-to\-GIF conversions, in bits per pixels, so \*(Aq\-c 8\*(Aq actually specifies 256 colors (maximum and default)\&. .RE .PP \-s width height .RS 4 Sets RGB\-to\-GIF conversion mode and specifies the size of the image to read\&. .RE .PP \-o .RS 4 specifies the name of the out file (see also `\-1\*(Aq above)\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .PP By default, convert a GIF input file to RGB triplets\&. If \-s is specified, convert RGB input to a GIF\&. .PP If no input file is given, gif2rgb will try to read data from stdin\&. .SH "BUGS" .PP Feeding this utility a GIF with an invalid colormap, or other kinds of malformations, index will produce invalid output and may core\-dump the tool\&. Don\*(Aqt do that\&. .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/00README0000664000175000017500000000047115166751647012734 0ustar esresrThis directory contains documentation on the API and tools. The most convenient way to view it is with a browser pointed at the project website, but... An introduction to the package is in intro.xml API documentation lives in gif_lib.xml GIF standards documents can be found in the directory gifstandard/ giflib-6.1.3/doc/gifcolor.xml0000664000175000017500000000424315166751647014243 0ustar esresr 2 May 2012 gifcolor 1 GIFLIB GIFLIB Documentation gifcolor generate color test-pattern GIFs gifcolor -v -b background -h colormap-file Description A program to generate color test patterns. Feed it a color map file (as generated, say, by the -s option of gifclrmp) and it will generate a GIF containing lines of the form. Color %-3d: [%-3d, %-3d, %-3d]: where the first number is the zero-based color index, and the triple is the index's [Red, Green, Blue] value. There will be one such line for each color. Each line will be set in a simple 8x8 font in the color it describes; thus, any lines corresponding to the GIF's background color will be blank. Options -v Verbose mode (show progress). Enables printout of running scan lines. -b Set the image's backround color to a given numeric index. -h Print one line of command line help, similar to Usage above. If no colormap file is specified, the color map will be read from stdin. Author Gershon Elber. giflib-6.1.3/doc/gifwedge.html0000664000175000017500000000377115166751647014371 0ustar esresr gifwedge

Name

gifwedge — create a GIF test pattern

Synopsis

gifwedge [-v] [-l levels] [-s sizex sizey] [-h] [gif-file]

Description

A program to create a test GIF image with intensity levels of the RGB colors YCM colors and white.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-l levels

Set number of intensity levels per color. This number must be power of two up to 32, as Gif format can only have 256 color simultaneously and 7 basic colors are to be displayed.

-s sizex sizey

Force image size to be SizeX by SizeY pixels. Image size will be rounded down to be a multiple of number of intensities horizontally, and 7 (colors) vertically.

-h

Print one line command line help, similar to Usage above.

Author

Gershon Elber.

giflib-6.1.3/doc/giffilter.html0000664000175000017500000000244115166751647014554 0ustar esresr giffilter

Name

giffilter — expensive GIF copy, a model for filter utilities

Synopsis

giffilter

Description

This is an expensive way to copy a GIF. The source is included as a skeleton for more sophisticated filters. See the source in the util directory for details.

Also has some utility as a test of the sequential GIF record I/O routines. The output should be bytewise identical to the input.

Author

Eric S. Raymond

giflib-6.1.3/doc/gif2rgb.html0000664000175000017500000000533515166751647014130 0ustar esresr gif2rgb

Name

gif2rgb — convert images saved as GIF to 24-bit RGB triplets

Synopsis

gif2rgb [-v] [-1] [-c colors] [-s width height] [-o outfile] [-h] [gif-file]

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-1

Only one file in the format of RGBRGB... triplets (Each of R, G,B is a byte) is being read or written. This file size is 3 * Width * Height. If stdin is used for input or stdout for output, this option is implicitly applied. The default (if not `-1') is 3 files with the names OutFileName.R, OutFileName.G, OutFileName.B, each of which is Width * Height bytes.

-c colors

Specifies number of colors to use in RGB-to-GIF conversions, in bits per pixels, so '-c 8' actually specifies 256 colors (maximum and default).

-s width height

Sets RGB-to-GIF conversion mode and specifies the size of the image to read.

-o

specifies the name of the out file (see also `-1' above).

-h

Print one line of command line help, similar to Usage above.

By default, convert a GIF input file to RGB triplets. If -s is specified, convert RGB input to a GIF.

If no input file is given, gif2rgb will try to read data from stdin.

Bugs

Feeding this utility a GIF with an invalid colormap, or other kinds of malformations, index will produce invalid output and may core-dump the tool. Don't do that.

Author

Gershon Elber.

giflib-6.1.3/doc/gifinto.xml0000664000175000017500000000425515166751647014101 0ustar esresr 2 May 2012 gifinto 1 GIFLIB GIFLIB Documentation gifinto save GIF on stdin to file if size over set threshold gifinto -v -s minsize -h outfile Description A program to save stdin into a file with given name, if and only if the result file has size bigger than specified (see below). This can be used to save a result under the same filename we started with in a chain of pipes. Always reads a GIF file from stdin. Options -v Verbose mode (show progress). Enables printout of running scan lines. -s MinFileSize If file is less than MinFileSize, it is deleted and not renamed to the given name. This will prevent killing the file we started with if the result is an empty file, or the pipeline did not complete. The default file threshold size is 14 bytes, which is 1 bigger than GIF file stamp (6 bytes) plus a GIF file screen descriptor (7 bytes), so a GIF file with only GIF stamp and screen descriptor will not be renamed. -h Print one line of command line help, similar to Usage above. Author Gershon Elber. giflib-6.1.3/doc/giffix.xml0000664000175000017500000000314615166751647013714 0ustar esresr 2 May 2012 giffix 1 GIFLIB GIFLIB Documentation giffix attempt to fix up broken GIFs giffix -v -h gif-file Description A program that attempts to fix broken GIF images. Currently will "fix" images terminated prematurely by filling the rest of the image with the darkest color found in the image. If no GIF file is given, giffix will try to read a GIF file from stdin. The fixed file is dumped to stdout. Options -t Verbose mode (show progress). Enables printout of running scan lines. -h Print one line of command line help, similar to Usage above. Author Gershon Elber. giflib-6.1.3/doc/gifstandard/0000775000175000017500000000000015166751647014200 5ustar esresrgiflib-6.1.3/doc/gifstandard/main.css0000664000175000017500000000100615166751647015633 0ustar esresr/* some pages also use their own CSS files, so: NO CUSTOM CLASS NAMES HERE */ body { background:white; color:black; font-family:sans-serif; } table { background:black; border-spacing:2px; } th, td { padding:3px 5px; vertical-align:middle; empty-cells:show; } th { background:silver; } td { background:white; } h1 { text-align:center; } pre, tt { font-size:120%; } abbr { text-decoration:underline; } @media print { .noprint { display:none; } a[href] { color:black; text-decoration:none; } } giflib-6.1.3/doc/gifstandard/gif-aspectratio.png0000664000175000017500000000305315166751647017770 0ustar esresrPNG  IHDR,,-$0PLTE'''777HHHTTThhhxxxQЃIDATx^klSC&^MD[4UF 6d-mœ4v c*m%vf%vm7:clZi0LҔ9ؾ~\ߕ*Ekdiˑ~|8TP]G֧,a fӂlҳR3_nf8L ޓ6>p, zCYDr:<R ǃYyųX%Pn zV:dHMbAf,"!A3: =`_1O/9q @Ik0,uȃ=: `fIڅc%.ٜf/W9pl9?A $ tDK#!w핁[*DG|W Kzc1UF+ϓh.r^5l=%1Z}ų3gG? ih#1jԑq^u'/}$S58r筕]'{YsQIދ|TN?LPt֡hQ/56s[L4;Ģ ϯ0ۃ'林ΡE #lbHJa }>+,nXf\ 0T3`W  ݉v`5Þ.|pu Ca~Qqd|80Wm@2Bm -xJV=#k w2\ջoQO~ &f-YHBe}`j\ymX玾vj8&on+$%Bn7SrVuq"`ՒE<L46q! vzU?0jols0]Oݩ;,J/\WCnE\\kb <~\5Ȇ! j>űl=iWCBwkL3Mq>>MRQw#:eZRLEL3H3GΧ<Ν*  Er kƒtKm\ Ud֦s2آd=Q4ds%lwWZJHLo{T-Ġh/-+5kTW8/DFvLSX֡7)}ٲ֪*67nx4֍>+` Z=(Õ] _; ;l?D*Wuu1v FV~>z~ FVI)JHdZFM %(*^׋M$ʌvo 5Rfn"A bsٱ:w6=YeX>zdbeW/.mw _=kQ$QIENDB`giflib-6.1.3/doc/gifstandard/LZW-and-GIF-explained.html0000664000175000017500000004167015166751647020664 0ustar esresr An Introduction to Data Compression

LZW and GIF explained
by Steve Blackstock

I hope this little document will help enlighten those of you out there who want to know more about the Lempel-Ziv Welch (LZW) compression algorithm, and, specifically, the implementation that GIF uses.

Before we start, here's a little terminology, for the purposes of this document:

  • character: a fundamental data element. In normal text files, this is just a single byte. In raster images, which is what we're interested in, it's an index that specifies the color of a given pixel. I'll refer to an arbitrary character as "K".
  • charstream: a stream of characters, as in a data file.
  • string: a number of continuous characters, anywhere from one to very many characters in length. I can specify an arbitrary string as "[...]K".
  • prefix: almost the same as a string, but with the implication that a prefix immediately precedes a character, and a prefix can have a length of zero. So, a prefix and a character make up a string. I will refer to an arbitrary prefix as "[...]".
  • root: a single-character string. For most purposes, this is a character, but we may occasionally make a distinction. It is [...]K, where [...] is empty.
  • code: a number, specified by a known number of bits, which maps to a string.
  • codestream: the output stream of codes, as in the "raster data"
  • entry: a code and its string.
  • string table: a list of entries; usually, but not necessarily, unique.

LZW is a way of compressing data that takes advantage of repetition of strings in the data. Since raster data usually contains a lot of this repetition, LZW is a good way of compressing and decompressing it. For the moment, lets consider normal LZW encoding and decoding. GIF's variation on the concept is just an extension from there.

LZW manipulates three objects in both compression and decompression: the charstream, the codestream, and the string table. In compression, the charstream is the input and the codestream is the output. In decompression, the codestream is the input and the charstream is the output. The string table is a product of both compression and decompression, but is never passed from one to the other.

Compression

The first thing we do in LZW compression is initialize our string table. To do this, we need to choose a code size (how many bits) and know how many values our characters can possibly take. Let's say our code size is 12 bits, meaning we can store 0->FFF, or 4096 entries in our string table. Lets also say that we have 32 possible different characters. (This corresponds to, say, a picture in which there are 32 different colors possible for each pixel.) To initialize the table, we set code#0 to character#0, code #1 to character#1, and so on, until code#31 to character#31. Actually, we are specifying that each code from 0 to 31 maps to a root. There will be no more entries in the table that have this property.

Now we start compressing data. Let's first define something called the "current prefix". It's just a prefix that we'll store things in and compare things to now and then. I will refer to it as "[.c.]". Initially, the current prefix has nothing in it. Let's also define a "current string", which will be the current prefix plus the next character in the charstream. I will refer to the current string as "[.c.]K", where K is some character. OK, look at the first character in the charstream. Call it P. Make [.c.]P the current string. (At this point, of course, it's just the root P.) Now search through the string table to see if [.c.]P appears in it. Of course, it does now, because our string table is initialized to have all roots. So we don't do anything. Now make [.c.]P the current prefix. Look at the next character in the charstream. Call it Q. Add it to the current prefix to form [.c.]Q, the current string. Now search through the string table to see if [.c.]Q appears in it. In this case, of course, it doesn't. Aha! Now we get to do something. Add [.c.]Q (which is PQ in this case) to the string table for code#32, and output the code for [.c.] to the codestream. Now start over again with the current prefix being just the root Q. Keep adding characters to [.c.] to form [.c.]K, until you can't find [.c.]K in the string table. Then output the code for [.c.] and add [.c.]K to the string table. In pseudo-code, the algorithm goes something like this:

     [1] Initialize string table;
     [2] [.c.] <- empty;
     [3] K <- next character in charstream;
     [4] Is [.c.]K in string table?
         (yes: [.c.] <- [.c.]K;
               go to [3];
         )
         (no: add [.c.]K to the string table;
              output the code for [.c.] to the codestream;
              [.c.] <- K;
              go to [3];
         )

It's as simple as that! Of course, when you get to step [3] and there aren't any more characters left, you just output the code for [.c.] and throw the table away. You're done.

Wanna do an example? Let's pretend we have a four-character alphabet: A,B,C,D. The charstream looks like ABACABA. Let's compress it. First, we initialize our string table to: #0=A, #1=B, #2=C, #3=D. The first character is A, which is in the string table, so [.c.] becomes A. Next we get AB, which is not in the table, so we output code #0 (for [.c.]), and add AB to the string table as code #4. [.c.] becomes B. Next we get [.c.]A = BA, which is not in the string table, so output code #1, and add BA to the string table as code #5. [.c.] becomes A. Next we get AC, which is not in the string table. Output code #0, and add AC to the string table as code #6. Now [.c.] becomes C. Next we get [.c.]A = CA, which is not in the table. Output #2 for C, and add CA to table as code#7. Now [.c.] becomes A. Next we get AB, which IS in the string table, so [.c.] gets AB, and we look at ABA, which is not in the string table, so output the code for AB, which is #4, and add ABA to the string table as code #8. [.c.] becomes A. We can't get any more characters, so we just output #0 for the code for A, and we're done. So, the codestream is #0#1#0#2#4#0.

A few words (four) should be said here about efficiency: use a hashing strategy. The search through the string table can be computationally intensive, and some hashing is well worth the effort. Also, note that "straight LZW" compression runs the risk of overflowing the string table - getting to a code which can't be represented in the number of bits you've set aside for codes. There are several ways of dealing with this problem, and GIF implements a very clever one, but we'll get to that.

An important thing to notice is that, at any point during the compression, if [...]K is in the string table, [...] is there also. This fact suggests an efficient method for storing strings in the table. Rather than store the entire string of K's in the table, realize that any string can be expressed as a prefix plus a character: [...]K. If we're about to store [...]K in the table, we know that [...] is already there, so we can just store the code for [...] plus the final character K.

Decompression

Decompression is perhaps more difficult conceptually, but it is really easier to program. We again have to start with an initialized string table. This table comes from what knowledge we have about the charstream that we will eventually get, like what possible values the characters can take. In GIF files, this information is in the header as the number of possible pixel values. The beauty of LZW, though, is that this is all we need to know. We will build the rest of the string table as we decompress the codestream. The compression is done in such a way that we will never encounter a code in the codestream that we can't translate into a string.

We need to define something called a "current code", which I will refer to as "<code>", and an "old-code", which I will refer to as "<old>". To start things off, look at the first code. This is now <code>. This code will be in the intialized string table as the code for a root. Output the root to the charstream. Make this code the old-code <old>. *Now look at the next code, and make it <code>. It is possible that this code will not be in the string table, but let's assume for now that it is. Output the string corresponding to <code> to the codestream. Now find the first character in the string you just translated. Call this K. Add this to the prefix [...] generated by <old> to form a new string [...]K. Add this string [...]K to the string table, and set the old-code <old> to the current code <code>. Repeat from where I typed the asterisk, and you're all set. This is the most common case so you should understand this before going on.

Now let's consider the possibility that <code> is not in the string table, which as we will see can only occur for strings of the form P[...]P (for any character P). Think back to compression, and try to understand what happens when you have a string like P[...]P[...]PQ appear in the charstream. Suppose P[...] is already in the string table, but P[...]P is not. The compressor will parse out P[...], and find that P[...]P is not in the string table. It will output the code for P[...], and add P[...]P to the string table. Then it will get up to P[...]P for the next string, and find that P[...]P is in the table, as the code just added. So it will output the code for P[...]P if it finds that P[...]PQ is not in the table. The decompressor is always "one step behind" the compressor. When the decompressor sees the code for P[...]P, it will not have added that code to its string table yet because it needed the beginning character of P[...]P to add to the string for the last code, P[...], to form the code for P[...]P. However, when a decompressor finds a code that it doesn't know yet, it will always be the very next one to be added to the string table. So it can guess at what the string for the code should be, and, in fact, it will always be correct. If I am a decompressor, and I see code#124, and yet my string table has entries only up to code#123, I can figure out what code#124 must be, add it to my string table, and output the string. If code#123 generated the string [...], which I will refer to here as a prefix, then code#124, in this special case, will be [...] plus the first character of [...]. So just add the first character of [...] to the end of itself. Not too bad.

As an example (and a very common one) of this special case, let's assume we have a raster image in which the first three pixels have the same color value. That is, my charstream looks like: QQQ.... For the sake of argument, let's say we have 32 colors, and Q is the color#12. The compressor will generate the code sequence 12,32,.... (if you don't know why, take a minute to understand it.) Remember that #32 is not in the initial table, which goes from #0 to #31. The decompressor will see #12 and translate it just fine as color Q. Then it will see #32 and not yet know what that means. But if it thinks about it long enough, it can figure out that QQ should be entry#32 in the table and QQ should be the next string output. So the decompression pseudo-code goes something like:

     [1] Initialize string table;
     [2] get first code: <code>
     [3] output the string for <code> to the charstream;
     [4] <old> = <code>
     [5] <code> <- next code in codestream;
     [6] does <code> exist in the string table?
         (yes: output the string for <code> to the charstream;
            [...] <- translation for <old>
            K <- first character of translation for <code>
            add [...]K to the string table;        
            <old> <- <code>
         )
         (no: [...] <- translation for <old>
            K <- first character of [...];
            output [...]K to charstream and add it to string table;
            <old> <- <code>
         )
     [7] go to [5];

Again, when you get to step [5] and there are no more codes, you're finished. Outputting of strings, and finding of initial characters in strings are efficiency problems all to themselves, but I'm not going to suggest ways to do them here. Half the fun of programming is figuring these things out!

GIF variation

Now for the GIF variations on the theme. In part of the header of a GIF file, there is a field, in the Raster Data stream, called "code size". This is a very misleading name for the field, but we have to live with it. What it is really is the "root size". The actual size, in bits, of the compression codes actually changes during compression/decompression, and I will refer to that size here as the "compression size". The initial table is just the codes for all the roots, as usual, but two special codes are added on top of those. The "code size" N is set to max(2,bits-per-pixel). In the table the roots take up slots #0 through #(2**N-1), and the special codes are (2**N) and (2**N + 1). The initial compression size will be N+1 bits per code. If you're encoding, you output the codes (N+1) bits at a time to start with, and if you're decoding, you grab (N+1) bits from the codestream at a time. As for the special codes: <CC> or the clear code, is (2**N), and <EOI>, or end-of-information, is (2**N + 1). <CC> tells the compressor to re- initialize the string table, and to reset the compression size to (N+1). <EOI> means there's no more in the codestream.

If you're encoding or decoding, you should start adding things to the string table at <CC> + 2. If you're encoding, you should output <CC> as the very first code, and then whenever after that you reach code #4095 (hex FFF), because GIF does not allow compression sizes to be greater than 12 bits. If you're decoding, you should reinitialize your string table when you observe <CC>. The variable compression sizes are really no big deal. If you're encoding, you start with a compression size of (N+1) bits, and, whenever you output the code (2**(compression size)-1), you bump the compression size up one bit. So the next code you output will be one bit longer. Remember that the largest compression size is 12 bits, corresponding to a code of 4095. If you get that far, you must output <CC> as the next code, and start over. If you're decoding, you must increase your compression size AS SOON AS YOU write entry #(2**(compression size) - 1) to the string table. The next code you READ will be one bit longer. Don't make the mistake of waiting until you need to add the code (2**compression size) to the table. You'll have already missed a bit from the last code. The packaging of codes into a bitstream for the raster data is also a potential stumbling block for the novice encoder or decoder. The lowest order bit in the code should coincide with the lowest available bit in the first available byte in the codestream. For example, if you're starting with 5-bit compression codes, and your first three codes are, say, <abcde>, <fghij>, <klmno>, where e, j, and o are bit#0, then your codestream will start off like:

       byte#0: hijabcde
       byte#1: .klmnofg

So the differences between straight LZW and GIF LZW are: two additional special codes and variable compression sizes. If you understand LZW, and you understand those variations, you understand it all!

Just as sort of a P.S., you may have noticed that a compressor has a little bit of flexibility at compression time. I specified a "greedy" approach to the compression, grabbing as many characters as possible before outputting codes. This is, in fact, the standard LZW way of doing things, and it will yield the best compression ratio. But there's no rule saying you can't stop anywhere along the line and just output the code for the current prefix, whether it's already in the table or not, and add that string plus the next character to the string table. There are various reasons for wanting to do this, especially if the strings get extremely long and make hashing difficult. If you need to, do it.

Hope this helps out.----steve blackstock

Further information

The original paper that describes the LZW algorithm is:
Terry A. Welch. A Technique for High Performance Data Compression. IEEE Computer, Vol. 17, No. 6, 1984, pp. 8-19.
The GIF format is described in more detail in the GIF87(5) - GIF 87 and GIF89a(5) - GIF 89a standards. giflib-6.1.3/doc/gifstandard/GIF89a.html0000664000175000017500000027323315166751647016027 0ustar esresr Graphics Interchange Format Version 89a

Graphics Interchange Format Version 89a

The document below is a copy of http://www.w3.org/Graphics/GIF/spec-gif89a.txt, reformatted into HTML to make it easier to read and print.

Notable changes:

  • moved chapter "Cover Sheet for the GIF89a Specification" from the beginning to the end
  • removed page numbers
  • removed redundant rows from Quick Reference Table
You can also read the original flat text.

© 1987, 1988, 1989, 1990

Copyright
CompuServe Incorporated
Columbus, Ohio

Graphics Interchange Format Programming Reference

CompuServe Incorporated

Document Date: 31 July 1990

hide all chapters | show all chapters

Table of Contents (hide/show)

1. Disclaimer (hide/show)

The information provided herein is subject to change without notice. In no event will CompuServe Incorporated be liable for damages, including any loss of revenue, loss of profits or other incidental or consequential damages arising out of the use or inability to use the information; CompuServe Incorporated makes no claim as to the suitability of the information.

2. Foreword (hide/show)

This document defines the Graphics Interchange Formatࡈ. The specification given here defines version 89a, which is an extension of version 87a.

The Graphics Interchange Formatࡈ as specified here should be considered complete; any deviation from it should be considered invalid, including but not limited to, the use of reserved or undefined fields within control or data blocks, the inclusion of extraneous data within or between blocks, the use of methods or algorithms not specifically listed as part of the format, etc. In general, any and all deviations, extensions or modifications not specified in this document should be considered to be in violation of the format and should be avoided.

3. Licensing (hide/show)

The Graphics Interchange Format© is the copyright property of CompuServe Incorporated. Only CompuServe Incorporated is authorized to define, redefine, enhance, alter, modify or change in any way the definition of the format.

CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free license for the use of the Graphics Interchange Formatࡈ in computer software; computer software utilizing GIFࡈ must acknowledge ownership of the Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in User and Technical Documentation. Computer software utilizing GIF, which is distributed or may be distributed without User or Technical Documentation must display to the screen or printer a message acknowledging ownership of the Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in this case, the acknowledgement may be displayed in an opening screen or leading banner, or a closing screen or trailing banner. A message such as the following may be used:

The Graphics Interchange Format© is the Copyright property of CompuServe Incorporated. GIFࡈ is a Service Mark property of CompuServe Incorporated.

For further information, please contact:

CompuServe Incorporated
Graphics Technology Department
5000 Arlington Center Boulevard
Columbus, Ohio 43220
U. S. A.

CompuServe Incorporated maintains a mailing list with all those individuals and organizations who wish to receive copies of this document when it is corrected or revised. This service is offered free of charge; please provide us with your mailing address.

4. About the Document (hide/show)

This document describes in detail the definition of the Graphics Interchange Format. This document is intended as a programming reference; it is recommended that the entire document be read carefully before programming, because of the interdependence of the various parts. There is an individual section for each of the Format blocks. Within each section, the sub-section labeled Required Version refers to the version number that an encoder will have to use if the corresponding block is used in the Data Stream. Within each section, a diagram describes the individual fields in the block; the diagrams are drawn vertically; top bytes in the diagram appear first in the Data Stream. Bits within a byte are drawn most significant on the left end. Multi-byte numeric fields are ordered Least Significant Byte first. Numeric constants are represented as Hexadecimal numbers, preceded by "0x". Bit fields within a byte are described in order from most significant bits to least significant bits.

5. General Description (hide/show)

The Graphics Interchange Formatࡈ defines a protocol intended for the on-line transmission and interchange of raster graphic data in a way that is independent of the hardware used in their creation or display.

The Graphics Interchange Format is defined in terms of blocks and sub-blocks which contain relevant parameters and data used in the reproduction of a graphic. A GIF Data Stream is a sequence of protocol blocks and sub-blocks representing a collection of graphics. In general, the graphics in a Data Stream are assumed to be related to some degree, and to share some control information; it is recommended that encoders attempt to group together related graphics in order to minimize hardware changes during processing and to minimize control information overhead. For the same reason, unrelated graphics or graphics which require resetting hardware parameters should be encoded separately to the extent possible.

A Data Stream may originate locally, as when read from a file, or it may originate remotely, as when transmitted over a data communications line. The Format is defined with the assumption that an error-free Transport Level Protocol is used for communications; the Format makes no provisions for error-detection and error-correction.

The GIF Data Stream must be interpreted in context, that is, the application program must rely on information external to the Data Stream to invoke the decoder process.

6. Version Numbers (hide/show)

The version number in the Header of a Data Stream is intended to identify the minimum set of capabilities required of a decoder in order to fully process the Data Stream. An encoder should use the earliest possible version number that includes all the blocks used in the Data Stream. Within each block section in this document, there is an entry labeled Required Version which specifies the earliest version number that includes the corresponding block. The encoder should make every attempt to use the earliest version number covering all the blocks in the Data Stream; the unnecessary use of later version numbers will hinder processing by some decoders.

7. The Encoder (hide/show)

The Encoder is the program used to create a GIF Data Stream. From raster data and other information, the encoder produces the necessary control and data blocks needed for reproducing the original graphics.

The encoder has the following primary responsibilities.

  • Include in the Data Stream all the necessary information to reproduce the graphics.
  • Insure that a Data Stream is labeled with the earliest possible Version Number that will cover the definition of all the blocks in it; this is to ensure that the largest number of decoders can process the Data Stream.
  • Ensure encoding of the graphics in such a way that the decoding process is optimized. Avoid redundant information as much as possible.
  • To the extent possible, avoid grouping graphics which might require resetting hardware parameters during the decoding process.
  • Set to zero (off) each of the bits of each and every field designated as reserved. Note that some fields in the Logical Screen Descriptor and the Image Descriptor were reserved under Version 87a, but are used under version 89a.

8. The Decoder (hide/show)

The Decoder is the program used to process a GIF Data Stream. It processes the Data Stream sequentially, parsing the various blocks and sub-blocks, using the control information to set hardware and process parameters and interpreting the data to render the graphics.

The decoder has the following primary responsibilities.

  • Process each graphic in the Data Stream in sequence, without delays other than those specified in the control information.
  • Set its hardware parameters to fit, as closely as possible, the control information contained in the Data Stream.

9. Compliance (hide/show)

An encoder or a decoder is said to comply with a given version of the Graphics Interchange Format if and only if it fully conforms with and correctly implements the definition of the standard associated with that version. An encoder or a decoder may be compliant with a given version number and not compliant with some subsequent version.

10. About Recommendations (hide/show)

Each block section in this document contains an entry labeled Recommendation; this section lists a set of recommendations intended to guide and organize the use of the particular blocks. Such recommendations are geared towards making the functions of encoders and decoders more efficient, as well as making optimal use of the communications bandwidth. It is advised that these recommendations be followed.

11. About Color Tables (hide/show)

The GIF format utilizes color tables to render raster-based graphics. A color table can have one of two different scopes: global or local.

A Global Color Table is used by all those graphics in the Data Stream which do not have a Local Color Table associated with them. The scope of the Global Color Table is the entire Data Stream.

A Local Color Table is always associated with the graphic that immediately follows it; the scope of a Local Color Table is limited to that single graphic. A Local Color Table supersedes a Global Color Table, that is, if a Data Stream contains a Global Color Table, and an image has a Local Color Table associated with it, the decoder must save the Global Color Table, use the Local Color Table to render the image, and then restore the Global Color Table.

Both types of color tables are optional, making it possible for a Data Stream to contain numerous graphics without a color table at all. For this reason, it is recommended that the decoder save the last Global Color Table used until another Global Color Table is encountered. In this way, a Data Stream which does not contain either a Global Color Table or a Local Color Table may be processed using the last Global Color Table saved. If a Global Color Table from a previous Stream is used, that table becomes the Global Color Table of the present Stream. This is intended to reduce the overhead incurred by color tables. In particular, it is recommended that an encoder use only one Global Color Table if all the images in related Data Streams can be rendered with the same table. If no color table is available at all, the decoder is free to use a system color table or a table of its own. In that case, the decoder may use a color table with as many colors as its hardware is able to support; it is recommended that such a table have black and white as its first two entries, so that monochrome images can be rendered adequately.

The Definition of the GIF Format allows for a Data Stream to contain only the Header, the Logical Screen Descriptor, a Global Color Table and the GIF Trailer. Such a Data Stream would be used to load a decoder with a Global Color Table, in preparation for subsequent Data Streams without a color table at all.

12. Blocks, Extensions and Scope (hide/show)

Blocks can be classified into three groups: Control, Graphic-Rendering and Special Purpose.

Control blocks, such as the Header, the Logical Screen Descriptor, the Graphic Control Extension and the Trailer, contain information used to control the process of the Data Stream or information used in setting hardware parameters.

Graphic-Rendering blocks such as the Image Descriptor and the Plain Text Extension contain information and data used to render a graphic on the display device.

Special Purpose blocks such as the Comment Extension and the Application Extension are neither used to control the process of the Data Stream nor do they contain information or data used to render a graphic on the display device.

With the exception of the Logical Screen Descriptor and the Global Color Table, whose scope is the entire Data Stream, all other Control blocks have a limited scope, restricted to the Graphic-Rendering block that follows them. Special Purpose blocks do not delimit the scope of any Control blocks; Special Purpose blocks are transparent to the decoding process. Graphic-Rendering blocks and extensions are used as scope delimiters for Control blocks and extensions.

The labels used to identify labeled blocks fall into three ranges:

  • 0x000x7F (0–127) are the Graphic Rendering blocks, excluding the Trailer (0x3B, 59)
  • 0x800xF9 (128–249) are the Control blocks
  • 0xFA0xFF (250–255) are the Special Purpose blocks

These ranges are defined so that decoders can handle block scope by appropriately identifying block labels, even when the block itself cannot be processed.

13. Block Sizes (hide/show)

The Block Size field in a block, counts the number of bytes remaining in the block, not counting the Block Size field itself, and not counting the Block Terminator, if one is to follow. Blocks other than Data Blocks are intended to be of fixed length; the Block Size field is provided in order to facilitate skipping them, not to allow their size to change in the future. Data blocks and sub-blocks are of variable length to accommodate the amount of data.

14. Using GIF as an embedded protocol (hide/show)

As an embedded protocol, GIF may be part of larger application protocols, within which GIF is used to render graphics. In such a case, the application protocol could define a block within which the GIF Data Stream would be contained. The application program would then invoke a GIF decoder upon encountering a block of type GIF. This approach is recommended in favor of using Application Extensions, which become overhead for all other applications that do not process them. Because a GIF Data Stream must be processed in context, the application must rely on some means of identifying the GIF Data Stream outside of the Stream itself.

15. Data Sub-blocks (hide/show)

a. Description

Data Sub-blocks are units containing data. They do not have a label, these blocks are processed in the context of control blocks, wherever data blocks are specified in the format. The first byte of the Data sub-block indicates the number of data bytes to follow. A data sub-block may contain from 0 to 255 data bytes. The size of the block does not account for the size byte itself, therefore, the empty sub-block is one whose size field contains 0x00 (0).

b. Required Version

87a.

c. Syntax

Byte # Field Name Type
0 Block Size Byte
1 Data Values Byte
2
3
up to 255
  1. Block Size:
    • Number of bytes in the Data Sub-block; the size must be within 0 and 255 bytes, inclusive.
  2. Data Values:
    • Any 8-bit value. There must be exactly as many Data Values as specified by the Block Size field.

d. Extensions and Scope

This type of block always occurs as part of a larger unit. It does not have a scope of itself.

e. Recommendation

None.

16. Block Terminator (hide/show)

a. Description

This zero-length Data Sub-block is used to terminate a sequence of Data Sub-blocks. It contains a single byte in the position of the Block Size field and does not contain data.

b. Required Version

87a.

c. Syntax

Byte # Field Name Type
0 Block Size Byte
  1. Block Size:
    • Number of bytes in the Data Sub-block; this field contains the fixed value 0x00 (0).
  2. Data Values:
    • This block does not contain any data.

d. Extensions and Scope

This block terminates the immediately preceding sequence of Data Sub-blocks. This block cannot be modified by any extension.

e. Recommendation

None.

a. Description

The Header identifies the GIF Data Stream in context. The Signature field marks the beginning of the Data Stream, and the Version field identifies the set of capabilities required of a decoder to fully process the Data Stream. This block is required; exactly one Header must be present per Data Stream.

b. Required Version

Not applicable. This block is not subject to a version number. This block must appear at the beginning of every Data Stream.

c. Syntax

Byte # Field Name Type
0 Signature 3 Bytes
1
2
3 Version 3 Bytes
4
5
  1. Signature:
    • Identifies the GIF Data Stream. This field contains the fixed value 'GIF' (0x47 0x49 0x46).
  2. Version:
    • Version number used to format the data stream. Identifies the minimum set of capabilities necessary to a decoder to fully process the contents of the Data Stream.
    • Version Numbers as of 10 July 1990:
      • "87a" (0x38 0x37 0x61) – May 1987
      • "89a" (0x38 0x39 0x61) – July 1989
    • Version numbers are ordered numerically increasing on the first two digits starting with 87 (87, 88, …, 99, 00, …, 85, 86) and alphabetically increasing on the third character (a, …, z).
  3. Extensions and Scope:
    • The scope of this block is the entire Data Stream. This block cannot be modified by any extension.

d. Recommendations

  1. Signature:
    • This field identifies the beginning of the GIF Data Stream; it is not intended to provide a unique signature for the identification of the data. It is recommended that the GIF Data Stream be identified externally by the application. (Refer to Appendix G for on-line identification of the GIF Data Stream.)
  2. Version:
    • Encoder: An encoder should use the earliest possible version number that defines all the blocks used in the Data Stream. When two or more Data Streams are combined, the latest of the individual version numbers should be used for the resulting Data Stream.
    • Decoder: A decoder should attempt to process the data stream to the best of its ability; if it encounters a version number which it is not capable of processing fully, it should nevertheless, attempt to process the data stream to the best of its ability, perhaps after warning the user that the data may be incomplete.

18. Logical Screen Descriptor (hide/show)

a. Description

The Logical Screen Descriptor contains the parameters necessary to define the area of the display device within which the images will be rendered. The coordinates in this block are given with respect to the top-left corner of the virtual screen; they do not necessarily refer to absolute coordinates on the display device. This implies that they could refer to window coordinates in a window-based environment or printer coordinates when a printer is used.

This block is required; exactly one Logical Screen Descriptor must be present per Data Stream.

b. Required Version

Not applicable. This block is not subject to a version number. This block must appear immediately after the Header.

c. Syntax

Byte # Bits Field Name Type
7 6 5 4 3 2 1 0
0 Logical Screen Width Unsigned
1
2 Logical Screen Height Unsigned
3
4 <Packed Fields> See below
5 Background Color Index Byte
6 Pixel Aspect Ratio Byte

<Packed Fields> =

Global Color Table Flag 1 Bit
Color Resolution 3 Bits
Sort Flag 1 Bit
Size of Global Color Table 3 Bits
  1. Logical Screen Width:
    • Width, in pixels, of the Logical Screen where the images will be rendered in the displaying device.
  2. Logical Screen Height:
    • Height, in pixels, of the Logical Screen where the images will be rendered in the displaying device.
  3. Global Color Table Flag:
    • Flag indicating the presence of a Global Color Table; if the flag is set, the Global Color Table will immediately follow the Logical Screen Descriptor. This flag also selects the interpretation of the Background Color Index; if the flag is set, the value of the Background Color Index field should be used as the table index of the background color. (This field is the most significant bit of the byte.)
    • Values:
      • 0: No Global Color Table follows, the Background Color Index field is meaningless.
      • 1: A Global Color Table will immediately follow, the Background Color Index field is meaningful.
  4. Color Resolution:
    • Number of bits per primary color available to the original image, minus 1. This value represents the size of the entire palette from which the colors in the graphic were selected, not the number of colors actually used in the graphic. For example, if the value in this field is 3, then the palette of the original image had 4 bits per primary color available to create the image. This value should be set to indicate the richness of the original palette, even if not every color from the whole palette is available on the source machine.
  5. Sort Flag:
    • Indicates whether the Global Color Table is sorted. If the flag is set, the Global Color Table is sorted, in order of decreasing importance. Typically, the order would be decreasing frequency, with most frequent color first. This assists a decoder, with fewer available colors, in choosing the best subset of colors; the decoder may use an initial segment of the table to render the graphic.
    • Values:
      • 0: Not ordered.
      • 1: Ordered by decreasing importance, most important color first.
  6. Size of Global Color Table:
    • If the Global Color Table Flag is set to 1, the value in this field is used to calculate the number of bytes contained in the Global Color Table. To determine that actual size of the color table, raise 2 to [the value of the field + 1]. Even if there is no Global Color Table specified, set this field according to the above formula so that decoders can choose the best graphics mode to display the stream in. (This field is made up of the 3 least significant bits of the byte.)
  7. Background Color Index:
    • Index into the Global Color Table for the Background Color. The Background Color is the color used for those pixels on the screen that are not covered by an image. If the Global Color Table Flag is set to (zero), this field should be zero and should be ignored.
  8. Pixel Aspect Ratio:
    • Factor used to compute an approximation of the aspect ratio of the pixel in the original image. If the value of the field is not 0, this approximation of the aspect ratio is computed based on the formula:
      Aspect Ratio = (Pixel Aspect Ratio + 15) ÷ 64
    • The Pixel Aspect Ratio is defined to be the quotient of the pixel's width over its height. The value range in this field allows specification of the widest pixel of 4:1 to the tallest pixel of 1:4 in increments of 1/64.
    • Values:
      • 0: No aspect ratio information is given.
      • 1…255: Value used in the computation.

d. Extensions and Scope

The scope of this block is the entire Data Stream. This block cannot be modified by any extension.

e. Recommendations

None.

19. Global Color Table (hide/show)

a. Description

This block contains a color table, which is a sequence of bytes representing red-green-blue color triplets. The Global Color Table is used by images without a Local Color Table and by Plain Text Extensions. Its presence is marked by the Global Color Table Flag being set to 1 in the Logical Screen Descriptor; if present, it immediately follows the Logical Screen Descriptor and contains a number of bytes equal to:

3 &tumes; 2Size of Global Color Table + 1

This block is optional; at most one Global Color Table may be present per Data Stream.

b. Required Version

87a.

c. Syntax

Byte # Field Name Type
0 Red 0 Byte
1 Green 0 Byte
2 Blue 0 Byte
3 Red 1 Byte
4 Green 1 Byte
766 Green 255 Byte
up to 767 Blue 255 Byte

d. Extensions and Scope

The scope of this block is the entire Data Stream. This block cannot be modified by any extension.

e. Recommendation

None.

20. Image Descriptor (hide/show)

a. Description

Each image in the Data Stream is composed of an Image Descriptor, an optional Local Color Table, and the image data. Each image must fit within the boundaries of the Logical Screen, as defined in the Logical Screen Descriptor.

The Image Descriptor contains the parameters necessary to process a table based image. The coordinates given in this block refer to coordinates within the Logical Screen, and are given in pixels. This block is a Graphic-Rendering Block, optionally preceded by one or more Control blocks such as the Graphic Control Extension, and may be optionally followed by a Local Color Table; the Image Descriptor is always followed by the image data.

This block is required for an image. Exactly one Image Descriptor must be present per image in the Data Stream. An unlimited number of images may be present per Data Stream.

b. Required Version

87a.

c. Syntax

Byte # Bits Field Name Type
7 6 5 4 3 2 1 0
0 Image Separator Byte
1 Image Left Position Unsigned
2
3 Image Top Position Unsigned
4
5 Image Width Unsigned
6
7 Image Height Unsigned
8
9 <Packed Fields> See below

<Packed Fields> =

Local Color Table Flag 1 Bit
Interlace Flag 1 Bit
Sort Flag 1 Bit
Reserved 2 Bits
Size of Local Color Table 3 Bits
  1. Image Separator:
    • Identifies the beginning of an Image Descriptor. This field contains the fixed value 0x2C (44, ',').
  2. Image Left Position:
    • Column number, in pixels, of the left edge of the image, with respect to the left edge of the Logical Screen. Leftmost column of the Logical Screen is 0.
  3. Image Top Position:
    • Row number, in pixels, of the top edge of the image with respect to the top edge of the Logical Screen. Top row of the Logical Screen is 0.
  4. Image Width:
    • Width of the image in pixels.
  5. Image Height:
    • Height of the image in pixels.
  6. Local Color Table Flag:
    • Indicates the presence of a Local Color Table immediately following this Image Descriptor. (This field is the most significant bit of the byte.)
    • Values:
      • 0: Local Color Table is not present. Use Global Color Table if available.
      • 1: Local Color Table present, and to follow immediately after this Image Descriptor.
  7. Interlace Flag:
    • Indicates if the image is interlaced. An image is interlaced in a four-pass interlace pattern; see Appendix E for details.
    • Values:
      • 0: Image is not interlaced.
      • 1: Image is interlaced.
  8. Sort Flag:
    • Indicates whether the Local Color Table is sorted. If the flag is set, the Local Color Table is sorted, in order of decreasing importance. Typically, the order would be decreasing frequency, with most frequent color first. This assists a decoder, with fewer available colors, in choosing the best subset of colors; the decoder may use an initial segment of the table to render the graphic.
    • Values:
      • 0: Not ordered.
      • 1: Ordered by decreasing importance, most important color first.
  9. Size of Local Color Table:
    • If the Local Color Table Flag is set to 1, the value in this field is used to calculate the number of bytes contained in the Local Color Table. To determine that actual size of the color table, raise 2 to [the value of the field + 1]. This value should be 0 if there is no Local Color Table specified. (This field is made up of the 3 least significant bits of the byte.)

d. Extensions and Scope

The scope of this block is the Table-based Image Data Block that follows it. This block may be modified by the Graphic Control Extension.

e. Recommendation

None.

21. Local Color Table (hide/show)

a. Description

This block contains a color table, which is a sequence of bytes representing red-green-blue color triplets. The Local Color Table is used by the image that immediately follows. Its presence is marked by the Local Color Table Flag being set to 1 in the Image Descriptor; if present, the Local Color Table immediately follows the Image Descriptor and contains a number of bytes equal to:

3 &tumes; 2Size of Local Color Table + 1

If present, this color table temporarily becomes the active color table and the following image should be processed using it. This block is optional; at most one Local Color Table may be present per Image Descriptor and its scope is the single image associated with the Image Descriptor that precedes it.

b. Required Version

87a.

c. Syntax

Byte # Field Name Type
0 Red 0 Byte
1 Green 0 Byte
2 Blue 0 Byte
3 Red 1 Byte
4 Green 1 Byte
766 Green 255 Byte
up to 767 Blue 255 Byte

d. Extensions and Scope

The scope of this block is the Table-based Image Data Block that immediately follows it. This block cannot be modified by any extension.

e. Recommendations

None.

22. Table Based Image Data (hide/show)

a. Description

The image data for a table based image consists of a sequence of sub-blocks, of size at most 255 bytes each, containing an index into the active color table, for each pixel in the image. Pixel indices are in order of left to right and from top to bottom. Each index must be within the range of the size of the active color table, starting at 0. The sequence of indices is encoded using the LZW Algorithm with variable-length code, as described in Appendix F.

b. Required Version

87a.

c. Syntax

The image data format is as follows:

Byte # Field Name Type
0 LZW Minimum Code Size Byte

Field Name Type
Image Data Data Sub-blocks
  1. LZW Minimum Code Size:
    • This byte determines the initial number of bits used for LZW codes in the image data, as described in Appendix F.

d. Extensions and Scope

This block has no scope, it contains raster data. Extensions intended to modify a Table-based image must appear before the corresponding Image Descriptor.

e. Recommendations

None.

23. Graphic Control Extension (hide/show)

a. Description

The Graphic Control Extension contains parameters used when processing a graphic rendering block. The scope of this extension is the first graphic rendering block to follow. The extension contains only one data sub-block.

This block is optional; at most one Graphic Control Extension may precede a graphic rendering block. This is the only limit to the number of Graphic Control Extensions that may be contained in a Data Stream.

b. Required Version

89a.

c. Syntax

Byte # Field Name Type
0 Extension Introducer Byte
1 Graphic Control Label Byte

Byte # Bits Field Name Type
7 6 5 4 3 2 1 0
0 Block Size Byte
1 <Packed Fields> See below
2 Delay Time Unsigned
3
4 Transparent Color Index Byte

Byte # Field Name Type
0 Block Terminator Byte

<Packed Fields> =

Reserved 3 Bits
Disposal Method 3 Bits
User Input Flag 1 Bit
Transparent Color Flag 1 Bit
  1. Extension Introducer:
    • Identifies the beginning of an extension block. This field contains the fixed value 0x21 (33, '!').
  2. Graphic Control Label:
    • Identifies the current block as a Graphic Control Extension. This field contains the fixed value 0xF9 (249).
  3. Block Size:
    • Number of bytes in the block, after the Block Size field and up to but not including the Block Terminator. This field contains the fixed value 0x04 (4).
  4. Disposal Method:
    • Indicates the way in which the graphic is to be treated after being displayed.
    • Values:
      • 0: No disposal specified. The decoder is not required to take any action.
      • 1: Do not dispose. The graphic is to be left in place.
      • 2: Restore to background color. The area used by the graphic must be restored to the background color.
      • 3: Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic.
      • 4–7: To be defined.
  5. User Input Flag:
    • Indicates whether or not user input is expected before continuing. If the flag is set, processing will continue when user input is entered. The nature of the User input is determined by the application (Carriage Return, Mouse Button Click, etc.).
    • Values:
      • 0: User input is not expected.
      • 1: User input is expected.
    • When a Delay Time is used and the User Input Flag is set, processing will continue when user input is received or when the delay time expires, whichever occurs first.
  6. Transparency Flag:
    • Indicates whether a transparency index is given in the Transparent Index field. (This field is the least significant bit of the byte.)
    • Values:
      • 0: Transparent Index is not given.
      • 1: Transparent Index is given.
  7. Delay Time:
    • If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered. This field may be used in conjunction with the User Input Flag field.
  8. Transparency Index:
    • The Transparency Index is such that when encountered, the corresponding pixel of the display device is not modified and processing goes on to the next pixel. The index is present if and only if the Transparency Flag is set to 1.
  9. Block Terminator:
    • This zero-length data block marks the end of the Graphic Control Extension.

d. Extensions and Scope

The scope of this Extension is the graphic rendering block that follows it; it is possible for other extensions to be present between this block and its target. This block can modify the Image Descriptor Block and the Plain Text Extension.

e. Recommendations

  1. Disposal Method:
    • The mode Restore To Previous is intended to be used in small sections of the graphic; the use of this mode imposes severe demands on the decoder to store the section of the graphic that needs to be saved. For this reason, this mode should be used sparingly. This mode is not intended to save an entire graphic or large areas of a graphic; when this is the case, the encoder should make every attempt to make the sections of the graphic to be restored be separate graphics in the data stream. In the case where a decoder is not capable of saving an area of a graphic marked as Restore To Previous, it is recommended that a decoder restore to the background color.
  2. User Input Flag:
    • When the flag is set, indicating that user input is expected, the decoder may sound the bell (0x07, 7) to alert the user that input is being expected. In the absence of a specified Delay Time, the decoder should wait for user input indefinitely. It is recommended that the encoder not set the User Input Flag without a Delay Time specified.

24. Comment Extension (hide/show)

a. Description

The Comment Extension contains textual information which is not part of the actual graphics in the GIF Data Stream. It is suitable for including comments about the graphics, credits, descriptions or any other type of non-control and non-graphic data. The Comment Extension may be ignored by the decoder, or it may be saved for later processing; under no circumstances should a Comment Extension disrupt or interfere with the processing of the Data Stream.

This block is optional; any number of them may appear in the Data Stream.

b. Required Version

89a.

c. Syntax

Byte # Field Name Type
0 Extension Introducer Byte
1 Comment Label Byte

Byte # Field Name Type
N Comment Data Data Sub-blocks

Byte # Field Name Type
0 Block Terminator Byte
  1. Extension Introducer:
    • Identifies the beginning of an extension block. This field contains the fixed value 0x21 (33, '!').
  2. Comment Label:
    • Identifies the block as a Comment Extension. This field contains the fixed value 0xFE (254).
  3. Comment Data:
    • Sequence of sub-blocks, each of size at most 255 bytes and at least 1 byte, with the size in a byte preceding the data. The end of the sequence is marked by the Block Terminator.
  4. Block Terminator:
    • This zero-length data block marks the end of the Comment Extension.

d. Extensions and Scope

This block does not have scope. This block cannot be modified by any extension.

e. Recommendations

  1. Data:
    • This block is intended for humans. It should contain text using the 7-bit ASCII character set. This block should not be used to store control information for custom processing.
  2. Position:
    • This block may appear at any point in the Data Stream at which a block can begin; however, it is recommended that Comment Extensions do not interfere with Control or Data blocks; they should be located at the beginning or at the end of the Data Stream to the extent possible.

25. Plain Text Extension (hide/show)

a. Description

The Plain Text Extension contains textual data and the parameters necessary to render that data as a graphic, in a simple form. The textual data will be encoded with the 7-bit printable ASCII characters. Text data are rendered using a grid of character cells defined by the parameters in the block fields. Each character is rendered in an individual cell. The textual data in this block is to be rendered as mono-spaced characters, one character per cell, with a best fitting font and size. For further information, see the section on Recommendations below.

The data characters are taken sequentially from the data portion of the block and rendered within a cell, starting with the upper left cell in the grid and proceeding from left to right and from top to bottom. Text data is rendered until the end of data is reached or the character grid is filled. The Character Grid contains an integral number of cells; in the case that the cell dimensions do not allow for an integral number, fractional cells must be discarded; an encoder must be careful to specify the grid dimensions accurately so that this does not happen.

This block requires a Global Color Table to be available; the colors used by this block reference the Global Color Table in the Stream if there is one, or the Global Color Table from a previous Stream, if one was saved.

This block is a graphic rendering block, therefore it may be modified by a Graphic Control Extension.

This block is optional; any number of them may appear in the Data Stream.

b. Required Version

89a.

c. Syntax

Byte # Field Name Type
0 Extension Introducer Byte
1 Plain Text Label Byte

Byte # Field Name Type
0 Block Size Byte
1 Text Grid Left Position Unsigned
2
3 Text Grid Top Position Unsigned
4
5 Text Grid Width Unsigned
6
7 Text Grid Height Unsigned
8
9 Character Cell Width Byte
10 Character Cell Height Byte
11 Text Foreground Color Index Byte
12 Text Background Color Index Byte

Byte # Field Name Type
N Plain Text Data Data Sub-blocks

Byte # Field Name Type
0 Block Terminator Byte
  1. Extension Introducer:
    • Identifies the beginning of an extension block. This field contains the fixed value 0x21 (33, '!').
  2. Plain Text Label:
    • Identifies the current block as a Plain Text Extension. This field contains the fixed value 0x01 (1).
  3. Block Size:
    • Number of bytes in the extension, after the Block Size field and up to but not including the beginning of the data portion. This field contains the fixed value 0x0C (12).
  4. Text Grid Left Position:
    • Column number, in pixels, of the left edge of the text grid, with respect to the left edge of the Logical Screen.
  5. Text Grid Top Position:
    • Row number, in pixels, of the top edge of the text grid, with respect to the top edge of the Logical Screen.
  6. Image Grid Width:
    • Width of the text grid in pixels.
  7. Image Grid Height:
    • Height of the text grid in pixels.
  8. Character Cell Width:
    • Width, in pixels, of each cell in the grid.
  9. Character Cell Height:
    • Height, in pixels, of each cell in the grid.
  10. Text Foreground Color Index:
    • Index into the Global Color Table to be used to render the text foreground.
  11. Text Background Color Index:
    • Index into the Global Color Table to be used to render the text background.
  12. Plain Text Data:
    • Sequence of sub-blocks, each of size at most 255 bytes and at least 1 byte, with the size in a byte preceding the data. The end of the sequence is marked by the Block Terminator.
  13. Block Terminator:
    • This zero-length data block marks the end of the Plain Text Data Blocks.

d. Extensions and Scope

The scope of this block is the Plain Text Data Block contained in it. This block may be modified by the Graphic Control Extension.

e. Recommendations

The data in the Plain Text Extension is assumed to be preformatted. The selection of font and size is left to the discretion of the decoder. If characters less than 0x20 (32) or greater than 0xF7 (247) are encountered, it is recommended that the decoder display a Space character (0x20, 32). The encoder should use grid and cell dimensions such that an integral number of cells fit in the grid both horizontally as well as vertically. For broadest compatibility, character cell dimensions should be around 8&tumes;8 or 8&tumes;16 (width &tumes; height); consider an image for unusual sized text.

Editor's (Kalle's) note: the upper limit for a printable character, 0xF7, seems odd. Maybe they meant 0x7E (126, '~', the last printable 7-bit ASCII character)?

26. Application Extension (hide/show)

a. Description

The Application Extension contains application-specific information; it conforms with the extension block syntax, as described below, and its block label is 0xFF (255).

b. Required Version

89a.

c. Syntax

Byte # Field Name Type
0 Extension Introducer Byte
1 Extension Label Byte

Byte # Field Name Type
0 Block Size Byte
1…8 Application Identifier 8 Bytes
9…11 Application Authentication Code 3 Bytes

Field Name Type
Application Data Data Sub-blocks

Byte # Field Name Type
0 Block Terminator Byte
  1. Extension Introducer:
    • Defines this block as an extension. This field contains the fixed value 0x21 (33, '!').
  2. Application Extension Label:
    • Identifies the block as an Application Extension. This field contains the fixed value 0xFF (255).
  3. Block Size:
    • Number of bytes in this extension block, following the Block Size field, up to but not including the beginning of the Application Data. This field contains the fixed value 0x0B (11).
  4. Application Identifier:
    • Sequence of eight printable ASCII characters used to identify the application owning the Application Extension.
  5. Application Authentication Code:
    • Sequence of three bytes used to authenticate the Application Identifier. An Application program may use an algorithm to compute a binary code that uniquely identifies it as the application owning the Application Extension.

d. Extensions and Scope

This block does not have scope. This block cannot be modified by any extension.

e. Recommendation

None.

27. Trailer (hide/show)

a. Description

This block is a single-field block indicating the end of the GIF Data Stream. It contains the fixed value 0x3B (59, ';').

b. Required Version

87a.

c. Syntax

Byte # Field Name Type
0 GIF Trailer Byte

d. Extensions and Scope

This block does not have scope, it terminates the GIF Data Stream. This block may not be modified by any extension.

e. Recommendations

None.

Appendix A. Quick Reference Table (hide/show)

Block Name Required? Label Extension Version
Unlabeled Blocks
Header required (one occurrence) none no N/A
Logical Screen Descriptor required (one occurrence) none no 87a (89a)
Global Color Table optional (at most one occurrence) none no 87a
Local Color Table optional (zero or more occurrences) none no 87a
Graphic-Rendering Blocks
Plain Text Extension optional (zero or more occurrences) 0x01 (1) yes 89a
Image Descriptor optional (zero or more occurrences) 0x2C (44, ',') no 87a (89a)
Control Blocks
Graphic Control Extension optional (zero or more occurrences) 0xF9 (249) yes 89a
Special Purpose Blocks
Trailer required (one occurrence) 0x3B (59, ';') no 87a
Comment Extension optional (zero or more occurrences) 0xFE (254) yes 89a
Application Extension optional (zero or more occurrences) 0xFF (255) yes 89a

Notes:

  • The Header is not subject to Version Numbers.
  • (89a) The Logical Screen Descriptor and the Image Descriptor retained their syntax from version 87a to version 89a, but some fields reserved under version 87a are used under version 89a.

Appendix B. GIF Grammar (hide/show)

A Grammar is a form of notation to represent the sequence in which certain objects form larger objects. A grammar is also used to represent the number of objects that can occur at a given position. The grammar given here represents the sequence of blocks that form the GIF Data Stream. A grammar is given by listing its rules. Each rule consists of the left-hand side, followed by some form of equals sign, followed by the right-hand side. In a rule, the right-hand side describes how the left-hand side is defined. The right-hand side consists of a sequence of entities, with the possible presence of special symbols. The following legend defines the symbols used in this grammar for GIF.

Legend:

< > grammar word
::= defines symbol
* zero or more occurrences
+ one or more occurrences
| alternate element
[ ] optional element

Example:

<GIF Data Stream> ::= Header <Logical Screen> <Data>* Trailer

This rule defines the entity <GIF Data Stream> as follows. It must begin with a Header. The Header is followed by an entity called Logical Screen, which is defined below by another rule. The Logical Screen is followed by the entity Data, which is also defined below by another rule. Finally, the entity Data is followed by the Trailer. Since there is no rule defining the Header or the Trailer, this means that these blocks are defined in the document. The entity Data has a special symbol (*) following it which means that, at this position, the entity Data may be repeated any number of times, including 0 times. For further reading on this subject, refer to a standard text on Programming Languages.

The Grammar

Note: The grammar indicates that it is possible for a GIF Data Stream to contain the Header, the Logical Screen Descriptor, a Global Color Table and the GIF Trailer. This special case is used to load a GIF decoder with a Global Color Table, in preparation for subsequent Data Streams without color tables at all.

Appendix C. Glossary (hide/show)

Active Color Table Color table used to render the next graphic. If the next graphic is an image which has a Local Color Table associated with it, the active color table becomes the Local Color Table associated with that image. If the next graphic is an image without a Local Color Table, or a Plain Text Extension, the active color table is the Global Color Table associated with the Data Stream, if there is one; if there is no Global Color Table in the Data Stream, the active color table is a color table saved from a previous Data Stream, or one supplied by the decoder.
Block Collection of bytes forming a protocol unit. In general, the term includes labeled and unlabeled blocks, as well as Extensions.
Data Stream The GIF Data Stream is composed of blocks and sub-blocks representing images and graphics, together with control information to render them on a display device. All control and data blocks in the Data Stream must follow the Header and must precede the Trailer.
Decoder A program capable of processing a GIF Data Stream to render the images and graphics contained in it.
Encoder A program capable of capturing and formatting image and graphic raster data, following the definitions of the Graphics Interchange Format.
Extension A protocol block labeled by the Extension Introducer 0x21 (33, '!').
Extension Introducer Label (0x21, 33, '!') defining an Extension.
Graphic Data which can be rendered on the screen by virtue of some algorithm. The term graphic is more general than the term image; in addition to images, the term graphic also includes data such as text, which is rendered using character bit-maps.
Image Data representing a picture or a drawing; an image is represented by an array of pixels called the raster of the image.
Raster Array of pixel values representing an image.

Appendix D. Conventions (hide/show)

Animation The Graphics Interchange Format is not intended as a platform for animation, even though it can be done in a limited way.
Byte Ordering Unless otherwise stated, multi-byte numeric fields are ordered with the Least Significant Byte first.
Color Indices Color indices always refer to the active color table, either the Global Color Table or the Local Color Table.
Color Order Unless otherwise stated, all triple-component RGB color values are specified in Red-Green-Blue order.
Color Tables Both color tables, the Global and the Local, are optional; if present, the Global Color Table is to be used with every image in the Data Stream for which a Local Color Table is not given; if present, a Local Color Table overrides the Global Color Table. However, if neither color table is present, the application program is free to use an arbitrary color table. If the graphics in several Data Streams are related and all use the same color table, an encoder could place the color table as the Global Color Table in the first Data Stream and leave subsequent Data Streams without a Global Color Table or any Local Color Tables; in this way, the overhead for the table is eliminated. It is recommended that the decoder save the previous Global Color Table to be used with the Data Stream that follows, in case it does not contain either a Global Color Table or any Local Color Tables. In general, this allows the application program to use past color tables, significantly reducing transmission overhead.
Extension Blocks Extensions are defined using the Extension Introducer code (0x21, 33, '!') to mark the beginning of the block, followed by a block label, identifying the type of extension. Extension Codes are numbers in the range from 0x00 (0) to 0xFF (255), inclusive. Special purpose extensions are transparent to the decoder and may be omitted when transmitting the Data Stream on-line. The GIF capabilities dialogue makes the provision for the receiver to request the transmission of all blocks; the default state in this regard is no transmission of Special purpose blocks.
Reserved Fields All Reserved Fields are expected to have each bit set to zero (off).

Appendix E. Interlaced Images (hide/show)

The rows of an Interlaced images are arranged in the following order:

Group 1 Pass 1 Every 8th row, starting with row 0
Group 2 Pass 2 Every 8th row, starting with row 4
Group 3 Pass 3 Every 4th row, starting with row 2
Group 4 Pass 4 Every 2nd row, starting with row 1

The following example illustrates how the rows of an interlaced image are ordered.

Row Number Interlace Pass
0 1
1 4
2 3
3 4
4 2
5 4
6 3
7 4
8 1
9 4
10 3
11 4
12 2
13 4
14 3
15 4
16 1
17 4
18 3
19 4

Appendix F. Variable-Length-Code LZW Compression (hide/show)

The Variable-Length-Code LZW Compression is a variation of the Lempel-Ziv Compression algorithm in which variable-length codes are used to replace patterns detected in the original data. The algorithm uses a code or translation table constructed from the patterns encountered in the original data; each new pattern is entered into the table and its index is used to replace it in the compressed stream.

The compressor takes the data from the input stream and builds a code or translation table with the patterns as it encounters them; each new pattern is entered into the code table and its index is added to the output stream; when a pattern is encountered which had been detected since the last code table refresh, its index from the code table is put on the output stream, thus achieving the data compression. The expander takes input from the compressed data stream and builds the code or translation table from it; as the compressed data stream is processed, codes are used to index into the code table and the corresponding data is put on the decompressed output stream, thus achieving data decompression. The details of the algorithm are explained below. The Variable-Length-Code aspect of the algorithm is based on an initial code size (LZW-initial code size), which specifies the initial number of bits used for the compression codes. When the number of patterns detected by the compressor in the input stream exceeds the number of patterns encodable with the current number of bits, the number of bits per LZW code is increased by one.

The Raster Data stream that represents the actual output image can be represented as:

Field name
LZW code size

Field name
block size Repeated as many times as necessary.
data bytes

(The code that terminates the LZW compressed data must appear before Block Terminator.)

Field name
Block Terminator (0x00, 0)

The conversion of the image from a series of pixel values to a transmitted or stored character stream involves several steps. In brief these steps are:

  1. Establish the Code Size – Define the number of bits needed to represent the actual data.
  2. Compress the Data – Compress the series of image pixels to a series of compression codes.
  3. Build a Series of Bytes – Take the set of compression codes and convert to a string of 8-bit bytes.
  4. Package the Bytes – Package sets of bytes into blocks preceded by character counts and output.

1. Establish Code Size

The first byte of the Compressed Data stream is a value indicating the minimum number of bits required to represent the set of actual pixel values. Normally this will be the same as the number of color bits. Because of some algorithmic constraints however, black & white images which have one color bit must be indicated as having a code size of 2. This code size value also implies that the compression codes must start out one bit longer.

2. Compression

The LZW algorithm converts a series of data values into a series of codes which may be raw values or a code designating a series of values. Using text characters as an analogy, the output code consists of a character or a code representing a string of characters.

The LZW algorithm used in GIF matches algorithmically with the standard LZW algorithm with the following differences:

  1. A special Clear code is defined which resets all compression/decompression parameters and tables to a start-up state. The value of this code is 2<code size>. For example if the code size indicated was 4 (image was 4 bits/pixel) the Clear code value would be 16 (10000 binary). The Clear code can appear at any point in the image data stream and therefore requires the LZW algorithm to process succeeding codes as if a new data stream was starting. Encoders should output a Clear code as the first code of each image data stream.
  2. An End of Information code is defined that explicitly indicates the end of the image data stream. LZW processing terminates when this code is encountered. It must be the last code output by the encoder for an image. The value of this code is <Clear code>+1.
  3. The first available compression code value is <Clear code> + 2.
  4. The output codes are of variable length, starting at <code size> + 1 bits per code, up to 12 bits per code. This defines a maximum code value of 4095 (0xFFF). Whenever the LZW code value would exceed the current code length, the code length is increased by one. The packing/unpacking of these codes must then be altered to reflect the new code length.

Editor's (Kalle's) note: see also the Cover Sheet.

3. Build 8-bit Bytes

Because the LZW compression used for GIF creates a series of variable length codes, of between 3 and 12 bits each, these codes must be reformed into a series of 8-bit bytes that will be the characters actually stored or transmitted. This provides additional compression of the image. The codes are formed into a stream of bits as if they were packed right to left and then picked off 8 bits at a time to be output.

Assuming a character array of 8 bits per character and using 5 bit codes to be packed, an example layout would be similar to:

Byte # Bits
0 bbbaaaaa
1 dcccccbb
2 eeeedddd
3 ggfffffe
4 hhhhhggg
N

Note that the physical packing arrangement will change as the number of bits per compression code change but the concept remains the same.

4. Package the Bytes

Once the bytes have been created, they are grouped into blocks for output by preceding each block of 0 to 255 bytes with a character count byte. A block with a zero byte count terminates the Raster Data stream for a given image. These blocks are what are actually output for the GIF image. This block format has the side effect of allowing a decoding program the ability to read past the actual image data if necessary by reading block counts and then skipping over the data.

Further Reading

  1. Ziv, J. and Lempel, A.: A Universal Algorithm for Sequential Data Compression, IEEE Transactions on Information Theory, May 1977
  2. Welch, T.: A Technique for High-Performance Data Compression, Computer, June 1984
  3. Nelson, M.R.: LZW Data Compression, Dr. Dobb's Journal, October 1989

Editor's (Kalle's) note: see also Wikipedia – Lempel–Ziv–Welch.

Appendix G. On-line Capabilities Dialogue (hide/show)

Note: This section is currently (10 July 1990) under revision; the information provided here should be used as general guidelines. Code written based on this information should be designed in a flexible way to accommodate any changes resulting from the revisions.

The following sequences are defined for use in mediating control between a GIF sender and GIF receiver over an interactive communications line. These sequences do not apply to applications that involve downloading of static GIF files and are not considered part of a GIF file.

GIF Capabilities Enquiry

The GIF Capabilities Enquiry sequence is issued from a host and requests an interactive GIF decoder to return a response message that defines the graphics parameters for the decoder. This involves returning information about available screen sizes, number of bits/color supported and the amount of color detail supported. The escape sequence for the GIF Capabilities Enquiry is defined as:

ESC 0x1B (27)
[ 0x5B (91)
> 0x3E (62)
0 0x30 (48)
g 0x67 (103)

GIF Capabilities Response

The GIF Capabilities Response message is returned by an interactive GIF decoder and defines the decoder's display capabilities for all graphics modes that are supported by the software. Note that this can also include graphics printers as well as a monitor screen. The general format of this message is:

#version;protocol{;dev, width, height, color-bits, color-res}…<CR>

'#' GIF Capabilities Response identifier character.
version GIF format version number; initially '87a'.
protocol='0' No end-to-end protocol supported by decoder Transfer as direct 8-bit data stream.
protocol='1' Can use CIS B+ error correction protocol to transfer GIF data interactively from the host directly to the display.
dev='0' Screen parameter set follows.
dev='1' Printer parameter set follows.
width Maximum supported display width in pixels.
height Maximum supported display height in pixels.
color-bits Number of bits per pixel supported. The number of supported colors is therefore 2color-bits.
color-res Number of bits per color component supported in the hardware color palette. If color-res is '0' then no hardware palette table is available.

Note that all values in the GIF Capabilities Response are returned as ASCII decimal numbers and the message is terminated by a Carriage Return character (0x0D, 13).

The following GIF Capabilities Response message describes three standard IBM PC Enhanced Graphics Adapter configurations with no printer; the GIF data stream can be processed within an error correcting protocol:

#87a;1;0,320,200,4,0;0,640,200,2,2;0,640,350,4,2<CR>

Enter GIF Graphics Mode

Two sequences are currently defined to invoke an interactive GIF decoder into action. The only difference between them is that different output media are selected. These sequences are:

ESC 0x1B (27) Display GIF image on screen
[ 0x5B (91)
> 0x3E (62)
1 0x31 (49)
g 0x67 (103)

ESC 0x1B (27) Display image directly to an attached graphics printer. The image may optionally be displayed on the screen as well.
[ 0x5B (91)
> 0x3E (62)
2 0x32 (50)
g 0x67 (103)

Note that the 'g' character terminating each sequence is in lowercase.

Interactive Environment

The assumed environment for the transmission of GIF image data from an interactive application is a full 8-bit data stream from host to micro. All 256 character codes must be transferrable. The establishing of an 8-bit data path for communications will normally be taken care of by the host application programs. It is however up to the receiving communications programs supporting GIF to be able to receive and pass on all 256 8-bit codes to the GIF decoder software.

Cover Sheet for the GIF89a Specification (hide/show)

Deferred clear code in LZW compression

There has been confusion about where clear codes can be found in the data stream. As the specification says, they may appear at anytime. There is not a requirement to send a clear code when the string table is full.

It is the encoder's decision as to when the table should be cleared. When the table is full, the encoder can chose to use the table as is, making no changes to it until the encoder chooses to clear it. The encoder during this time sends out codes that are of the maximum Code Size.

As we can see from the above, when the decoder's table is full, it must not change the table until a clear code is received. The Code Size is that of the maximum Code Size. Processing other than this is done normally.

Because of a large base of decoders that do not handle the decompression in this manner, we ask developers of GIF encoding software to not implement this feature until at least January 1991 and later if they see that their particular market is not ready for it. This will give developers of GIF decoding software time to implement this feature and to get it into the hands of their clients before the decoders start "breaking" on the new GIF's. It is not required that encoders change their software to take advantage of the deferred clear code, but it is for decoders.

Application Extension Block – Application Identifier

There will be a Courtesy Directory file located on CompuServe in the PICS forum. This directory will contain Application Identifiers for Application Extension Blocks that have been used by developers of GIF applications. This file is intended to help keep developers that wish to create Application Extension Blocks from using the same Application Identifiers. This is not an official directory; it is for voluntary participation only and does not guarantee that someone will not use the same identifier.

E-Mail can be sent to Larry Wood (forum manager of PICS) indicating the request for inclusion in this file with an identifier.


giflib-6.1.3/doc/gifstandard/gif89a.js0000664000175000017500000000064215166751647015627 0ustar esresrfunction ToggleVis(number) { // toggle visibility of a single chapter id = "p" + number; c = document.getElementById(id).className; c = (c == "" ? "hiddenparagraph" : ""); document.getElementById(id).className = c; } function SetEveryVis(status) { // set visibility of every chapter c = (status == 0 ? "hiddenparagraph" : ""); for(i = 0; i <= 35; i++) { document.getElementById("p" + i).className = c; } } giflib-6.1.3/doc/gifstandard/gif87.txt0000664000175000017500000007451515166751647015701 0ustar esresr G I F (tm) Graphics Interchange Format (tm) A standard defining a mechanism for the storage and transmission of raster-based graphics information June 15, 1987 (c) CompuServe Incorporated, 1987 All rights reserved While this document is copyrighted, the information contained within is made available for use in computer software without royalties, or licensing restrictions. GIF and 'Graphics Interchange Format' are trademarks of CompuServe, Incorporated. an H&R Block Company 5000 Arlington Centre Blvd. Columbus, Ohio 43220 (614) 457-8600 Page 2 Graphics Interchange Format (GIF) Specification Table of Contents INTRODUCTION . . . . . . . . . . . . . . . . . page 3 GENERAL FILE FORMAT . . . . . . . . . . . . . page 3 GIF SIGNATURE . . . . . . . . . . . . . . . . page 4 SCREEN DESCRIPTOR . . . . . . . . . . . . . . page 4 GLOBAL COLOR MAP . . . . . . . . . . . . . . . page 5 IMAGE DESCRIPTOR . . . . . . . . . . . . . . . page 6 LOCAL COLOR MAP . . . . . . . . . . . . . . . page 7 RASTER DATA . . . . . . . . . . . . . . . . . page 7 GIF TERMINATOR . . . . . . . . . . . . . . . . page 8 GIF EXTENSION BLOCKS . . . . . . . . . . . . . page 8 APPENDIX A - GLOSSARY . . . . . . . . . . . . page 9 APPENDIX B - INTERACTIVE SEQUENCES . . . . . . page 10 APPENDIX C - IMAGE PACKAGING & COMPRESSION . . page 12 APPENDIX D - MULTIPLE IMAGE PROCESSING . . . . page 15 Graphics Interchange Format (GIF) Page 3 Specification INTRODUCTION 'GIF' (tm) is CompuServe's standard for defining generalized color raster images. This 'Graphics Interchange Format' (tm) allows high-quality, high-resolution graphics to be displayed on a variety of graphics hardware and is intended as an exchange and display mechanism for graphics images. The image format described in this document is designed to support current and future image technology and will in addition serve as a basis for future CompuServe graphics products. The main focus of this document is to provide the technical information necessary for a programmer to implement GIF encoders and decoders. As such, some assumptions are made as to terminology relavent to graphics and programming in general. The first section of this document describes the GIF data format and its components and applies to all GIF decoders, either as standalone programs or as part of a communications package. Appendix B is a section relavent to decoders that are part of a communications software package and describes the protocol requirements for entering and exiting GIF mode, and responding to host interrogations. A glossary in Appendix A defines some of the terminology used in this document. Appendix C gives a detailed explanation of how the graphics image itself is packaged as a series of data bytes. Graphics Interchange Format Data Definition GENERAL FILE FORMAT +-----------------------+ | +-------------------+ | | | GIF Signature | | | +-------------------+ | | +-------------------+ | | | Screen Descriptor | | | +-------------------+ | | +-------------------+ | | | Global Color Map | | | +-------------------+ | . . . . . . | +-------------------+ | ---+ | | Image Descriptor | | | | +-------------------+ | | | +-------------------+ | | | | Local Color Map | | |- Repeated 1 to n times | +-------------------+ | | | +-------------------+ | | | | Raster Data | | | | +-------------------+ | ---+ . . . . . . |- GIF Terminator -| +-----------------------+ Graphics Interchange Format (GIF) Page 4 Specification GIF SIGNATURE The following GIF Signature identifies the data following as a valid GIF image stream. It consists of the following six characters: G I F 8 7 a The last three characters '87a' may be viewed as a version number for this particular GIF definition and will be used in general as a reference in documents regarding GIF that address any version dependencies. SCREEN DESCRIPTOR The Screen Descriptor describes the overall parameters for all GIF images following. It defines the overall dimensions of the image space or logical screen required, the existance of color mapping information, background screen color, and color depth information. This information is stored in a series of 8-bit bytes as described below. bits 7 6 5 4 3 2 1 0 Byte # +---------------+ | | 1 +-Screen Width -+ Raster width in pixels (LSB first) | | 2 +---------------+ | | 3 +-Screen Height-+ Raster height in pixels (LSB first) | | 4 +-+-----+-+-----+ M = 1, Global color map follows Descriptor |M| cr |0|pixel| 5 cr+1 = # bits of color resolution +-+-----+-+-----+ pixel+1 = # bits/pixel in image | background | 6 background=Color index of screen background +---------------+ (color is defined from the Global color |0 0 0 0 0 0 0 0| 7 map or default map if none specified) +---------------+ The logical screen width and height can both be larger than the physical display. How images larger than the physical display are handled is implementation dependent and can take advantage of hardware characteristics (e.g. Macintosh scrolling windows). Otherwise images can be clipped to the edges of the display. The value of 'pixel' also defines the maximum number of colors within an image. The range of values for 'pixel' is 0 to 7 which represents 1 to 8 bits. This translates to a range of 2 (B & W) to 256 colors. Bit 3 of word 5 is reserved for future definition and must be zero. Graphics Interchange Format (GIF) Page 5 Specification GLOBAL COLOR MAP The Global Color Map is optional but recommended for images where accurate color rendition is desired. The existence of this color map is indicated in the 'M' field of byte 5 of the Screen Descriptor. A color map can also be associated with each image in a GIF file as described later. However this global map will normally be used because of hardware restrictions in equipment available today. In the individual Image Descriptors the 'M' flag will normally be zero. If the Global Color Map is present, it's definition immediately follows the Screen Descriptor. The number of color map entries following a Screen Descriptor is equal to 2**(# bits per pixel), where each entry consists of three byte values representing the relative intensities of red, green and blue respectively. The structure of the Color Map block is: bits 7 6 5 4 3 2 1 0 Byte # +---------------+ | red intensity | 1 Red value for color index 0 +---------------+ |green intensity| 2 Green value for color index 0 +---------------+ | blue intensity| 3 Blue value for color index 0 +---------------+ | red intensity | 4 Red value for color index 1 +---------------+ |green intensity| 5 Green value for color index 1 +---------------+ | blue intensity| 6 Blue value for color index 1 +---------------+ : : (Continues for remaining colors) Each image pixel value received will be displayed according to its closest match with an available color of the display based on this color map. The color components represent a fractional intensity value from none (0) to full (255). White would be represented as (255,255,255), black as (0,0,0) and medium yellow as (180,180,0). For display, if the device supports fewer than 8 bits per color component, the higher order bits of each component are used. In the creation of a GIF color map entry with hardware supporting fewer than 8 bits per component, the component values for the hardware should be converted to the 8-bit format with the following calculation: = *255/(2** -1) This assures accurate translation of colors for all displays. In the cases of creating GIF images from hardware without color palette capability, a fixed palette should be created based on the available display colors for that hardware. If no Global Color Map is indicated, a default color map is generated internally which maps each possible incoming color index to the same hardware color index modulo where is the number of available hardware colors. Graphics Interchange Format (GIF) Page 6 Specification IMAGE DESCRIPTOR The Image Descriptor defines the actual placement and extents of the following image within the space defined in the Screen Descriptor. Also defined are flags to indicate the presence of a local color lookup map, and to define the pixel display sequence. Each Image Descriptor is introduced by an image separator character. The role of the Image Separator is simply to provide a synchronization character to introduce an Image Descriptor. This is desirable if a GIF file happens to contain more than one image. This character is defined as 0x2C hex or ',' (comma). When this character is encountered between images, the Image Descriptor will follow immediately. Any characters encountered between the end of a previous image and the image separator character are to be ignored. This allows future GIF enhancements to be present in newer image formats and yet ignored safely by older software decoders. bits 7 6 5 4 3 2 1 0 Byte # +---------------+ |0 0 1 0 1 1 0 0| 1 ',' - Image separator character +---------------+ | | 2 Start of image in pixels from the +- Image Left -+ left side of the screen (LSB first) | | 3 +---------------+ | | 4 +- Image Top -+ Start of image in pixels from the | | 5 top of the screen (LSB first) +---------------+ | | 6 +- Image Width -+ Width of the image in pixels (LSB first) | | 7 +---------------+ | | 8 +- Image Height-+ Height of the image in pixels (LSB first) | | 9 +-+-+-+-+-+-----+ M=0 - Use global color map, ignore 'pixel' |M|I|0|0|0|pixel| 10 M=1 - Local color map follows, use 'pixel' +-+-+-+-+-+-----+ I=0 - Image formatted in Sequential order I=1 - Image formatted in Interlaced order pixel+1 - # bits per pixel for this image The specifications for the image position and size must be confined to the dimensions defined by the Screen Descriptor. On the other hand it is not necessary that the image fill the entire screen defined. Graphics Interchange Format (GIF) Page 7 Specification LOCAL COLOR MAP A Local Color Map is optional and defined here for future use. If the 'M' bit of byte 10 of the Image Descriptor is set, then a color map follows the Image Descriptor that applies only to the following image. At the end of the image, the color map will revert to that defined after the Screen Descriptor. Note that the 'pixel' field of byte 10 of the Image Descriptor is used only if a Local Color Map is indicated. This defines the parameters not only for the image pixel size, but determines the number of color map entries that follow. The bits per pixel value will also revert to the value specified in the Screen Descriptor when processing of the image is complete. RASTER DATA The format of the actual image is defined as the series of pixel color index values that make up the image. The pixels are stored left to right sequentially for an image row. By default each image row is written sequentially, top to bottom. In the case that the Interlace or 'I' bit is set in byte 10 of the Image Descriptor then the row order of the image display follows a four-pass process in which the image is filled in by widely spaced rows. The first pass writes every 8th row, starting with the top row of the image window. The second pass writes every 8th row starting at the fifth row from the top. The third pass writes every 4th row starting at the third row from the top. The fourth pass completes the image, writing every other row, starting at the second row from the top. A graphic description of this process follows: Image Row Pass 1 Pass 2 Pass 3 Pass 4 Result --------------------------------------------------- 0 **1a** **1a** 1 **4a** **4a** 2 **3a** **3a** 3 **4b** **4b** 4 **2a** **2a** 5 **4c** **4c** 6 **3b** **3b** 7 **4d** **4d** 8 **1b** **1b** 9 **4e** **4e** 10 **3c** **3c** 11 **4f** **4f** 12 **2b** **2b** . . . The image pixel values are processed as a series of color indices which map into the existing color map. The resulting color value from the map is what is actually displayed. This series of pixel indices, the number of which is equal to image-width*image-height pixels, are passed to the GIF image data stream one value per pixel, compressed and packaged according to a version of the LZW compression algorithm as defined in Appendix C. Graphics Interchange Format (GIF) Page 8 Specification GIF TERMINATOR In order to provide a synchronization for the termination of a GIF image file, a GIF decoder will process the end of GIF mode when the character 0x3B hex or ';' is found after an image has been processed. By convention the decoding software will pause and wait for an action indicating that the user is ready to continue. This may be a carriage return entered at the keyboard or a mouse click. For interactive applications this user action must be passed on to the host as a carriage return character so that the host application can continue. The decoding software will then typically leave graphics mode and resume any previous process. GIF EXTENSION BLOCKS To provide for orderly extension of the GIF definition, a mechanism for defining the packaging of extensions within a GIF data stream is necessary. Specific GIF extensions are to be defined and documented by CompuServe in order to provide a controlled enhancement path. GIF Extension Blocks are packaged in a manner similar to that used by the raster data though not compressed. The basic structure is: 7 6 5 4 3 2 1 0 Byte # +---------------+ |0 0 1 0 0 0 0 1| 1 '!' - GIF Extension Block Introducer +---------------+ | function code | 2 Extension function code (0 to 255) +---------------+ ---+ | byte count | | +---------------+ | : : +-- Repeated as many times as necessary |func data bytes| | : : | +---------------+ ---+ . . . . . . +---------------+ |0 0 0 0 0 0 0 0| zero byte count (terminates block) +---------------+ A GIF Extension Block may immediately preceed any Image Descriptor or occur before the GIF Terminator. All GIF decoders must be able to recognize the existence of GIF Extension Blocks and read past them if unable to process the function code. This ensures that older decoders will be able to process extended GIF image files in the future, though without the additional functionality. Graphics Interchange Format (GIF) Page 9 Appendix A - Glossary GLOSSARY Pixel - The smallest picture element of a graphics image. This usually corresponds to a single dot on a graphics screen. Image resolution is typically given in units of pixels. For example a fairly standard graphics screen format is one 320 pixels across and 200 pixels high. Each pixel can appear as one of several colors depending on the capabilities of the graphics hardware. Raster - A horizontal row of pixels representing one line of an image. A typical method of working with images since most hardware is oriented to work most efficiently in this manner. LSB - Least Significant Byte. Refers to a convention for two byte numeric values in which the less significant byte of the value preceeds the more significant byte. This convention is typical on many microcomputers. Color Map - The list of definitions of each color used in a GIF image. These desired colors are converted to available colors through a table which is derived by assigning an incoming color index (from the image) to an output color index (of the hardware). While the color map definitons are specified in a GIF image, the output pixel colors will vary based on the hardware used and its ability to match the defined color. Interlace - The method of displaying a GIF image in which multiple passes are made, outputting raster lines spaced apart to provide a way of visualizing the general content of an entire image before all of the data has been processed. B Protocol - A CompuServe-developed error-correcting file transfer protocol available in the public domain and implemented in CompuServe VIDTEX products. This error checking mechanism will be used in transfers of GIF images for interactive applications. LZW - A sophisticated data compression algorithm based on work done by Lempel-Ziv & Welch which has the feature of very efficient one-pass encoding and decoding. This allows the image to be decompressed and displayed at the same time. The original article from which this technique was adapted is: Terry A. Welch, "A Technique for High Performance Data Compression", IEEE Computer, vol 17 no 6 (June 1984) This basic algorithm is also used in the public domain ARC file compression utilities. The CompuServe adaptation of LZW for GIF is described in Appendix C. Graphics Interchange Format (GIF) Page 10 Appendix B - Interactive Sequences GIF Sequence Exchanges for an Interactive Environment The following sequences are defined for use in mediating control between a GIF sender and GIF receiver over an interactive communications line. These sequences do not apply to applications that involve downloading of static GIF files and are not considered part of a GIF file. GIF CAPABILITIES ENQUIRY The GCE sequence is issued from a host and requests an interactive GIF decoder to return a response message that defines the graphics parameters for the decoder. This involves returning information about available screen sizes, number of bits/color supported and the amount of color detail supported. The escape sequence for the GCE is defined as: ESC [ > 0 g (g is lower case, spaces inserted for clarity) (0x1B 0x5B 0x3E 0x30 0x67) GIF CAPABILITIES RESPONSE The GIF Capabilities Response message is returned by an interactive GIF decoder and defines the decoder's display capabilities for all graphics modes that are supported by the software. Note that this can also include graphics printers as well as a monitor screen. The general format of this message is: #version;protocol{;dev, width, height, color-bits, color-res}... '#' - GCR identifier character (Number Sign) version - GIF format version number; initially '87a' protocol='0' - No end-to-end protocol supported by decoder Transfer as direct 8-bit data stream. protocol='1' - Can use an error correction protocol to transfer GIF data interactively from the host directly to the display. dev = '0' - Screen parameter set follows dev = '1' - Printer parameter set follows width - Maximum supported display width in pixels height - Maximum supported display height in pixels color-bits - Number of bits per pixel supported. The number of supported colors is therefore 2**color-bits. color-res - Number of bits per color component supported in the hardware color palette. If color-res is '0' then no hardware palette table is available. Note that all values in the GCR are returned as ASCII decimal numbers and the message is terminated by a Carriage Return character. Graphics Interchange Format (GIF) Page 11 Appendix B - Interactive Sequences The following GCR message describes three standard EGA configurations with no printer; the GIF data stream can be processed within an error correcting protocol: #87a;1 ;0,320,200,4,0 ;0,640,200,2,2 ;0,640,350,4,2 ENTER GIF GRAPHICS MODE Two sequences are currently defined to invoke an interactive GIF decoder into action. The only difference between them is that different output media are selected. These sequences are: ESC [ > 1 g Display GIF image on screen (0x1B 0x5B 0x3E 0x31 0x67) ESC [ > 2 g Display image directly to an attached graphics printer. The image may optionally be displayed on the screen as well. (0x1B 0x5B 0x3E 0x32 0x67) Note that the 'g' character terminating each sequence is in lower case. INTERACTIVE ENVIRONMENT The assumed environment for the transmission of GIF image data from an interactive application is a full 8-bit data stream from host to micro. All 256 character codes must be transferrable. The establishing of an 8-bit data path for communications will normally be taken care of by the host application programs. It is however up to the receiving communications programs supporting GIF to be able to receive and pass on all 256 8-bit codes to the GIF decoder software. Graphics Interchange Format (GIF) Page 12 Appendix C - Image Packaging & Compression The Raster Data stream that represents the actual output image can be represented as: 7 6 5 4 3 2 1 0 +---------------+ | code size | +---------------+ ---+ |blok byte count| | +---------------+ | : : +-- Repeated as many times as necessary | data bytes | | : : | +---------------+ ---+ . . . . . . +---------------+ |0 0 0 0 0 0 0 0| zero byte count (terminates data stream) +---------------+ The conversion of the image from a series of pixel values to a transmitted or stored character stream involves several steps. In brief these steps are: 1. Establish the Code Size - Define the number of bits needed to represent the actual data. 2. Compress the Data - Compress the series of image pixels to a series of compression codes. 3. Build a Series of Bytes - Take the set of compression codes and convert to a string of 8-bit bytes. 4. Package the Bytes - Package sets of bytes into blocks preceeded by character counts and output. ESTABLISH CODE SIZE The first byte of the GIF Raster Data stream is a value indicating the minimum number of bits required to represent the set of actual pixel values. Normally this will be the same as the number of color bits. Because of some algorithmic constraints however, black & white images which have one color bit must be indicated as having a code size of 2. This code size value also implies that the compression codes must start out one bit longer. COMPRESSION The LZW algorithm converts a series of data values into a series of codes which may be raw values or a code designating a series of values. Using text characters as an analogy, the output code consists of a character or a code representing a string of characters. Graphics Interchange Format (GIF) Page 13 Appendix C - Image Packaging & Compression The LZW algorithm used in GIF matches algorithmically with the standard LZW algorithm with the following differences: 1. A special Clear code is defined which resets all compression/decompression parameters and tables to a start-up state. The value of this code is 2**. For example if the code size indicated was 4 (image was 4 bits/pixel) the Clear code value would be 16 (10000 binary). The Clear code can appear at any point in the image data stream and therefore requires the LZW algorithm to process succeeding codes as if a new data stream was starting. Encoders should output a Clear code as the first code of each image data stream. 2. An End of Information code is defined that explicitly indicates the end of the image data stream. LZW processing terminates when this code is encountered. It must be the last code output by the encoder for an image. The value of this code is +1. 3. The first available compression code value is +2. 4. The output codes are of variable length, starting at +1 bits per code, up to 12 bits per code. This defines a maximum code value of 4095 (hex FFF). Whenever the LZW code value would exceed the current code length, the code length is increased by one. The packing/unpacking of these codes must then be altered to reflect the new code length. BUILD 8-BIT BYTES Because the LZW compression used for GIF creates a series of variable length codes, of between 3 and 12 bits each, these codes must be reformed into a series of 8-bit bytes that will be the characters actually stored or transmitted. This provides additional compression of the image. The codes are formed into a stream of bits as if they were packed right to left and then picked off 8 bits at a time to be output. Assuming a character array of 8 bits per character and using 5 bit codes to be packed, an example layout would be similar to: byte n byte 5 byte 4 byte 3 byte 2 byte 1 +-.....-----+--------+--------+--------+--------+--------+ | and so on |hhhhhggg|ggfffffe|eeeedddd|dcccccbb|bbbaaaaa| +-.....-----+--------+--------+--------+--------+--------+ Note that the physical packing arrangement will change as the number of bits per compression code change but the concept remains the same. PACKAGE THE BYTES Once the bytes have been created, they are grouped into blocks for output by preceeding each block of 0 to 255 bytes with a character count byte. A block with a zero byte count terminates the Raster Data stream for a given image. These blocks are what are actually output for the Graphics Interchange Format (GIF) Page 14 Appendix C - Image Packaging & Compression GIF image. This block format has the side effect of allowing a decoding program the ability to read past the actual image data if necessary by reading block counts and then skipping over the data. Graphics Interchange Format (GIF) Page 15 Appendix D - Multiple Image Processing Since a GIF data stream can contain multiple images, it is necessary to describe processing and display of such a file. Because the image descriptor allows for placement of the image within the logical screen, it is possible to define a sequence of images that may each be a partial screen, but in total fill the entire screen. The guidelines for handling the multiple image situation are: 1. There is no pause between images. Each is processed immediately as seen by the decoder. 2. Each image explicitly overwrites any image already on the screen inside of its window. The only screen clears are at the beginning and end of the GIF image process. See discussion on the GIF terminator. giflib-6.1.3/doc/gifstandard/gif89a.css0000664000175000017500000000126015166751647016000 0ustar esresrul { list-style-type:disc; } ul ul { list-style-type:circle; } div#notes { font-style:italic; } table.invisible { border-spacing:0; } table#interlace td { text-align:center; } div.hiddenparagraph { display:none; } @media not print { a[href*="#"] { text-decoration:none; color:blue; } span.rcomp { background:#FAA; } span.gcomp { background:#8F8; } span.bcomp { background:#BBF; } h2 span { font-size:small; font-weight:normal; text-decoration:underline; } div.togglevisall span { font-weight:bold; text-decoration:underline; } } @media print { table, li { page-break-inside:avoid; } h2 span, div.togglevisall { display:none; } } giflib-6.1.3/doc/gifstandard/gif-1over64.png0000664000175000017500000000045515166751647016663 0ustar esresrPNG  IHDR,Y 0PLTEfffDDD333ݙ"""UUUwww5HIDAT(c` bPxOy ¨%7K5#t P``WBԶ,+D5@x<[6Bb ئCK:pRep#>'0p]q` \ `܇@oroq |mV0``q a.%  See below +---------------+ 5 | | Background Color Index Byte +---------------+ 6 | | Pixel Aspect Ratio Byte +---------------+ 9 = Global Color Table Flag 1 Bit Color Resolution 3 Bits Sort Flag 1 Bit Size of Global Color Table 3 Bits i) Logical Screen Width - Width, in pixels, of the Logical Screen where the images will be rendered in the displaying device. ii) Logical Screen Height - Height, in pixels, of the Logical Screen where the images will be rendered in the displaying device. iii) Global Color Table Flag - Flag indicating the presence of a Global Color Table; if the flag is set, the Global Color Table will immediately follow the Logical Screen Descriptor. This flag also selects the interpretation of the Background Color Index; if the flag is set, the value of the Background Color Index field should be used as the table index of the background color. (This field is the most significant bit of the byte.) Values : 0 - No Global Color Table follows, the Background Color Index field is meaningless. 1 - A Global Color Table will immediately follow, the Background Color Index field is meaningful. iv) Color Resolution - Number of bits per primary color available to the original image, minus 1. This value represents the size of the entire palette from which the colors in the graphic were selected, not the number of colors actually used in the graphic. For example, if the value in this field is 3, then the palette of the original image had 4 bits per primary color available to create the image. This value should be set to indicate the richness of the original palette, even if not every color from the whole palette is available on the source machine. v) Sort Flag - Indicates whether the Global Color Table is sorted. If the flag is set, the Global Color Table is sorted, in order of decreasing importance. Typically, the order would be decreasing frequency, with most frequent color first. This assists a decoder, with fewer available colors, in choosing the best subset of colors; the decoder may use an initial segment of the table to render the graphic. Values : 0 - Not ordered. 1 - Ordered by decreasing importance, most important color first. vi) Size of Global Color Table - If the Global Color Table Flag is set to 1, the value in this field is used to calculate the number of bytes contained in the Global Color Table. To determine that actual size of the color table, raise 2 to [the value of the field + 1]. Even if there is no Global Color Table specified, set this field according to the above formula so that decoders can choose the best graphics mode to display the stream in. (This field is made up of the 3 least significant bits of the byte.) vii) Background Color Index - Index into the Global Color Table for 10 the Background Color. The Background Color is the color used for those pixels on the screen that are not covered by an image. If the Global Color Table Flag is set to (zero), this field should be zero and should be ignored. viii) Pixel Aspect Ratio - Factor used to compute an approximation of the aspect ratio of the pixel in the original image. If the value of the field is not 0, this approximation of the aspect ratio is computed based on the formula: Aspect Ratio = (Pixel Aspect Ratio + 15) / 64 The Pixel Aspect Ratio is defined to be the quotient of the pixel's width over its height. The value range in this field allows specification of the widest pixel of 4:1 to the tallest pixel of 1:4 in increments of 1/64th. Values : 0 - No aspect ratio information is given. 1..255 - Value used in the computation. d. Extensions and Scope. The scope of this block is the entire Data Stream. This block cannot be modified by any extension. e. Recommendations. None. 19. Global Color Table. a. Description. This block contains a color table, which is a sequence of bytes representing red-green-blue color triplets. The Global Color Table is used by images without a Local Color Table and by Plain Text Extensions. Its presence is marked by the Global Color Table Flag being set to 1 in the Logical Screen Descriptor; if present, it immediately follows the Logical Screen Descriptor and contains a number of bytes equal to 3 x 2^(Size of Global Color Table+1). This block is OPTIONAL; at most one Global Color Table may be present per Data Stream. b. Required Version. 87a 11 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +===============+ 0 | | Red 0 Byte +- -+ 1 | | Green 0 Byte +- -+ 2 | | Blue 0 Byte +- -+ 3 | | Red 1 Byte +- -+ | | Green 1 Byte +- -+ up | | +- . . . . -+ ... to | | +- -+ | | Green 255 Byte +- -+ 767 | | Blue 255 Byte +===============+ d. Extensions and Scope. The scope of this block is the entire Data Stream. This block cannot be modified by any extension. e. Recommendation. None. 20. Image Descriptor. a. Description. Each image in the Data Stream is composed of an Image Descriptor, an optional Local Color Table, and the image data. Each image must fit within the boundaries of the Logical Screen, as defined in the Logical Screen Descriptor. The Image Descriptor contains the parameters necessary to process a table based image. The coordinates given in this block refer to coordinates within the Logical Screen, and are given in pixels. This block is a Graphic-Rendering Block, optionally preceded by one or more Control blocks such as the Graphic Control Extension, and may be optionally followed by a Local Color Table; the Image Descriptor is always followed by the image data. This block is REQUIRED for an image. Exactly one Image Descriptor must be present per image in the Data Stream. An unlimited number of images may be present per Data Stream. b. Required Version. 87a. 12 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | Image Separator Byte +---------------+ 1 | | Image Left Position Unsigned +- -+ 2 | | +---------------+ 3 | | Image Top Position Unsigned +- -+ 4 | | +---------------+ 5 | | Image Width Unsigned +- -+ 6 | | +---------------+ 7 | | Image Height Unsigned +- -+ 8 | | +---------------+ 9 | | | | | | See below +---------------+ = Local Color Table Flag 1 Bit Interlace Flag 1 Bit Sort Flag 1 Bit Reserved 2 Bits Size of Local Color Table 3 Bits i) Image Separator - Identifies the beginning of an Image Descriptor. This field contains the fixed value 0x2C. ii) Image Left Position - Column number, in pixels, of the left edge of the image, with respect to the left edge of the Logical Screen. Leftmost column of the Logical Screen is 0. iii) Image Top Position - Row number, in pixels, of the top edge of the image with respect to the top edge of the Logical Screen. Top row of the Logical Screen is 0. iv) Image Width - Width of the image in pixels. v) Image Height - Height of the image in pixels. vi) Local Color Table Flag - Indicates the presence of a Local Color Table immediately following this Image Descriptor. (This field is the most significant bit of the byte.) Values : 0 - Local Color Table is not present. Use Global Color Table if available. 1 - Local Color Table present, and to follow immediately after this Image Descriptor. 13 vii) Interlace Flag - Indicates if the image is interlaced. An image is interlaced in a four-pass interlace pattern; see Appendix E for details. Values : 0 - Image is not interlaced. 1 - Image is interlaced. viii) Sort Flag - Indicates whether the Local Color Table is sorted. If the flag is set, the Local Color Table is sorted, in order of decreasing importance. Typically, the order would be decreasing frequency, with most frequent color first. This assists a decoder, with fewer available colors, in choosing the best subset of colors; the decoder may use an initial segment of the table to render the graphic. Values : 0 - Not ordered. 1 - Ordered by decreasing importance, most important color first. ix) Size of Local Color Table - If the Local Color Table Flag is set to 1, the value in this field is used to calculate the number of bytes contained in the Local Color Table. To determine that actual size of the color table, raise 2 to the value of the field + 1. This value should be 0 if there is no Local Color Table specified. (This field is made up of the 3 least significant bits of the byte.) d. Extensions and Scope. The scope of this block is the Table-based Image Data Block that follows it. This block may be modified by the Graphic Control Extension. e. Recommendation. None. 21. Local Color Table. a. Description. This block contains a color table, which is a sequence of bytes representing red-green-blue color triplets. The Local Color Table is used by the image that immediately follows. Its presence is marked by the Local Color Table Flag being set to 1 in the Image Descriptor; if present, the Local Color Table immediately follows the Image Descriptor and contains a number of bytes equal to 3x2^(Size of Local Color Table+1). If present, this color table temporarily becomes the active color table and the following image should be processed using it. This block is OPTIONAL; at most one Local Color Table may be present per Image Descriptor and its scope is the single image associated with the Image Descriptor that precedes it. b. Required Version. 87a. 14 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +===============+ 0 | | Red 0 Byte +- -+ 1 | | Green 0 Byte +- -+ 2 | | Blue 0 Byte +- -+ 3 | | Red 1 Byte +- -+ | | Green 1 Byte +- -+ up | | +- . . . . -+ ... to | | +- -+ | | Green 255 Byte +- -+ 767 | | Blue 255 Byte +===============+ d. Extensions and Scope. The scope of this block is the Table-based Image Data Block that immediately follows it. This block cannot be modified by any extension. e. Recommendations. None. 22. Table Based Image Data. a. Description. The image data for a table based image consists of a sequence of sub-blocks, of size at most 255 bytes each, containing an index into the active color table, for each pixel in the image. Pixel indices are in order of left to right and from top to bottom. Each index must be within the range of the size of the active color table, starting at 0. The sequence of indices is encoded using the LZW Algorithm with variable-length code, as described in Appendix F b. Required Version. 87a. c. Syntax. The image data format is as follows: 7 6 5 4 3 2 1 0 Field Name Type +---------------+ | | LZW Minimum Code Size Byte +---------------+ +===============+ | | / / Image Data Data Sub-blocks | | +===============+ 15 i) LZW Minimum Code Size. This byte determines the initial number of bits used for LZW codes in the image data, as described in Appendix F. d. Extensions and Scope. This block has no scope, it contains raster data. Extensions intended to modify a Table-based image must appear before the corresponding Image Descriptor. e. Recommendations. None. 23. Graphic Control Extension. a. Description. The Graphic Control Extension contains parameters used when processing a graphic rendering block. The scope of this extension is the first graphic rendering block to follow. The extension contains only one data sub-block. This block is OPTIONAL; at most one Graphic Control Extension may precede a graphic rendering block. This is the only limit to the number of Graphic Control Extensions that may be contained in a Data Stream. b. Required Version. 89a. c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | Extension Introducer Byte +---------------+ 1 | | Graphic Control Label Byte +---------------+ +---------------+ 0 | | Block Size Byte +---------------+ 1 | | | | | See below +---------------+ 2 | | Delay Time Unsigned +- -+ 3 | | +---------------+ 4 | | Transparent Color Index Byte +---------------+ +---------------+ 0 | | Block Terminator Byte +---------------+ = Reserved 3 Bits Disposal Method 3 Bits User Input Flag 1 Bit Transparent Color Flag 1 Bit i) Extension Introducer - Identifies the beginning of an extension 16 block. This field contains the fixed value 0x21. ii) Graphic Control Label - Identifies the current block as a Graphic Control Extension. This field contains the fixed value 0xF9. iii) Block Size - Number of bytes in the block, after the Block Size field and up to but not including the Block Terminator. This field contains the fixed value 4. iv) Disposal Method - Indicates the way in which the graphic is to be treated after being displayed. Values : 0 - No disposal specified. The decoder is not required to take any action. 1 - Do not dispose. The graphic is to be left in place. 2 - Restore to background color. The area used by the graphic must be restored to the background color. 3 - Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic. 4-7 - To be defined. v) User Input Flag - Indicates whether or not user input is expected before continuing. If the flag is set, processing will continue when user input is entered. The nature of the User input is determined by the application (Carriage Return, Mouse Button Click, etc.). Values : 0 - User input is not expected. 1 - User input is expected. When a Delay Time is used and the User Input Flag is set, processing will continue when user input is received or when the delay time expires, whichever occurs first. vi) Transparency Flag - Indicates whether a transparency index is given in the Transparent Index field. (This field is the least significant bit of the byte.) Values : 0 - Transparent Index is not given. 1 - Transparent Index is given. vii) Delay Time - If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered. This field may be used in conjunction with the User Input Flag field. viii) Transparency Index - The Transparency Index is such that when encountered, the corresponding pixel of the display device is not modified and processing goes on to the next pixel. The index is present if and only if the Transparency Flag is set to 1. ix) Block Terminator - This zero-length data block marks the end of 17 the Graphic Control Extension. d. Extensions and Scope. The scope of this Extension is the graphic rendering block that follows it; it is possible for other extensions to be present between this block and its target. This block can modify the Image Descriptor Block and the Plain Text Extension. e. Recommendations. i) Disposal Method - The mode Restore To Previous is intended to be used in small sections of the graphic; the use of this mode imposes severe demands on the decoder to store the section of the graphic that needs to be saved. For this reason, this mode should be used sparingly. This mode is not intended to save an entire graphic or large areas of a graphic; when this is the case, the encoder should make every attempt to make the sections of the graphic to be restored be separate graphics in the data stream. In the case where a decoder is not capable of saving an area of a graphic marked as Restore To Previous, it is recommended that a decoder restore to the background color. ii) User Input Flag - When the flag is set, indicating that user input is expected, the decoder may sound the bell (0x07) to alert the user that input is being expected. In the absence of a specified Delay Time, the decoder should wait for user input indefinitely. It is recommended that the encoder not set the User Input Flag without a Delay Time specified. 24. Comment Extension. a. Description. The Comment Extension contains textual information which is not part of the actual graphics in the GIF Data Stream. It is suitable for including comments about the graphics, credits, descriptions or any other type of non-control and non-graphic data. The Comment Extension may be ignored by the decoder, or it may be saved for later processing; under no circumstances should a Comment Extension disrupt or interfere with the processing of the Data Stream. This block is OPTIONAL; any number of them may appear in the Data Stream. b. Required Version. 89a. 18 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | Extension Introducer Byte +---------------+ 1 | | Comment Label Byte +---------------+ +===============+ | | N | | Comment Data Data Sub-blocks | | +===============+ +---------------+ 0 | | Block Terminator Byte +---------------+ i) Extension Introducer - Identifies the beginning of an extension block. This field contains the fixed value 0x21. ii) Comment Label - Identifies the block as a Comment Extension. This field contains the fixed value 0xFE. iii) Comment Data - Sequence of sub-blocks, each of size at most 255 bytes and at least 1 byte, with the size in a byte preceding the data. The end of the sequence is marked by the Block Terminator. iv) Block Terminator - This zero-length data block marks the end of the Comment Extension. d. Extensions and Scope. This block does not have scope. This block cannot be modified by any extension. e. Recommendations. i) Data - This block is intended for humans. It should contain text using the 7-bit ASCII character set. This block should not be used to store control information for custom processing. ii) Position - This block may appear at any point in the Data Stream at which a block can begin; however, it is recommended that Comment Extensions do not interfere with Control or Data blocks; they should be located at the beginning or at the end of the Data Stream to the extent possible. 25. Plain Text Extension. a. Description. The Plain Text Extension contains textual data and the parameters necessary to render that data as a graphic, in a simple form. The textual data will be encoded with the 7-bit printable ASCII characters. Text data are rendered using a grid of character cells 19 defined by the parameters in the block fields. Each character is rendered in an individual cell. The textual data in this block is to be rendered as mono-spaced characters, one character per cell, with a best fitting font and size. For further information, see the section on Recommendations below. The data characters are taken sequentially from the data portion of the block and rendered within a cell, starting with the upper left cell in the grid and proceeding from left to right and from top to bottom. Text data is rendered until the end of data is reached or the character grid is filled. The Character Grid contains an integral number of cells; in the case that the cell dimensions do not allow for an integral number, fractional cells must be discarded; an encoder must be careful to specify the grid dimensions accurately so that this does not happen. This block requires a Global Color Table to be available; the colors used by this block reference the Global Color Table in the Stream if there is one, or the Global Color Table from a previous Stream, if one was saved. This block is a graphic rendering block, therefore it may be modified by a Graphic Control Extension. This block is OPTIONAL; any number of them may appear in the Data Stream. b. Required Version. 89a. 20 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | Extension Introducer Byte +---------------+ 1 | | Plain Text Label Byte +---------------+ +---------------+ 0 | | Block Size Byte +---------------+ 1 | | Text Grid Left Position Unsigned +- -+ 2 | | +---------------+ 3 | | Text Grid Top Position Unsigned +- -+ 4 | | +---------------+ 5 | | Text Grid Width Unsigned +- -+ 6 | | +---------------+ 7 | | Text Grid Height Unsigned +- -+ 8 | | +---------------+ 9 | | Character Cell Width Byte +---------------+ 10 | | Character Cell Height Byte +---------------+ 11 | | Text Foreground Color Index Byte +---------------+ 12 | | Text Background Color Index Byte +---------------+ +===============+ | | N | | Plain Text Data Data Sub-blocks | | +===============+ +---------------+ 0 | | Block Terminator Byte +---------------+ i) Extension Introducer - Identifies the beginning of an extension block. This field contains the fixed value 0x21. ii) Plain Text Label - Identifies the current block as a Plain Text Extension. This field contains the fixed value 0x01. iii) Block Size - Number of bytes in the extension, after the Block Size field and up to but not including the beginning of the data portion. This field contains the fixed value 12. 21 iv) Text Grid Left Position - Column number, in pixels, of the left edge of the text grid, with respect to the left edge of the Logical Screen. v) Text Grid Top Position - Row number, in pixels, of the top edge of the text grid, with respect to the top edge of the Logical Screen. vi) Image Grid Width - Width of the text grid in pixels. vii) Image Grid Height - Height of the text grid in pixels. viii) Character Cell Width - Width, in pixels, of each cell in the grid. ix) Character Cell Height - Height, in pixels, of each cell in the grid. x) Text Foreground Color Index - Index into the Global Color Table to be used to render the text foreground. xi) Text Background Color Index - Index into the Global Color Table to be used to render the text background. xii) Plain Text Data - Sequence of sub-blocks, each of size at most 255 bytes and at least 1 byte, with the size in a byte preceding the data. The end of the sequence is marked by the Block Terminator. xiii) Block Terminator - This zero-length data block marks the end of the Plain Text Data Blocks. d. Extensions and Scope. The scope of this block is the Plain Text Data Block contained in it. This block may be modified by the Graphic Control Extension. e. Recommendations. The data in the Plain Text Extension is assumed to be preformatted. The selection of font and size is left to the discretion of the decoder. If characters less than 0x20 or greater than 0xf7 are encountered, it is recommended that the decoder display a Space character (0x20). The encoder should use grid and cell dimensions such that an integral number of cells fit in the grid both horizontally as well as vertically. For broadest compatibility, character cell dimensions should be around 8x8 or 8x16 (width x height); consider an image for unusual sized text. 26. Application Extension. a. Description. The Application Extension contains application-specific information; it conforms with the extension block syntax, as described below, and its block label is 0xFF. b. Required Version. 89a. 22 c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | Extension Introducer Byte +---------------+ 1 | | Extension Label Byte +---------------+ +---------------+ 0 | | Block Size Byte +---------------+ 1 | | +- -+ 2 | | +- -+ 3 | | Application Identifier 8 Bytes +- -+ 4 | | +- -+ 5 | | +- -+ 6 | | +- -+ 7 | | +- -+ 8 | | +---------------+ 9 | | +- -+ 10 | | Appl. Authentication Code 3 Bytes +- -+ 11 | | +---------------+ +===============+ | | | | Application Data Data Sub-blocks | | | | +===============+ +---------------+ 0 | | Block Terminator Byte +---------------+ i) Extension Introducer - Defines this block as an extension. This field contains the fixed value 0x21. ii) Application Extension Label - Identifies the block as an Application Extension. This field contains the fixed value 0xFF. iii) Block Size - Number of bytes in this extension block, following the Block Size field, up to but not including the beginning of the Application Data. This field contains the fixed value 11. 23 iv) Application Identifier - Sequence of eight printable ASCII characters used to identify the application owning the Application Extension. v) Application Authentication Code - Sequence of three bytes used to authenticate the Application Identifier. An Application program may use an algorithm to compute a binary code that uniquely identifies it as the application owning the Application Extension. d. Extensions and Scope. This block does not have scope. This block cannot be modified by any extension. e. Recommendation. None. 27. Trailer. a. Description. This block is a single-field block indicating the end of the GIF Data Stream. It contains the fixed value 0x3B. b. Required Version. 87a. c. Syntax. 7 6 5 4 3 2 1 0 Field Name Type +---------------+ 0 | | GIF Trailer Byte +---------------+ d. Extensions and Scope. This block does not have scope, it terminates the GIF Data Stream. This block may not be modified by any extension. e. Recommendations. None. 24 Appendix A. Quick Reference Table. Block Name Required Label Ext. Vers. Application Extension Opt. (*) 0xFF (255) yes 89a Comment Extension Opt. (*) 0xFE (254) yes 89a Global Color Table Opt. (1) none no 87a Graphic Control Extension Opt. (*) 0xF9 (249) yes 89a Header Req. (1) none no N/A Image Descriptor Opt. (*) 0x2C (044) no 87a (89a) Local Color Table Opt. (*) none no 87a Logical Screen Descriptor Req. (1) none no 87a (89a) Plain Text Extension Opt. (*) 0x01 (001) yes 89a Trailer Req. (1) 0x3B (059) no 87a Unlabeled Blocks Header Req. (1) none no N/A Logical Screen Descriptor Req. (1) none no 87a (89a) Global Color Table Opt. (1) none no 87a Local Color Table Opt. (*) none no 87a Graphic-Rendering Blocks Plain Text Extension Opt. (*) 0x01 (001) yes 89a Image Descriptor Opt. (*) 0x2C (044) no 87a (89a) Control Blocks Graphic Control Extension Opt. (*) 0xF9 (249) yes 89a Special Purpose Blocks Trailer Req. (1) 0x3B (059) no 87a Comment Extension Opt. (*) 0xFE (254) yes 89a Application Extension Opt. (*) 0xFF (255) yes 89a legend: (1) if present, at most one occurrence (*) zero or more occurrences (+) one or more occurrences Notes : The Header is not subject to Version Numbers. (89a) The Logical Screen Descriptor and the Image Descriptor retained their syntax from version 87a to version 89a, but some fields reserved under version 87a are used under version 89a. 25 Appendix B. GIF Grammar. A Grammar is a form of notation to represent the sequence in which certain objects form larger objects. A grammar is also used to represent the number of objects that can occur at a given position. The grammar given here represents the sequence of blocks that form the GIF Data Stream. A grammar is given by listing its rules. Each rule consists of the left-hand side, followed by some form of equals sign, followed by the right-hand side. In a rule, the right-hand side describes how the left-hand side is defined. The right-hand side consists of a sequence of entities, with the possible presence of special symbols. The following legend defines the symbols used in this grammar for GIF. Legend: <> grammar word ::= defines symbol * zero or more occurrences + one or more occurrences | alternate element [] optional element Example: ::= Header * Trailer This rule defines the entity as follows. It must begin with a Header. The Header is followed by an entity called Logical Screen, which is defined below by another rule. The Logical Screen is followed by the entity Data, which is also defined below by another rule. Finally, the entity Data is followed by the Trailer. Since there is no rule defining the Header or the Trailer, this means that these blocks are defined in the document. The entity Data has a special symbol (*) following it which means that, at this position, the entity Data may be repeated any number of times, including 0 times. For further reading on this subject, refer to a standard text on Programming Languages. The Grammar. ::= Header * Trailer ::= Logical Screen Descriptor [Global Color Table] ::= | ::= [Graphic Control Extension] ::= | Plain Text Extension ::= Image Descriptor [Local Color Table] Image Data ::= Application Extension | Comment Extension 26 NOTE : The grammar indicates that it is possible for a GIF Data Stream to contain the Header, the Logical Screen Descriptor, a Global Color Table and the GIF Trailer. This special case is used to load a GIF decoder with a Global Color Table, in preparation for subsequent Data Streams without color tables at all. 27 Appendix C. Glossary. Active Color Table - Color table used to render the next graphic. If the next graphic is an image which has a Local Color Table associated with it, the active color table becomes the Local Color Table associated with that image. If the next graphic is an image without a Local Color Table, or a Plain Text Extension, the active color table is the Global Color Table associated with the Data Stream, if there is one; if there is no Global Color Table in the Data Stream, the active color table is a color table saved from a previous Data Stream, or one supplied by the decoder. Block - Collection of bytes forming a protocol unit. In general, the term includes labeled and unlabeled blocks, as well as Extensions. Data Stream - The GIF Data Stream is composed of blocks and sub-blocks representing images and graphics, together with control information to render them on a display device. All control and data blocks in the Data Stream must follow the Header and must precede the Trailer. Decoder - A program capable of processing a GIF Data Stream to render the images and graphics contained in it. Encoder - A program capable of capturing and formatting image and graphic raster data, following the definitions of the Graphics Interchange Format. Extension - A protocol block labeled by the Extension Introducer 0x21. Extension Introducer - Label (0x21) defining an Extension. Graphic - Data which can be rendered on the screen by virtue of some algorithm. The term graphic is more general than the term image; in addition to images, the term graphic also includes data such as text, which is rendered using character bit-maps. Image - Data representing a picture or a drawing; an image is represented by an array of pixels called the raster of the image. Raster - Array of pixel values representing an image. 28 Appendix D. Conventions. Animation - The Graphics Interchange Format is not intended as a platform for animation, even though it can be done in a limited way. Byte Ordering - Unless otherwise stated, multi-byte numeric fields are ordered with the Least Significant Byte first. Color Indices - Color indices always refer to the active color table, either the Global Color Table or the Local Color Table. Color Order - Unless otherwise stated, all triple-component RGB color values are specified in Red-Green-Blue order. Color Tables - Both color tables, the Global and the Local, are optional; if present, the Global Color Table is to be used with every image in the Data Stream for which a Local Color Table is not given; if present, a Local Color Table overrides the Global Color Table. However, if neither color table is present, the application program is free to use an arbitrary color table. If the graphics in several Data Streams are related and all use the same color table, an encoder could place the color table as the Global Color Table in the first Data Stream and leave subsequent Data Streams without a Global Color Table or any Local Color Tables; in this way, the overhead for the table is eliminated. It is recommended that the decoder save the previous Global Color Table to be used with the Data Stream that follows, in case it does not contain either a Global Color Table or any Local Color Tables. In general, this allows the application program to use past color tables, significantly reducing transmission overhead. Extension Blocks - Extensions are defined using the Extension Introducer code to mark the beginning of the block, followed by a block label, identifying the type of extension. Extension Codes are numbers in the range from 0x00 to 0xFF, inclusive. Special purpose extensions are transparent to the decoder and may be omitted when transmitting the Data Stream on-line. The GIF capabilities dialogue makes the provision for the receiver to request the transmission of all blocks; the default state in this regard is no transmission of Special purpose blocks. Reserved Fields - All Reserved Fields are expected to have each bit set to zero (off). 29 Appendix E. Interlaced Images. The rows of an Interlaced images are arranged in the following order: Group 1 : Every 8th. row, starting with row 0. (Pass 1) Group 2 : Every 8th. row, starting with row 4. (Pass 2) Group 3 : Every 4th. row, starting with row 2. (Pass 3) Group 4 : Every 2nd. row, starting with row 1. (Pass 4) The Following example illustrates how the rows of an interlaced image are ordered. Row Number Interlace Pass 0 ----------------------------------------- 1 1 ----------------------------------------- 4 2 ----------------------------------------- 3 3 ----------------------------------------- 4 4 ----------------------------------------- 2 5 ----------------------------------------- 4 6 ----------------------------------------- 3 7 ----------------------------------------- 4 8 ----------------------------------------- 1 9 ----------------------------------------- 4 10 ----------------------------------------- 3 11 ----------------------------------------- 4 12 ----------------------------------------- 2 13 ----------------------------------------- 4 14 ----------------------------------------- 3 15 ----------------------------------------- 4 16 ----------------------------------------- 1 17 ----------------------------------------- 4 18 ----------------------------------------- 3 19 ----------------------------------------- 4 30 Appendix F. Variable-Length-Code LZW Compression. The Variable-Length-Code LZW Compression is a variation of the Lempel-Ziv Compression algorithm in which variable-length codes are used to replace patterns detected in the original data. The algorithm uses a code or translation table constructed from the patterns encountered in the original data; each new pattern is entered into the table and its index is used to replace it in the compressed stream. The compressor takes the data from the input stream and builds a code or translation table with the patterns as it encounters them; each new pattern is entered into the code table and its index is added to the output stream; when a pattern is encountered which had been detected since the last code table refresh, its index from the code table is put on the output stream, thus achieving the data compression. The expander takes input from the compressed data stream and builds the code or translation table from it; as the compressed data stream is processed, codes are used to index into the code table and the corresponding data is put on the decompressed output stream, thus achieving data decompression. The details of the algorithm are explained below. The Variable-Length-Code aspect of the algorithm is based on an initial code size (LZW-initial code size), which specifies the initial number of bits used for the compression codes. When the number of patterns detected by the compressor in the input stream exceeds the number of patterns encodable with the current number of bits, the number of bits per LZW code is increased by one. The Raster Data stream that represents the actual output image can be represented as: 7 6 5 4 3 2 1 0 +---------------+ | LZW code size | +---------------+ +---------------+ ----+ | block size | | +---------------+ | | | +-- Repeated as many | data bytes | | times as necessary. | | | +---------------+ ----+ . . . . . . ------- The code that terminates the LZW compressed data must appear before Block Terminator. +---------------+ |0 0 0 0 0 0 0 0| Block Terminator +---------------+ The conversion of the image from a series of pixel values to a transmitted or stored character stream involves several steps. In brief these steps are: 1. Establish the Code Size - Define the number of bits needed to represent the actual data. 2. Compress the Data - Compress the series of image pixels to a series of 31 compression codes. 3. Build a Series of Bytes - Take the set of compression codes and convert to a string of 8-bit bytes. 4. Package the Bytes - Package sets of bytes into blocks preceded by character counts and output. ESTABLISH CODE SIZE The first byte of the Compressed Data stream is a value indicating the minimum number of bits required to represent the set of actual pixel values. Normally this will be the same as the number of color bits. Because of some algorithmic constraints however, black & white images which have one color bit must be indicated as having a code size of 2. This code size value also implies that the compression codes must start out one bit longer. COMPRESSION The LZW algorithm converts a series of data values into a series of codes which may be raw values or a code designating a series of values. Using text characters as an analogy, the output code consists of a character or a code representing a string of characters. The LZW algorithm used in GIF matches algorithmically with the standard LZW algorithm with the following differences: 1. A special Clear code is defined which resets all compression/decompression parameters and tables to a start-up state. The value of this code is 2**. For example if the code size indicated was 4 (image was 4 bits/pixel) the Clear code value would be 16 (10000 binary). The Clear code can appear at any point in the image data stream and therefore requires the LZW algorithm to process succeeding codes as if a new data stream was starting. Encoders should output a Clear code as the first code of each image data stream. 2. An End of Information code is defined that explicitly indicates the end of the image data stream. LZW processing terminates when this code is encountered. It must be the last code output by the encoder for an image. The value of this code is +1. 3. The first available compression code value is +2. 4. The output codes are of variable length, starting at +1 bits per code, up to 12 bits per code. This defines a maximum code value of 4095 (0xFFF). Whenever the LZW code value would exceed the current code length, the code length is increased by one. The packing/unpacking of these codes must then be altered to reflect the new code length. BUILD 8-BIT BYTES Because the LZW compression used for GIF creates a series of variable length codes, of between 3 and 12 bits each, these codes must be reformed into a series of 8-bit bytes that will be the characters actually stored or transmitted. This provides additional compression of the image. The codes are formed into a stream of bits as if they were packed right to left and then 32 picked off 8 bits at a time to be output. Assuming a character array of 8 bits per character and using 5 bit codes to be packed, an example layout would be similar to: +---------------+ 0 | | bbbaaaaa +---------------+ 1 | | dcccccbb +---------------+ 2 | | eeeedddd +---------------+ 3 | | ggfffffe +---------------+ 4 | | hhhhhggg +---------------+ . . . +---------------+ N | | +---------------+ Note that the physical packing arrangement will change as the number of bits per compression code change but the concept remains the same. PACKAGE THE BYTES Once the bytes have been created, they are grouped into blocks for output by preceding each block of 0 to 255 bytes with a character count byte. A block with a zero byte count terminates the Raster Data stream for a given image. These blocks are what are actually output for the GIF image. This block format has the side effect of allowing a decoding program the ability to read past the actual image data if necessary by reading block counts and then skipping over the data. FURTHER READING [1] Ziv, J. and Lempel, A. : "A Universal Algorithm for Sequential Data Compression", IEEE Transactions on Information Theory, May 1977. [2] Welch, T. : "A Technique for High-Performance Data Compression", Computer, June 1984. [3] Nelson, M.R. : "LZW Data Compression", Dr. Dobb's Journal, October 1989. 33 Appendix G. On-line Capabilities Dialogue. NOTE : This section is currently (10 July 1990) under revision; the information provided here should be used as general guidelines. Code written based on this information should be designed in a flexible way to accommodate any changes resulting from the revisions. The following sequences are defined for use in mediating control between a GIF sender and GIF receiver over an interactive communications line. These sequences do not apply to applications that involve downloading of static GIF files and are not considered part of a GIF file. GIF CAPABILITIES ENQUIRY The GIF Capabilities Enquiry sequence is issued from a host and requests an interactive GIF decoder to return a response message that defines the graphics parameters for the decoder. This involves returning information about available screen sizes, number of bits/color supported and the amount of color detail supported. The escape sequence for the GIF Capabilities Enquiry is defined as: ESC[>0g 0x1B 0x5B 0x3E 0x30 0x67 GIF CAPABILITIES RESPONSE The GIF Capabilities Response message is returned by an interactive GIF decoder and defines the decoder's display capabilities for all graphics modes that are supported by the software. Note that this can also include graphics printers as well as a monitor screen. The general format of this message is: #version;protocol{;dev, width, height, color-bits, color-res}... '#' GIF Capabilities Response identifier character. version GIF format version number; initially '87a'. protocol='0' No end-to-end protocol supported by decoder Transfer as direct 8-bit data stream. protocol='1' Can use CIS B+ error correction protocol to transfer GIF data interactively from the host directly to the display. dev = '0' Screen parameter set follows. dev = '1' Printer parameter set follows. width Maximum supported display width in pixels. height Maximum supported display height in pixels. color-bits Number of bits per pixel supported. The number of supported colors is therefore 2**color-bits. color-res Number of bits per color component supported in the hardware color palette. If color-res is '0' then no hardware palette table is available. Note that all values in the GIF Capabilities Response are returned as ASCII decimal numbers and the message is terminated by a Carriage Return character. The following GIF Capabilities Response message describes three standard IBM PC Enhanced Graphics Adapter configurations with no printer; the GIF data stream 34 can be processed within an error correcting protocol: #87a;1;0,320,200,4,0;0,640,200,2,2;0,640,350,4,2 ENTER GIF GRAPHICS MODE Two sequences are currently defined to invoke an interactive GIF decoder into action. The only difference between them is that different output media are selected. These sequences are: ESC[>1g Display GIF image on screen 0x1B 0x5B 0x3E 0x31 0x67 ESC[>2g Display image directly to an attached graphics printer. The image may optionally be displayed on the screen as well. 0x1B 0x5B 0x3E 0x32 0x67 Note that the 'g' character terminating each sequence is in lowercase. INTERACTIVE ENVIRONMENT The assumed environment for the transmission of GIF image data from an interactive application is a full 8-bit data stream from host to micro. All 256 character codes must be transferrable. The establishing of an 8-bit data path for communications will normally be taken care of by the host application programs. It is however up to the receiving communications programs supporting GIF to be able to receive and pass on all 256 8-bit codes to the GIF decoder software. giflib-6.1.3/doc/gifbg.xml0000664000175000017500000001025615166751647013516 0ustar esresr 2 May 2012 gifbg 1 GIFLIB GIFLIB Documentation gifbg generate a test-pattern GIF gifbg -v -d dir -l levels -c R G B -m min -o max -s w h -h Description A program to generate a single-color test pattern GIF with gradually changing intensity in any of the basic 8 directions. The gifbg program reads no input, and will dump the created GIF file to stdout. Options -v Verbose mode (show progress). Enables printout of running scan lines. -d dir Select direction the intensity of the background should increase. Direction can be one of the 8 principal directions: "T" for Top "TR" for Top Right "R" for Right "BR" for Bottom Right "B" for Bottom "BL" for Bottom Left "L" for left "TL" for Top Left The compass directions may be use as synonyms for the above directions, so for example "NE" is equal to "TR". Direction is case insensitive. The default direction is Top (North). -l levels Numeric, number of levels the color will be scaled to. Default is 16. -c R G B What to use as the primary background color to scale. This color is scaled between the minimum intensity (min) and maximum intensity (max) from one end of the screen to the other as defined by dir. See below (-m & -M) for min & max. Default is Blue (0, 0, 255). -m min Minimum intensity (in percent) to scale color. Default 10% [-M max Maximum intensity (in percent) to scale color. Default 100% -s W H Size of image to create. Default 640 by 350. -h Print one line of command line help, similar to Usage above. If min == max = 100 (%) and levels == 2 then boolean mask image of specified size will be created - all foreground. Author Gershon Elber. giflib-6.1.3/doc/giflib.html0000664000175000017500000000367215166751647014044 0ustar esresr giflib

Name

giflib — GIFLIB utilities

Description

GIFLIB is a linkable service library and a set of utilities for processing images encoded using GIF (Graphics Interchange Format).

These utilities are not intended to compete with or replace multi-format graphics toolkits like ImageMagick or the Python Imaging Library, or graphics editors such as the GIMP. Find one of those, or an equivalent, if you need to crop, scale, rotate, toggle interlacing, or perform other conventional image transformations. Rather, these are intended to facilitate GIF-specific operations which multi-format tools may not adequately support.

API documentation for the service library is best viewed through a browser at the project website: http://sourceforge.net/projects/giflib/?source=directory.

See Also

gifbuild(1), giffix(1), giftext(1), giftool(1), gifclrmap(1).

Authors

Gershon Elber, Eric S. Raymond, Toshio Kuratomi.

giflib-6.1.3/doc/gifecho.10000664000175000017500000000631215166751647013402 0ustar esresr'\" t .\" Title: gifecho .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFECHO" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifecho \- generate a GIF from ASCII text .SH "SYNOPSIS" .HP \w'\fBgifecho\fR\ 'u \fBgifecho\fR [\-v] [\-s\ \fIcolormap\-size\fR] [\-f\ \fIforeground\fR] [\-c\ \fIR\fR\ \fIG\fR\ \fIB\fR] [\-t\ \fItext\fR] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program to generate GIF images out of regular text\&. Text can be one line or multi\-line, and is converted using 8 by 8 fixed font\&. .PP This program reads stdin if no text is provided on the command line (\-t), and will dump the created GIF file to stdout\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-s colormap\-size .RS 4 Explicitly defines the size of the color map of the resulting gif image\&. Usually the image will be bicolor with fg as color 1, unless [\-f] is explicitly given in case the color map size will be big enough to hold it\&. However it is sometimes convenient to set the color map size to certain size while the fg color is small mainly so this image may be merged with another (images must match color map size)\&. .RE .PP \-f foreground .RS 4 Select foreground index (background is always 0)\&. By default it is one and therefore the image result is bicolored\&. if FG is set to n then color map will be created with 2^k entries where 2^k > n for minimum k, assuming k <= 8\&. This color map will be all zeros except this foreground index\&. This option is useful if this text image should be integrated into other image colormap using their colors\&. .RE .PP \-c R G B .RS 4 The color to use as the foreground color\&. White by default\&. .RE .PP \-t text .RS 4 One line of text can be provided on the command line\&. Note you must encapsulate the Text within quotes if it has spaces (The quotes themselves are not treated as part of the text)\&. If no \-t option is provided, stdin is read until end of file\&. .RE .PP \-h .RS 4 Print one line command line help, similar to Usage above\&. .RE .SH "NOTES" .PP There is a hardcoded limit of 100 the number of lines\&. .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/gifbg.html0000664000175000017500000000734215166751647013664 0ustar esresr gifbg

Name

gifbg — generate a test-pattern GIF

Synopsis

gifbg [-v] [-d dir] [-l levels] [-c R G B] [-m min] [-o max] [-s w h] [-h]

Description

A program to generate a single-color test pattern GIF with gradually changing intensity in any of the basic 8 directions.

The gifbg program reads no input, and will dump the created GIF file to stdout.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-d dir

Select direction the intensity of the background should increase. Direction can be one of the 8 principal directions:

"T"

for Top

"TR"

for Top Right

"R"

for Right

"BR"

for Bottom Right

"B"

for Bottom

"BL"

for Bottom Left

"L"

for left

"TL"

for Top Left

The compass directions may be use as synonyms for the above directions, so for example "NE" is equal to "TR".

Direction is case insensitive. The default direction is Top (North).

-l levels

Numeric, number of levels the color will be scaled to. Default is 16.

-c R G B

What to use as the primary background color to scale. This color is scaled between the minimum intensity (min) and maximum intensity (max) from one end of the screen to the other as defined by dir. See below (-m & -M) for min & max. Default is Blue (0, 0, 255).

-m min

Minimum intensity (in percent) to scale color. Default 10%

[-M max

Maximum intensity (in percent) to scale color. Default 100%

-s W H

Size of image to create. Default 640 by 350.

-h

Print one line of command line help, similar to Usage above.

If min == max = 100 (%) and levels == 2 then boolean mask image of specified size will be created - all foreground.

Author

Gershon Elber.

giflib-6.1.3/doc/gif_lib.html0000664000175000017500000014251615166751647014204 0ustar esresr The GIFLIB Library

The GIFLIB Library

Eric Steven Raymond


Introduction

The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated.

This document explains the GIF library code in directory `lib'. The code is collected into a service library which is used in all the utilities in `util'. It can be used in any application needs to read/write the GIF file format. This document does not explain the GIF file format and assumes you know it, at least to the level of the GIF file structure.

Credit and Blame

Gershon wrote: "This library was written because I couldn't find anything similar and I wanted one. I was inspired by the RLE Utah tool kit, which I hoped to port to an IBM PC, but found it to be too machine specific, and its compression ratio too low. I compromised on the GIF format, but I am not sure how long 8 bits per pixel will be enough."

During his first spell of maintainership between 1989 and 1994, Eric S. Raymond (aka "ESR") ported the code to Unix, wrote the high-level DGifSlurp()/EGifSpew() interface, rationalized the internal data structures, and did a lot of general cleanup and refactoring to improve the code quality.

Between 1994 and 2012 Toshio Kuratomi fixed various tool bugs, build-recipe problems and rare segfaults. He partially untangled the somewhat misdesigned extension-block handling in earlier versions. The core code was very stable during this period.

During his second spell of maintainership, ESR fixed the extension API, made the library re-entrant and thread-safe, wrote a regression-test suite, greatly improved the documentation, and discarded a lot of obsolete code.

The GIF descriptor

When a GIF file is opened, a GIF file descriptor is created which is a pointer to GifFileType structure as follows:

typedef struct GifFileType {
    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;

This structure was copied from gif_lib.h - the header file for the GIF library. Any application program that uses the libgif.a library should include it. Members beginning with S refer to the GIF screen; others hold properties of the current image (a GIF file may have more than one image) or point to allocated store used by various routines.

The user almost never writes into this structure (exception: it may occasionally be useful to alter things in the SavedImages array and Trailing member), but can read any of these items at any time it is valid (Image information is invalid until the first image has been read; read; SavedImages information is valid only after a DGifSlurp() call).

As the library needs to keep its own internal data, a Private pointer to hidden data is included. Applications should ignore this.

The library allocates its own memory dynamically, on opening of files, and releases that once closed. The user is never required to allocate any memory for any of the functions of this library, and is almost never required to free them directly. The "almost" in the latter clause is because one manual free() call may be required on a failed file close; see the documentation of DGifClose() and EGifClose() for details.

Here is a module summary:

egif_lib.c

Encoding routines, all prefixed with E.

dgif_lib.c

Decoding routines, all prefixed with D.

gifalloc.c

Routines for colormap handling and GIF record allocation.

gif_font.c

The 8x8 font table for the GIF utility font.

The library includes a sixth file of hash-function code which is accessed internally only.

Most of the routines return GIF_ERROR (see gif_lib.h) if something went wrong, GIF_OK otherwise. After an error return, all routines that take a pointer-to-GifFileType argument set the Error member with a code that can be interpreted into an explanatory string with the function GifErrorString() in gif_err.c. (The exception to this is the DGifClose() and EGifClose() routines, which deallocate that structure and must therefore return any error code through a pointer argument.)

Decoding (dgif_lib.c)

The following functions are used to set up input from a GIF:

GifFileType *DGifOpenFileName(char *GifFileName, int *ErrorCode)

Open a new GIF file (in binary mode, if under Windows) using the given GifFileName, and read its Screen information.

If any error occurs, NULL is returned and ErrorCode is set (if non-NULL).

GifFileType *DGifOpenFileHandle(int FileHandle, int *ErrorCode)

Open a new GIF file using the given FileHandle, and read its Screen information.

If any error occurs, NULL is returned and ErrorCode is set (if non-NULL).

Once you have acquired a handle on a GIF, the high-level function

int DGifSlurp(GifFileType)

reads the rest of a complete (possibly multi-image) GIF file from the indicated file handle into in-core allocated structures. It returns GIF_OK on success, GIF_ERROR on failure; on failure, the Error member will be set.

Once you have done this, all image, raster, and extension-block data in the GIF is accessible in the SavedImages member (see the structures in gif_lib.h). When you have modified the image to taste, write it out with EGifSpew().

One detail that may not be clear from just looking at the structures is how extension blocks and sub-blocks are stored. Each ExtensionBlock structure represents an extension data block. Those with a zero function code represent continuation data blocks attached to previous blocks with nonzero function codes.

You can read from a GIF file through a function hook. Initialize with

GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *ErrorCode)

and see the library header file for the type of InputFunc.

There is also a set of deprecated functions for sequential I/O, described in a later section.

Encoding (egif_lib.c)

The high-level function

int EGifSpew(GifFileType *GifFile, int *ErrorCode)

writes a complete (possibly multi-image) GIF file to the indicated file handle from in-core allocated structures created by a previous DGifSlurp() or equivalent operations. Its argument is a GIF file descriptor, which implicitly points to storage previously allocated by DGifSlurp().

If ErrorCode is non-NULL, it returns a GIFLIB error code on failure; otherwise it may be NULL. The function returns GIF_OK or GIF_ERROR.

The file is written with a GIF87 stamp unless it contains one of the four special extension blocks defined in GIF89, in which case it is written with a GIF89 stamp.

EGifSpew() finishes by closing the GIF (writing a termination record to it) and deallocating the associated storage.

You can write to a GIF file through a function hook. Initialize with

GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *ErrorCode)

and see the library header file for the type of OutputFunc.

There is also a set of deprecated functions for sequential I/O, described in a later section.

Color map handling and allocation routines

ColorMapObject *GifMakeMapObject(int ColorCount, GifColorType *ColorMap)

Allocate storage for a color map object with the given number of RGB triplet slots. If the second argument is non-NULL, initialize the color table portion of the new map from it. Returns NULL if memory is exhausted or if the size is not a power of 2 <= 256.

void GifFreeMapObject(ColorMapObject *Object)

Free the storage occupied by a ColorMapObject that is no longer needed.

ColorMapObject *GifUnionColorMap(
        ColorMapObject *ColorIn1, ColorMapObject *ColorIn2,
        GifPixelType ColorTransIn2[])

Create the union of two given color maps and return it. If the result won't fit into 256 colors, NULL is returned, the allocated union otherwise. ColorIn1 is copied as it to ColorUnion, while colors from ColorIn2 are copied if and only if they didn't exist before. ColorTransIn2 maps the old ColorIn2 into ColorUnion color map table.

SavedImage *GifAttachImage(GifFileType *GifFile)

Add an image block to the SavedImages array. The image block is initially zeroed out. This image block will be seen by any following EGifSpew() calls.

Graphics control extension handling

GIF89 added a graphics control extension block, but versions of GIFLIB before 5.0 weren't much help in reading or modifying them. This lack has been remedied with the following structure and functions:

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;

int DGifSavedExtensionToGCB(GifFileType *GifFile, 
			    int ImageIndex, 
			    GraphicsControlBlock *GCB);
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, 
			    GifFileType *GifFile, 
			    int ImageIndex);

With these functions you can extract the data from a graphics control extension associated with a saved image into a GraphicsControlBlock, modify it, and write it back out. Note that if the specified saved image doesn't have a graphics control extension, DGifSavedExtensionToGCB() will fill the GCB with default values and return GIF_ERROR (which can be ignored); EGifGCBToSavedExtension() will create a new leading extension block.

Error Handling (gif_err.c)

int GifErrorString(int ErrorCode)

Returns a string describing the specified GIFLIB error code. Return NULL if the argument is not a valid error code.

The GIF Utility Font

The 8x8 utility font used in the (obsolete, no longer installed) gifecho and gifcolor lives in the library module gif_font.c, in a table called GifAsciiTable. The library header file includes suitable externs and defines.

The GIF utility font support includes entry points for drawing legends on in-core images, drawing boxes and rectangles, and boxing text. These entry points are as follows:

void GifDrawText8x8(
        SavedImage *Image,
        const int x, const int y,
        const char *legend,
        const int color)

Draw text using the 8x8 utility font on the saved image. Upper left corner of the text is at image pixel (x, y). Use the specified color index.

void GifDrawBox(SavedImage *Image,
        const int x, const int y,
        const int w, const int h,
        const int color)

Draw a box on the saved image. Upper left corner of the box is at image pixels (x, y), width is w, height is h. Use the specified color index.

void GifDrawRectangle(SavedImage *Image,
        const int x, const int y,
        const int w, const int h,
        const int color)

Draw a (filled) rectangle on the saved image. Upper left corner of the box is at image pixels (x, y), width is w, height is h. Use the specified color index.

void GifDrawBoxedText8x8(SavedImage *Image,
        const int x, const int y,
        const char *legend,
        const int border,
        const int bg, const int fg)

Draw text on a filled rectangle. The rectangle will be sized to fit the text, with upper left hand corner at (x, y) on the saved image. The `border' argument specifies a pixel margin around the text. The `bg' argument is the color table index to fill the rectangle with; `fg' is the color table index to draw the text with.

This function interprets some characters in the legend string specially. A tab (\t) is interpreted as a command to center the following text in the box. A carriage return (\r) is interpreted as a request for a line break.

Error codes

Errors as reported from the GIFLIB library are divided to two major categories: the encoder (errors prefixed by E_GIF_ERR), and the decoder (errors prefixed by D_GIF_ERR). This document explains them briefly.

Encoding errors

E_GIF_ERR_OPEN_FAILED

Message printed using PrintGifError: "Failed to open given file" IO error result when attempt to open the given GIF file.

E_GIF_ERR_WRITE_FAILED

Message printed using PrintGifError: "Failed to Write to given file" IO error result when attempt to write to the given GIF file.

E_GIF_ERR_HAS_SCRN_DSCR

Message printed using PrintGifError: "Screen Descriptor already been set" Attempt to write second screen descriptor to same GIF file. GIF file should have exactly one screen descriptor which should be set directly after the file is opened.

E_GIF_ERR_HAS_IMAG_DSCR

Message printed using PrintGifError: "Image Descriptor is still active" Image descriptor should be sent before and image dump, and no second image descriptor should be sent before current image dump ended. This error occurred probably because current image was not complete.

E_GIF_ERR_NO_COLOR_MAP

Message printed using PrintGifError: "Neither Global Nor Local color map" An image must have either global (screen) or local (image) color map. Neither were given in this case.

E_GIF_ERR_DATA_TOO_BIG

Message printed using PrintGifError: "#Pixels bigger than Width * Height" The number of pixels dumped for this image is bigger than specified by image Height times image Width.

E_GIF_ERR_NOT_ENOUGH_MEM

Message printed using PrintGifError: "Fail to allocate required memory" Once an attempt is made to open GIF file, special structures are allocated to hold internal data for it. If allocation fails this error is returned.

E_GIF_ERR_DISK_IS_FULL

Message printed using PrintGifError: "Write failed (disk full?)" Writing encoded data failed.

E_GIF_ERR_CLOSE_FAILED

Message printed using PrintGifError: "Failed to close given file" Closing file failed.

E_GIF_ERR_NOT_WRITEABLE

Message printed using PrintGifError: "Given file was not opened for write" GIF files can be opened both for read (DGIF part of library) and write (EGIF part of library). This error occurs when a file is opened for read (using DGIF) is given to one of the encoding (EGIF) routines.

Decoding errors

D_GIF_ERR_OPEN_FAILED

Message printed using PrintGifError: "Failed to open given file" IO error result when attempt to open the given GIF file.

D_GIF_ERR_READ_FAILED

Message printed using PrintGifError: "Failed to read from given file" IO error result when attempt to write to the given GIF file.

D_GIF_ERR_NOT_GIF_FILE

Message printed using PrintGifError: "Data is not a GIF file" GIF files should have special stamp identifies them as such, If that stamp is not found, this error is issued.

D_GIF_ERR_NO_SCRN_DSCR

Message printed using PrintGifError: "No screen descriptor detected" Each GIF file should have screen descriptor in its header. This error will be generated if no such descriptor was found.

D_GIF_ERR_NO_IMAG_DSCR

Message printed using PrintGifError: "No image descriptor detected" Each image should have image descriptor in its header. This error will be generated if no such descriptor was found.

D_GIF_ERR_NO_COLOR_MAP

Message printed using PrintGifError: "Neither global nor local color map" An image must have either global (screen) or local (image) color map. Neither were given in this case.

D_GIF_ERR_WRONG_RECORD

Message printed using PrintGifError: "Wrong record type detected" Each record in a GIF file has a special identifier in its header. If the record has an unrecognized identifier, this error is generated.

D_GIF_ERR_DATA_TOO_BIG

Message printed using PrintGifError: "Number of pixels bigger than width * height" The number of pixels dumped for this image is bigger than specified by image Height times image Width.

D_GIF_ERR_NOT_ENOUGH_MEM

Message printed using PrintGifError: "Failed to allocate required memory" Once an attemp is made to open GIF file, special structures are allocated to hold internal data for it. If allocation fails this error is returned.

D_GIF_ERR_CLOSE_FAILED

Message printed using PrintGifError: "Failed to close given file" Closing file failed.

D_GIF_ERR_NOT_READABLE

Message printed using PrintGifError: "Given file was not opened for read" GIF files can be opened both for read (DGIF part of library) and write (EGIF part of library). This error occurs when a file is opened for write (using EGIF) is given to one of the decoding (DGIF) routines.

D_GIF_ERR_IMAGE_DEFECT

Message printed using PrintGifError: "Image is defective, decoding aborted" This error is generated, once the decoding failed - probably image is defect.

D_GIF_ERR_EOF_TOO_SOON

Message printed using PrintGifError: "Image EOF detected, before image complete" This error is generated once EOF errorname is detected in encoded image before all the pixels (Width * Height) has be decoded.

Utility support library

These functions are not part of the core GIF library. They are part of the getarg library that supports the utilities.

Error Handling

void PrintGifError(void)

Print a one-line diagnostic on the last giflib error to stderr.

Command Line Parsing

bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...)

Main routine of this module. Given argc & argv as received by the main procedure, the command line CtrlStr, and the addresses of all parameters, parse the command line, and update the parameters.

The CtrlStr defines what types of variables should follow. Look at the beginning of getarg.c for exact usage.

Returns false if successful, returns true on failure.

void GAPrintErrMsg(int Error)

If an error occurred in GAGetArgs, this routine may be used to print one line diagnostic to stderr.

void GAPrintHowTo(char *CtrlStr)

Given the same CtrlStr as for GAGetArgs, can be used to print a one line 'how to use'.

Sequential access

If you are handling large images on an extremely memory-limited machine, you may need to use the following functions for sequential read and write. It's better to avoid them and use the simpler DGifSlurp()/EGifSpew() interface.

Sequential reading

int DGifGetScreenDesc(GifFileType *GifFile)

Reads the screen information into the GifFile structure. Note this routine is automatically called once a file is opened, and therefore usually need not be called explicitly.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType)

As the GIF file can have different records in arbitrary order, this routine should be called once the file was open to detect the next record type, and act upon it. It can return these types in GifType:

1. UndefinedRecordType

something is wrong!

2. ScreenDescRecordType

screen information. As the screen info is automatically read in when the file is open, this should not happen.

3. ImageDescRecordType

next record is an image descriptor.

4. ExtensionRecordType

next record is extension block.

5. TrailerRecordType

last record reached, can close the file.

The first two types can usually be ignored. The function returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetImageDesc(GifFileType *GifFile)

Reads image information into the GifFile structure. Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen)

Load a block of pixels from the GIF file. The line can be of any length. More than that, this routine may be interleaved with DGifGetPixel until all pixels have been read.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetPixel(GifFileType *GifFile, PixelType GifPixel)

Loads one pixel from the GIF file. This routine may be interleaved with DGifGetLine(), until all pixels are read. Because of the overhead per each call, use of this routine is not recommended.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetExtension(
        GifFileType *GifFile,
        int *GifExtCode,
        ByteType **GifExtension)

Loads an extension block from the GIF file. Extension blocks are optional in GIF files. This routine should be followed by DGifGetExtensionNext.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetExtensionNext(GifFileType *GifFile, ByteType **GifExtension)

As extensions may contain more than one block, use this routine to continue after DGifGetExtension, until *GifExtension is NULL.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetCode(
        GifFileType *GifFile, 
        int *GifCodeSize, ByteType **GifCodeBlock)

It sometimes may be desired to read the compressed code as is without decoding it. This routine does exactly that (with DGifGetCodeNext), and can be used instead of DGifGetLine.

This compressed code information can be written out using the EGifPutCode/EGifPutCodeNext sequence (see gifpos.c for example). Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifGetCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock)

See DGifGetCode above.

int DGifGetLZCodes(GifFileType *GifFile, int *GifCode)

This routine can be called instead of DGifGetLine/DGifGetPixel or DGifGetCode/DGifGetCodeNext to get the 12 bits LZ codes of the images. It will be used mainly for debugging purposes (see GifText.c for example).

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int DGifCloseFile(GifFileType *GifFile, int *ErrorCode)

Write a termination block to the GIF, close the GIF file and free all memory allocated for managing it. GifFile should not be used after this routine has been called.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise. When GIF_ERROR is returned, the diagnostic error code is left in ErrorCode. The GifFile structure is unconditionally freed.

(Note: In versions before 5.1.0, the ErrorCode argument was absent and the GifFile structure was not freed so that the diagnostic error code will remain accessible in GifFile->Error. This behavior was changed because it caused problems for the implementation of library wrappers in dynamic languages.)

const char * DGifGetGifVersion(GifFileType *GifFile)

Get the GIF version collected during sequential read. This is handy for sequential API users who want to set an encoder's version from a decoder (e.g. for gif resizing). For the all-at-once users this isn't necessary because gif encoder inspects all the extension blocks, but sequential users do not have that luxury.

Sequential writing

If you are handling large images on a memory-limited machine, you may need to use the following functions for sequential write.

GifFileType *EGifOpenFileName(char *GifFileName, bool GifTestExistance, int *ErrorCode)

Open a new GIF file using the given GifFileName (in binary mode, if under Windows). If GifTestExistance is TRUE, and file exists, the file is not destroyed, and NULL returned.

If any error occurs, NULL is returned and the ErrorCode is set.

GifFileType *EGifOpenFileHandle(int GifFileHandle, int *ErrorCode)

Open a new GIF file using the given GifFileHandle.

If any error occurs, NULL is returned and ErrorCode is set.

The file is opened in binary mode, and its buffer size is set to FILE_BUFFER_SIZE bytes.

char *EGifGetGifVersion(GifFileType *GifFile)

That version computation is available through this function.

void EGifSetGifVersion(GifFileType *GifFile, bool gif89)

Set the GIF type, to GIF89 if the argument is true and GIF87 if it is false. The default type is GIF87. This function may be called after the GifFile record is allocated but before EGifPutScreenDesc().

int EGifPutScreenDesc(GifFileType *GifFile,
        const int GifWidth, const GifHeight,
        const int GifColorRes, const int GifBackGround,
        ColorMapObject *GifColorMap)

Update the GifFile Screen parameters, in GifFile structure and in the real file. If error occurs, returns GIF_ERROR (see gif_lib.h), otherwise GIF_OK.

This routine should be called immediately after the GIF file was opened.

int EGifPutImageDesc(GifFileType *GifFile,
        const int GifLeft, const int GifTop,
        const int GifWidth, const GifHeight,
        const bool GifInterlace,
        ColorMapObject *GifColorMap)

Update GifFile Image parameters, in GifFile structure and in the real file. if error occurs returns GIF_ERROR (see gif_lib.h), otherwise GIF_OK.

This routine should be called each time a new image must be dumped to the file.

int EGifPutLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen)

Dumps a block of pixels out to the GIF file. The slab can be of any length. More than that, this routine may be interleaved with EGifPutPixel(), until all pixels have been sent.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutPixel(GifFileType *GifFile, const PixelType GifPixel)

Dumps one pixel to the GIF file. This routine may be interleaved with EGifPutLine(), until all pixels were sent. Because of the overhead for each call, use of this routine is not recommended.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutComment(GifFileType *GifFile, char *GifComment)

Uses extension GIF records to save a string as a comment is the file. The extension code is 'C' (for Comment).

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutExtension(
        GifFileType *GifFile,
        const int GifExtCode,
        const int GifExtLen,
        void *GifExtension)

Dumps the given extension block into the GIF file. Extension blocks are optional in GIF file. Extension blocks of more than 255 bytes or more than one block are not supported in this function. Please use EGifPutExtensionFirst, EGifPutExtensionBlock, and EGifPutExtensionTrailer if your extension blocks may fall into this category.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutExtensionLeader(
        GifFileType * GifFile,
        const int GifExtCode)

Dumps the beginning of a GIF extension block to a GIF file. Extension blocks are optional in GIF files. This function outputs the type code information necessary for a GIF extension block.

Further blocks of the GIF Extension should be dumped using EGifPutExtensionBlock. When finished with this extension block, EGifPutExtensionTrailer should be called to output the block termination.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutExtensionBlock(
        GifFileType * GifFile,
        const int GifExtLen,
        const VoidPtr GifExtension)

Dumps a subblock of a GIF extension to a GIF File; should be used only following an initializing call to EGifPutExtensionLeader(). Extension blocks are optional in GIF files. This function will write the Extension Data in GifExtension to the file as a subblock of the preceding Extension Block. Repeat calling of this function until all data subblocks have been output.

Note that EGifPutExtensionLeader needs to be called before any calls to this function. EGifPutExtensionTrailer should be called to finish the Extension block after all data subblocks have been output.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutExtensionTrailer(
        GifFileType * GifFile,
        const VoidPtr GifExtension)

Dumps the GIF extension block terminator to a GIF File to end the current Extension block.

Note that a call to EGifPutExtensionLeader is needed to open the GIF Extension Block prior to calling this function.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutCode(
        GifFileType *GifFile,
        int *GifCodeSize,
        ByteType **GifCodeBlock)

It sometimes may be desired to write the compressed code as is without decoding it. For example a filter for a GIF file that change only screen size (GifPos), does not need the exact pixel values. Piping out the compressed image as is makes this process much faster.

This routine does exactly that (with EGifPutCodeNext), and can be used instead of EGifPutLine. You'll usually use this with the DGifGetCode/DGifGetCodeNext routines, which reads the compressed code, while EGifPutCode/EGifPutCodeNext write it out. See gifpos.c for example.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise.

int EGifPutCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock)

See EGifPutCode above.

int EGifCloseFile(GifFileType *GifFile)

Write a termination block to the GIF, close the GIF file, and free all memory allocated for managing it. GifFile should not be used after this routine has been called.

Returns GIF_ERROR if something went wrong, GIF_OK otherwise. When GIF_ERROR is returned, the diagnostic error code is left in ErrorCode. The GifFile structure is unconditionally freed.

(Note: In versions before 5.1.0, the ErrorCode argument was absent and the GifFile structure was not freed so that the diagnostic error code will remain accessible in GifFile->Error. This behavior was changed because it caused problems for the implementation of library wrappers in dynamic languages.)

Forward and Backward Compatibility

Except for some details of extension-block handling and the addition of read/write function hooks, the DGifSlurp()/EGifSpew() interface has been stable since 1990. It is expected to remain so.

However, the signatures of the file-opener functions were changed in 5.0 in order to make the library fully reentrant and thread-safe - earlier library versions did not feature the final pointer-to-error-code argument in DGifOpen() and friends. For the same reason, the static storage queried by GifLastError() in older versions is gone, and that function abolished.

The library header contains some version #defines you can use if you need to condition your code so it can compile with different library versions

Versions up to 4.1.6 defined a GIF_LIB_VERSION macro that was string-valued with a tricky format to parse. This macro has been retired.

Versions after 4.1.6 define integer-valued GIFLIB_MAJOR, GIFLIB_MINOR, and GIFLIB_RELEASE macros for the three components of the version. See the NEWS file in the GIFLIB distribution to track API changes.

The following functions are entirely new:

  • New functions DGifSavedExtensionToGCB() and EGifGCBToSavedExtension() make it easy to read and edit GIF89 graphics control blocks in saved images.

  • The new function DGifGetGifVersion() is convenient for people doing sequential reads.

A few changes in behavior were introduced in 5.0:

General behavior

  • The library is now fully re-entrant and thread-safe.

  • All functions exported by this library now have DGif, EGif, or Gif as a name prefix.

  • The default GIF version to write is now computed at write time from the types of an image's extension blocks. (Formerly EGifSpew() behaved this way, but the sequential-writing code didn't.) The result of this computation is available through the new function EGifGetGifVersion().

In documented functions:

  • GIF file openers and closers - DGifOpenFileName(), DGifOpenFileHandle(), DGifOpen(), DGifClose(), EGifOpenFileName(), EGifOpenFileHandle(), EGifOpen(), and EGifClose() - 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.

  • EGifSlurp() and EGifSpew() read and write extension blocks trailing after the last image, handle interlaced images properly.

  • EGifPutExtensionFirst() has been replaced by EGifPutExtensionLeader(); the difference is the new function doesn't take an optional block, it just writes a block leader.

  • EGifPutExtensionNext() has been replaced by EGifPutExtensionBlock(); the difference is that the new function does not take and then discard a function code argument.

  • EGifPutExtensionLast() has been replaced by EGifPutExtensionTrailer(); all it does is write the terminator block. Split your old EGifPutExtensionLast() calls into EGifPutExtensionBlock() followed by EGifPutExtensionTrailer().

In undocumented functions:

  • Some undocumented functions have been renamed. AddExtensionBlock() is now GifAddExtensionBlock(), and takes an additional function code argument. ApplyTranslation() is now GifApplyTranslation(); FreeExtension() has become GifFreeExtensions() and takes a different argument type; MakeSavedImage() is now GifMakeSavedImage(), FreeSavedImages() is now GifFreeSavedImages(), and BitSize() is now GifBitSize().

  • Three documented functions - MakeMapObject(), FreeMapObject(), and UnionColorMap() - have been renamed to GifMakeMapObject(), GifFreeMapObject(), and GifUnionColorMap() respectively.

Error handling:

  • 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 Error code is now put in an Error member of the GifFileType structure.

  • The GifError() and 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.

Skeletons of GIF filters

If you are developing on a virtual-memory OS such as most flavors of UNIX, or are otherwise sure of having enough memory to keep all of GIFs you need to operate in core, writing a filter is trivial. See the file gifsponge.c in util.

A sequential filter skeleton will usually look like the example file giffilter.c in util.

Please look at the utilities in the util directory for more ideas once you feel comfortable with these skeletons. Also try to follow the coding standards of this package if you want the maintainer to officially add your new utility to it.

Unimplemented features

Some features of the original GIF specification have not stood the test of time. This library mostly ignores them, but they are described here for completeness.

The GIF standard fails to be explicit about a small but crucial detail: the unsigned two-byte integer fields in it are little-endian.

The GIF format seems to have been designed with the idea that viewers would render multiple images in a GIF on a common canvas, giving an effect like a picture wall. The 'logical screen descriptor block' (LSDB), 6 bytes right after the 6-byte GIF stamp and version header at the beginning of a GIF file, includes both two-byte canvas width and canvas height fields and a canvas background color. Each image, besides height and width, also has 'left' and 'top' coordinates specifying where it is to be placed on the canvas.

GIFLIB can read and set these fields; the gifpos and giftool utilities will enable you to script such changes. But browsers and modern image viewers ignore them. Nowadays multiple-image GIFs are generally used either as animations in which each sub-image is a frame or as image libraries, with the GIF client handling compositing into some canvas about which the GIF format holds no information.

Another feature of the LSDB that is generally ignored is the pixel aspect ratio byte. Until 5.0, GIFLIB ignored this flag on input and zeroed it on output; now it is read and preserved if present. The GIF standard doesn't give a rationale for it, but it seems likely that the designers intended it for representing image captures from the analog television of the day, which had rectangular pixel-equivalents.

Yet another ignored feature of both the LSDB and sub-images is the sort flag, which is supposed to signal whether the colors in the associated color map are sorted by decreasing importance in case the display device can only render a limited number of them. This feature reflected the high cost of dual-port memory at the time the GIF specification was written in the late 1980s. That kind of limit disappeared in the mid-1990s. Until 5.0, GIFLIB ignored this flag on input and zeroed it on output; now it is read and preserved if present.

Finally, the plaintext extension block. This is an extension block that contains instructions for overlaying text captions on a following image. GIFLIB treats these blocks as raw data, not attempting to parse out the location and text data.

giflib-6.1.3/doc/gifcolor.html0000664000175000017500000000410715166751647014406 0ustar esresr gifcolor

Name

gifcolor — generate color test-pattern GIFs

Synopsis

gifcolor [-v] [-b background] [-h] [colormap-file]

Description

A program to generate color test patterns. Feed it a color map file (as generated, say, by the -s option of gifclrmp) and it will generate a GIF containing lines of the form.

Color %-3d: [%-3d, %-3d, %-3d]:

where the first number is the zero-based color index, and the triple is the index's [Red, Green, Blue] value. There will be one such line for each color. Each line will be set in a simple 8x8 font in the color it describes; thus, any lines corresponding to the GIF's background color will be blank.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-b

Set the image's backround color to a given numeric index.

-h

Print one line of command line help, similar to Usage above.

If no colormap file is specified, the color map will be read from stdin.

Author

Gershon Elber.

giflib-6.1.3/doc/gifsponge.xml0000664000175000017500000000221015166751647014410 0ustar esresr ]> 20 Dec 2020 gifsponge 1 GIFLIB GIFLIB Documentation gifsponge expensive GIF copy, a model for slurp utilities gifsponge Description Slurp a GIF into core, operate on it, spew it out again. This is an expensive way to copy a GIF. The source is included as a skeleton for more sophisticated slurp utilities. See the source in the util directory for details. Author David Suárez &email; giflib-6.1.3/doc/giflib.70000664000175000017500000000424115166751647013237 0ustar esresr'\" t .\" Title: giflib .\" Author: [see the "Authors" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 3 June 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFLIB" "7" "3 June 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" giflib \- GIFLIB utilities .SH "DESCRIPTION" .PP GIFLIB is a linkable service library and a set of utilities for processing images encoded using GIF (Graphics Interchange Format)\&. .PP These utilities are not intended to compete with or replace multi\-format graphics toolkits like ImageMagick or the Python Imaging Library, or graphics editors such as the GIMP\&. Find one of those, or an equivalent, if you need to crop, scale, rotate, toggle interlacing, or perform other conventional image transformations\&. Rather, these are intended to facilitate GIF\-specific operations which multi\-format tools may not adequately support\&. .PP API documentation for the service library is best viewed through a browser at the project website: http://sourceforge\&.net/projects/giflib/?source=directory\&. .SH "SEE ALSO" .PP \fBgifbuild\fR(1), \fBgiffix\fR(1), \fBgiftext\fR(1), \fBgiftool\fR(1), \fBgifclrmap\fR(1)\&. .SH "AUTHORS" .PP Gershon Elber, Eric S\&. Raymond, Toshio Kuratomi\&. giflib-6.1.3/doc/gifsponge.10000664000175000017500000000320615166751647013756 0ustar esresr'\" t .\" Title: gifsponge .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 20 Dec 2020 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFSPONGE" "1" "20 Dec 2020" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifsponge \- expensive GIF copy, a model for slurp utilities .SH "SYNOPSIS" .HP \w'\fBgifsponge\fR\ 'u \fBgifsponge\fR .SH "DESCRIPTION" .PP Slurp a GIF into core, operate on it, spew it out again\&. This is an expensive way to copy a GIF\&. The source is included as a skeleton for more sophisticated slurp utilities\&. See the source in the util directory for details\&. .SH "AUTHOR" .PP David Su\(~A\(r!rez giflib-6.1.3/doc/gifinto.10000664000175000017500000000446515166751647013444 0ustar esresr'\" t .\" Title: gifinto .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFINTO" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifinto \- save GIF on stdin to file if size over set threshold .SH "SYNOPSIS" .HP \w'\fBgifinto\fR\ 'u \fBgifinto\fR [\-v] [\-s\ \fIminsize\fR] [\-h] [\fIoutfile\fR] .SH "DESCRIPTION" .PP A program to save stdin into a file with given name, if and only if the result file has size bigger than specified (see below)\&. This can be used to save a result under the same filename we started with in a chain of pipes\&. .PP Always reads a GIF file from stdin\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-s MinFileSize .RS 4 If file is less than MinFileSize, it is deleted and not renamed to the given name\&. This will prevent killing the file we started with if the result is an empty file, or the pipeline did not complete\&. .sp The default file threshold size is 14 bytes, which is 1 bigger than GIF file stamp (6 bytes) plus a GIF file screen descriptor (7 bytes), so a GIF file with only GIF stamp and screen descriptor will not be renamed\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/gifbuild.html0000664000175000017500000002052115166751647014365 0ustar esresr gifbuild

Name

gifbuild — dump GIF data in a textual format, or undump it to a GIF

Synopsis

gifbuild [-v] [-a] [-d] [-t translation-table] [-h] [gif-file]

Options

A program to convert a series of editable text GIF icon specifications and named GIF files into a multi-image GIF, usable as a graphic resource file. It can also dump existing GIFs in this format. Both directions are lossless and mutually inverse.

When dumping a GIF, certain sanity checks are performed which may result in a warning emitted to standard error.

If no GIF file is given, gifbuild will try to read a text input from stdin.

Specification Syntax

Here is a syntax summary in informal BNF. The token `NL' represents a required newline.

<gif-spec> ::= <header-block> <image-block>...

<header-block> ::= <header-declaration>...

<header-declaration ::=
		| screen width <digits> NL
		| screen height <digits> NL
		| screen colors <digits> NL
		| screen background <digits> NL
		| pixel aspect byte <digits> NL
		| screen map <color-table> NL

<color-table> ::= <color-declaration>... end NL

<color-declaration> ::= rgb <digits> <digits> <digits> [ is <key>] NL
                | sort flag {on|off} NL

<image-block> ::= include <file-name> NL
		| image NL
			<image-declaration>...
			<raster-picture>
			[ <extension> ]

<image-declarations> ::= image top <digits> NL
			| image left <digits> NL
			| image interlaced NL
			| image map <color-table> NL
			| image bits <digits> by <digits> [hex|ascii] NL <raster-block>

<extension> := <comment> NL <extension-block> NL end NL
		| <plaintext> NL <extension-block> NL end NL
                | graphics control NL <GCB-part> NL end NL
                | netscape loop  <digits> NL
		| extension <hex-digits> NL <extension-block> NL end NL

<GCB-part> ::= disposal mode <digits> NL
                | user input flag {on|off} NL
                | delay <digits> NL
                | transparent index <digits> NL

If the data types of the screen height, screen width, screen background, image top, and image left declarations aren't obvious to you, what are you doing with this software?

The pixel aspect byte declaration sets an integer denominator for a fraction expressing the pixel aspect ratio. See the GIF standard for details; this field is actually long obsolete.

A color table declares color indices (in ascending order from 0) and may associate them with key characters (these associations are absent when the map is more than 94 colors lang and raster blocks using it must use hex pairs). These characters can later be used in raster blocks. As these must be printable and non-whitespace, you can only specify 94 colors per icon. Life is like that sometimes.

A color table declaration can also set the table's sort flag with "sort flag on" or "sort flag off" on any line before the end.

An ascii raster block is just a block of key characters (used for a color map of 94 or fewer colors). A hex raster block uses hex digit pairs instead (used for a color map with more than 94 colors). The default is ASCII. It should be sized correctly for the image bits declaration that leads it. Raster blocks from interlaced GIFs are dumped with the lines in non-interlaced order.

The comment, plaintext or graphics control keywords lead defined GIF89 extension record data. The final GIF89 type, graphics control and application block, are not yet supported, but the code does recognize a Netscape loop block. You can also say extension followed by a hexadecimal record type. All of these extension declarations must be followed by an extension block, which is terminated by the keyword end on its own line.

An extension block is a series of text lines, each interpreted as a string of bytes to fill an extension block (the terminating newline is stripped). Text may include standard C-style octal and hex escapes preceded by a backslash.

A graphics control block declaration creates a graphics control extension block; for the field semantics see the GIF89 standard, part 23.

A netscape loop declaration creates an application extension block containing a NETSCAPE 2.0 animation loop control with a specified repeat count (repeat count 0 means loop forever). This must be immediately after the header declaration. These loop blocks are interpreted by the Netscape/Mozilla/Firefox line of browsers.

All <digits> tokens are interpreted as decimal numerals; <hex-digits> tokens are interpreted as two hex digits (a byte). All coordinates are zero-origin with the top left corner (0,0). Range checking is weak and signedness checking nonexistent; caveat hacker!

In general, the amount of whitespace and order of declarations within a header or image block is not significant, except that a raster picture must immediately follow its image bits bits declaration.

The include declaration includes a named GIF as the next image. The global color maps of included GIFs are merged with the base table defined by any screen color declaration. All images of an included multi-image GIF will be included in order.

Comments (preceded with #) will be ignored.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-d

Dump the input GIF file(s) into the text form described above.

-t

Specify name characters to use when dumping raster blocks. Only valid with -d option.

-h

Print one line of command line help, similar to Usage above.

Bugs

Error checking is rudimentary.

Example:

A sample icon file called sample.ico is included in the pic directory of the GIFLIB source distribution.

Author

Eric S. Raymond

giflib-6.1.3/doc/gif2rgb.xml0000664000175000017500000000567415166751647013772 0ustar esresr 2 May 2012 gif2rgb 1 GIFLIB GIFLIB Documentation gif2rgb convert images saved as GIF to 24-bit RGB triplets gif2rgb -v -1 -c colors -s width height -o outfile -h gif-file Options -v Verbose mode (show progress). Enables printout of running scan lines. -1 Only one file in the format of RGBRGB... triplets (Each of R, G,B is a byte) is being read or written. This file size is 3 * Width * Height. If stdin is used for input or stdout for output, this option is implicitly applied. The default (if not `-1') is 3 files with the names OutFileName.R, OutFileName.G, OutFileName.B, each of which is Width * Height bytes. -c colors Specifies number of colors to use in RGB-to-GIF conversions, in bits per pixels, so '-c 8' actually specifies 256 colors (maximum and default). -s width height Sets RGB-to-GIF conversion mode and specifies the size of the image to read. -o specifies the name of the out file (see also `-1' above). -h Print one line of command line help, similar to Usage above. By default, convert a GIF input file to RGB triplets. If -s is specified, convert RGB input to a GIF. If no input file is given, gif2rgb will try to read data from stdin. Bugs Feeding this utility a GIF with an invalid colormap, or other kinds of malformations, index will produce invalid output and may core-dump the tool. Don't do that. Author Gershon Elber. giflib-6.1.3/doc/gifwedge.10000664000175000017500000000414015166751647013554 0ustar esresr'\" t .\" Title: gifwedge .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFWEDGE" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifwedge \- create a GIF test pattern .SH "SYNOPSIS" .HP \w'\fBgifwedge\fR\ 'u \fBgifwedge\fR [\-v] [\-l\ \fIlevels\fR] [\-s\ \fIsizex\fR\ \fIsizey\fR] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program to create a test GIF image with intensity levels of the RGB colors YCM colors and white\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-l levels .RS 4 Set number of intensity levels per color\&. This number must be power of two up to 32, as Gif format can only have 256 color simultaneously and 7 basic colors are to be displayed\&. .RE .PP \-s sizex sizey .RS 4 Force image size to be SizeX by SizeY pixels\&. Image size will be rounded down to be a multiple of number of intensities horizontally, and 7 (colors) vertically\&. .RE .PP \-h .RS 4 Print one line command line help, similar to Usage above\&. .RE .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/gifsponge.html0000664000175000017500000000235315166751647014564 0ustar esresr gifsponge

Name

gifsponge — expensive GIF copy, a model for slurp utilities

Synopsis

gifsponge

Description

Slurp a GIF into core, operate on it, spew it out again. This is an expensive way to copy a GIF. The source is included as a skeleton for more sophisticated slurp utilities. See the source in the util directory for details.

Author

David Suárez

giflib-6.1.3/doc/gifhisto.html0000664000175000017500000000552515166751647014423 0ustar esresr gifhisto

Name

gifhisto — make a color histogram from GIF color frequencies

Synopsis

gifhisto [-v] [-t] [-s width height] [-n image-number] [-b] [-h] [gif-file]

Description

A program to create histogram of number of pixels using each color. The output can be formatted into a GIF histogram file, or as text file - both go to stdout.

If no GIF file is given, gifhisto will try to read a GIF file from stdin.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-t

Force output to be text file of the following form: (colormap size) lines each containing two integers: number of times color appeared, and color index. Lines are in increasing color index order. This output can be fed directly to a sort program if ordering by color frequency is desired.

The colormap picked is the one to be used for the image to generate histogram for, as defined in GIF format.

-s width height

Size of GIF histogram file. The height of the histogram should be power of 2 divisible by number of colors in colormap.

Width sets the resolution (accuracy if you like) of the histogram as the maximum histogram bar is scaled to fit it.

-n image-number

Image number to test. Default is one.

-b

Zeros the background color count. As only linear scale bars are supported and usually the background appears much more often then other colors, deleting the background count will improve the scaling of other colors.

-h

Print one line of command line help, similar to Usage above.

Author

Gershon Elber

giflib-6.1.3/doc/gifecho.xml0000664000175000017500000000676415166751647014055 0ustar esresr 2 May 2012 gifecho 1 GIFLIB GIFLIB Documentation gifecho generate a GIF from ASCII text gifecho -v -s colormap-size -f foreground -c R G B -t text -h gif-file Description A program to generate GIF images out of regular text. Text can be one line or multi-line, and is converted using 8 by 8 fixed font. This program reads stdin if no text is provided on the command line (-t), and will dump the created GIF file to stdout. Options -v Verbose mode (show progress). Enables printout of running scan lines. -s colormap-size Explicitly defines the size of the color map of the resulting gif image. Usually the image will be bicolor with fg as color 1, unless [-f] is explicitly given in case the color map size will be big enough to hold it. However it is sometimes convenient to set the color map size to certain size while the fg color is small mainly so this image may be merged with another (images must match color map size). -f foreground Select foreground index (background is always 0). By default it is one and therefore the image result is bicolored. if FG is set to n then color map will be created with 2^k entries where 2^k > n for minimum k, assuming k <= 8. This color map will be all zeros except this foreground index. This option is useful if this text image should be integrated into other image colormap using their colors. -c R G B The color to use as the foreground color. White by default. -t text One line of text can be provided on the command line. Note you must encapsulate the Text within quotes if it has spaces (The quotes themselves are not treated as part of the text). If no -t option is provided, stdin is read until end of file. -h Print one line command line help, similar to Usage above. Notes There is a hardcoded limit of 100 the number of lines. Author Gershon Elber. giflib-6.1.3/doc/giffix.html0000664000175000017500000000307715166751647014063 0ustar esresr giffix

Name

giffix — attempt to fix up broken GIFs

Synopsis

giffix [-v] [-h] [gif-file]

Description

A program that attempts to fix broken GIF images. Currently will "fix" images terminated prematurely by filling the rest of the image with the darkest color found in the image.

If no GIF file is given, giffix will try to read a GIF file from stdin. The fixed file is dumped to stdout.

Options

-t

Verbose mode (show progress). Enables printout of running scan lines.

-h

Print one line of command line help, similar to Usage above.

Author

Gershon Elber.

giflib-6.1.3/doc/giffix.10000664000175000017500000000353315166751647013254 0ustar esresr'\" t .\" Title: giffix .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFFIX" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" giffix \- attempt to fix up broken GIFs .SH "SYNOPSIS" .HP \w'\fBgiffix\fR\ 'u \fBgiffix\fR [\-v] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program that attempts to fix broken GIF images\&. Currently will "fix" images terminated prematurely by filling the rest of the image with the darkest color found in the image\&. .PP If no GIF file is given, giffix will try to read a GIF file from stdin\&. The fixed file is dumped to stdout\&. .SH "OPTIONS" .PP \-t .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/index.html.in0000664000175000017500000001103315166751647014312 0ustar esresr The GIFLIB project

The GIFLIB project

The GIFLIB project maintains the giflib service library, which has been pulling images out of GIFs since 1989. It is deployed everywhere you can think of and some places you probably can't - graphics applications and web browsers on multiple operating systems, game consoles, smartphones, and likely your ATM too.

Yes, this code is he reason GIFs were in Mosaic, the first web browser that could do inline graphics; it is the implementation Andreesen and Bina used.

This is very mature, stable, small-footprint code with minimal dependencies (suitable for use in embedded deployments) that needs only occasional very minor bugfixes. Test reports from odd platforms and better regression tests are particularly welcome. Don't try to redesign it, applications beyond counting would break if you did.

It's "GIFLIB" in caps as a nod to the code's origins in the dark and backward abysm of MS-DOS, but Unix hackers are encouraged to spell it "giflib" in deference to local conventions. :-)

Before October 2006 the GIF format was encumbered by patents on the LZW compression it uses. This first became an issue in 1993 when the patent-holders made ambiguous noises about requiring royalties. For some time a subset of this code travelled as "libungif", supporting decompression but not compression. You can read a more detailed history here.

Note: The 5.x versions change the API slightly in a way that isn't compatible with older shared libraries. This was required to fix some known problems with the extensions API and with thread-safety.

If you require shared-library compatibility back to ancient versions, build from 4.2. 4.2 and the 5.0 version are behaviorally almost identical; the few differences are explained here.

The SourceForge summary page (where you can download the source, review the project, find links to the bugtracker and mailing list pages, or ask to join the project as a developer) is here.

People to thank for this code: Gershon Elber, Eric S. Raymond, Toshio Kuratomi.

If you appreciate this project, and especially if you make money from it, please support continuing maintainance on Patreon.

GIFLIB technical documentation:

GIF resources:

To support this ubiquitous code, Become a Patreon patron!

giflib-6.1.3/doc/giflib-logo.gif0000664000175000017500000000234515166751647014577 0ustar esresrGIF89a22    "          "      ĺ!,22  121!!1323% (9..9.22ìɳ̿DZ2ߦ.2hYq 9M3Fqj :`E.6dq6q(`@G3߽` pb@"H- ~|QH*6l3mrPWb8@†#!CYWQ$< G#I~HBx/PÐ(@eʖ)#1(i` 9siQp&j+T PM4e՝eKN7<,ie(Ņ/Iʏ:T‘\r ٟG/rѶWF,QaR{}$6r?<}~X (hw5w@ (A(!zA((` >(EP .أĠ J`B`A.@!A|N e GPYW o)N #݅iw$ҜPfL1&|rVGgZZ ^$< ]X%j`2IP )aN5<#6`?0]x !Z7vjV 6pX`aF>w, PT  6 %Qj;me.x0p+1Kf j5^"T4R  yEC]P/L!؋ Z p&\r'ڭ$ .@ AΜ$X" R"F@ ;giflib-6.1.3/doc/giftext.xml0000664000175000017500000000535115166751647014112 0ustar esresr 2 May 2012 giftext 1 GIFLIB GIFLIB Documentation giftext dump GIF pixels and metadata as text giftext -v -c -e -z -p -r -h gif-file Description A program to dump (text only) general information about GIF file. If no GIF file is given, giftext will try to read a GIF file from stdin. Options -v Verbose mode (show progress). Enables printout of running scan lines. -c Dumps the color maps. -e Dumps encoded bytes - the pixels after compressed using LZ algorithm and chained to form bytes. This is the form the data is saved in the GIF file. Dumps in hex - 2 digit per byte. -z Dumps the LZ codes of the image. Dumps in hex - 3 digits per code (as we are limited to 12 bits). -p Dumps the pixels of the image. Dumps in hex - 2 digit per pixel (<=byte). -r Dumps raw pixels as one byte per pixel. This option inhibits all other options and only the pixels are dumped. This option may be used to convert GIF files into raw data. Note: the color map can be extracted by gifclrmp utility. If more than one image is included in the file, all images will be dumped in order. -h Print one line of command line help, similar to Usage above. Author Gershon Elber. giflib-6.1.3/doc/whatsinagif/0000775000175000017500000000000015166751647014216 5ustar esresrgiflib-6.1.3/doc/whatsinagif/header_block.gif0000664000175000017500000000345415166751647017315 0ustar esresrGIF89ad@@@ 000```PPPppp!,d $dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N|}:zU$~9O#7M:H"    "  "0  "ٌ"~~ 9PG=̛"SBe3PQ2=0X|\To ;)9|_ 5_)_9cCF0Xj:' (dH;KⰧgnZJ@nCF>nPB #H}tqFY@$>* @:^ͺ׭2  TdH#;TȓVV8`^? >0+ZK 09n &X^S!h.Ayl H H~& ~$mX~4+=XPHGi^ "@BA|uhV"|>^ #@"@H^ xX2VoK$ Kk@R 0ڛyv܉g4zdrH<Bm+0(f@PP>ʅ|؇ FC& SxC%~yi#IY[qޚ@JJ@Ȧ"H_:zI@R͈9*IpKlQ.~bp;Yh}n$v.ϲ0Jv $s,|ʊ۽B]:x:Hj[ 0| @'Be .˒lG4obs8i"=C\tGKPG]TW jX?=u\+t`-6rWmQlp/}4v67 8:B~_Kz>BeU .7f ! b2 y FZvދ}4 y v#4tb ,/ Jv$Q1a~F; n]MJ 4`R`YŔY%"rETC% PI<]Y` B`|^PSSԃ:#$@,@"rq`;ƯFpGSt$1 ,p]s܈yqŢGp)( p]&DA_@q#t<1--" Zd((5qȂ|, d6^IbIA8 wRDVJ[ hX=A4X&q `KMb:d'KZ7!;giflib-6.1.3/doc/whatsinagif/sample_2_animation_green.gif0000664000175000017500000000015315166751647021625 0ustar esresrGIF89a !, 0x#H!b%ӓ'ס4ϭ7zo0(9vd;giflib-6.1.3/doc/whatsinagif/sample_1.gif0000664000175000017500000000010515166751647016402 0ustar esresrGIF89a !, -*3u`L;giflib-6.1.3/doc/whatsinagif/lzw_decoding_bytes.gif0000664000175000017500000003307715166751647020575 0ustar esresrGIF89aƻ鼴߳Ωѱ9==100 NII˝˟ ڎ𡩨Հ@@@```pppLRRPPP___r{{&((ooo///Ҿ{_gfhbbä/33U\\BHGhqpzzA==[UUunnÈĘ!,GB~~A~ (RH/A Ea "!^fd /\kN$ԏSǗ1DERɲQS;L O A': GJ?zGgOIX B; sbd`]WU;LR?r9D%H7/aAx%s1|Ma.DMvG.9ƥLp`#7.aPA# z\nI;{y;=' 䬓By~\YO $ \>u]pV1UW^sއY~ TSɓV|~ע 7eXW>q6#d~oUR7Hgh!}1"!A9!H|W ҂2 {3HObTCADCFTa"G 9';%@VV'~HF 1uxegQ)-`?嗢=d~ޝtBA&Ɉ=BPA,HY#TUXF墭yCڝG lZ담r,}W] gso KE;%$Ę:6ӱp5+Ca`5eW$1,cR &bS(KTYBpˬϰ5θC$A_Cr!b H?mq8o%|kDp |gAjqk eZ ,l KENt@W9╾S^dBxEsBosv?^)Zv'fAu{Q2ȳ [!ƎpxB ^am*f̗m@0+Q"n]uO0 ~q?3CN %HC B 7 q\HL")UqHU NԲ*z` H2hLpH:u@+v > IB7X#Pz0'O#cGNF%롄K^Hvr*^V򕰌,gIZڒ`+4^ 0IbR"B !MQ45V 8 @1vR2ing!ODD@A?$BPs3D'ʀxʓfczQCl5G B;Mŧ=OTڕTUKU^kXwj< XD,5cY˰]7;μU_G V;5DLbt-!`Mef9[[z|*i{LӞVk4STB,7ZȀtKZͮvb(xKMz׋^wBA@:a}`7Vȯk׷}'D\I [ΰ7{wGч(NW8{SKƃq9?v*>L"cZ;P2c,*RZ.ύŇ12*@+-9VA 'WxƳ >\L*#7fFOaDh* 2f>`' ELgP8 ԅxl ՒMm1kZ:ևH(- xO GtdR|Z( TbhY6YZ 1Mr֣*A|𵱵 Ic 9pƐlM3{xPbla bpM,qZ^pKLj@(&\ ŅшD 4/w W9 H ]Gg 1|'@@b *(B:^C xVFKnB *D x` ( ?x@@kbAbTo L-A"<އ H8B@fXy &Ű0V0LYQDaXCp_Ypeٗ0P_ş~_D6 *Y0D j> Y} iS `~T8&6CEfQ5 ,%m~pP2:0LZdlYHy&:jè -OiBTD0CgL1OQ`*+VX 5R֤~ bK@rUv^ ݤeyj{bT@ f0y+aaP6YPza'Z:e2РP{:zYg%[x0Y0"ՠ?Yd2غz媯ޚr Π!e W*5Cj6=Qc5H. 4Z*gڭ `V2 ]PY LXp_䥂QcBzܒJvJe BMycO:PAUsa6w_b6b Pxcu`# :(eIM  [' 9ۀؙH~Z1 I0[{Pq;[{u+ Q G@%A@t+C M;KJ{+mjDdԎ;^$^k qB F+ $`'mKE { Gysfΰɰb@Y@bI$1k9 ۰0+;\C\ ; ɛbL | TQ $\[pA4<6 &B ?e's)VH Y9a"ծ -+Fb~ycv W[gvp1%rt>{ƒF>'"'J)\jFp5^'&[0^mN(|] znbT^b~^z!ha([vPb޺^a^'6jBX^^> ^b͞(WbP~AI*FB~>9פ^}~bj) ω}ym.>^D)~Z@oM싱2<."N@(}O_g>NPBnMn3ꃰ<>ރ9./ib@>nNn>ž…_/`b"`(6..X_# " Yq>ܗ /Y_}>bמknb1bW/{0}Pv?+f.o,v(V ?x?0'+m>pZ-Pίbb柏>o#`#*& b}?P  BF%}¾üۭHܠ]MSTM2͆}hT\jɆEhBˠb :C}~(DZǏ C"'HLPݾ>(4!yg64AQ],*SWAg!6 =fgqׯ`~I)Li>~t-t 2$5AExFM~.ޕV˘3kjs}ֺ4T`8uPj63;bHl(mñw&fPQٳУO趱Qsz=?'}udL9QyaQClA?ӎB(gQuvWGv)v:~䣠 fUKv!bG^a9 W AE 0(#7zK EQq,fHW^bZf!K"OTP "~dif'5nv,ͱp?RS fB0'0aՖ9ڙad8>c䬄 X1gٙv)$ij@8kќtC,*IF+CBJ?IZ6lfZ-0{ :: rBSK`J+g;o^;74r 0+{Fo ,}L(%&ovp&3l1 &G FpH$~H+t(Tî!u#(!LO5 N`AΚ} 8AON~#Dψ[>Pԍl ^A Xjܮ лE8v3BeVYr q?h-w~xn/4!|p@ ޶Rn!NGCS7О:- ` J*\tBE,Mkc4@> , oJ)>@ħɑ,h9h0: 7q ri`?2̂69?,o%Y4VHkz[&?,8Le~~`E`Aʩ2[Ddi{%W@LQ?{&-iEhl,"#|dBИ4Ch8QǏ(a̳֮9çia^C>]6IriD,>1!'kZ2i+],/թOX3ي t@`42H͡&#:Hw/9aHq$r XGؑ"g3AJ4$Xfe>ɧboYgO7OLcZ>KB5%qi,4!>zR36YpfX NlfwŷYPl}h;ƷPrdn5RV|(@ aqDyh60Uq8̓BϾ%N %\T~X7V.wI#E2w)@6Po=z`?Nb ~i*!s0B ,tN)oGOz/zg^=mje ݉ u?e4~8SMp#@ %h@')XƲU2ˋiF+oDylV=Y9 GC%h`ѐ 4'XҘHN?! /4=@$/LTz՚ ָV^W@ 1m]/.Ec[rXa?X`z!(zn +¸(0EO#VDV!Ap!< E [H)~7 3x *`O^`&Yg{;!=A7uK!EzP >6} !ly3Bwo_`oII Ba?bxXPyK!ϓ/GzzgsL{G|Yg{W {|P7W{uW{ dwF0wmkg~`rwp& Wd vpSVw'8pVЃwwy@G Ir r/zrz''7 Xu'|{_uvJ7{ c|a5me,nׇw7~{p}8 X9hGxQ0sL؄"qySy/qW(r@'G[H8Jqtsu(i luR`ht`F'thtVEg|1 df}& LMwp +J qR芣zJhhpȁXtVjX {U|Jwmx@׌wx%+ 惑Aݸ=~ ICx))@Dxyid_9xq؏)r'YGˈx 9 tRYv0_Yr:嘒 '}8n)p`=`=8:Гה7zxGiqI<ى?sOI?'WyXi [it}ox{¨Y! :P} @oo gvth:/8)wDhǜ/hogщ0ggpٝ޹) 3Yي晞  ,Оd\) 50Z` : Z Y Z=PP6# ?ШgPX9,n-1JcAq 7N}9;3OP^"w,{T*N,>C)W+)G0VRhjl_\ nIwpgiP}M̤ޤL$:k . Z`R=;?GڈQNYPAgv`gF%pkXY0wM`G.pYG\eYomiХ_m(|W/֡Z ФkTpL#noM+L; ]T]}}?\f0(j?}2%%h?5gTT%\%PѡA~BDCCB+%QDQCV~ۢ~~JXd+w9A' 6'a Yhܨ$݀F $&qō4 ?WNO fJ\%8r $4W4~ँ'&JibJV3hl+Ҥ>3eN")%4 v\MZ5IƔfjUȒ\(AϠCfB"C  pJN5PKHP !b?D!BiR+J8?wzLOxgQy%2Ua$[8h]y` TW!MbJaL2! PPBWfp6ڌ4h258ȜvM2Xd2LwBG$0 v`!tّy߅SaRF; !`${o^Nd'pGQ7R}IޛB0P%Ӂ(hYYB2LI "n(BDqSMBV Ch'іm䥟m]Ue^ (ǚũ^TmoP4S(3``T@h, ʀoE! $NF ArSaT-*%(K00Bz"#H'}+P(+!A߆8()<|koS;8yB$_IU*W/~'`Z?;IbA#$8ApȌbc ,6LhT(&e7|*GR@&C!ߙBEh%`Ж%2t%!؆0!ale0Oڬ+>}[#}ooչ z$9H8ݙBr"u:I<$~`>f mCB4bnh. -hQ[TdAE (}&V~ pKqRdt%(pSQ䴦Bh 5=6-,5&J}j,ԥĨOWTZs 2qW !| >4i˼,A bE3:JB<:\K3 ~0PPYFBQkSZ3j!3[(&fzכ<~h!9V ;yvW6mj#oF _5?b!b- aG C#O9\qD3A$4[$> +OLC”]m;6F(|w`Ht  >oKXiK8f #Y Fq~bձN{is_El;HRO[ϼ7{GOқOW@;giflib-6.1.3/doc/whatsinagif/sample_1_enlarged.gif0000664000175000017500000000163615166751647020255 0ustar esresrGIF89add!,dd(0@8}ৄHIp SL7- 5 ׎5k=ӆDVUXƢ6on fɳz+f];|Auz~NRdEs|Tw]_ GilrP">yCanZ-ɚq<DZxٕӶJTGГ)>pݳ >fёXb1dBq$0BǓ/Qg!ǘf|8&9?e6TɲuHtȔP !XjʵWT&m`ٳfEvmڲnH&ٸrmWڹ:{ */[gEnͱCū0elj \91gΘGz$3eq9 꾧/>űSfwȇwh]87Ԡgϰ9nW?}e캥_c^{wmۼgo%ShTSOz\B9hy"bH"k&~4"Jɤ=j',rН6y^XNYAYFѧ&:Tň.@+^ 5N(p€$vŇ ^NỲF 3vElz}27`rO9LL,X LpW/SVk X 6>l4?38 < dI97u8/Pr) :`M `^0Lc3#oZ` Yʸg7+!& 'IJ 0̥ n^0saSdB(wL`ФA2 Tsc4i$7o&a=yti" ^h#r-!Egw^סafJI@F&Z^T,7VPL[VĠsD)%̋r3=dO[%,ѱ.(Ly Sl4P])vk#(FƠs;(*<f ٴ@א(#G?Ҍ&)#[A"r x0 `H+k250֤;8Vdoʶ39N) `<#4O΍+,4BMxzEΔ.zjmp[4W#VRm2k!p!gr] J7f 9UN|[/sϫ9J!eiR&F (mwV`r_ Ǻd$l wG a3$S̓bTh>Ak0TjSBk'Ԓ̆85gH0(8fӄ5!㹍gkۺ.J(Z6iꢋ*Ë́ O=[2pl0 HOȵ =팚sfjz !iFսnY] X782ԝx]|J p*&=‰ܼ_`'Nt;=6H2[6䄆.q4<[JMbvA4g>ǂSE9d@fwB?a 2?[74Yz ^Dvt.!R4:uW*.q.N g/UIjʂKFuHU:3B\"wj|mt j(t:-A4]–xgOw-:mN9gŞqB_f܏ݻw S^B?w|t ǁL?"W4`YUڟUg1w{%VYz ؀Xx̗h.JHr&tkXmy.#s;@y>d#U7e3~#P+0KN8p%a$g{6E=a]V':(dd[/vPhWcO"x#XYWMv|R  j(&KAyR#UejWXr"t^E}TR]"U5@rW5MWR"GtUX~vhNPT,lT+G SM>HlQhqqH5wHH1JEa n",Tgp!^1nHgGa1B 4/AgH!Q:Cԧj3^Xx((zɊ972ؐU(spđ" 5 Yx&9%,~2yhB7(QtP6|<&@9"DyJaC)rNPR9TYVyXZyv& ph0bJ; P%BaOzaIK,+U+5gI ,@xd*m U+`R\k,`$඀{-0v&e o*qksKt˞籸)Ʒ)0u۶zzahЊs|BK L[S2l ۬Z[5;)`۩JR*pw7D!Oj7=&9-3MМ< JzԈJJ źӚb8ٚe"Ձ` *[vjt E{W?N{ FmMC،`S}wK*; l-)++@ mۍP2r{ܘ¿ (#0HO,&LI-<]L kEb \,HoJ1eqÏ̼-H'(0&P>Z+<9Kix.EK!Bj(ޒ9yn4qѺGLrIU`㯕[X;SFD F.䏸:~RT9NY[|PY_>Z]ed LD)y)w\>桅?~ԗT$@I}Kv4(~"N蹥bލ8[ ""$ bd[  nv@v i Z<5UӉbAS+HNJnh(ҞZ\r C)E&xRȆwaI >n@#2pF$s_S&ʳ-4 \Chf-@Wa<+y2 ̲H? jƕB)ÎmP_bcȬ\I"*sNO$[`HI x#+}Dsfň`:SϯG_o@}~bvXHMa TBb+C10]3H*X&P8$c1k@܏wl Ÿ¡@)q 

l8i޷6Uk%t3C}&{zõmn$H_^,^Y?0&@;Vn:;O[(6XXO mҧ||,j!Z0#?'}A!q2k#2Ñ% _ 4`8@I`8Is抎0MC= } hѶ[QjQ<<IgrCbBTÚ vWZEDt\ pGpMJ YOZݒ&?r{6%8-emjtBꨟ胍Y9J7AJԠI"* xf@qʧ d)ưj9JY'r7>+mU /tCƙ% ꐭК@!QF.NFAVT^qAkݠ@~TA7F,2 S7`00s`Su~%%Δ=烎 ɒOO%s=1( >KcKnU5臤Rr~fKuH{1NA%.}4&90xO;h? Ā(3|5 E2A8aNl֐xǵPvpNXQI H&}ؚ[ 0ܠ椄q0Q0@'"Q$B*j( !ŤSaA ^Gp.ʔ>8P'c ),bǬA"4IF 頰ƫQB]HPoUA0)@,T~&<aS o)3l܌̂g6j(xc޸2-B󞕒T/ִD@z %D̉R]KE3*Hr- =*Ҳt/JP_ n Ȕ6iMcӜ┧?]MkK>$+KHZұ/JժZXͪVjUd `Ѐ6 zִլhU+[ֲunūZ%` u!Q̀`K*A}6UZͬf7j zH$ҚMjWZ ٚ(AͭnQ`SzM.rлt#!nf4tlpAټXK5^4uK3@}kv讀[vp =x!`Lΰ'GLb%N53xm/2Pxy6αwcAp4x0 wX ~qO,e)%gc`!;v9rds؁T'9j; JjX̐$9`Xb "ֲicC3Y5[5LbFFlfY. w^u0 g* C D =LوyMhA{UpbȀ28,`wNwB)V,C%@ yck`.Hp,ẍ+s+ka v0m:ȩ ?~v` ;B~m{A@a!>2(XˋãЁ)XBQ(Co[;\Vqu %85mATmE̓Z =@[?q]< @3hC@h1W'Wz>> *?DAk^w#p{Sx4(O}W8@0}<6 69F~,g=,o<_@yX{%!{Y``{_v^gp` '00Q0V{Wwɧ|L"_|}엂ח}}l``G%2g)wP(k" P" O_4u w!`S `pTX {Hf"X! #&x0tXvxxHPmptX| =(!؈Ȉ",xh>(88p0S `׆T1wb"`1DEzPt; ? Ë_ȉ8XX茽؍<(䌳DG,"+ 0?Cސ؏ ̨_sGА9Y 渑 B y8?w2N,"!tQ$4 Xp:6>Pf b` iN)0 P9Y[ƍ(X82+/ Vo1 0t9P|ٗ}yv)9A2`PY')əX)cYY;2(i֚Ykp !iy0Y#r0| wyFYYY ٝY*@ib ^qjBG^a!A0|0 g@%pY SP wI%p~)TWn ):o &0fgb`-g)Tri?8-: kePk0ФT(o`yNْzn mЦnwP @~m@`qZ P m@ m S` mj聢6%-cq`{@;{o)ʣ8FqȢE'&o'N Bz8p W'0b`]J)caj2gU\{|¦ SP p@ 4n ڦڦ:e ;%K+z pb`" X+ 00b"o*8`Y0/{ Y-zH"ȭTqk> 0C NPMKQS+UWY[xnl P n m@zlঁGq[ڦml x+ykr [[2칙@+w Y'{{:y`۳|/BF+$EpW{k;Ż̫ۼ˛K+ kѫ 07T @~T +싿lgnK0 18 "0%h ) +8Y ,.줞wR1 _Xppq .laA»{H@NPR@yD\. JLNPR Mu XZExp5}hjM7e Ers׾eS|~׀؂=؄SeՊX]!( P.PP9ֳ`+  6] f1Cfl0۴]۶}۸ۺۺ}lyt=]}ȝ4=]-|_=->qk -DPޟDD E9P ` nߋ ,0^~ ~">$^&~(.gŽ]M@M  P D DP  I>ތ LVOCNDK.T.  r>t^v~xz^矠 kNn胞臞*茾/ o8.013$ꮾ `EEP+ilM;@Nn+EPj컠껀2 w0vn/,>ĨNHa1@`3@`+ 0+PMӎӎ^@~2Mb-H83+>V0` ^fO~N_oq_tO.HJ0O0V?@4?@O`I?_/?zo'P[ Tao__5@I5@adI04 O_|?M=p_Aan#ځ'=^([=#X V;*fQ5:DjǂCs>%ZQI.eSQvUUWc eKWaŎ%[YL1([qSݻ:_v=%<7hZĉ/f\T‘fpkc̙5oڢ2dځԩUf@okرeϦX;@^6JqɕM9QkÎweuc{TrojyկgC_Ў}BS'o?m"= $kJAtIBrB 3V[GC^pD ST1 Bc AFsqGBVTџ-!B "aI`y+A u%0rG6[+M:ȝspO@%OU ӟ]1 G"T LXH""PTMӱtuVkY_VTIW`VXW-HU~Ղ$HGBIHb_U-4 \%UW]\]޴^|#q}}u]6]١f0X%T1\ssyo]6}%W׭|C^L^9dҵߞz}ecYic.ff_f^.eE b`ğ[\PgvZf0֔pIkliF !ex\ `pgAmRF}Bi&kA.)r.sCr ȅq&) āPwnQT0p! (}4;/^tEϧ/yzY~{{z/}6' |ŗ\ro9Xw@WO(1( @FP`-xA V N#$a MxBP+d Ձ ǃ2 m>jE}C d-l KdbD(FQSbxEh"1 }5PRPQkdcF8Qsd#&g[0FG@R$d! yHD&ҏ.("fXQ*P@H%" $2N~&G)MҔDe(K JU²| ` e/}K`S$f1yLdr0e"9IhCkZe+fU_|'8ũMlsLiffz5 xSg=yO|S<7Aw6r(`T_4 i^T1PFThE-zQfT@)PR# OB#+e))T .`iM;GN}S)4?%jQYzSFF3&JӫjdUhUkYVRXXAU,mUk]z,u]l*$E*U_Ș &\FleXf YnEAZ} AZУ^Sr[Vmo}[|.,Fd̠X2PUX[E\E]E^E_E`U("8HR-Q=38_m؁B { MUQTL%Q-l3$R]Eq|"`R`[8VdMVe]VfmVg+,R.RS@MM;؁-].`V^P;S/nR=P4R;Wz W,-Ԭ9*XX XM*{0!{XRUXZX*!hذ,X RU-qd/Rm?$@YYYjYV,Z.HWUnr`r֡Cӧeڡw؄;Zn-{װ%ۨ8 h[}[m[S!dr0zu8>@VxdwP.w8h "@w@px,7dK$L&eL6`Ni^inic6=riid>g-uis* ꡶7xk磮`:f'90j9jjz6v(n h꩖lkkȀ kklΚ8Nl^lnl~lȎl&\iFc&7`zF؁.B>@g;~jj6jj98v"vVݦm vPm-nnNnnh >f (o>o!`oFo ?VS n׾c&ݦ7p$胱&zp@ 8 $8p؞E90Dq9@# /(#:# q#@nq榰Jq r~XT ?r$!$w$$-`be>>1Gzr/ op p0{vPm>jHFjV.nk@:4?x7K4.#HqP7J8^S?uT!?^H0TX7~Uu\J F _uf0w_'_u.?ve_ve'se?eW*h]isvB6?F6PHnPv:m 9ywKw7/wKDDwK/D78ywJx!]y҄XNITTЄ}MyZVT`yy(yx] g?veOv^w8cov U 8w`9 3HP?v1 *Q/_{F"sqOh{||/|ÏOJ75UH6 `r_~Ph}x|Ɵ71vVS0688S?Y80^ ~zx x߁88e PgDOo{7R0Or'Gt#`{{̕>>,h BrkaCPhb }UjRJM3Q@%R?6i "ЊB8@Ҥ"2Q*b,owt)8iU HyG;gIpJ?YPUWѼ1/.l0Ċ3n1d 6f̙-}3f_\N\"7Y3lP +(6@M7ə*:0P\'E.5M-=8P5`6WVjmRoNeV7S[p]uSwWd * : :8cEs!j!zlv%x")-18#/;P4R/P#KX]FSd %;bv4Z)x1 ]z?qx t;0X 0 ٥?\2C{0` SV0*(:cVnZJPa4z):*j*Q* ?8\*;BK;ǒ)R) <ٲ_[ <T/;m .0t`u돻\ˮ,f`Ŝ p`_*0 ;0a2Z6?Y1!<2%?=)21G͐Ls):̑=@?/s GG t O<זh,`5 xAؘ`Ѐ_uksmv`@ژu[a >8^ƊQ";qbo#[~9ky~`,S=:饛N?NZb >;~;x‡;?,bR*+Ea?fH?=[=s ?>5>-{???ڻ(0RC v1s_P 3A yC(&!O B )RV"-rQ_S1f<#ӨF5=|"(01 Wia{NCH<$"E2#*dypMfrd&=IQғ*%'KI"D c)Y6s\!6)a<&2cnυE MȀҼ&5yMdsܬ7Mqb㔁^- '>+Jy%p'@πA t}c Ѽ(F3эr(HC*ґ2LCOҕE,epҴ6)Nsӝ>O ԑIQR;1*թRV*Vխr^T ufu(SOn}+\*׹ҵv+^׷gGY*؀u 02},d#+R] j,,Db=-jSղ}-lckv--AP-p+\=.r2ȥ`mQ2]r.xë xsxӫ U@uE]sz+XRBBE RÂ, ] x88C<)+XPc,+@#` 3 a&L@1Z`3(2"{}t f dd@kQ`/xp2rAd`r @L2 IYS#и1~u5Eű> ]hҖQ\L  AG #;\ #pCwB @kKC0`Z$yjP ɓvw`L8-X 3/=hIӸ4h-o9-f}[#0u A;Ʃ= 2:\(`>}"ԆF]o2 ƴ 0}+ W\폀cZ7™l}LЂIo~A7-=rw: K] ; Pr :@t|^ԧd:1w(Zg[B_I>CA?usOu}6:3o8x< l0 ӓxw@;X_ } x= ka_CAO؃;B]

遟z>octͳR"ԛ 7; 2hEQC Q}^_`:4A `:4lɟ +ձP@_ .Jѽy ,! 1!'x'++HC^ D!'DJ+FH xJ<,rB:aƒ|a"+́zr"@6a`a af"X%#|"((.("**"++",'>&j"..H-ػud00#+(020&2.#363>#4F1.-"6FT/ӽ@ |#88#99#::#;#%>65f#=*F5P76>#??#@@$AA$?5#@c=>$,T)E^$FfFn$GvG~$HHE>cAJJ= P L$M֤M$NN$OOH>)C$REKqETN%UVU^%VfVn%WvI%%Y*R O[[%\ƥ\,CQ%Yee^"%`]>da `J&f=:&,&c"&defd2T]Vg]h&i&d&6Bh&kkn|lD7&nn&ooff.q'r&r^ͦsfVt>'u>tuVvVfvUwn'x&w*xyFpby'{gz>D r'}֧}nbg{gq((&.(6h" Rb'V9] .|v~(JU.g:]^([^s%ިy:a](2։(iuhɖ.)6Vg)Z&bq-s}is!*"o )Nip(v ~)~'l @Wx!n|נi")!FXw‚qY*'`a!ט2pBئت^V6*2@U#?@-E+-[0Z XڴE$YڳZ=+Q jkRhޫBYcZ&dąhڗ@&\Zf¶zBdf+%MB뿝Z&޼+b+,a&>e 0[΁?p\ƕ -[ˍܶ-4E-4]]--C.\[ ]ah&BZާԨ_-lS5.6J2.`r0睛1}ƥb^:L_}.mA.hA a zn왜?.r2H pDNot@F>lo6Ώ/~?o6D 2@` ^`3>i`, 4.+½0+L`c N_:Jp.d@C02,0C+ "",_1,w%+)&q0]T 1-+\1h?P;EM1 3;aL^0a4ü_t:$Aq ?!2"{!s"7#?!+"$N#;!G%cr#k%;r_]E)a`)b@Z++#?_M {@2 31132'2/3373?33(!)?Q~%0/b`),j/I.;58'F/+xc;ֳ=3>;(QysCusmRj3Q7KQh  \t_@tChS]:5;TDS܀"Z DS t?D67D< o;-Ea1@2,S,+SrD7Ns?25,w( H]Cr9stdpVuEr][4!R$Iffo6gw6F$T?2Cp /KV[^|>@踛0@t@*45t¼5CDowt,E9o?6m3)KO+U7p6`KXo8je$"~!yy7zz7{{wz H6`sNC .qj084 nCs[Vow7`Cr+wQw?%,58Qsł56܀rw\{qwe:%Tv%Ǹ8OW%}?S,g@WC>?sk+?d5T>tXTG899C_܀;/`agwt[r ,4rI9eŖZΥ99]hDz~+T't7D*DLVuNx*ySy-D-_ kSVk XUW@9pL4uW8=U_N@X]DzXc@rұ'ts_X-%5uCrvO~/7{_{ﺻSm>8?-N3;DLFV3bH86><`T4 G՘NFC&wAQ*ܭoӺ'K"*n^ʫ|-XY&oηZPWSP'= 7?=GO=W_=go=w=؇؏=ٟٗ=3H@;giflib-6.1.3/doc/whatsinagif/image_data_block.gif0000664000175000017500000001027415166751647020136 0ustar esresrGIF89aT@@@000 PPP```ppp!,T $dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~WT }}S .fR ,`"+]   $# $$ ôN፞ "֪)zQB lt%!hny! zO@8N6"\>X@0EȤ( eGn hX҉ϯCwˢʔ{FG`mi.ؿ<ľ $32J>xf֭⧐˥*"R!hUQQfCLKEdP@H/[eeӔWA.40 Țս|]w"5LXvUxY9A8Y9wmNĽ(G`w,gg`wBA@5$(N(<XD #H8aH"9Z}^vap ? A;PSOuB@0 ԈC1@S* %H{PAQO&7][.O-`ya`^@'0!f }"00A`@S pˣD 5! `}&z,%!9KB-Hy#dXck )f0bZSBp*&Im@@n(P CJzZ'`9Ap+A0@ di=2m&>9mMxuciSf*  PL$H P̰qLɹ@ l-X& i&9!+agm$oCjR-->KRrlxgSRꞜdW"nslR'͸^<&KlEKM7y'D3H$ гЄkx{{ď1|{q|gOb?% OFpco2XP~ip?/=%~%_ zHL u 'HAƑ)xχ6z G$2! IqJ^Uͯd77CC?dz0aX#e_D >QkJ$}C!Jp1\*ܟ o1*RH1Oǃʨ:`Z^/G?6zUHC_`爩F:2(}@b1f `2B& U %1!Rt(X![V2M`y$Y 'K<:SdL-*O.@ H/P$(@NLUj< Koud !K^:x\ܦըUK>5)-_H d[R% WADMyܦ~կ#a˄4xYI8h`gpA l58$Ok5 5 ٍ:UqDhDԏ|F 1q@2$5J[ʐ 8eItBxL% 9CQ-E; b[L ((:55 "b]2aKIhg긎)Qz'8d$h;E7bJ}E A !)rGPSsP% !H܇(#`- e# EX&a&2DKB1Ò4B-((dhvBv&Fw qE_2Xd$V)8iR.ɇE-PW@0uX{H295*}ҔQ)Cّ4/9't vvFvgVr-IvM% IV?Ü`QBhY{kq䙝>2`f IJ:gWuS H~?Zs>ӡ< ɓ%2wFHvu^*!QК hnk="9v8.ӟ&p/C92Ek uY4 L5`C:kfU8s-0Dkoړ*Nd3iR ?j2 sr-0X{bL`PceXx܀:^%6S }7$`0`I2gZF6n1{2U߂ Y)Жӧ1I@V5 What's In A GIF - Bits and Bytes

What's In A GIF

(Bits and bytes)

The authority on the content of GIFs is the GIF89a specification. Originally developed at CompuServe in the late 1980s, it is now a W3C standard.

A GIF file is made up of a sequence of data blocks. The first two blocks are fixed length and fixed format. Later ones are variable length but self-describing; they consisting of a byte identifying the block type, followed by a payload length byte, followed by payload.

The following railroad diagram shows all of the different types of blocks and where they can be in the file. Every path following the arrows corresponds to a valid block sequence. The large middle section, in particular, can be repeated any number of times.

GIF file stream diagram

We will learn more by walking through a sample GIF file. You can see the sample file and its corresponding bytes below.

Actual Size

sample gif, actual size
(10x10)

Enlarged

sample gif, enlarged
(100x100)

Bytes

47 49 46 38 39 61 0A 00 0A 00 91 00 00 FF FF FF FF 00 00 00 00 FF 00 00 00 21 F9 04 00 00 00 00 00 2C 00 00 00 00 0A 00 0A 00 00 02 16 8C 2D 99 87 2A 1C DC 33 A0 02 75 EC 95 FA A8 DE 60 8C 04 91 4C 01 00 3B

Note that not all possible block types are represented in this sample file. Later we'll provide samples of missing block types where appropriate. The different types of blocks include: header, logical screen descriptor, global color table, graphics control extension, image descriptor, local color table, image data, plain text extension, application extension, comment extension, and trailer. Let's get started with the first block!

Header Block

From the sample file: 47 49 46 38 39 61

All GIF files must start with a header block. The header takes up the first six bytes of the file. These bytes should all correspond to ASCII character codes. The first three bytes are called the signature. These should always be "GIF" (ie 47="G", 49="I", 46="F"). The next three specify the version of the specification that was used to encode the image.

Normally the version string will be either "89a" (ie 38="8", 39="9",61="a") or "87a" (ie 38="8", 37="7",61="a"). All modern GIF-processing software recognizes both versions, For maximum compatibility, GIFLIB will normally write an 87a signature unless the file contains GIF89 features.

GIF header block layout

Logical Screen Descriptor

From Sample File: 0A 00 0A 00 91 00 00

The logical screen descriptor always immediately follows the header. This block tells the decoder how much room this image will take up. It is exactly seven bytes long. It starts with the canvas width and canvas height. These value can be found in the first two pairs of two bytes each. Both are 16-bit, nonnegative integers (0-65,535).

As with all the other multi-byte values in the GIF format, the least significant byte is stored first (little-endian format). This means where we would read 0A 00 from the byte stream, we would normally write it as 000A which is the same as 10. Thus the width of our sample image is 10 pixels. As a further example 255 would be stored as FF 00 but 256 would be 00 01 .

The canvas width and height are usually ignored by modern viewers. The GIF format seems to have been designed with the idea that viewers would render multiple images in a GIF on a common canvas, giving an effect like a picture wall. But nowadays multiple-image GIFs are generally used either as animations in which each sub-image is a frame or as image libraries, with the GIF client handling compositing into some canvas about which the GIF format holds no information.Thus, the canvas width and height are mainly fossils. GIFLIB does extract them and allow you to set them, however.

The next byte contains four fields of packed data, the "logical screen descriptor". To understand these, we need to expand the byte 91 to binary as 10010001 and look at the fields inside it.

GIF logical screen descriptor block layout

The first (most-significant) bit is the global color table flag. If it's 0, then there is no global color table. If it's 1, then a global color table will follow. In our sample image, we can see that we will have a global color table (as will usually be the case).

The next three bits are the color resolution. They are only meaningful if there is a global color table, and allow you to compute its size. If the value of this field is N, the number of entries in the global color table will be 2 ^ (N+1) - that is, two raised to the power (N+1). Thus, the 001 in the sample image represents 2 bits/pixel; 111 would represent 8 bits/pixel.

The GIF format shows its age here. A more modern design would simply have allocated a byte or two for color table length. But GIF was designed when memory was much more expensive than it is today, and the designers felt strong pressure to economize on every bit. The consequence is that color table lengths have to be an exact power of two. Perversely, this can force a waste of memory space in images with odd color counts.

The next single bit is the sort flag. If the values is 1, then the colors in the global color table are sorted in order of "decreasing importance," which typically means "decreasing frequency" in the image. This can help the image decoder, but is not required. In the sample file this value has been left at 0.

The sort flag reflected the high cost of dual-port memory at the time the GIF specification was written in the late 1980s. That kind of limit disappeared in the mid-1990s, and modern GIF software ignores this flag. Until version 5.0, GIFLIB ignored it on input and zeroed it on output; 5.0 and later versions read and preserve it.

The next byte gives us the background color index. This byte is only meaningful if the global color table flag is 1, and if there is no global color table, this byte should be 0.. To understand it you have to remember the original "picture wall" rendering model for GIFs in which sub-images are composited onto a larger canvas. It represents which index in the global color table should be used for pixels on the virtual canvas that aren't overlaid by an image. GIFLIB supports reading and setting this byte, but modern viewers and browsers generally have no use for it.

The last byte of the logical screen descriptor is the pixel aspect ratio. Modern viewers don't use this. Until 5.0, GIFLIB ignored this flag on input and zeroed it on output; now it is read and preserved if present. The GIF standard doesn't give a rationale for it, but it seems likely that the designers intended it for representing image captures from the analog television of the day, which had rectangular pixel-equivalents. The GIF specification says that if there was a value specified in this byte, N, the actual ratio used would be (N + 15) / 64 for all N<>0.

Global Color Table

From the sample file: FF FF FF FF 00 00 00 00 FF 00 00 00

GIFs can have either a global color table or local color tables for each sub-image. Each color table consists of a list of RGB (Red-Green-Blue) color component intensities, three bytes for each color, with intensities ranging from 0 (least) to 255 (most). The color (0,0,0) is deepest black, the color (255,255,255) brightest white. The other extreme colors are red at (255,0,0), green at (0,255,0) and blue at (0,0,255).

As previously noted, the length of the global color table is 2^(N+1) entries where N is the value of the color depth field in the logical screen descriptor. The table will take up 3*2^(N+1) bytes in the stream.

Size In Logical
Screen Desc
Number Of
Colors
Byte
Length
026
1412
2824
31648
43296
564192
6128384
7256768

Our sample file has a global color table size of 1. This means it holds 2^(1+1)=2^2=4 colors. We can see that it takes up 12, (3*4), bytes as expected. We read the bytes three at a time to get each of the colors. The first color is #FFFFFF (white). This value is given an index of 0. The second color is #FF0000 (red). The color with an index value of 2 is #0000FF (blue). The last color is #000000 (black). The index numbers will be important when we decode the actual image data.

Note that this block is labeled as "optional." Not every GIF has to specify a global color table. However, if the global color table flag is set to 1 in the logical screen descriptor block, the color table is then required to immediately follow that block.

GIF global color table block layout

Graphics Control Extension

From the sample file: 21 F9 04 00 00 00 00 00

Graphic control extension blocks are used to specify transparency settings and control animations. They are an optional GIF89 extension. The semantics of this extension will be described in detail in a later section (see Transparency and Animation); for completeness we'll describe the data fields here.

The first byte is the extension introducer. All extension blocks begin with 21. Next is the graphic control label, F9, which is the value that flags this as a graphic control extension. Third up is the total block size in bytes. Next is a packed field. Bits 1-3 are reserved for future use. Bits 4-6 indicate disposal method. The penultimate bit is the user input flag and the last is the transparent color flag. The delay time value follows in the next two bytes stored in unsigned format. After that we have the transparent color index byte. Finally we have the block terminator which is always 00.

GIF graphic control extension block layout

Image Descriptor

From the sample file: 2C 00 00 00 00 0A 00 0A 00 00

A single GIF file may contain multiple images. In the original GIF rendering model these wwere meant to be composited onto a larger virtual canvas. Nowadays nultiple images are normally used for animations.

Each image begins with an image descriptor block. This block is exactly 10 bytes long.

The first byte is the image separator. Every image descriptor begins with the value 2C. The next 8 bytes represent the location and size of the following image.

An image in the stream may not necessarily take up the entire canvas size defined by the logical screen descriptor. Therefore, the image descriptor specifies the image left position and image top position of where the image should begin on the canvas. Both these fields are usually ignored by modern viewers and browsers.

Next, this block specifies the image width and image height. Each of these values is in the two-byte, unsigned little-endian format. Our sample image indicates that the image starts at (0,0) and is 10 pixels wide by 10 pixels tall. (This image does take up the whole canvas size.)

The last byte is another packed field. In our sample file this byte is 0 so all of the sub-values will be zero. The first (most significant) bit in the byte is the local color table flag. Setting this flag to 1 allows you to specify that the image data that follows uses a different color table than the global color table. (More information on the local color table follows.)

The second bit is the interlace flag. Interlacing changes the way images are rendered onto the screen in a way that may reduce annoying visual flicker. The effect of interlacing on a display is that the first pass of appears immediately, displaying the graphic as a first as a blur and then sharpening it up as later passes fill in lines. That allows the human viewer to at least get an idea of what's coming up rather than waiting for the entire image to be painted, line by line. See an example. To support this, the scan lines of the image need to be stored in a different order than the normal top-down, separated into sections that will be rendered in four separate passes.

GIF image descriptor block layout

Local Color Table

A local color table is organized the same as a global color table. The local color table would always immediately follow an image descriptor but will only be there if the local color table flag is set to 1. It is effective only for the block of image data that immediately follows it. If no local color table is specified, the global color table is used for the following image data.

The size of the local color table can be calculated by the value given in the image descriptor. Just like with the global color table, if the image descriptor specifies a size of N, the color table will contain 2^(N+1) colors and will take up 3*2^(N+1) bytes.

Image Data

From the sample file: 02 16 8C 2D 99 87 2A 1C DC 33 A0 02 75 EC 95 FA A8 DE 60 8C 04 91 4C 01 00

Finally we get to the actual image data. The image data is composed of a series of output codes which tell the decoder which colors to emit to the canvas. These codes are combined into the bytes that make up the block.

There's another section on decoding these output code into an image (see LZW Image Data). Here we'll just see how to determine how long the block will be.

The first byte of this block is the LZW minimum code size. This value is used to decode the compressed output codes. (Again, see the section on LZW compression to see how this works.) The rest of the bytes represent data sub-blocks. Data sub-blocks are are groups of 1 - 256 bytes. The first byte in the sub-block tells you how many bytes of actual data follow. This can be a value from 0 (00) to 255 (FF). After you've read those bytes, the next byte you read will tell you now many more bytes of data follow that one. You continue to read until you reach a sub-block that says that zero bytes follow.

You can see our sample file has a LZW minimum code size of 2. The next byte tells us that 22 bytes of data follow it (16 hex = 22). After we've read those 22 bytes, we see the next value is 0. This means that no bytes follow and we have read all the data in this block.

GIF image data block layout

Plain Text Extension

Example (not in the sample file): 21 01 0C 00 00 00 00 64 00 64 00 14 14 01 00 0B 68 65 6C 6C 6F 20 77 6F 72 6C 64 00

The GIF89 specification allows you to specify text captions to be overlaid on the following image. This feature never took off; browsers and image-processing applications such as Photoshop ignore it, and GIFLIB doesn't try to interpret it.

The block begins with an extension introducer as all extension block types do. This value is always 21. The next byte is the plain text label. This value of 01 is used to distinguish plain text extensions from all other extensions. The next byte is the block size. This tells you how many bytes there are until the actual text data begins, or in other words, how many bytes you can now skip. The byte value will probably be 0C which means you should jump forward 12 bytes. The text that follows is encoded in data sub-blocks (see Image Data to see how these sub-blocks are formed). The block ends when you reach a sub-block of length 0.

Application Extension

Example (not in sample file): 21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 05 00 00

The GIF89 specification allows for application-specific information to be embedded in the GIF file itself. This capability is not much used. About the only known public one is the Netscape 2.0 extension (described below) which is used to loop an animated GIF file. We'll go into more detail on looping in when we talk about animation.

The Netscape 2.0 looping block must appear immediately after the global color table of the logical screen descriptor. It is 19 bytes long.

byte  1        : 33 (hex 0x21) GIF Extension code
byte  2        : 255 (hex 0xFF) Application Extension Label
byte  3        : 11 (hex 0x0B) Length of Application Block
                 (eleven bytes of data to follow)
bytes 4 to 11  : "NETSCAPE"
bytes 12 to 14 : "2.0"
byte  15       : 3 (hex 0x03) Length of Data Sub-Block
                 (three bytes of data to follow)
byte  16       : 1 (hex 0x01)
bytes 17 to 18 : 0 to 65535, an unsigned integer in
                 little-endian byte format. This specifies the
                 number of times the loop should
                 be executed.
byte  19       : 0 (hex 0x00) a Data Sub-Block Terminator.

As with all extensions, we start with 21 which is the extension introducer. Next is the extension label which for application extensions is FF. The next value is the block size which tells you how many bytes there are before the actual application data begins. This byte value should be 0B which indicates 11 bytes. These 11 bytes hold two pieces of information. First is the application identifier which takes up the first 8 bytes. These bytes should contain ASCII character codes that identify to which application the extension belongs. In the case of the example above, the application identifier is "NETSCAPE" which is conveniently 8 characters long. The next three bytes are the application authentication code. The spec says these bytes can be used to "authenticate the application identifier." With the Netscape 2.0 extension, this value is simply a version number, "2.0", hence the extensions name. What follows is the application data broken into data sub-blocks. As with the other extensions, the block terminates when you read a sub-block that has zero bytes of data.

Comment Extension

Example (not in sample file): 21 FE 09 62 6C 75 65 62 65 72 72 79 00

One last GIF89 extension type is the comment extension. This allows you to embed ASCII text in a GIF file, and is sometimes used to include an image description, image credit, or other human-readable metadata such as the GPS location of the image capture.

It's probably no surprise by now that the first byte is the extension introducer which is 21. The next byte is always FE which is the comment label. Then we jump right to data sub-blocks containing ASCII character codes for your comment. As you can see from the example we have one data sub-block that is 9 bytes long. If you translate the character codes you see that the comment is "blueberry." The final byte, 00, indicates a sub-block with zero bytes that follow which lets us know we have reached the end of the block.

GIF comment extension block layout

Trailer

From sample file: 3B

The trailer block indicates when you've reached the end of the file. It is always a byte with a value of 3B.

GIF
trailer block layout

Next: LZW Image Data

Now that you know what the basic parts of a GIF file are, let's next focus our attention on how the actual image data is stored and compressed.

Continue...

giflib-6.1.3/doc/whatsinagif/animation_and_transparency.html0000664000175000017500000005536115166751647022510 0ustar esresr What's In A GIF - Animation and Transparency

What's In A GIF

(animation and transparency)

In addition to being able to store simple image data, GIF files (specifically GIF89a files) allow for some special features. Tricks such as transparency and animation can be accomplished with the help of the Graphics Control Extension block. Here's a sample of what this block looks like:

GIF graphics control ext block layout

I'll show you how to manipulate the bytes in this block to achieve special effects.

Animation

Cartoons are created by animators who draw a sequence of pictures, each slightly different from the one before, which, when rapidly shown one after the other, give the illusion of motion. Animation in GIF images is achieved in much the same way. Multiple images may be stored in the same file and you can tell the computer how much time to wait before showing the next image. Let's walk though the parts that make up this simple traffic light animation.

sample animated traffic light

47 49 46 38 39 61 0B 00 1D 00 A2 05 00 FF 00 00 00 FF 00 FF FF 00 8E 8E 8E 00 00 00 FF FF FF 00 00 00 00 00 00 21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 00 00 00 21 F9 04 04 64 00 00 00 2C 00 00 00 00 0B 00 1D 00 00 03 30 48 BA DC DE 23 BE 48 21 AD EB 62 A5 25 D3 93 F7 8C E4 27 9A 1B D7 A1 17 9B 1E A0 F3 96 34 13 DC CF AD 37 7A 6F F7 B8 05 30 28 F4 39 76 B5 64 02 00 21 F9 04 04 32 00 00 00 2C 02 00 0B 00 07 00 10 00 00 03 19 78 27 AC CB 0D CA 49 E1 B3 0A BB CD F7 F8 CE 27 1E 62 69 9E A3 19 82 47 02 00 21 F9 04 04 64 00 00 00 2C 02 00 02 00 07 00 10 00 00 03 19 78 07 AC CB 0D CA 49 E1 B3 0A BB CD F7 F8 CE 27 1E 62 69 9E A3 19 82 47 02 00 3B

This file is similar to the ones we've previously encountered. The bytes start out with the GIF header. Next we have a logical screen descriptor which tells us that our image is 11px by 29 px and will have a global color table with 8 colors in it (of which we only really need 5). Immediately after, follows the global color table which tells us what those colors are (0=red, 1=green, 2=yellow, 3=light grey, 4=black, 5=white, 6=black [not used], 7=black [not used] ).

Next we encounter an application extension block. This is this block that causes our animation to repeat rather than play once and stop. The first three bytes tell us we are looking at (1) an extension block (2) of type "application" which is followed by (3) 11 bytes of fixed length data. These 11 bytes contain the ASCII character codes for "NETSCAPE2.0". Then begins the actual "application data" which is contained in sub-blocks. There are two values that are stored in these sub-blocks. The first value is always the byte 01. Then we have a value in the unsigned (lo-hi byte) format that says how many times the animation should repeat. You can see that our sample image has a value of 0; this means the animation should loop forever. These three bytes are preceded by the 03 that lets the decoder know that three bytes of data follow, and they are terminated by 00, the block terminator.

This very basic animation is essentially made up of three different "scenes". The first is the one with the green light lit, the second with the yellow, and the last with the red. You should be able to see three separate chunks of image data in the bytes above.

123
scene 1: green light scene 2: yellow light scene 3: red light

The first chunk begins immediately after the application extension block. It is there we encounter our first graphic control extension. As with all extensions, it begins with 21. Next, the type specific label for the graphic control type of extension is F9. Next we see the byte size of the data in the block; this should always be 04. The first of these four data blocks is a packed field.

The packed field stores three values. The first three (highest) bits are "reserved for future use" so those have been left as zeros. The next three bits indicate the disposal method. The disposal method specifies what happens to the current image data when you move onto the next. We have three bits which means we can represent a number between 0 and 7. Our sample animated image has a value of 1 which tells the decoder to leave the image in place and draw the next image on top of it. A value of 2 would have meant that the canvas should be restored to the background color (as indicated by the logical screen descriptor). A value of 3 is defined to mean that the decoder should restore the canvas to its previous state before the current image was drawn. I don't believe that this value is widely supported but haven't had the chance to test it out. The behavior for values 4-7 are yet to be defined. If this image were not animated, these bits would have been set to 0 which indicates that do not wish to specify a disposal method. The seventh bit in they byte is the user input flag. When set to 1, that means that the decoder will wait for some sort of "input" from the person viewing the image before moving on to the next scene. I'm guessing it's highly unlikely that you will encounter any other value that 0 for this bit. The final bit is the transparency flag. We will go into more detail about transparency in the next section. Since this image isn't using any transparency, we see this bit has been left at 0.

The next two bytes are the delay time. This value is in the same unsigned lformat as all the other integers in the file. This number represents the number of hundredths of a second to wait before moving on to the next scene. We see that our sample image has specified a value of 100 (64 00) in the first graphics control block which means we would wait 1 second before changing our green light to yellow.

Our graphics control extension block ends with the block terminator 00. You will notice this type of block appearing two more times in this image, the second instance differing only in the delay time (the yellow light only stays up for half a second).

The next chunk is an image descriptor. The block declares that it will be drawing an image starting at the top left corner and taking up the whole canvas (11px x 29px). This block is followed by the image data that contains all the codes to draw the first scene, the one with the green light on.

Green(Difference)Yellow
green light enlarged difference between green and yellow images yellow light enlarged

If we compare the first and the second scene, we see they share many of the same pixel color values. Rather than redrawing the whole canvas, we can specify just the part that changes (that is, the smallest rectangle that covers the part that changes). You'll see that the image descriptor before the second block of image data specifies that it will start at the pixel at (2, 11) and draws a box that's 7px wide by 16px tall. This is just large enough to cover the bottom two lights. The works because we chose the "do not dispose" disposal method for out graphics control extension block. In the same way, the third and final image data block only renders the top two circles to both fill in the red and cover up the yellow.

Transparency

Normally, GIF images are rectangles that cover up what ever background may be beneath them. Transparency allows you to "see though" the image to whatever is below. This is a very simple trick to pull off in a GIF image. You can set up one color in your color table that is converted to "invisible ink." Then, as the image is drawn, whenever this special color is encountered, the background is allowed to show through.

There are only two pieces of data we have to set to pull this off. First we must set the Transparency Color Flag to 1. This is the lowest bit in the packed byte of the Graphic Control Extension. This will tell the decoder that we want our image to have a transparent component. Secondly we must tell the decoder which color we want to use as our invisible ink. The decoder will then all you to see thought every pixel that contains this color. Therefore make sure it's not a color that you are using else where in your image. The color you choose must be in the active color table and you specify its value in the Transparent Color Index byte by setting this value to the index of the color in the color table.

Let's demonstrate this by revisiting the sample image we used in Bits and Bytes. We will update this file to make the white center part transparent. Let's start creating the Graphic Control Extension block that will do this for us. Again we start with the 21 F9 04 punch. In the next byte, we need to flip the transparent color flag to 1 (we can leave the others at zero) so this whole byte is simply 01. The next two bytes can be left at zero.

We must now specify which color to disappear. Recall that our sample image had the following global color table:

IndexColor
0White
1Red
2Blue
3Black

We already know what we want to make all the white sections transparent. The color white has an index of 0. Therefore we will specify a value of 00 for the transparent color index block. Had we wanted to make the red transparent we would have used 01, or 02 for blue. Lastly we tack on the block terminator of 00 and we're done. We have created the following block:

21 F9 04 01 00 00 00 00

Now, all we have to do is plug this into our sample image right before the image descriptor. I've placed our original sample image on a black background as well as the one we just made so you can see the results. I've also included ones where red or blue are transparent. The last three differ by only the transparent color index byte.

Original Transparent
White (00)
Transparent
Red (01)
Transparent
Blue (02)
previous sample transparent white transparent red transparent blue

This concludes our description of the bits inside GIFs. If you have not already read the documentation of the GIFLIB API, you may wish to continue with that.

giflib-6.1.3/doc/whatsinagif/sample_1_trans.gif0000664000175000017500000000010515166751647017611 0ustar esresrGIF89a !, -*3u`L;giflib-6.1.3/doc/whatsinagif/sample_2_green_large.gif0000664000175000017500000000033615166751647020743 0ustar esresrGIF89a!W!,!Wڋ#zyY詮P4jdO}!at[f‰)Ujjܮ[E㧬3זI mQδq6G1wQ))i5iYiI ` z)1j a:ڹʚ:+I[{+:[K,:IQ;giflib-6.1.3/doc/whatsinagif/sample_2_animation_red.gif0000664000175000017500000000015415166751647021300 0ustar esresrGIF89a !, 1x H!b%ӓ$3ϩ6jkDze>]/ϧ!;giflib-6.1.3/doc/whatsinagif/logical_screen_desc_block.gif0000664000175000017500000001461615166751647022036 0ustar esresrGIF89a^@@@ 000PPP```ppp!,^ $dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~{; 3 ' SGr;3& RB/a;%Q@,Ŀ`;2#P ?,^$ nx$тP!4@ATD+QK^}"=80B~ D8`wKpP*XKlBHƎV2|N88c xh >l=P X(l,$'`JIl>*,T0 xHეȠVāRd!DPkQ[TݖbDĶ"EL3:sY[&hj"@t%a8`1"`lJh x`~US];^>CDsd8=;RXDݨ@4&^ւH V%?͒!@)Ĵj\%5H( n^x#H69vZ{WW}bV% wƠ40I!EY$e%A+} Q@zs8b$ ZlV/$teP>EZtaXI$N9&Q~i" 2BΊn%!(] v!M{mmYJ s @$`X<%]`e$tS)fdI"dNtĪi%NJ٢*QY{ACp" U_~D\j_M6ƪ+HިSf(V\hb0/YB3Bsevb/LGqj#LyC*bh,m+HVk04 ~X;U,/e1rbobBcDk` C"x$bR!#jM.$qL%r P;,23B`~B&hf myI`CugNa 17>M&a("u9Gc0"TQL;ѱSmȫ-PoE01,<(oFx 0ژ@2@Yo#,á܊`]&~8%9 QTQH@VkCJCb@`a rwѱ 1C%/AS Rz`]p<p,*]LJC )p8e/w `Eb03o[#g-BYS#, _|E">,?"&79Mr~$(GQt0d6 yC\@PU~o pXx-k/n Ia]` *Mz ^^QalD@c0z1@ aO ȩ .ZRreW:Q;N*ЯSa4GHHFWp+"Pa|i*AC[F1g.P44t 4U71R3\D3Nd -PWM 5MRw8p5I kѦ1 r[ޙRJDŊaA"ƵCĮ?p ̾˚_j$+Y /3ێ-}]Jjrw^1b˅ (|LF `!̙F"DF^3I Ea"q̺2l;P:% yl2+vOYy? vȉ;dg2HXʜpG=b6\g?0S#dܨ77U:<$0/. $Aq+yJ/qn|{{@?!9޺g^7kuVz&}= Shnn4K|=`䥁*} exW6 (Q`3-kew4@[5HkGp\{+I8A1J& P8pp&?;(u!C:E8U"JNF^)?$ &H,@_$=A 0XF"=dq[Q pGV]P vsiLa`tPNO'X@|Ddf6A8i`?*p1{EATQAy a%h>x5 s& G7uVrfvTւ??VX{tTyWDSxs?hvOXWu7^3fl6yVO)-XYaVzgB Lu8xt#?DW`=0Bt@sv;h@~|aPɘ%LPzx 0 Z4i9h8>i&؍HWB J2YhKZSV!pZY?з^9c%\hUW bVفWURbr9O8v)]yh)lyMy9YyPpNi>~#`c2@܈c0p#ChgYAP!% I=20z>$ Q{ Il29 1"#U)ɝwٜD !;ט"vk$6F<Q/0#0eiw)V>E0W*i8 )"P@-J6%0@>" !1hU Nٜ#!/.Z0&:*9--3sBB3XfW=J J"u)@6cU쀒| EХop Cb:}}N&J:+2, U!6LXmk"*Z%e8DP>& 60  @E`6eL*Y cd LĪ尧,~Z:@{G!r"a|fPb  v%GL9Z z60PǮ*q'z-i(^[!ıU) pI_*X:Dm:bz '6 "8fJgtZ0jʣ)`*`jI9wP>h:'˯Z?K p BS::-Y52}pb-h3: R l3@GH.4Vev*@EgZ"N3I5Ђl2`K::ߋ f{)GIe!L^\uZ |p\<\| Jy,!,)% ?y:9: ;%‹bIy `,ӝ * 99晝ĵ ӧ[IO*QGK@6[Y ND?YR\t?J>7̢>pl:ŲW+}+-'\{AgkQ ȁclDe-Z~ŴܬHê ۩jSuzHqc,[tL)[-}[_LYʳA+7[6朓<_yK|[Zzr[45&g:&˸ T4a?»3H{Ӌ#b&9:'-}8ӟeA~Ylӕ"_y\^4Q9nyF%|UXM[51a=3@VwsN ?t(*Sa-!)CHZE6b4)lCͶ)0jPsɭ`{]h!y3`q1aPR&q&,A p&p_w+$R_G>&cިT1]DTS {F9 9E@ p0ļ'BAQ -zw}{rHϊbcrF\@@G/8^,Bn6!u?kxb-jbSq7#>hH1 !?6yG@LU1ts1]?#a ;9CIhW8 plC>3X7G}& @81=L6>@`w~p=[9{9636 9R^xp -u*.֖J_V( ~gšL<`DDDݫ*n*qcʱr&dh3 e␄aL.*,/? ^ۀ5?4` R=7 0MaA>^İ0N_ ՃvNZ"r?z_.ю:r3.vqs_@r=لaPn t0A.7f)\~{/ =ז '] =7D q8Ժ tsVLq9BW-ۍCtttijsZx?aG6y%|aN_A_wwgǔ$@8@@)Ɛ 5 !h<"%|Bҩ `x3!`T,x6傼 J,%x%|A 4 (hB,ĜENBT!Z" (48`(@0 CW9ܼ⚟ꪷ "D0!ÆX䀈 ŌJY# 5k@c&(sfEF(p X8"ˊQ d$ p A;D84bbsWBH"͖, 6ȲYBuco (# _ @6`bU@vX@H,Ճt@p*@P ="Qt5wA&"MAހ.3J~{dO:5<lA`QJ]o(k8W!@aƩ MXa{_}  ;@߆`2Eu4%IL=5PB C0Ao$ZW$M3^ HWWB@bX>" G ܨ+5ds0 XF!SP jFզS]1&ECRPzbiB @?J1PڪZ⚫ګ["2۬BR[ b;giflib-6.1.3/doc/whatsinagif/lzw_image_data.html0000664000175000017500000012501215166751647020054 0ustar esresr What's In A GIF - LZW Image Data

What's In A GIF

(LZW image data)

Now let's look at exactly how we go about storing an image in a GIF file. The GIF format is a raster format, meaning it stores image data by remembering the color of every pixel in the image. More specifically, GIF files remember the index of the color in a color table for each pixel. To make that clearer, let's review the sample image we used in the first section.

Actual Size

sample gif, actual size
(10x10)

Enlarged

sample gif, enlarged
(100x100)

Color Table

IndexColor
0White
1Red
2Blue
3Black

The color table came from the global color table block. The colors are listed in the order which they appear in the file. The first color is given an index of zero. When we send the codes, we always start at the top left of the image and work our way right. When we get to the end of the line, the very next code is the one that starts the next line. (The decoder will "wrap" the image based on the image dimensions.) We could encode our sample image in the following way:

1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, ...

The above listing shows the sequence required to render the first five lines of the image. We could continue with this method until we've specified the color for every pixel; however, this can result in a rather large file. Luckily for us, the GIF format allows us to take advantage of repetition in our output and to compress our data.

Much of the following information came from John Barkaus's tutorial LZW and GIF Explained, which seems to have fallen off the web. I've tried to provide more detailed samples as well as illustrations to make the process even clearer

LZW Compression

The compression method GIF use is a variant of LZW (Lempel-Ziv-Welch) compression. To start using this method, we need a code table. This code table will allow us to use special codes to indicate a sequence of colors rather than just one at a time. The first thing we do is to initialize the code table. We start by adding a code for each of the colors in the color table. This would be a local color table if one was provided, or the global color table. (I will be starting all codes with "#" to distinguish them from color indexes.)

CodeColor(s)
#00
#11
#22
#33
#4Clear Code
#5End Of Information Code

I added a code for each of the colors in the global color table of our sample image. I also snuck in two special control codes. (These special codes are only used in the GIF version of LZW, not in standard LZW compression.) Our code table is now considered initialized.

Let me now explain what those special codes are for. The first new code is the clear code (CC). Whenever you come across the clear code in the image data, it's your cue to reinitialize the code table. (I'll explain why you might need to do this in a bit.) The second new code is the end of information code (EOI). When you come across this code, this means you've reached the end of the image. Here I've placed the special codes right after the color codes, but actually the value of the special codes depends on the value of the LZW minimum code size from the image data block. If the LZW minimum code size is the same as the color table size, then special codes immediately follow the colors; however it is possible to specify a larger LZW minimum code size which may leave a gap in the codes where no colors are assigned. This can be summarized in the following table.

LZW Min Code
Size
Color
Codes
Clear
Code
EOI
Code
2#0-#3#4#5
3#0-#7#8#9
4#0-#15#16#17
5#0-#31#32#33
6#0-#63#64#65
7#0-#127#128#129
8#0-#255#256#257

Before we proceed, let me define two more terms. First the index stream will be the list of indexes of the color for each of the pixels. This is the input we will be compressing. The code stream will be the list of codes we generate as output. The index buffer will be the list of color indexes we care "currently looking at." The index buffer will contain a list of one or more color indexes. Now we can step though the LZW compression algorithm. First, I'll just list the steps. After that I'll walk through the steps with our specific example.

  • Initialize code table
  • Always start by sending a clear code to the code stream.
  • Read first index from index stream. This value is now the value for the index buffer
  • <LOOP POINT>
  • Get the next index from the index stream to the index buffer. We will call this index, K
  • Is index buffer + K in our code table?
  • Yes:
    • add K to the end of the index buffer
    • if there are more indexes, return to LOOP POINT
  • No:
    • Add a row for index buffer + K into our code table with the next smallest code
    • Output the code for just the index buffer to our code steam
    • Index buffer is set to K
    • K is set to nothing
    • if there are more indexes, return to LOOP POINT
  • Output code for contents of index buffer
  • Output end-of-information code

Seems simple enough, right? It really isn't all that bad. Let's walk though our sample image to show you how this works. (The steps I will be describing are summarized in the following table. Numbers highlighted in green are in the index buffer; numbers in purple are the current K value.) We have already initialized our code table. We start by doing two things: we output our clear code (#4) to the code stream, and we read the first color index from the index stream, 1, into our index buffer [Step 0].

Now we enter the main loop of the algorithm. We read the next index in the index stream, 1, into K [Step 1]. Next we see if we have a record for the index buffer plus K in the code stream. In this case we looking for 1,1. Currently our code table only contains single colors so this value is not in there. Now we will actually add a new row to our code table that does contain this value. The next available code is #6, we will let #6 be 1,1. Note that we do not actually send this code to the code stream, instead we send just the code for the value(s) in the index buffer. The index buffer is just 1 and the code for 1 is #1. This is the code we output. We now reset the index buffer to just the value in K and K becomes nothing. [Step 2].

We continue by reading the next index into K. [Step 3]. Now K is 1 and the index buffer is 1. Again we look to see if there is a value in our code table for the buffer plus K (1,1) and this time there is. (In fact we just added it.) Therefore we add K to the end of the index buffer and clear out K. Now our index buffer is 1,1. [Step 4].

The next index in the index stream is yet another 1. This is our new K [Step 5]. Now the index buffer plus K is 1,1,1 which we do not have a code for in our code table. As we did before, we define a new code and add it to the code table. The next code would be #7; thus #7 = 1, 1, 1. Now we kick out the code for just the values in the index buffer (#6 = 1,1) to the code stream and set the index buffer to be K. [Step 6].

Step Action Index Stream New Code Table Row Code Stream
0 Init 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4
1 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4
2 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #6 - 1, 1 #4 #1
3 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1
4 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1
5 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1
6 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #7 - 1, 1, 1 #4 #1 #6
7 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6
8 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6
9 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6
10 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #8 - 1, 1, 2 #4 #1 #6 #6
11 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6
12 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #9 - 2, 2 #4 #1 #6 #6 #2
13 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2
14 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2
15 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2
16 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #10 - 2, 2, 2 #4 #1 #6 #6 #2 #9
17 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9
18 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9
19 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9
20 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #11 - 2, 2, 1 #4 #1 #6 #6 #2 #9 #9
21 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9 #9
22 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9 #9
23 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9 #9
24 Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9 #9
25 Read 1 1 1 1 1 2 2 2 2 2 1 1 1 1...   #4 #1 #6 #6 #2 #9 #9
26 Not Found 1 1 1 1 1 2 2 2 2 2 1 1 1 1... #12 - 1, 1, 1, 1 #4 #1 #6 #6 #2 #9 #9 #7

I've included a few more steps to help you see the pattern. You keep going until you run out of indexes in the index stream. When there is nothing new to read, you simply write out the code for whatever values you may have in your index buffer. Finally you should send the end-of-information code to the code stream. In this example, that code is #5. (View the complete code table.)

As you can see we dynamically built many new codes for our code table as we compressed the data. For large files this can turn into a large number of codes. It turns out that the GIF format specifies a maximum code of #4095 (this happens to be the largest 12-bit number). If you want to use a new code, you have to clear out all of your old codes. You do this by sending the clear code (which for our sample was the #4). This tells the decoder that you are reinitializing your code table and it should too. Then you start building your own codes again starting just after the value for your end-of-information code (in our sample, we would start again at #6).

The final code stream would look like this:

#4 #1 #6 #6 #2 #9 #9 #7 #8 #10 #2 #12 #1 #14 #15 #6 #0 #21 #0 #10 #7 #22 #23 #18 #26 #7 #10 #29 #13 #24 #12 #18 #16 #36 #12 #5

This is only 36 codes versus the 100 that would be required without compression.

LZW Decompression

At some point we will need to turn this code stream back into a picture. To do this, we only need to know the values in the stream and the size of the color table that was used. That's it. You remember that big code table we built during compression? We actually have enough information in the code stream itself to be able to rebuild it.

Again, I'll list the algorithm and then we will walk though an example. Let me define a few terms I will be using. CODE will be current code we're working with. CODE-1 will be the code just before CODE in the code stream. {CODE} will be the value for CODE in the code table. For example, using the code table we created during compression, if CODE=#7 then {CODE}=1,1,1. In the same way, {CODE-1} would be the value in the code table for the code that came before CODE. Looking at step 26 from the compression, if CODE=#7, then {CODE-1} would be {#9}, not {#6}, which was 2,2.

  • Initialize code table
  • let CODE be the first code in the code stream
  • output {CODE} to index stream
  • <LOOP POINT>
  • let CODE be the next code in the code stream
  • is CODE in the code table?
  • Yes:
    • output {CODE} to index stream
    • let K be the first index in {CODE}
    • add {CODE-1}+K to the code table
  • No:
    • let K be the first index of {CODE-1}
    • output {CODE-1}+K to index stream
    • add {CODE-1}+K to code table
  • return to LOOP POINT

Let's start reading though the code stream we've created to show how to turn it back into a list of color indexes. The first value in the code stream should be a clear code. This means we should initialize our code table. To do this we must know how many colors are in our color table. (This information comes from the first byte in the image data block in the file. More on this later.) Again we will set up codes #0-#3 to be each of the four colors and add in the clear code (#4) and end of information code (#5).

The next step is to read the first color code. In the following table you will see the values of CODE highlighted in purple, and the values for CODE-1 highlighted in green. Our first CODE value is #1. We then output {#1}, or simply 1, to the index stream [Step 0].

Now we enter the main loop of the algorithm. The next code gets assigned to CODE which now makes that value #6. Next we check to see if this value is in our code table. At this time, it is not. This means we must find the first index in the value of {CODE-1} and call this K. Thus K = first index of {CODE-1} = first index of {#1} = 1. Now we output {CODE-1} + K to the index stream and add this value to our code table. The means we output 1,1 and give this value a code of #6 [Step 1].

Step Action Code Stream New Code Table Row Index Stream
0 Init #4 #1 #6 #6 #2 #9 #9 #7 ...   1
1 Not Found #4 #1 #6 #6 #2 #9 #9 #7 ... #6 - 1, 1 1, 1, 1
2 Found #4 #1 #6 #6 #2 #9 #9 #7 ... #7 - 1, 1, 1 1, 1, 1, 1, 1
3 Found #4 #1 #6 #6 #2 #9 #9 #7 ... #8 - 1, 1, 2 1, 1, 1, 1, 1, 2
4 Not Found #4 #1 #6 #6 #2 #9 #9 #7 ... #9 - 2, 2 1, 1, 1, 1, 1, 2, 2, 2
5 Found #4 #1 #6 #6 #2 #9 #9 #7 ... #10 - 2, 2, 2 1, 1, 1, 1, 1, 2, 2, 2, 2, 2
6 Found #4 #1 #6 #6 #2 #9 #9 #7 ... #11 - 2, 2, 1 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1

We start the loop again by reading the next code. CODE now would be #6 and this time we do have a record for this code in our code table. Thus we dump {#6} to the index stream which would be 1,1. Now we take the first index in {#6} and call that K. Here, {#6} has two indexes, the first of which is 1; thus K = 1. Before moving on, we add {CODE-1}+K to the code table. This #7 is now 1, 1, 1 [Step 2].

I've included a few more steps so you can see the algorithm in action. While the explanation may sound complicated, you can see it's actually quite simple. You'll also notice that you end up building the exact same code table as the one that was created during compression. This is the reason that LZW is so great; we can just share the codes and not the table.

Saving the Code Stream as Bytes

I've shown you how to go back and forth between index and code stream, but haven't told you what to do with them. The index stream is used to specify the color of each of the pixel of your image and really only shows up on screen. It is the code stream that is actually saved in the GIF files on your computer or transmitted over the internet. In order to save these code streams, we must turn them into bytes. The first thought might be to store each of the codes as its own byte; however this would limit the max code to just #255 and result in a lot of wasted bits for the small codes. To solve these problems, the GIF file format actually uses flexible code sizes.

Flexible code sizes allow for further compression by limiting the bits needed to save the code stream as bytes. The code size is the number of bits it takes to store the value of the code. When we talk about bits, we're referring to the 1's and 0's that make up a byte. The codes are converted to their binary values to come up with the bits. To specify the code for #4, you would look at this binary equivalent, which is 100, and see that you would need three bits to store this value. The largest code value in our sample code stream is #36 (binary: 100100) which would take 6 bits to encode. Note that the number of bits I've just given is the minimum number. You can make the number take up more bits by adding zeros to the front.

GIF image data block layout

We need a way to know what size each of the codes are. Recall that the image data block begins with a single byte value called the LZW minimum code size. The GIF format allows sizes as small as 2 bits and as large as 12 bits. This minimum code size value is typically the number of bits/pixel of the image. So if you have 32 colors in your image, you will need 5 bits/pixel (for numbers 0-31 because 31 in binary is 11111). Thus, this will most likely be one more than the bit value for the size of the color table you are using. (Even if you only have two colors, the minimum code size most be at least 2.) Refer to the code table above to remind yourself how that works.

Here's the funny thing: the value for minimum code size isn't actually the smallest code size that's used in the encoding process. Because the minimum code size tells you how many bits are needed just for the different colors of the image, you still have to account for the two special codes that we always add to the code table. Therefore the actual smallest code size that will be used is one more than the value specified in the "minimum" code size byte. I'll call this new value the first code size.

We now know how many bytes the first code will be. This size will probably work for the next few codes as well, but recall that the GIF format allows for flexible code sizes. As larger code values get added to your code table, you will soon realize that you need larger code sizes if you were to output those values. When you are encoding the data, you increase your code size as soon as your write out the code equal to 2^(current code size)-1. If you are decoding from codes to indexes, you need to increase your code size as soon as you add the code value that is equal to 2^(current code size)-1 to your code table. That is, the next time you grab the next section of bits, you grab one more.

Note that the largest code size allowed is 12 bits. If you get to this limit, the next code you encounter should be the clear code which would tell you to reinitialize the code table. You then go back to using the first code size and grow again when necessary.

Jumping back to our sample image, we see that we have a minimum code size value of 2 which means out first code size will be 3 bits long. Out first three codes, #1 #6 and #6, would be coded as 001 110 and 110. If you see at Step 6 of the encoding, we added a code of #7 to our code table. This is our clue to increase our code size because 7 is equal to 2^3-1 (where 3 is our current code size). Thus, the next code we write out, #2, will use the new code size of 4 and therefore look like 0100. In the decoding process, we again would increase our code size when we read the code for #7 and would read the next 4, rather than the next 3 bits, to get the next code. In the sample table above this occurs in Step 2.

Finally we must turn all these bit values into bytes. The lowest bit of the code bit value gets placed in the lowest available bit of the byte. After you've filled up the 8 bits in the byte, you take any left over bits and start a new byte. Take a look at the following illustration to see how that works with the codes from our sample image.

Encoding LZW Codes

You can see in the first byte that was returned (8C) that the lowest three bits (because that was our first code size) contain 010 which is the binary value of 4 so that would be the clear code we started with, #4. In the three bits to the left, you see 001 which out or first data code of #1. You can also see when we switched into code sizes of 4 bits in the second byte (2D).

When you run out of codes but have filled less than 8 bits of the byte, you should just fill the remaining bits with zeros. Recall that the image data must be broken up onto data sub-blocks. Each of the data sub-blocks begins with a byte that specifies how many bytes of data. The value will be between 1 and 255. After you read those bytes, the next byte indicates again how many bytes of data follow. You stop when you encounter a subblock that has a length of zero. That tells you when you've reached the end of the image data. In our sample the image the byte just after the LZW code size is 16 which indicates that 22 bytes of data follow. After we reach those, we see the next byte is 00 which means we are all done.

Return codes from bytes the basically just the same process in reverse. A sample illustration of the process follows which shows how you would extract codes if the first code size were 5 bits.

Decoding LZW Bytes

Next: Animation and Transparency

That is pretty much everything you need to know to read or generate a basic image file. One of the reasons the GIF became such a popular format was because it also allowed for "fancier" features. These features include animation and transparency. Next we'll look at how those work.

Continue...

giflib-6.1.3/doc/whatsinagif/sample_1_trans_blue.gif0000664000175000017500000000010515166751647020620 0ustar esresrGIF89a !, -*3u`L;giflib-6.1.3/doc/whatsinagif/lzw_image_data_code_table.html0000664000175000017500000000564715166751647022230 0ustar esresr What's In A GIF - LZW Image Data

What's In A GIF

(full code table)

Here's the complete code table that is generated by the sample image.

Code Color Index(es)
#0 0
#1 1
#2 2
#3 3
#4 clear code
#5 end of information code
#6 1, 1
#7 1, 1, 1
#8 1, 1, 2
#9 2, 2
#10 2, 2, 2
#11 2, 2, 1
#12 1, 1, 1, 1
#13 1, 1, 2, 2
#14 2, 2, 2, 2
#15 2, 1
#16 1, 1, 1, 1, 1
#17 1, 2
#18 2, 2, 2, 2, 2
#19 2, 1, 1
#20 1, 1, 0
#21 0, 0
#22 0, 0, 0
#23 0 ,2
#24 2, 2, 2, 1
#25 1, 1, 1, 0
#26 0, 0, 0, 0
#27 0, 2, 2
#28 2, 2, 2, 2, 2, 0
#29 0, 0, 0, 0, 1
#30 1, 1, 1, 2
#31 2, 2, 2, 0
#32 0, 0, 0, 0, 1, 1
#33 1, 1, 2, 2, 2
#34 2, 2, 2, 1, 1
#35 1, 1, 1, 1, 2
#36 2, 2, 2, 2, 2, 1
#37 1, 1, 1, 1, 1, 2
#38 2, 2, 2, 2, 2, 1, 1
giflib-6.1.3/doc/whatsinagif/sample_2_animation_yellow.gif0000664000175000017500000000015315166751647022040 0ustar esresrGIF89a !, 0x#H!b%ӓ$#ϩ6jkDze>neNuC;giflib-6.1.3/doc/whatsinagif/graphic_control_ext.gif0000664000175000017500000002035515166751647020747 0ustar esresrGIF89a@@@ 000```PPPppp!, $dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N-x1: 9~#Hz[&2 1(08  #<  " V*F'/7" 9  Gͻ# " "# @zE@`H |c vITc@, 4X^BSH=nqT8!]tЗHJJb֢UTjUiG:GvDk%d* ?U2 [ɘ($p,JJiSUGmh%2S-bׁQ+LѦ u+ fgF\޸y& C3>4g; w7kz(}S鲃@j|}e 40ܑ"+ |ULTMd@L0)Th s"A蘮8ԉ[z' s)3a3$,a> 6'ݪP>*dCb^B@< ,Väf\0DK+ 3Ljyo a`bΓN'&mfSBikr?0 b" ȍfm9 bg"fP=o~60@b0+ FCAq^,$ q0;#J2بO!}3` WY0as3Th^׮D`@0 @, met#(&k1 0m.0qBЪӹ= AUҤF<;x|4,1TrMc$y5kRʖ@õr,ZV޴)0>2Njp"DGNʵ̀CIP O\NxP,`$XϑXzPC(Ð/>,'T`~ !Exɹb{% GO̺$DO^`xmj}NL 4yjKwP+pZho1El4&|C'b-Cտ<5rG)gjAȄеQlf4\Ҝ z`"` ᓜe lveJF[|̀K:Q4)&L藺y[xc"&H3 6,~yd rwg>xmDzz%>H:sWWê%n3?S1G85j. @J 4\z"0Nmc;\ ےCb|Ѳ3abS N 0:ᧃu\.%YRI+wN= l=SbjۏvKD k _WdHrt$D`}BHnGMs nrvDc Q /tÇy:j(H^$<<ݲj.y7D/\% 3ZK884P엃>;_nD+oGF0Z.PY b'`<SE( AVH*%c*0H4]tzYCEM -`NvIE bHdô r I"Eeuhtŷ6! D @B2KU.10 ^ 5 '$ U`C Gab(p! pX~A4[8@% u4Dݨ 'WgW]"D#r Ɂ_h&򇙀Yx'ljHiٓ=Ёݹ )$YixiZ)aOXg̙ @ȡi pk 4%M%тhjj J699Ƃ֕#Zf *q'wAJKJcU@\_8 畖pT&'d1B)&&OD(`lТ? 5P%~ItnAbQyyP"`T#XF# & V90Oe_Zx[Ni0zg_IirP>L$*ONZWpJ>zbDaJ6J0Y,0 qw0ʬ)4dr 2ahPvJ)I1 ,+ s6`6ۨLPJH8i:kk)RxEc +;i:Ӫ7_XeF[WXkRи۲XD1U f)sK+"QqyI]BV 7 ]йj2*ll JڢTAX01$9rW!YTр/&P0"Yڶb Rwm:") ^f1  $eã0 #4O%F(o *qdEJ `B+A鸴R6`UB(7cJ. mqLh\## <5 t2'! ں;qrAbv U U'_Yܲ+16[!224<ؚVTm1mjs`L\+IsC$!3yY`=']1\ɔ μМ `rf x.jόmеE̘;ps(3{-d&g(=-nI ݸg<*iÊ9cFO@1FaI)KDMI MMxIOP\͘IF}FM]KhmYAn W%q]nq-y|~׀؂=؄]؆}؈-xTAkT=F-U2VfP B)s}EW$x&0aj*$(/l ! + 4%(Nmn##@-i~.suA~Npꝁwꈮ3h&A! Ba(Fq 0q鑡&@^ؤs!y؎¤Nž+N X9Q j$$7>+~0#C 0nA並*.nOU\h|>b8]N.bf_+`m%+_(3d&$zΓ$òOo#dgU?Ew >i& Ee_`ρlsS_&EIK|=No@51<&},pn>Nu"N3$Wo ">(fda8SrU?&Pyܮ"m _iȯf &Y#ңQA.(-2'8sq3/>e/0130P3< 8 XAC2};M^o׃|%|B)j,1lj5~譼nzyz  "&*N.:>BFhUZ^bfjnZpH̠֢2 #/;?) $x:(8x&|O P[chv4C{I4<|28X`@@hD<'_$&\HB{L  0KD DT!xn|  (q Su6q. Tbze8@ E ,  d\l^EwZVOj xR H x   E[N|A/ #G<²΂_Æܦ+ pNlٹԆ[('BsY83QwL0.IJ'xid9JFdYaehȔh @@ !>Kb0 R=@*/s*@*j *]橯/A,`&CFCBBR[Fd )!mlkn(ZrV"V%[ %:o3Ap _x8\E4@q1#r& 2+1362;s01Cc>G 8@F%,L!Ft7f@HU78؃Zo3fmR/Ҥ {Y &o=KЋ*; + emC- P G7Y@5g^j`܎'F٦ XC5+0 @$H NT - xRKK5 5hIl'O6)!d6Pe} XJ6Ƞl(<1ea 83!wBb4*QxQ4B:z9VQL0\b* n4*$ PDc3uz."kU@"ӕ*p:q;![EEsAH@NB(r jEYAD!, p Av-.?:y8̈nx*̒} ٣jc=jbX+(YŤ@ ֤`}V0~zf}MFKR\<*u-P79zXeM[r:%,.)JLQJh5R<$RL2L㳉싖]]hf8bEz׻/n+`tT(EE/613-QoB#3âLH(RP`hHHVqma`bu8 @H'kLxVdo2ޑop1fu%.p^*f+ 8e@5; f:pmLs%gw P-k@>gXdwbFaB TYΦ.Uܮ|~( rf@ꙗ(`tiIKp39D󴖕P=[i:)@. K`yQE#֥5ʧg2E@5DmDlc}BfUmUOz#A*w?}7MpwXC~K~+Ơ?E/ رG A 9 /h4M1b<уM b &M dA0t1*?.tcP/Vj|ɶ-000L53.fzC`L]v:0ф 0/ )@B6^y-~4ySXO")J.d/XJE1఻wa(;.ho^Gӣ\n7sDyO]ܶf6>%PTqy&t!xp:(E_a!50Ӡr 1C+Xaa#P ]8Pi]!p##/ƨe=0 0@`1df$X6$I0m^$ئ& fP`^ৈO[&h"P@eF*),b8ef馜`Sjzj_@>VH!q ɽ+­P kP:,r5bf_E>|acRk-j+^[ؐZ뮻D80j1 7.PD`M[l 0q 3lp M, PZ/ZLd,2@aG 3l+2p1 ]MCg $U#S$A$K~, |a;m4DgD̅!Kd" qǃ zZ EQ{X4 "b0re|mLƗC͑(. dQK_P_~@dp):R̙$)I?K@c&#!̂-YſE!E\9d5=&3"]ͬ'`qq5)rn[giwsh!iA] BՇynED}ofRl QJt]!.Z bj>ttS&Јg֋j) 1S֡3u75eN/7x3G{Qz}"$`R4trx79qIUՆ-`4)OEgVwַf \ܢ`.B `jJ/zPS}F^J,zӛh կ"Bb]dA.8u@k)]}9Sdi_׃Qm-F=1.ö ZIH-iu.MPp"{Ӌm1) d@`F=D@ [8ΰ|a c/ (N1 hq_3q@>60}`n'5, ◽V/ kf9Ro3Ї2/__GtI7}O+E2Y#q`Jc{e }G]s7ۺv _]_t' .xo>ww4klK_/oO>|ˇWr&qp%u`r^rfxGkqfwJzzi{-Gp'Utwlgxpu|vMu` ed@yzm7fgցo۷wfjhhhwhw5X nD Fx^HvJ^ls@h79w~xFg!Ѕ6V2hXm8R(yV'p8EA7}&}ԧn^ 0^%rN:@_,+|}Аi9 2 Bpw P2i' @w6}@'%7%xkNv^Aw^‡>%7 舋xap{h+"p{P{G  mB03gfX9|h9PfHu:|׃P#'~p:p~@2e2x}5ه3  XfCdfmC # ؘw2 PgRPoA7^6e >(8l|Fihƶ1hlG04pNiؔ}\)RIe&3Gu]Ȇ;u8QP-9Duq''*sI:`Gk^FSZO9?ٙWwJYf^ay~0y@Z&_DО- (pX,8Yv헂iYl+laИtl"VxYHC}39gJ^  <8p^ s):y?r VO))) Ř"z*L@f㕬i}VzfM(Kɕآoi.Xj9M$W^*,$~GIolꠅ@ʧ^ݹ3cJ( $ـ&ـ(5 :i&8ḣ eC 7 㹪"qꮂ*JZ~/]Z*Rfh:|`lG X'JZq y*ffYfJK|Ю}jE v^7vYv.9:Z@ o..p}PGk۴⹔ډDZr^*P{2Pʬv=|@813k:ZapzAK᧔p s[fjL9jR e Х|9Ei?"ڧ395Н8 V%Jo Sb9Bz^ ``񍼛R,ֲhFp+40lm,G,6i֦.`{[ʊ'D+Dp0 e{0  ٧Z IDlqKęƽ^ɩœ:Yx\s8WZ&@hm hȿi,igƉ@f5Iə#JF|oCp&žP+y*Ƀ]]ڧw8p%0ҩmȉu8l ~"^^׈{^JbN{|PX|k8@eX;;Zw7 5Ұ։uau zhʊR̐Lx\x)̜ͥ'YzEyω'hhh80h\lu,Bn@ $&|}f}pF7:F*ENߚVJg, |f,`o'> `meΜeg昐vʶ)P@+.jZ^s^.ja>zZ,>^~阞难`e> ~e,. !0^@=P*^=.О~3޴[Ip9,e@@S4e0#PUN ^D[D:h?-unNdpBCdUPpMH4\\o`z\Sе7;ܴR99?3>#:>7UJ UY9SIR:G3BH*@.?3PO32/Do6?E-|'/X/A0.W21/ZUL{dVZ-sVdOW ~G4QrY $bh#xP?Q@0?Jx`_~6w/p=ֻ퉌a.Lε'¯o{]ʯ/Qc}=mޏ D! "1\0/|/\+|\\}%Y%} YY YY]˨0҄+\|ڍ}f]00&`` H 2gд1:Zj~'.]t(# / CzT4R0cʜI/yˆ;U$ 'Mb+BM5զիXj݊jԴ9H#@]d88LJ@2Lyp^ 1 0@*^Z榜v Й#hIARC `% .4`[}( pzjjj.#O|X"ęFXF >ɬ> Q +t;`k-K޸-YH~FFE`:%w1/l#ЮȆ j6C'[lX7W a{boqD*#+ ?"A;C  \"e-`Hm薸o c9ugy{mVO5`["9'qb및y*+"/Oꔫȏ6;*X8d_%gwイ[XЋMb7fNó^J/Lu>!G+|B;wLFƁZL,q=KdX̠ W JȢF2,h @4 .;̊(ԍn'0Xb .z)H(act0*pc, 8QM(ʢ XA+$"c))JZ4&7ɕ!C (/QRiN)J&0TZ*n@%b2T@ Ќ4HDpy ܠܔ& 4@vn -r':clg ~vxf8y'XsD`  LPNyn /Ey.a|ր JL`hBQ`=@Q gްs-J L4xBL2O)CZ ]PjT| JeZG_<Lf5](X7j4uB zϳnf hVA8{L0 /7U g 0`>tɃEŭ|q+g渺wspXu4 Už\gZ|.0Igҫ$[;^ IS,V'^=R˨>#hڥLY/ZQy]u_W>xh{| 9 \'yM~u#oqKǻ T<^RQKɃ"<0boV_c  T@ }; H{؏gF'5c#00`uB,%[GlMx7H blz>S@>'k>@S`ePQWJ(P~tG;k'#P1"iP%B$ iI8%s!]`eft8'hdp~DdDfxOl肎SlHG"P278imP-'bp'V ړuNxl^b 0m]l  p 6:@dD*0nxdlJ4Xm҇P-;'&x1EuiՈz86cC6 o`@RgiKwi(O6K:H8/-s#V1 8r]E]ecځj0s%Z~p)؍xi~0exi|H 8rXӏ,oϠPa0%]ŗvPh!HR:#x%8RPPD0iЎ!qheq"Hp-3Ҁ.I_.6leH00 pIPhdL4ewuq gPy#''25s6`!} ӒeZppe`u[O&D@OIOqGَ18țnR36`4ƘRZքexgerW}wwwklx tWnKIG֗zطzv!0lWwUVywExafNMizu nӠ xyԷ zzW: 'ӗny}‡i@0z@P0:2vj砊; ;ڣ$fvbq`cv8nD<ʤZ?fzg:h *lWqF^PpxE$"}*HGs$MJP⨐:zc" @ y$UV#tU70YLpPMWH e'WתbP=<@jTgEMXQu׊M EZg_AͪuZ@E^O^޺S5Zth`骮Ǯ஄:aO`^WSR^eb;kk [V<<аPNZuW%fQ+뱶F5%+'KU WTS.N0S X6{8bij%uR?KXPM3bղ<1\@մNUHRkRdPev:dS]M:aN@%Tf{hZ:m,sEYYWzDf[Z d[04 hR(e` ۻ}*EؓY@)zUC0fŋX C `&; { 0f[/ 0EZ!:9ۼ۟W۾` P  }'phy @` G>ڿ|\,: , 0fP/u: L!M |=ڽ%[ekիk1<+]  f 8 & !|$\94)L-|RLߑ6`sy0!f6K8 23s0BX6Ň<[vD L|m:& (<|?۴  ız` %[j=| aư@ vPa@f `sZĕ3˗PL|VF  Ugvo%op@6})c m z<͸u#cPQ Y{,pl*,|.|٫uWr(W(gelCfĴuz ̀ h$ ͬyj)uʫ]sB<H\=r+-=/]Ϲ KӾ, 8 ;mr:M{1 %A][@[N=>ͨWm]Ψ &xm Ԛ, R$b $ !gD wq)hOfS3{p264a`8x,o%g͝o=}̭u[̭5N!M͎ݓmٱޙm[Gd |H !V 3o4}Pg?)OP: @ڐ~顃Z="`#x2|e 1l ̚2_} ƃ /  V`A})F=|[$<@[XĈ=%R~ 4QG~~Yp荻'y2#6v!>~mjk,1!Q` |㆞mG MΠ1m3 p $Md|x F*˦= T$rܐFJ'NM-Ț\j*"`' svy f,m }Ι [#Τ^0"߫>8 ^Pv끸,"x-H`)\qom_l0pd}J j` ✙f {>$}X@ɀ iPU"%cexq=n0960I0>[K=D 8 ߋ4R1̆f9i ~~gKFD7S I)1׼ÓdtB B uSy k믍 Čh"Hס|Y|?p C`G@s0NLl~0hoOFa]4~1E{ N4@%:f kBl {Zs2mOޏ/ r|/\+\/\\gP0] }YY}Y4~ (~(((ق݂&ÿ̜6m5lඁ HIHŋ)ר] I@?OJ;ypBp =$͛8sTG#C;rJ\Z3È;JJE@ okp)LF!Aʶ۷p[i`FnM=zQ.È;, zJ,hpiS_PL>$Xͺ5?c'!GŃ۸s#ȓǀ#s"8&b$ZFr18Tu-Kē`>Z~@:LC,WVe=`uPa*@B%(Uq9R_+.4ѓl_X TS_)E4<>n"c Lp%!`^YTQt@ ||Ur͘epf('c9W ׅ69BdsN.P<^jgY:e&NRk B" _nR@yBQAPk ֐Mhf\:L}&dAd/ӰBM Bg!D epy٠tX""Bs7 x ej@_9 uUD< xJT2 'q@+X > q.* Xc.Ha`c v !QFJ25AVèd?qGy%`l5X B*A|gL %UI |ζ'i]/}C]p \hXG4q?SA2_8 ? /KKw >zR=U8 '>1~"4 8U(*)Tt'юzHGJҒ"J2JI*ҕt@xL;ҙ4_MwS(= PKӡRԦ:PTJժZ5o:]J;LtTQWGUOG0 luk%b0)hP7yP׻jE{[p  @fF/!W;ЁD|(٭#vaoF]d%u[p`lw'IH0+4,'DBOP,0ȓ%&0c;KݕR |RzD@&H RB&QfGp #+.0' e)2ӍS oOqV7" lR<7-wspChr<4]B{57&3Qgu3܌g fG ^|fT]oČ<*:fi!BKS#c+ٔ5((Ԝr6;2=`tc) g-Q**.- * {h{;ziS yw׵c| -}=_$V/ۖ%$r !ɛI\gA[0/5Os-2-g ,ܺKO|2G)=s.\}lVɆ n,pC)㤫3xb^dYk$tn g&nyrmY9 Bƣ]DOe$S&0 hjwRRp.€<-=M[5=>_,jYvOoS颎qS'H'-w2u$@@ZB~{ & /_5HAe@:cJR!+0W6lc6?AWSZ7Xx؁ "8$X&x(*,؂.0284X6x8:;giflib-6.1.3/doc/whatsinagif/sample_2_green_yellow_diff.gif0000664000175000017500000000061115166751647022150 0ustar esresrGIF89a!W!,!WH:AVuN9ؖb$}f\ 4^=^nh($(T~P]pFͬʤjWnk-wJ4;fwZxu ?>#B ? EĄnʳ31؛Xތɐ搼Eͦ!GR3x-‡m 'C&UX0N Ӂ(r$"&!Jp%K_+)͚Aľ'jd$ 1 1iG2ӆly;giflib-6.1.3/doc/whatsinagif/index.html0000664000175000017500000000254515166751647016221 0ustar esresr What's In A GIF

What's In A GIF

(main page)

These pages explain down to the bit level what's inside a GIF, and are offered in the hope they will be useful to programmers using GIFLIB.

The explanation is in three parts:

  1. Bits and Bytes - first we look at the file format that makes up a GIF file
  2. LZW Image Data - a closer look at how image data is compressed within a GIF file
  3. Transparency and Animation - how some of the more advanced features of GIF files work

Due credit: much of this material was written by one Mike Flickinger in 2005, though it has been significantly revised and expanded for GIFLIB. The illustrations are all his.

giflib-6.1.3/doc/whatsinagif/comment_ext.gif0000664000175000017500000001261015166751647017227 0ustar esresrGIF89a@@@000 ```PPPppp!, $dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ 8 i M|n _&.< i_'* >c\/? ½^# " #  #  MJ  c%8 8 =@Uρ 0#`1Y=<ȇF.v Nb0 4 hk&DiLSLI*h(,BfI$)5E 4V#fnᄵXJReSV 2왠P& tA& I"5)cOJ;] $A=JB@{ lnGimuM(-bnN4`pso5)韎66J aͻh%S!u'=rqsi WYphEF]# =x%s.j܀.Q XBD-AS {ʙyv)w%@I "-V)C@ Kp4#N1‹/ @=x Wl@$9"QUwB{>ڥ$S9 S!VH=pUz#&]r0hY ϡ@y0R1*BiC= Pt#q"Rʩjb<!ʼ&n֓2T6DtWdpy؂5Uފ˒+"mH*sb!'jtL$ {SpB;(9Ib 69/99+\F6 #@:`&@ذBl1C<{ʠ'iij58p#PEVQ4TaFZ{KGZ1h j@1qiMQ,8#/XEs|ad$<u64m6ӛS7Ir@L:eu(h'< Oygjԛ,T`(%}`Ϫ&:=4Mq'%A|69d p)9xEXШe&OٖkE?eִI0MXXȰ걇}Ȁ45t6+ hlFub8pù^mRoh+ђFDDNR:z:52q};$g¥x#b*aCHO5dtGi`vV 4/T-kS̾ԣ м3;SBo6JI$!$=:z!.;,^dJE@$89p *wmeT$!zSJ"|lE95+_Qm,pj<0&8nF%QG-7R@m%IL1'@Y%s I[s\vT5N%<ic@hђ.1\Q*\u&,}۩o_ګ 0A[o9(I^1J181`r|GwjU:+p!^{U \-u~D(bӣan~V:'M;X~l|r$Xp4{`fBW-c 6WQW\C3cVM3FSg+f}9<K3;q[E;2ERɠ g% vLZe}V}#(0eC;@.<5eBp[5A_5BbP(V!Ql7{~wTt0dChc' *ʐг?賉DVdz$ SVS!$PIqQ*@hHI*LafVqgkTEZf1-z)<6h:ЅH*v݆ r;&jkm V I"XV:6&mA^vr@ &y4"ȏq'o4D)9WV2ypH|X{lPfVYoC9@|ЌB2xG(8<-bu4PhДUF)&'%W7ZOyyדP0qP,|(@xGYGMj >0FL7Cjp!31WC29OS(Ә_R 7xr^b [xt4GrM#,@H\K7x^$/ Rϔ gZ@r^ťu-j<49W9`Q ĸ_ƘRF3*ťc#yys x_F vkqdt&x2ae9LPw5%'9zj4@r6Ck]ǐ*y ٣{BH=:u@=ED:pIyET 86I kФOE0KdOgzfzt1iprJsZvzxz-Modx{ʊJųڨsڧ'g9iKPS^:` }|z|j*SI 1‰dzjo$T PMC 30=a B&"l(5jJS$#7)srHHZfаJهY&Jmf*9 ;}NtCvW+O ɯLfHE 3L!V"ڠP$ʷ< ʏI[Q3d432JټOƬ+(a ['j9b#Pt? X`',3d2<Z>Crѣ: -/Bd\?8[ , ҩ[241 7Z<]DGN8R]3@VV\X`}de}2h_ZnmpR=tv}2}À10e !ȆY 7'\kP w?g*Oc--H!E Aa92s0<ed_Zڗ MSr TA&' ,epi t"(`W53ZK3T24>݌М@̄2$W* $ k82 '2a:e;Qf+h0kafa1ᕶ^=6ZZ(91h?!=36{ޡ#'#5N;S Z__fU? A~;C =ʍUfu!xT.Mb5.AE`j4Hq "`fZdH7;p"Tg] !$'ERSi?]x^IkBI@B$:T;J* )ϡ%-cꮃ JRh O? XHӐ,cWx!׉9dV8.R9 n5@B?D_FHJLNPR!;giflib-6.1.3/doc/whatsinagif/trailer_block.gif0000664000175000017500000000166615166751647017532 0ustar esresrGIF89aZ@@@```PPP 000ppp!,Z $dihlp,tmx|pH,Ȥrl:ШtJZجvX A Hx|>- @x+tt0}{}~Lr4 "J#k h"kmz|# il : r"r8nns5Άˣ s x 7"z0=/vA v`;v%xQFFxj@DQq5Q@2k͛A{&RPJJիXjʵׯ`ÊKٳhe( i0h;B Wģ@T0 `A`nr 8\1X쪁!' gifinto

Name

gifinto — save GIF on stdin to file if size over set threshold

Synopsis

gifinto [-v] [-s minsize] [-h] [outfile]

Description

A program to save stdin into a file with given name, if and only if the result file has size bigger than specified (see below). This can be used to save a result under the same filename we started with in a chain of pipes.

Always reads a GIF file from stdin.

Options

-v

Verbose mode (show progress). Enables printout of running scan lines.

-s MinFileSize

If file is less than MinFileSize, it is deleted and not renamed to the given name. This will prevent killing the file we started with if the result is an empty file, or the pipeline did not complete.

The default file threshold size is 14 bytes, which is 1 bigger than GIF file stamp (6 bytes) plus a GIF file screen descriptor (7 bytes), so a GIF file with only GIF stamp and screen descriptor will not be renamed.

-h

Print one line of command line help, similar to Usage above.

Author

Gershon Elber.

giflib-6.1.3/doc/gifclrmp.10000664000175000017500000000557515166751647013613 0ustar esresr'\" t .\" Title: gifclrmp .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFCLRMP" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifclrmp \- extract colormaps from GIF images .SH "SYNOPSIS" .HP \w'\fBgifclrmp\fR\ 'u \fBgifclrmp\fR [\-v] [\-s] [\-l\ \fImapfile\fR] [\-t\ \fItrans\fR] [\-g\ \fIgamma\fR] [\-i\ \fIimage\fR] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program to modify GIF image colormaps\&. Any local colormap in a GIF file can be modified at a time, or the global screen one\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-s .RS 4 Select the global screen color map\&. .RE .PP \-l mapfile .RS 4 Load color map from this file instead of selected color map\&. .RE .PP \-t trans .RS 4 Change color index values\&. The change is made to both the selected color table and the raster bits of the selected image\&. A translation file is a list of pairs of `before\*(Aq and `after\*(Aq index values\&. At present, the `before\*(Aq index values must be in ascending order starting from 0\&. .RE .PP \-g gamma .RS 4 Apply gamma correction to selected color map\&. .RE .PP \-i image .RS 4 Select the color map of the numbered image\&. .RE .PP \-h .RS 4 Print one command line help, similar to Usage above\&. .RE .PP If no GIF file is given, gifclip will try to read a GIF file from stdin\&. .SH "NOTES" .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The default operation is to dump out the selected color map in text format\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The file to load/dump is simply one color map entry per line\&. Each such entry line has four integers: "ColorIndex Red Green Blue", where color index is in ascending order starting from 1\&. .RE .SH "AUTHOR" .PP Gershon Elber\&. giflib-6.1.3/doc/gifbuild.xml0000664000175000017500000001737615166751647014237 0ustar esresr ]> 2 May 2012 gifbuild 1 GIFLIB GIFLIB Documentation gifbuild dump GIF data in a textual format, or undump it to a GIF gifbuild -v -a -d -t translation-table -h gif-file Options A program to convert a series of editable text GIF icon specifications and named GIF files into a multi-image GIF, usable as a graphic resource file. It can also dump existing GIFs in this format. Both directions are lossless and mutually inverse. When dumping a GIF, certain sanity checks are performed which may result in a warning emitted to standard error. If no GIF file is given, gifbuild will try to read a text input from stdin. Specification Syntax Here is a syntax summary in informal BNF. The token `NL' represents a required newline. <gif-spec> ::= <header-block> <image-block>... <header-block> ::= <header-declaration>... <header-declaration ::= | screen width <digits> NL | screen height <digits> NL | screen colors <digits> NL | screen background <digits> NL | pixel aspect byte <digits> NL | screen map <color-table> NL <color-table> ::= <color-declaration>... end NL <color-declaration> ::= rgb <digits> <digits> <digits> [ is <key>] NL | sort flag {on|off} NL <image-block> ::= include <file-name> NL | image NL <image-declaration>... <raster-picture> [ <extension> ] <image-declarations> ::= image top <digits> NL | image left <digits> NL | image interlaced NL | image map <color-table> NL | image bits <digits> by <digits> [hex|ascii] NL <raster-block> <extension> := <comment> NL <extension-block> NL end NL | <plaintext> NL <extension-block> NL end NL | graphics control NL <GCB-part> NL end NL | netscape loop <digits> NL | extension <hex-digits> NL <extension-block> NL end NL <GCB-part> ::= disposal mode <digits> NL | user input flag {on|off} NL | delay <digits> NL | transparent index <digits> NL If the data types of the screen height, screen width, screen background, image top, and image left declarations aren't obvious to you, what are you doing with this software? The pixel aspect byte declaration sets an integer denominator for a fraction expressing the pixel aspect ratio. See the GIF standard for details; this field is actually long obsolete. A color table declares color indices (in ascending order from 0) and may associate them with key characters (these associations are absent when the map is more than 94 colors lang and raster blocks using it must use hex pairs). These characters can later be used in raster blocks. As these must be printable and non-whitespace, you can only specify 94 colors per icon. Life is like that sometimes. A color table declaration can also set the table's sort flag with "sort flag on" or "sort flag off" on any line before the end. An ascii raster block is just a block of key characters (used for a color map of 94 or fewer colors). A hex raster block uses hex digit pairs instead (used for a color map with more than 94 colors). The default is ASCII. It should be sized correctly for the image bits declaration that leads it. Raster blocks from interlaced GIFs are dumped with the lines in non-interlaced order. The comment, plaintext or graphics control keywords lead defined GIF89 extension record data. The final GIF89 type, graphics control and application block, are not yet supported, but the code does recognize a Netscape loop block. You can also say extension followed by a hexadecimal record type. All of these extension declarations must be followed by an extension block, which is terminated by the keyword end on its own line. An extension block is a series of text lines, each interpreted as a string of bytes to fill an extension block (the terminating newline is stripped). Text may include standard C-style octal and hex escapes preceded by a backslash. A graphics control block declaration creates a graphics control extension block; for the field semantics see the GIF89 standard, part 23. A netscape loop declaration creates an application extension block containing a NETSCAPE 2.0 animation loop control with a specified repeat count (repeat count 0 means loop forever). This must be immediately after the header declaration. These loop blocks are interpreted by the Netscape/Mozilla/Firefox line of browsers. All <digits> tokens are interpreted as decimal numerals; <hex-digits> tokens are interpreted as two hex digits (a byte). All coordinates are zero-origin with the top left corner (0,0). Range checking is weak and signedness checking nonexistent; caveat hacker! In general, the amount of whitespace and order of declarations within a header or image block is not significant, except that a raster picture must immediately follow its image bits bits declaration. The include declaration includes a named GIF as the next image. The global color maps of included GIFs are merged with the base table defined by any screen color declaration. All images of an included multi-image GIF will be included in order. Comments (preceded with #) will be ignored. Options -v Verbose mode (show progress). Enables printout of running scan lines. -d Dump the input GIF file(s) into the text form described above. -t Specify name characters to use when dumping raster blocks. Only valid with -d option. -h Print one line of command line help, similar to Usage above. Bugs Error checking is rudimentary. Example: A sample icon file called sample.ico is included in the pic directory of the GIFLIB source distribution. Author Eric S. Raymond &email; giflib-6.1.3/doc/giflib.xml0000664000175000017500000000402015166751647013664 0ustar esresr ]> 3 June 2012 giflib 7 GIFLIB GIFLIB Documentation giflib GIFLIB utilities Description GIFLIB is a linkable service library and a set of utilities for processing images encoded using GIF (Graphics Interchange Format). These utilities are not intended to compete with or replace multi-format graphics toolkits like ImageMagick or the Python Imaging Library, or graphics editors such as the GIMP. Find one of those, or an equivalent, if you need to crop, scale, rotate, toggle interlacing, or perform other conventional image transformations. Rather, these are intended to facilitate GIF-specific operations which multi-format tools may not adequately support. API documentation for the service library is best viewed through a browser at the project website: &project;. See Also gifbuild1, giffix1, giftext1, giftool1, gifclrmap1. Authors Gershon Elber, Eric S. Raymond, Toshio Kuratomi. giflib-6.1.3/doc/giftool.xml0000664000175000017500000001441215166751647014101 0ustar esresr 3 June 2012 giftool 1 GIFLIB GIFLIB Documentation giftool GIF transformation tool giftool -a aspect -b bgcolor -d delaytime -i interlacing -n imagelist -p left,top -s width,height -t transcolor -u sort-flag -x disposal -z sort-flag Description A filter for transforming GIFS. With no options, it's an expensive copy of a GIF in standard input to standard output. Options specify filtering operations and are performed in the order specified on the command line. The -n option selects images, allowing the tool to act on a subset of images in a multi-image GIF. This option takes a comma-separated list of decimal integers which are interpreted as 1-origin image indices; these are the images that will be acted on. If no -n option is specified, the tool will select and transform all images. The -b option takes a decimal integer argument and uses it to set the (0-origin) screen background color index. The -f option accepts a printf-style format string and substitutes into it the values of image-descriptor and graphics-control fields. The string is formatted and output once for each selected image. Normal C-style escapes \b, \f, \n, \r, \t. \v, and \xNN are interpreted; also \e produces ESC (ASCII 0x1b). The following format cookies are substituted: %a Pixel aspect byte. %b Screen background color. %d Image delay time %h Image height (y dimension) %n Image index %p Image position (as an x,y pair) %s Screen size (as an x,y pair) %t Image transparent-color index %u Image user-input flag (boolean) %v GIF version string %w Image width (x dimension) %x Image GIF89 disposal mode %z Image's color table sort flag (boolean, false if no local color map) Boolean substitutions may take a prefix to modify how they are displayed: 1 "1" or "0" o "on" or "off" t "t" or "f" y "yes" or "no" Thus, for example, "%oz" displays image sort flags using the strings "on" and "off". The default with no prefix is numeric. The -a option takes an unsigned decimal integer argument and uses it to set the aspect-ratio bye in the logical screen descriptor block. The -b option takes an unsigned decimal integer argument and uses it to set the background color index in the logical screen descriptor block. The -d option takes a decimal integer argument and uses it to set a delay time, in hundredths of a second, on selected images. The -i option sets or clears interlacing in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f" The -p option takes a (0-origin) x,y coordinate-pair and sets it as the preferred upper-left-corner coordinates of selected images. The -s option takes a (0-origin) x,y coordinate-pair and sets it as the expected display screen size. The -t option takes a decimal integer argument and uses it to set the (0-origin) index of the transparency color in selected images. The -u option sets or clears the user-input flag in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f". The -x option takes a decimal integer argument and uses it to set the GIF89 disposal mode in selected images. The -z option sets or clears the color-table sort flag in selected images. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f". Note that the -a, -b, -p, -s, and -z options are included to complete the ability to modify all fields defined in the GIF standard, but should have no effect on how an image renders on browsers or modern viewers. Author Eric S. Raymond. giflib-6.1.3/doc/gifbuild.10000664000175000017500000001627715166751647013576 0ustar esresr'\" t .\" Title: gifbuild .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFBUILD" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifbuild \- dump GIF data in a textual format, or undump it to a GIF .SH "SYNOPSIS" .HP \w'\fBgifbuild\fR\ 'u \fBgifbuild\fR [\-v] [\-a] [\-d] [\-t\ \fItranslation\-table\fR] [\-h] [\fIgif\-file\fR] .SH "OPTIONS" .PP A program to convert a series of editable text GIF icon specifications and named GIF files into a multi\-image GIF, usable as a graphic resource file\&. It can also dump existing GIFs in this format\&. Both directions are lossless and mutually inverse\&. .PP When dumping a GIF, certain sanity checks are performed which may result in a warning emitted to standard error\&. .PP If no GIF file is given, gifbuild will try to read a text input from stdin\&. .SH "SPECIFICATION SYNTAX" .PP Here is a syntax summary in informal BNF\&. The token `NL\*(Aq represents a required newline\&. .sp .if n \{\ .RS 4 .\} .nf ::= \&.\&.\&. ::= \&.\&.\&. NL | screen height NL | screen colors NL | screen background NL | pixel aspect byte NL | screen map NL ::= \&.\&.\&. end NL ::= rgb [ is ] NL | sort flag {on|off} NL ::= include NL | image NL \&.\&.\&. [ ] ::= image top NL | image left NL | image interlaced NL | image map NL | image bits by [hex|ascii] NL := NL NL end NL | NL <extension\-block> NL end NL | graphics control NL <GCB\-part> NL end NL | netscape loop <digits> NL | extension <hex\-digits> NL <extension\-block> NL end NL <GCB\-part> ::= disposal mode <digits> NL | user input flag {on|off} NL | delay <digits> NL | transparent index <digits> NL .fi .if n \{\ .RE .\} .PP If the data types of the \(lqscreen height\(rq, \(lqscreen width\(rq, \(lqscreen background\(rq, \(lqimage top\(rq, and \(lqimage left\(rq declarations aren\*(Aqt obvious to you, what are you doing with this software? .PP The \(lqpixel aspect byte\(rq declaration sets an integer denominator for a fraction expressing the pixel aspect ratio\&. See the GIF standard for details; this field is actually long obsolete\&. .PP A color table declares color indices (in ascending order from 0) and may associate them with key characters (these associations are absent when the map is more than 94 colors lang and raster blocks using it must use hex pairs)\&. These characters can later be used in raster blocks\&. As these must be printable and non\-whitespace, you can only specify 94 colors per icon\&. Life is like that sometimes\&. .PP A color table declaration can also set the table\*(Aqs sort flag with "sort flag on" or "sort flag off" on any line before the end\&. .PP An \(lqascii\(rq raster block is just a block of key characters (used for a color map of 94 or fewer colors)\&. A \(lqhex\(rq raster block uses hex digit pairs instead (used for a color map with more than 94 colors)\&. The default is ASCII\&. It should be sized correctly for the \(lqimage bits\(rq declaration that leads it\&. Raster blocks from interlaced GIFs are dumped with the lines in non\-interlaced order\&. .PP The \(lqcomment\(rq, \(lqplaintext\(rq or \(lqgraphics control\(rq keywords lead defined GIF89 extension record data\&. The final GIF89 type, graphics control and application block, are not yet supported, but the code does recognize a Netscape loop block\&. You can also say \(lqextension\(rq followed by a hexadecimal record type\&. All of these extension declarations must be followed by an extension block, which is terminated by the keyword \(lqend\(rq on its own line\&. .PP An extension block is a series of text lines, each interpreted as a string of bytes to fill an extension block (the terminating newline is stripped)\&. Text may include standard C\-style octal and hex escapes preceded by a backslash\&. .PP A graphics control block declaration creates a graphics control extension block; for the field semantics see the GIF89 standard, part 23\&. .PP A netscape loop declaration creates an application extension block containing a NETSCAPE 2\&.0 animation loop control with a specified repeat count (repeat count 0 means loop forever)\&. This must be immediately after the header declaration\&. These loop blocks are interpreted by the Netscape/Mozilla/Firefox line of browsers\&. .PP All <digits> tokens are interpreted as decimal numerals; <hex\-digits> tokens are interpreted as two hex digits (a byte)\&. All coordinates are zero\-origin with the top left corner (0,0)\&. Range checking is weak and signedness checking nonexistent; caveat hacker! .PP In general, the amount of whitespace and order of declarations within a header or image block is not significant, except that a raster picture must immediately follow its \(lqimage bits\(rq bits declaration\&. .PP The \(lqinclude\(rq declaration includes a named GIF as the next image\&. The global color maps of included GIFs are merged with the base table defined by any \(lqscreen color\(rq declaration\&. All images of an included multi\-image GIF will be included in order\&. .PP Comments (preceded with \(lq#\(rq) will be ignored\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-d .RS 4 Dump the input GIF file(s) into the text form described above\&. .RE .PP \-t .RS 4 Specify name characters to use when dumping raster blocks\&. Only valid with \-d option\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .SH "BUGS" .PP Error checking is rudimentary\&. .SH "EXAMPLE:" .PP A sample icon file called sample\&.ico is included in the pic directory of the GIFLIB source distribution\&. .SH "AUTHOR" .PP Eric S\&. Raymond <esr@thyrsus\&.com> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifbg.1����������������������������������������������������������������������������0000664�0001750�0001750�00000006247�15166751647�013063� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: gifbg .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFBG" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifbg \- generate a test\-pattern GIF .SH "SYNOPSIS" .HP \w'\fBgifbg\fR\ 'u \fBgifbg\fR [\-v] [\-d\ \fIdir\fR] [\-l\ \fIlevels\fR] [\-c\ \fIR\fR\ \fIG\fR\ \fIB\fR] [\-m\ \fImin\fR] [\-o\ \fImax\fR] [\-s\ \fIw\fR\ \fIh\fR] [\-h] .SH "DESCRIPTION" .PP A program to generate a single\-color test pattern GIF with gradually changing intensity in any of the basic 8 directions\&. .PP The gifbg program reads no input, and will dump the created GIF file to stdout\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-d dir .RS 4 Select direction the intensity of the background should increase\&. Direction can be one of the 8 principal directions: .PP "T" .RS 4 for Top .RE .PP "TR" .RS 4 for Top Right .RE .PP "R" .RS 4 for Right .RE .PP "BR" .RS 4 for Bottom Right .RE .PP "B" .RS 4 for Bottom .RE .PP "BL" .RS 4 for Bottom Left .RE .PP "L" .RS 4 for left .RE .PP "TL" .RS 4 for Top Left .RE .sp The compass directions may be use as synonyms for the above directions, so for example "NE" is equal to "TR"\&. .sp Direction is case insensitive\&. The default direction is Top (North)\&. .RE .PP \-l levels .RS 4 Numeric, number of levels the color will be scaled to\&. Default is 16\&. .RE .PP \-c R G B .RS 4 What to use as the primary background color to scale\&. This color is scaled between the minimum intensity (min) and maximum intensity (max) from one end of the screen to the other as defined by dir\&. See below (\-m & \-M) for min & max\&. Default is Blue (0, 0, 255)\&. .RE .PP \-m min .RS 4 Minimum intensity (in percent) to scale color\&. Default 10% .RE .PP [\-M max .RS 4 Maximum intensity (in percent) to scale color\&. Default 100% .RE .PP \-s W H .RS 4 Size of image to create\&. Default 640 by 350\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .PP If min == max = 100 (%) and levels == 2 then boolean mask image of specified size will be created \- all foreground\&. .SH "AUTHOR" .PP Gershon Elber\&. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/giftext.1��������������������������������������������������������������������������0000664�0001750�0001750�00000005027�15166751647�013452� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: giftext .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFTEXT" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" giftext \- dump GIF pixels and metadata as text .SH "SYNOPSIS" .HP \w'\fBgiftext\fR\ 'u \fBgiftext\fR [\-v] [\-c] [\-e] [\-z] [\-p] [\-r] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program to dump (text only) general information about GIF file\&. .PP If no GIF file is given, giftext will try to read a GIF file from stdin\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-c .RS 4 Dumps the color maps\&. .RE .PP \-e .RS 4 Dumps encoded bytes \- the pixels after compressed using LZ algorithm and chained to form bytes\&. This is the form the data is saved in the GIF file\&. Dumps in hex \- 2 digit per byte\&. .RE .PP \-z .RS 4 Dumps the LZ codes of the image\&. Dumps in hex \- 3 digits per code (as we are limited to 12 bits)\&. .RE .PP \-p .RS 4 Dumps the pixels of the image\&. Dumps in hex \- 2 digit per pixel (<=byte)\&. .RE .PP \-r .RS 4 Dumps raw pixels as one byte per pixel\&. This option inhibits all other options and only the pixels are dumped\&. This option may be used to convert GIF files into raw data\&. Note: the color map can be extracted by gifclrmp utility\&. If more than one image is included in the file, all images will be dumped in order\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .SH "AUTHOR" .PP Gershon Elber\&. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifclrmp.xml�����������������������������������������������������������������������0000664�0001750�0001750�00000006156�15166751647�014247� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> <refentry id='gifclrmp.1'> <refentryinfo><date>2 May 2012</date></refentryinfo> <refmeta> <refentrytitle>gifclrmp</refentrytitle> <manvolnum>1</manvolnum> <refmiscinfo class="source">GIFLIB</refmiscinfo> <refmiscinfo class="manual">GIFLIB Documentation</refmiscinfo> </refmeta> <refnamediv id='name'> <refname>gifclrmp</refname> <refpurpose>extract colormaps from GIF images</refpurpose> </refnamediv> <refsynopsisdiv id='synopsis'> <cmdsynopsis> <command>gifclrmp</command> <arg choice='opt'>-v</arg> <arg choice='opt'>-s</arg> <arg choice='opt'>-l <replaceable>mapfile</replaceable></arg> <arg choice='opt'>-t <replaceable>trans</replaceable></arg> <arg choice='opt'>-g <replaceable>gamma</replaceable></arg> <arg choice='opt'>-i <replaceable>image</replaceable></arg> <arg choice='opt'>-h</arg> <arg choice='opt'><replaceable>gif-file</replaceable></arg> </cmdsynopsis> </refsynopsisdiv> <refsect1><title>Description</title> <para>A program to modify GIF image colormaps. Any local colormap in a GIF file can be modified at a time, or the global screen one.</para> </refsect1> <refsect1><title>Options</title> <variablelist> <varlistentry> <term>-v</term> <listitem> <para> Verbose mode (show progress). Enables printout of running scan lines. </para> </listitem> </varlistentry> <varlistentry> <term>-s</term> <listitem> <para>Select the global screen color map.</para> </listitem> </varlistentry> <varlistentry> <term>-l mapfile</term> <listitem> <para> Load color map from this file instead of selected color map.</para> </listitem> </varlistentry> <varlistentry> <term>-t trans</term> <listitem> <para>Change color index values. The change is made to both the selected color table and the raster bits of the selected image. A translation file is a list of pairs of `before' and `after' index values. At present, the `before' index values must be in ascending order starting from 0.</para> </listitem> </varlistentry> <varlistentry> <term>-g gamma</term> <listitem> <para>Apply gamma correction to selected color map.</para> </listitem> </varlistentry> <varlistentry> <term>-i image</term> <listitem> <para>Select the color map of the numbered image.</para> </listitem> </varlistentry> <varlistentry> <term>-h</term> <listitem> <para>Print one command line help, similar to Usage above.</para> </listitem> </varlistentry> </variablelist> <para>If no GIF file is given, gifclip will try to read a GIF file from stdin.</para> </refsect1> <refsect1><title>Notes</title> <itemizedlist> <listitem> <para>The default operation is to dump out the selected color map in text format.</para> </listitem> <listitem> <para>The file to load/dump is simply one color map entry per line. Each such entry line has four integers: "ColorIndex Red Green Blue", where color index is in ascending order starting from 1.</para> </listitem> </itemizedlist> </refsect1> <refsect1><title>Author</title> <para>Gershon Elber.</para> </refsect1> </refentry> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gif_lib.xml������������������������������������������������������������������������0000664�0001750�0001750�00000133463�15166751647�014041� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ <!ENTITY homepage "http://catb.org/~esr/"> <!ENTITY email "esr@thyrsus.com"> ]> <article><title>The GIFLIB Library</title> <articleinfo> <author> <firstname>Eric</firstname> <othername>Steven</othername> <surname>Raymond</surname> <affiliation> <orgname><ulink url="&homepage;"> Thyrsus Enterprises</ulink></orgname> <address> <email>&email;</email> </address> </affiliation> </author> <copyright> <year>2012</year> <holder role="mailto:&email;">Eric S. Raymond</holder> </copyright> </articleinfo> <!-- Gershon Elber, May 1991 Eric S. Raymond, Sep 1992 Toshio Kuratomi, May 2004 --> <sect1><title>Introduction</title> <para>The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated.</para> <para>This document explains the GIF library code in directory `lib'. The code is collected into a service library which is used in all the utilities in `util'. It can be used in any application needs to read/write the GIF file format. This document does <emphasis>not</emphasis> explain the GIF file format and assumes you know it, at least to the level of the GIF file structure.</para> </sect1> <sect1><title>Credit and Blame</title> <para>Gershon wrote: "This library was written because I couldn't find anything similar and I wanted one. I was inspired by the RLE Utah tool kit, which I hoped to port to an IBM PC, but found it to be too machine specific, and its compression ratio too low. I compromised on the GIF format, but I am not sure how long 8 bits per pixel will be enough."</para> <para>During his first spell of maintainership between 1989 and 1994, Eric S. Raymond (aka "ESR") ported the code to Unix, wrote the high-level DGifSlurp()/EGifSpew() interface, rationalized the internal data structures, and did a lot of general cleanup and refactoring to improve the code quality.</para> <para>Between 1994 and 2012 Toshio Kuratomi fixed various tool bugs, build-recipe problems and rare segfaults. He partially untangled the somewhat misdesigned extension-block handling in earlier versions. The core code was very stable during this period.</para> <para>During his second spell of maintainership, ESR fixed the extension API, made the library re-entrant and thread-safe, wrote a regression-test suite, greatly improved the documentation, and discarded a lot of obsolete code.</para> </sect1> <sect1><title>The GIF descriptor</title> <para>When a GIF file is opened, a GIF file descriptor is created which is a pointer to GifFileType structure as follows:</para> <programlisting> typedef struct GifFileType { 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; </programlisting> <para>This structure was copied from gif_lib.h - the header file for the GIF library. Any application program that uses the libgif.a library should include it. Members beginning with S refer to the GIF screen; others hold properties of the current image (a GIF file may have more than one image) or point to allocated store used by various routines.</para> <para>The user almost never writes into this structure (exception: it may occasionally be useful to alter things in the SavedImages array and Trailing member), but can read any of these items at any time it is valid (Image information is invalid until the first image has been read; read; SavedImages information is valid only after a DGifSlurp() call).</para> <para>As the library needs to keep its own internal data, a Private pointer to hidden data is included. Applications should ignore this.</para> <para>The library allocates its own memory dynamically, on opening of files, and releases that once closed. The user is never required to allocate any memory for any of the functions of this library, and is almost never required to free them directly. The "almost" in the latter clause is because one manual free() call may be required on a failed file close; see the documentation of DGifClose() and EGifClose() for details.</para> <para>Here is a module summary:</para> <variablelist> <varlistentry> <term>egif_lib.c</term> <listitem> <para>Encoding routines, all prefixed with E.</para> </listitem> </varlistentry> <varlistentry> <term>dgif_lib.c</term> <listitem> <para>Decoding routines, all prefixed with D.</para> </listitem> </varlistentry> <varlistentry> <term>gifalloc.c</term> <listitem> <para>Routines for colormap handling and GIF record allocation.</para> </listitem> </varlistentry> <varlistentry> <term>gif_font.c</term> <listitem> <para>The 8x8 font table for the GIF utility font.</para> </listitem> </varlistentry> </variablelist> <para>The library includes a sixth file of hash-function code which is accessed internally only.</para> <para>Most of the routines return GIF_ERROR (see gif_lib.h) if something went wrong, GIF_OK otherwise. After an error return, all routines that take a pointer-to-GifFileType argument set the Error member with a code that can be interpreted into an explanatory string with the function GifErrorString() in gif_err.c. (The exception to this is the DGifClose() and EGifClose() routines, which deallocate that structure and must therefore return any error code through a pointer argument.)</para> </sect1> <sect1><title>Decoding (dgif_lib.c)</title> <para>The following functions are used to set up input from a GIF:</para> <programlisting id="DGifOpenFileName"> GifFileType *DGifOpenFileName(char *GifFileName, int *ErrorCode) </programlisting> <para>Open a new GIF file (in binary mode, if under Windows) using the given GifFileName, and read its Screen information.</para> <para>If any error occurs, NULL is returned and ErrorCode is set (if non-NULL).</para> <programlisting id="DGifOpenFileHandle"> GifFileType *DGifOpenFileHandle(int FileHandle, int *ErrorCode) </programlisting> <para>Open a new GIF file using the given FileHandle, and read its Screen information.</para> <para>If any error occurs, NULL is returned and ErrorCode is set (if non-NULL).</para> <para>Once you have acquired a handle on a GIF, the high-level function</para> <programlisting id="DGifSlurp"> int DGifSlurp(GifFileType) </programlisting> <para>reads the rest of a complete (possibly multi-image) GIF file from the indicated file handle into in-core allocated structures. It returns GIF_OK on success, GIF_ERROR on failure; on failure, the Error member will be set.</para> <para>Once you have done this, all image, raster, and extension-block data in the GIF is accessible in the SavedImages member (see the structures in gif_lib.h). When you have modified the image to taste, write it out with EGifSpew().</para> <para>One detail that may not be clear from just looking at the structures is how extension blocks and sub-blocks are stored. Each ExtensionBlock structure represents an extension data block. Those with a zero function code represent continuation data blocks attached to previous blocks with nonzero function codes.</para> <para>You can read from a GIF file through a function hook. Initialize with </para> <programlisting id="DGifOpen"> GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *ErrorCode) </programlisting> <para>and see the library header file for the type of InputFunc.</para> <para>There is also a set of deprecated functions for sequential I/O, described in a later section.</para> </sect1> <sect1><title>Encoding (egif_lib.c)</title> <para>The high-level function</para> <programlisting id="EGifSpew"> int EGifSpew(GifFileType *GifFile, int *ErrorCode) </programlisting> <para>writes a complete (possibly multi-image) GIF file to the indicated file handle from in-core allocated structures created by a previous DGifSlurp() or equivalent operations. Its argument is a GIF file descriptor, which implicitly points to storage previously allocated by DGifSlurp().</para> <para>If ErrorCode is non-NULL, it returns a GIFLIB error code on failure; otherwise it may be NULL. The function returns GIF_OK or GIF_ERROR.</para> <para>The file is written with a GIF87 stamp unless it contains one of the four special extension blocks defined in GIF89, in which case it is written with a GIF89 stamp.</para> <para>EGifSpew() finishes by closing the GIF (writing a termination record to it) and deallocating the associated storage.</para> <para>You can write to a GIF file through a function hook. Initialize with </para> <programlisting id="EGifOpen"> GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *ErrorCode) </programlisting> <para>and see the library header file for the type of OutputFunc.</para> <para>There is also a set of deprecated functions for sequential I/O, described in a later section.</para> </sect1> <sect1><title>Color map handling and allocation routines</title> <programlisting id="GifMakeMapObject"> ColorMapObject *GifMakeMapObject(int ColorCount, GifColorType *ColorMap) </programlisting> <para>Allocate storage for a color map object with the given number of RGB triplet slots. If the second argument is non-NULL, initialize the color table portion of the new map from it. Returns NULL if memory is exhausted or if the size is not a power of 2 &lt;= 256.</para> <programlisting id="GifFreeMapObject"> void GifFreeMapObject(ColorMapObject *Object) </programlisting> <para>Free the storage occupied by a ColorMapObject that is no longer needed.</para> <programlisting id="GifUnionColorMap"> ColorMapObject *GifUnionColorMap( ColorMapObject *ColorIn1, ColorMapObject *ColorIn2, GifPixelType ColorTransIn2[]) </programlisting> <para>Create the union of two given color maps and return it. If the result won't fit into 256 colors, NULL is returned, the allocated union otherwise. ColorIn1 is copied as it to ColorUnion, while colors from ColorIn2 are copied if and only if they didn't exist before. ColorTransIn2 maps the old ColorIn2 into ColorUnion color map table.</para> <programlisting id="GifAttachImage"> SavedImage *GifAttachImage(GifFileType *GifFile) </programlisting> <para>Add an image block to the SavedImages array. The image block is initially zeroed out. This image block will be seen by any following EGifSpew() calls.</para> </sect1> <sect1><title>Graphics control extension handling</title> <para>GIF89 added a graphics control extension block, but versions of GIFLIB before 5.0 weren't much help in reading or modifying them. This lack has been remedied with the following structure and functions:</para> <programlisting> 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; int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex, GraphicsControlBlock *GCB); int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, GifFileType *GifFile, int ImageIndex); </programlisting> <para>With these functions you can extract the data from a graphics control extension associated with a saved image into a GraphicsControlBlock, modify it, and write it back out. Note that if the specified saved image doesn't have a graphics control extension, DGifSavedExtensionToGCB() will fill the GCB with default values and return GIF_ERROR (which can be ignored); EGifGCBToSavedExtension() will create a new leading extension block.</para> </sect1> <sect1><title>Error Handling (gif_err.c)</title> <programlisting> int GifErrorString(int ErrorCode) </programlisting> <para>Returns a string describing the specified GIFLIB error code. Return NULL if the argument is not a valid error code.</para> </sect1> <sect1><title>The GIF Utility Font</title> <para>The 8x8 utility font used in the (obsolete, no longer installed) gifecho and gifcolor lives in the library module gif_font.c, in a table called GifAsciiTable. The library header file includes suitable externs and defines.</para> <para>The GIF utility font support includes entry points for drawing legends on in-core images, drawing boxes and rectangles, and boxing text. These entry points are as follows:</para> <programlisting id="GifDrawText"> void GifDrawText8x8( SavedImage *Image, const int x, const int y, const char *legend, const int color) </programlisting> <para>Draw text using the 8x8 utility font on the saved image. Upper left corner of the text is at image pixel (x, y). Use the specified color index.</para> <programlisting id="GifDrawBox"> void GifDrawBox(SavedImage *Image, const int x, const int y, const int w, const int h, const int color) </programlisting> <para>Draw a box on the saved image. Upper left corner of the box is at image pixels (x, y), width is w, height is h. Use the specified color index.</para> <programlisting id="GifDrawRectangle"> void GifDrawRectangle(SavedImage *Image, const int x, const int y, const int w, const int h, const int color) </programlisting> <para>Draw a (filled) rectangle on the saved image. Upper left corner of the box is at image pixels (x, y), width is w, height is h. Use the specified color index.</para> <programlisting id="GifDrawBoxedText"> void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y, const char *legend, const int border, const int bg, const int fg) </programlisting> <para>Draw text on a filled rectangle. The rectangle will be sized to fit the text, with upper left hand corner at (x, y) on the saved image. The `border' argument specifies a pixel margin around the text. The `bg' argument is the color table index to fill the rectangle with; `fg' is the color table index to draw the text with.</para> <para>This function interprets some characters in the legend string specially. A tab (\t) is interpreted as a command to center the following text in the box. A carriage return (\r) is interpreted as a request for a line break.</para> </sect1> <sect1><title>Error codes</title> <para>Errors as reported from the GIFLIB library are divided to two major categories: the encoder (errors prefixed by E_GIF_ERR), and the decoder (errors prefixed by D_GIF_ERR). This document explains them briefly.</para> <sect2><title>Encoding errors</title> <variablelist> <varlistentry> <term><errorname>E_GIF_ERR_OPEN_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to open given file" IO error result when attempt to open the given GIF file.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_WRITE_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to Write to given file" IO error result when attempt to write to the given GIF file.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_HAS_SCRN_DSCR</errorname></term> <listitem> <para>Message printed using PrintGifError: "Screen Descriptor already been set" Attempt to write second screen descriptor to same GIF file. GIF file should have exactly one screen descriptor which should be set directly after the file is opened.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_HAS_IMAG_DSCR</errorname></term> <listitem> <para>Message printed using PrintGifError: "Image Descriptor is still active" Image descriptor should be sent before and image dump, and no second image descriptor should be sent before current image dump ended. This error occurred probably because current image was not complete.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_NO_COLOR_MAP</errorname></term> <listitem> <para>Message printed using PrintGifError: "Neither Global Nor Local color map" An image must have either global (screen) or local (image) color map. Neither were given in this case.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_DATA_TOO_BIG</errorname></term> <listitem> <para>Message printed using PrintGifError: "#Pixels bigger than Width * Height" The number of pixels dumped for this image is bigger than specified by image Height times image Width.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_NOT_ENOUGH_MEM</errorname></term> <listitem> <para>Message printed using PrintGifError: "Fail to allocate required memory" Once an attempt is made to open GIF file, special structures are allocated to hold internal data for it. If allocation fails this error is returned.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_DISK_IS_FULL</errorname></term> <listitem> <para>Message printed using PrintGifError: "Write failed (disk full?)" Writing encoded data failed.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>E_GIF_ERR_CLOSE_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to close given file" Closing file failed.</para> </listitem> </varlistentry> <varlistentry> <term><errorname> E_GIF_ERR_NOT_WRITEABLE</errorname></term> <listitem> <para>Message printed using PrintGifError: "Given file was not opened for write" GIF files can be opened both for read (DGIF part of library) and write (EGIF part of library). This error occurs when a file is opened for read (using DGIF) is given to one of the encoding (EGIF) routines.</para> </listitem> </varlistentry> </variablelist> </sect2> <sect2><title>Decoding errors</title> <variablelist> <varlistentry> <term><errorname>D_GIF_ERR_OPEN_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to open given file" IO error result when attempt to open the given GIF file.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_READ_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to read from given file" IO error result when attempt to write to the given GIF file.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NOT_GIF_FILE</errorname></term> <listitem> <para>Message printed using PrintGifError: "Data is not a GIF file" GIF files should have special stamp identifies them as such, If that stamp is not found, this error is issued.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NO_SCRN_DSCR</errorname></term> <listitem> <para>Message printed using PrintGifError: "No screen descriptor detected" Each GIF file should have screen descriptor in its header. This error will be generated if no such descriptor was found.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NO_IMAG_DSCR</errorname></term> <listitem> <para>Message printed using PrintGifError: "No image descriptor detected" Each image should have image descriptor in its header. This error will be generated if no such descriptor was found.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NO_COLOR_MAP</errorname></term> <listitem> <para>Message printed using PrintGifError: "Neither global nor local color map" An image must have either global (screen) or local (image) color map. Neither were given in this case.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_WRONG_RECORD</errorname></term> <listitem> <para>Message printed using PrintGifError: "Wrong record type detected" Each record in a GIF file has a special identifier in its header. If the record has an unrecognized identifier, this error is generated.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_DATA_TOO_BIG</errorname></term> <listitem> <para>Message printed using PrintGifError: "Number of pixels bigger than width * height" The number of pixels dumped for this image is bigger than specified by image Height times image Width.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NOT_ENOUGH_MEM</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to allocate required memory" Once an attemp is made to open GIF file, special structures are allocated to hold internal data for it. If allocation fails this error is returned.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_CLOSE_FAILED</errorname></term> <listitem> <para>Message printed using PrintGifError: "Failed to close given file" Closing file failed.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_NOT_READABLE</errorname></term> <listitem> <para>Message printed using PrintGifError: "Given file was not opened for read" GIF files can be opened both for read (DGIF part of library) and write (EGIF part of library). This error occurs when a file is opened for write (using EGIF) is given to one of the decoding (DGIF) routines.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_IMAGE_DEFECT</errorname></term> <listitem> <para>Message printed using PrintGifError: "Image is defective, decoding aborted" This error is generated, once the decoding failed - probably image is defect.</para> </listitem> </varlistentry> <varlistentry> <term><errorname>D_GIF_ERR_EOF_TOO_SOON</errorname></term> <listitem> <para>Message printed using PrintGifError: "Image EOF detected, before image complete" This error is generated once EOF errorname is detected in encoded image before all the pixels (Width * Height) has be decoded.</para> </listitem> </varlistentry> </variablelist> </sect2> </sect1> <sect1><title>Utility support library</title> <para>These functions are not part of the core GIF library. They are part of the getarg library that supports the utilities.</para> <sect2><title>Error Handling</title> <programlisting id="PrintGifError"> void PrintGifError(void) </programlisting> <para>Print a one-line diagnostic on the last giflib error to stderr.</para> </sect2> <sect2><title>Command Line Parsing</title> <programlisting id="GAGetArgs"> bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...) </programlisting> <para>Main routine of this module. Given argc &amp; argv as received by the main procedure, the command line CtrlStr, and the addresses of all parameters, parse the command line, and update the parameters.</para> <para>The CtrlStr defines what types of variables should follow. Look at the beginning of getarg.c for exact usage.</para> <para>Returns false if successful, returns true on failure.</para> <programlisting id="GAPrintErrMsg"> void GAPrintErrMsg(int Error) </programlisting> <para>If an error occurred in GAGetArgs, this routine may be used to print one line diagnostic to stderr.</para> <programlisting id="GAPrintHowTo"> void GAPrintHowTo(char *CtrlStr) </programlisting> <para>Given the same CtrlStr as for GAGetArgs, can be used to print a one line 'how to use'. </para> </sect2> </sect1> <sect1 id="sequential"><title>Sequential access</title> <para>If you are handling large images on an extremely memory-limited machine, you may need to use the following functions for sequential read and write. It's better to avoid them and use the simpler DGifSlurp()/EGifSpew() interface.</para> <sect2><title>Sequential reading</title> <programlisting id="DGifGetScreenDesc"> int DGifGetScreenDesc(GifFileType *GifFile) </programlisting> <para>Reads the screen information into the GifFile structure. Note this routine is automatically called once a file is opened, and therefore usually need not be called explicitly.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="DGifGetRecordType"> int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType) </programlisting> <para>As the GIF file can have different records in arbitrary order, this routine should be called once the file was open to detect the next record type, and act upon it. It can return these types in GifType:</para> <variablelist> <varlistentry> <term>1. UndefinedRecordType </term> <listitem> <para>something is wrong!</para> </listitem> </varlistentry> <varlistentry> <term>2. ScreenDescRecordType </term> <listitem> <para>screen information. As the screen info is automatically read in when the file is open, this should not happen.</para> </listitem> </varlistentry> <varlistentry> <term>3. ImageDescRecordType </term> <listitem> <para> next record is an image descriptor.</para> </listitem> </varlistentry> <varlistentry> <term>4. ExtensionRecordType</term> <listitem> <para> next record is extension block.</para> </listitem> </varlistentry> <varlistentry> <term>5. TrailerRecordType</term> <listitem> <para>last record reached, can close the file.</para> </listitem> </varlistentry> </variablelist> <para>The first two types can usually be ignored. The function returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="DGifGetImageDesc"> int DGifGetImageDesc(GifFileType *GifFile) </programlisting> <para>Reads image information into the GifFile structure. Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="DGifGetLine"> int DGifGetLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen) </programlisting> <para>Load a block of pixels from the GIF file. The line can be of any length. More than that, this routine may be interleaved with DGifGetPixel until all pixels have been read.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting> int DGifGetPixel(GifFileType *GifFile, PixelType GifPixel) </programlisting> <para>Loads one pixel from the GIF file. This routine may be interleaved with <link linkend="DGifGetLine">DGifGetLine()</link>, until all pixels are read. Because of the overhead per each call, use of this routine is not recommended.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting> int DGifGetExtension( GifFileType *GifFile, int *GifExtCode, ByteType **GifExtension) </programlisting> <para>Loads an extension block from the GIF file. Extension blocks are optional in GIF files. This routine should be followed by <link linkend="DGifGetExtensionNext">DGifGetExtensionNext</link>.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <para><programlisting id="DGifGetExtensionNext"> int DGifGetExtensionNext(GifFileType *GifFile, ByteType **GifExtension) </programlisting> As extensions may contain more than one block, use this routine to continue after DGifGetExtension, until *GifExtension is NULL.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting> int DGifGetCode( GifFileType *GifFile, int *GifCodeSize, ByteType **GifCodeBlock) </programlisting> <para>It sometimes may be desired to read the compressed code as is without decoding it. This routine does exactly that (with DGifGetCodeNext), and can be used instead of DGifGetLine.</para> <para>This compressed code information can be written out using the EGifPutCode/EGifPutCodeNext sequence (see gifpos.c for example). Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="DGifGetCodeNext"> int DGifGetCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock) </programlisting> <para>See DGifGetCode above.</para> <programlisting id="DGifGetLZCodes"> int DGifGetLZCodes(GifFileType *GifFile, int *GifCode) </programlisting> <para>This routine can be called instead of DGifGetLine/DGifGetPixel or DGifGetCode/DGifGetCodeNext to get the 12 bits LZ codes of the images. It will be used mainly for debugging purposes (see GifText.c for example).</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="DGifCloseFile"> int DGifCloseFile(GifFileType *GifFile, int *ErrorCode) </programlisting> <para>Write a termination block to the GIF, close the GIF file and free all memory allocated for managing it. GifFile should not be used after this routine has been called.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise. When GIF_ERROR is returned, the diagnostic error code is left in ErrorCode. The GifFile structure is unconditionally freed.</para> <para>(Note: In versions before 5.1.0, the ErrorCode argument was absent and the GifFile structure was not freed so that the diagnostic error code will remain accessible in GifFile->Error. This behavior was changed because it caused problems for the implementation of library wrappers in dynamic languages.)</para> <programlisting id="DGetGifVersion"> const char * DGifGetGifVersion(GifFileType *GifFile) </programlisting> <para>Get the GIF version collected during sequential read. This is handy for sequential API users who want to set an encoder's version from a decoder (e.g. for gif resizing). For the all-at-once users this isn't necessary because gif encoder inspects all the extension blocks, but sequential users do not have that luxury.</para> </sect2> <sect2><title>Sequential writing</title> <para>If you are handling large images on a memory-limited machine, you may need to use the following functions for sequential write.</para> <programlisting id="EGifOpenFileName"> GifFileType *EGifOpenFileName(char *GifFileName, bool GifTestExistance, int *ErrorCode) </programlisting> <para>Open a new GIF file using the given GifFileName (in binary mode, if under Windows). If GifTestExistance is TRUE, and file exists, the file is not destroyed, and NULL returned.</para> <para>If any error occurs, NULL is returned and the ErrorCode is set.</para> <programlisting id="EGifOpenFileHandle"> GifFileType *EGifOpenFileHandle(int GifFileHandle, int *ErrorCode) </programlisting> <para>Open a new GIF file using the given GifFileHandle.</para> <para>If any error occurs, NULL is returned and ErrorCode is set.</para> <para>The file is opened in binary mode, and its buffer size is set to FILE_BUFFER_SIZE bytes.</para> <programlisting> char *EGifGetGifVersion(GifFileType *GifFile) </programlisting> <para>That version computation is available through this function.</para> <programlisting id="EGifSetGifVersion"> void EGifSetGifVersion(GifFileType *GifFile, bool gif89) </programlisting> <para>Set the GIF type, to GIF89 if the argument is true and GIF87 if it is false. The default type is GIF87. This function may be called after the GifFile record is allocated but before EGifPutScreenDesc().</para> <programlisting> int EGifPutScreenDesc(GifFileType *GifFile, const int GifWidth, const GifHeight, const int GifColorRes, const int GifBackGround, ColorMapObject *GifColorMap) </programlisting> <para>Update the GifFile Screen parameters, in GifFile structure and in the real file. If error occurs, returns GIF_ERROR (see gif_lib.h), otherwise GIF_OK.</para> <para>This routine should be called immediately after the GIF file was opened.</para> <programlisting> int EGifPutImageDesc(GifFileType *GifFile, const int GifLeft, const int GifTop, const int GifWidth, const GifHeight, const bool GifInterlace, ColorMapObject *GifColorMap) </programlisting> <para>Update GifFile Image parameters, in GifFile structure and in the real file. if error occurs returns GIF_ERROR (see gif_lib.h), otherwise GIF_OK.</para> <para>This routine should be called each time a new image must be dumped to the file.</para> <programlisting id="EGifPutLine"> int EGifPutLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen) </programlisting> <para>Dumps a block of pixels out to the GIF file. The slab can be of any length. More than that, this routine may be interleaved with <link linkend="EGifPutPixel">EGifPutPixel()</link>, until all pixels have been sent.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutPixel"> int EGifPutPixel(GifFileType *GifFile, const PixelType GifPixel) </programlisting> <para>Dumps one pixel to the GIF file. This routine may be interleaved with <link linkend="EGifPutLine">EGifPutLine()</link>, until all pixels were sent. Because of the overhead for each call, use of this routine is not recommended.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutComment"> int EGifPutComment(GifFileType *GifFile, char *GifComment) </programlisting> <para>Uses extension GIF records to save a string as a comment is the file. The extension code is 'C' (for Comment).</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutExtension"> int EGifPutExtension( GifFileType *GifFile, const int GifExtCode, const int GifExtLen, void *GifExtension) </programlisting> <para>Dumps the given extension block into the GIF file. Extension blocks are optional in GIF file. Extension blocks of more than 255 bytes or more than one block are not supported in this function. Please use EGifPutExtensionFirst, EGifPutExtensionBlock, and EGifPutExtensionTrailer if your extension blocks may fall into this category.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutExtensionLeader"> int EGifPutExtensionLeader( GifFileType * GifFile, const int GifExtCode) </programlisting> <para>Dumps the beginning of a GIF extension block to a GIF file. Extension blocks are optional in GIF files. This function outputs the type code information necessary for a GIF extension block.</para> <para>Further blocks of the GIF Extension should be dumped using EGifPutExtensionBlock. When finished with this extension block, EGifPutExtensionTrailer should be called to output the block termination.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutExtensionBlock"> int EGifPutExtensionBlock( GifFileType * GifFile, const int GifExtLen, const VoidPtr GifExtension) </programlisting> <para>Dumps a subblock of a GIF extension to a GIF File; should be used only following an initializing call to EGifPutExtensionLeader(). Extension blocks are optional in GIF files. This function will write the Extension Data in GifExtension to the file as a subblock of the preceding Extension Block. Repeat calling of this function until all data subblocks have been output.</para> <para>Note that EGifPutExtensionLeader needs to be called before any calls to this function. EGifPutExtensionTrailer should be called to finish the Extension block after all data subblocks have been output.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutExtensionTrailer"> int EGifPutExtensionTrailer( GifFileType * GifFile, const VoidPtr GifExtension) </programlisting> <para>Dumps the GIF extension block terminator to a GIF File to end the current Extension block.</para> <para>Note that a call to EGifPutExtensionLeader is needed to open the GIF Extension Block prior to calling this function.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutCode"> int EGifPutCode( GifFileType *GifFile, int *GifCodeSize, ByteType **GifCodeBlock) </programlisting> <para>It sometimes may be desired to write the compressed code as is without decoding it. For example a filter for a GIF file that change only screen size (GifPos), does not need the exact pixel values. Piping out the compressed image as is makes this process much faster.</para> <para>This routine does exactly that (with EGifPutCodeNext), and can be used instead of EGifPutLine. You'll usually use this with the DGifGetCode/DGifGetCodeNext routines, which reads the compressed code, while EGifPutCode/EGifPutCodeNext write it out. See gifpos.c for example.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise.</para> <programlisting id="EGifPutCodeNext"> int EGifPutCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock) </programlisting> <para>See EGifPutCode above.</para> <programlisting id="EGifCloseFile"> int EGifCloseFile(GifFileType *GifFile) </programlisting> <para>Write a termination block to the GIF, close the GIF file, and free all memory allocated for managing it. GifFile should not be used after this routine has been called.</para> <para>Returns GIF_ERROR if something went wrong, GIF_OK otherwise. When GIF_ERROR is returned, the diagnostic error code is left in ErrorCode. The GifFile structure is unconditionally freed.</para> <para>(Note: In versions before 5.1.0, the ErrorCode argument was absent and the GifFile structure was not freed so that the diagnostic error code will remain accessible in GifFile->Error. This behavior was changed because it caused problems for the implementation of library wrappers in dynamic languages.)</para> </sect2> </sect1> <sect1 id="compatibility"><title>Forward and Backward Compatibility</title> <para>Except for some details of extension-block handling and the addition of read/write function hooks, the DGifSlurp()/EGifSpew() interface has been stable since 1990. It is expected to remain so.</para> <para>However, the signatures of the file-opener functions were changed in 5.0 in order to make the library fully reentrant and thread-safe - earlier library versions did not feature the final pointer-to-error-code argument in DGifOpen() and friends. For the same reason, the static storage queried by GifLastError() in older versions is gone, and that function abolished.</para> <para>The library header contains some version #defines you can use if you need to condition your code so it can compile with different library versions</para> <para>Versions up to 4.1.6 defined a GIF_LIB_VERSION macro that was string-valued with a tricky format to parse. This macro has been retired.</para> <para>Versions after 4.1.6 define integer-valued GIFLIB_MAJOR, GIFLIB_MINOR, and GIFLIB_RELEASE macros for the three components of the version. See the NEWS file in the GIFLIB distribution to track API changes.</para> <para>The following functions are entirely new:</para> <itemizedlist> <listitem><para>New functions DGifSavedExtensionToGCB() and EGifGCBToSavedExtension() make it easy to read and edit GIF89 graphics control blocks in saved images.</para></listitem> <listitem><para>The new function DGifGetGifVersion() is convenient for people doing sequential reads.</para></listitem> </itemizedlist> <para>A few changes in behavior were introduced in 5.0:</para> <sect2><title>General behavior</title> <itemizedlist> <listitem><para>The library is now fully re-entrant and thread-safe.</para></listitem> </itemizedlist> <itemizedlist> <listitem><para> All functions exported by this library now have DGif, EGif, or Gif as a name prefix.</para></listitem> <listitem><para>The default GIF version to write is now computed at write time from the types of an image's extension blocks. (Formerly EGifSpew() behaved this way, but the sequential-writing code didn't.) The result of this computation is available through the new function EGifGetGifVersion().</para></listitem> </itemizedlist> </sect2> <sect2><title>In documented functions:</title> <itemizedlist> <listitem><para>GIF file openers and closers - DGifOpenFileName(), DGifOpenFileHandle(), DGifOpen(), DGifClose(), EGifOpenFileName(), EGifOpenFileHandle(), EGifOpen(), and EGifClose() - 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.</para></listitem> <listitem><para>EGifSlurp() and EGifSpew() read and write extension blocks trailing after the last image, handle interlaced images properly.</para></listitem> <listitem><para>EGifPutExtensionFirst() has been replaced by EGifPutExtensionLeader(); the difference is the new function doesn't take an optional block, it just writes a block leader.</para></listitem> <listitem><para>EGifPutExtensionNext() has been replaced by EGifPutExtensionBlock(); the difference is that the new function does not take and then discard a function code argument.</para></listitem> <listitem><para>EGifPutExtensionLast() has been replaced by EGifPutExtensionTrailer(); all it does is write the terminator block. Split your old EGifPutExtensionLast() calls into EGifPutExtensionBlock() followed by EGifPutExtensionTrailer().</para></listitem> </itemizedlist> </sect2> <sect2><title>In undocumented functions:</title> <itemizedlist> <listitem><para>Some undocumented functions have been renamed. AddExtensionBlock() is now GifAddExtensionBlock(), and takes an additional function code argument. ApplyTranslation() is now GifApplyTranslation(); FreeExtension() has become GifFreeExtensions() and takes a different argument type; MakeSavedImage() is now GifMakeSavedImage(), FreeSavedImages() is now GifFreeSavedImages(), and BitSize() is now GifBitSize().</para></listitem> <listitem><para>Three documented functions - MakeMapObject(), FreeMapObject(), and UnionColorMap() - have been renamed to GifMakeMapObject(), GifFreeMapObject(), and GifUnionColorMap() respectively.</para></listitem> </itemizedlist> </sect2> <sect2><title>Error handling:</title> <itemizedlist> <listitem><para>Library error handling no longer uses a static cell to store the last error code registered; that made the library thread-unsafe.</para></listitem> <listitem><para>For functions other than GIF file openers, the Error code is now put in an Error member of the GifFileType structure.</para></listitem> <listitem><para>The GifError() and 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.</para></listitem> </itemizedlist> </sect2> </sect1> <sect1><title>Skeletons of GIF filters</title> <para>If you are developing on a virtual-memory OS such as most flavors of UNIX, or are otherwise sure of having enough memory to keep all of GIFs you need to operate in core, writing a filter is trivial. See the file gifsponge.c in util.</para> <para>A sequential filter skeleton will usually look like the example file giffilter.c in util.</para> <para>Please look at the utilities in the util directory for more ideas once you feel comfortable with these skeletons. Also try to follow the coding standards of this package if you want the maintainer to officially add your new utility to it.</para> </sect1> <sect1><title>Unimplemented features</title> <para>Some features of the original GIF specification have not stood the test of time. This library mostly ignores them, but they are described here for completeness.</para> <para>The GIF standard fails to be explicit about a small but crucial detail: the unsigned two-byte integer fields in it are little-endian.</para> <para>The GIF format seems to have been designed with the idea that viewers would render multiple images in a GIF on a common canvas, giving an effect like a picture wall. The 'logical screen descriptor block' (LSDB), 6 bytes right after the 6-byte GIF stamp and version header at the beginning of a GIF file, includes both two-byte canvas width and canvas height fields and a canvas background color. Each image, besides height and width, also has 'left' and 'top' coordinates specifying where it is to be placed on the canvas.</para> <para>GIFLIB can read and set these fields; the gifpos and giftool utilities will enable you to script such changes. But browsers and modern image viewers ignore them. Nowadays multiple-image GIFs are generally used either as animations in which each sub-image is a frame or as image libraries, with the GIF client handling compositing into some canvas about which the GIF format holds no information.</para> <para>Another feature of the LSDB that is generally ignored is the pixel aspect ratio byte. Until 5.0, GIFLIB ignored this flag on input and zeroed it on output; now it is read and preserved if present. The GIF standard doesn't give a rationale for it, but it seems likely that the designers intended it for representing image captures from the analog television of the day, which had rectangular pixel-equivalents.</para> <para>Yet another ignored feature of both the LSDB and sub-images is the sort flag, which is supposed to signal whether the colors in the associated color map are sorted by decreasing importance in case the display device can only render a limited number of them. This feature reflected the high cost of dual-port memory at the time the GIF specification was written in the late 1980s. That kind of limit disappeared in the mid-1990s. Until 5.0, GIFLIB ignored this flag on input and zeroed it on output; now it is read and preserved if present.</para> <para>Finally, the plaintext extension block. This is an extension block that contains instructions for overlaying text captions on a following image. GIFLIB treats these blocks as raw data, not attempting to parse out the location and text data.</para> </sect1> </article> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/intro.html�������������������������������������������������������������������������0000664�0001750�0001750�00000020745�15166751647�013743� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Introduction to GIFLIB</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /></head><body><div class="article"><div class="titlepage"><div><div><h2 class="title"><a id="id1337"></a>Introduction to GIFLIB</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Eric</span> <span class="othername">Steven</span> <span class="surname">Raymond</span></h3><div class="affiliation"><span class="orgname"><a class="ulink" href="http://catb.org/~esr/" target="_top"> Thyrsus Enterprises</a><br /></span><div class="address"><p><br />     <code class="email">&lt;<a class="email" href="mailto:esr@thyrsus.com">esr@thyrsus.com</a>&gt;</code><br />     </p></div></div></div></div><div><p class="copyright">Copyright © 2012 Eric S. Raymond</p></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="#id1343">Utilities</a></span></dt><dd><dl><dt><span class="sect2"><a href="#id1339">Image Manipulation Components</a></span></dt><dt><span class="sect2"><a href="#id1340">Report Generators</a></span></dt><dt><span class="sect2"><a href="#id1341">GIF Composition Tools</a></span></dt><dt><span class="sect2"><a href="#id1342">Obsolete utilities</a></span></dt></dl></dd><dt><span class="sect1"><a href="#id1344">Library Functions</a></span></dt><dt><span class="sect1"><a href="#id1345">The GIF Standard</a></span></dt><dt><span class="sect1"><a href="#id1346">Package Status</a></span></dt></dl></div><p>GIFLIB is a package of portable tools and library routines for working with GIF images.</p><p>The Graphics Interchange Format(c) specification is the copyrighted property of CompuServe Incorporated. GIF(sm) is a service mark property of CompuServe Incorporated.</p><p>This package has been released under an X Consortium-like open-source license. Use and copy as you see fit. If you make useful changes, add new tools, or find and fix bugs, please send your mods to the maintainers for general distribution.</p><p>The util directory includes programs to clip, rotate, scale, and position GIF images. These are no replacement for an interactive graphics editor, but they can be very useful for scripted image generation or transformation.</p><p>The library includes program-callable entry points for reading and writing GIF files, an 8x8 utility font for embedding text in GIFs, and an error handler. GIF manipulation can be done at a relatively low level by sequential I/O (which automatically does/undoes image compression) or at a higher level by slurping an entire GIF into allocated core.</p><p>This library speaks both GIF87a and GIF89. The differences between GIF87 and GIF89 are minor: in the latter, the interpretation of some extension block types is defined. The library never needs to actually interpret these, but <a class="ulink" href="giftext.html" target="_top">giftext</a> notices them and there are functions in the API to read and modify them.</p><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id1343"></a>Utilities</h2></div></div></div><p>Here is a summary of the utilities in this package. If you're looking at this page through a web browser, each utility name should be a hotlink to HTML documentation.</p><p>Most utilities have a -v (verbose) option that will cause them to print the current input scan line number (counting up) whenever they read image input, and will print output image line number (counting down) when they dump output. Utilities that only read or write always print in increasing order.</p><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="id1339"></a>Image Manipulation Components</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="gifclrmp.html" target="_top">gifclrmp</a></span></dt><dd><p>modify GIF image colormaps</p></dd><dt><span class="term"><a class="ulink" href="giffix.html" target="_top">giffix</a></span></dt><dd><p>clumsily attempts to fix truncated GIF images</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="id1340"></a>Report Generators</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="giftext.html" target="_top">giftext</a></span></dt><dd><p>print (text only) general information about a GIF</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="id1341"></a>GIF Composition Tools</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="gifbuild.html" target="_top">gifbuild</a></span></dt><dd><p>converter/deconverter to/from an editable text format</p></dd><dt><span class="term"><a class="ulink" href="giftool.html" target="_top">giftool</a></span></dt><dd><p>GIF transformation tool</p></dd></dl></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a id="id1342"></a>Obsolete utilities</h3></div></div></div><p>These are used for testing by the GFLIB developers and no longer installed by a normal build.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="gif2rgb.html" target="_top">gif2rgb</a></span></dt><dd><p>convert images saved as GIF to 24-bit RGB image(s) or vice-versa</p></dd><dt><span class="term"><a class="ulink" href="gifbg.html" target="_top">gifbg</a></span></dt><dd><p>generate a single-color test pattern GIF</p></dd><dt><span class="term"><a class="ulink" href="gifcolor.html" target="_top">gifcolor</a></span></dt><dd><p>generate color test patterns</p></dd><dt><span class="term"><a class="ulink" href="gifwedge.html" target="_top">gifwedge</a></span></dt><dd><p>create a test GIF image resembling a color monitor test pattern</p></dd><dt><span class="term"><a class="ulink" href="gifhisto.html" target="_top">gifhisto</a></span></dt><dd><p>generate color-frequency histogram from a GIF</p></dd><dt><span class="term"><a class="ulink" href="gifecho.html" target="_top">gifecho</a></span></dt><dd><p>generate GIF images out of regular text in 8x8 font</p></dd><dt><span class="term"><a class="ulink" href="gifinto.html" target="_top">gifinto</a></span></dt><dd><p>end-of-pipe fitting for GIF-processing pipelines</p></dd></dl></div></div></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id1344"></a>Library Functions</h2></div></div></div><p>The library contains two groups of C functions. One group does sequential I/O on the stream-oriented GIF format. The other supports grabbing an entire GIF into allocated core, operating on it in core, and then writing the modified in-core GIF out to disk.</p><p>Unless you are on extremely memory-limited machine, you probably want to use the second group.</p><p>Detailed documentation on the library entry points is in <a class="ulink" href="gif_lib.html" target="_top">gif_lib.html</a>.</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id1345"></a>The GIF Standard</h2></div></div></div><p>The doc subdirectory includes an <a class="ulink" href="gifstandard/GIF89a.html" target="_top">HTML presentation of the GIF standard</a>; an <a class="ulink" href="gifstandard/ LZW-and-GIF-explained.html" target="_top">explanation of Lempel-Ziv compression</a>, and the original flat-ASCII description of <a class="ulink" href="gifstandard/gif89.txt" target="_top">GIF89 format</a> . For historical completeness, we also include a copy of the <a class="ulink" href="gifstandard/gif87.txt" target="_top">GIF87 standard.</a></p><p>You can also read a <a class="ulink" href="whatsinagif/index.html" target="_top"> detailed narrative description</a> of how GIFs are laid out. It clarifies some points on which the standard is obscure.</p></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id1346"></a>Package Status</h2></div></div></div><p>GIFLIB's current maintainer is Eric S. Raymond. You can find his home page at <a class="ulink" href="http://catb.org/~esr/" target="_top">http://catb.org/~esr/</a>.</p><p>GIFLIB is not under active development, but bug fixes are being accepted.</p></div></div></body></html>���������������������������giflib-6.1.3/doc/Makefile���������������������������������������������������������������������������0000664�0001750�0001750�00000002605�15166751647�013355� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.SUFFIXES: .xml .html .txt .adoc .1 .7 .xml.html: xmlto xhtml-nochunks $< .xml.1: xmlto man $< .xml.7: xmlto man $< .xml.txt: xmlto txt $< .adoc.html: asciidoc $< all: allhtml manpages # The distinction between XMLMAN and XMLINTERNAL is because # some pages shouldn't be installed as part of a binary package; # they're just for test-pattern generators or obsolete utilities. XMLMAN1 = \ gifbuild.xml \ gifclrmp.xml \ giffilter.xml \ giffix.xml \ gifsponge.xml \ giftext.xml \ giftool.xml XMLMAN7 = \ giflib.xml XMLINTERNAL = \ gif2rgb.xml \ gifbg.xml \ gifcolor.xml \ gifecho.xml \ gifinto.xml \ gifhisto.xml \ gifwedge.xml XMLDOC = intro.xml gif_lib.xml XMLALL = $(XMLMAN1) $(XMLMAN7) $(XMLINTERNAL) $(XMLDOC) # Logo image file for HTML docs (only needed for website) giflib-logo.gif: ../pic/gifgrid.gif convert $^ -resize 50x50 $@ # Philosophical choice: the website gets the internal manual pages allhtml: $(XMLALL:.xml=.html) manpages: $(XMLMAN1:.xml=.1) $(XMLMAN7:.xml=.7) $(XMLINTERNAL:.xml=.1) # Prepare the website directory to deliver an update. # ImageMagick and asciidoc are required. website: allhtml giflib-logo.gif rm -fr staging; mkdir staging; cp -r $(XMLALL:.xml=.html) gifstandard whatsinagif giflib-logo.gif staging cp index.html.in staging/index.html asciidoc - <../history.adoc >staging/history.html clean: @rm -fr *.[17] d$(XMLALL:.xml=.html) staging ���������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/giftext.html�����������������������������������������������������������������������0000664�0001750�0001750�00000004625�15166751647�014261� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>giftext</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /></head><body><div class="refentry"><a id="giftext.1"></a><div class="titlepage"></div><div class="refnamediv"><a id="name"></a><h2>Name</h2><p>giftext — dump GIF pixels and metadata as text</p></div><div class="refsynopsisdiv"><a id="synopsis"></a><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">giftext</code> [-v] [-c] [-e] [-z] [-p] [-r] [-h] [<em class="replaceable"><code>gif-file</code></em>]</p></div></div><div class="refsect1"><a id="id1337"></a><h2>Description</h2><p>A program to dump (text only) general information about GIF file.</p><p>If no GIF file is given, giftext will try to read a GIF file from stdin.</p></div><div class="refsect1"><a id="id1338"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-v</span></dt><dd><p> Verbose mode (show progress). Enables printout of running scan lines. </p></dd><dt><span class="term">-c</span></dt><dd><p> Dumps the color maps.</p></dd><dt><span class="term">-e</span></dt><dd><p> Dumps encoded bytes - the pixels after compressed using LZ algorithm and chained to form bytes. This is the form the data is saved in the GIF file. Dumps in hex - 2 digit per byte.</p></dd><dt><span class="term">-z</span></dt><dd><p> Dumps the LZ codes of the image. Dumps in hex - 3 digits per code (as we are limited to 12 bits).</p></dd><dt><span class="term">-p</span></dt><dd><p> Dumps the pixels of the image. Dumps in hex - 2 digit per pixel (&lt;=byte).</p></dd><dt><span class="term">-r</span></dt><dd><p> Dumps raw pixels as one byte per pixel. This option inhibits all other options and only the pixels are dumped. This option may be used to convert GIF files into raw data. Note: the color map can be extracted by gifclrmp utility. If more than one image is included in the file, all images will be dumped in order.</p></dd><dt><span class="term">-h</span></dt><dd><p> Print one line of command line help, similar to Usage above.</p></dd></dl></div></div><div class="refsect1"><a id="id1339"></a><h2>Author</h2><p>Gershon Elber.</p></div></div></body></html>�����������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifecho.html�����������������������������������������������������������������������0000664�0001750�0001750�00000006477�15166751647�014222� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>gifecho</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /></head><body><div class="refentry"><a id="gifecho.1"></a><div class="titlepage"></div><div class="refnamediv"><a id="name"></a><h2>Name</h2><p>gifecho — generate a GIF from ASCII text</p></div><div class="refsynopsisdiv"><a id="synopsis"></a><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">gifecho</code> [-v] [-s <em class="replaceable"><code>colormap-size</code></em>] [-f <em class="replaceable"><code>foreground</code></em>] [-c <em class="replaceable"><code>R</code></em> <em class="replaceable"><code>G</code></em> <em class="replaceable"><code>B</code></em>] [-t <em class="replaceable"><code>text</code></em>] [-h] [<em class="replaceable"><code>gif-file</code></em>]</p></div></div><div class="refsect1"><a id="id1337"></a><h2>Description</h2><p>A program to generate GIF images out of regular text. Text can be one line or multi-line, and is converted using 8 by 8 fixed font.</p><p>This program reads stdin if no text is provided on the command line (-t), and will dump the created GIF file to stdout.</p></div><div class="refsect1"><a id="id1338"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-v</span></dt><dd><p>Verbose mode (show progress). Enables printout of running scan lines. </p></dd><dt><span class="term">-s colormap-size</span></dt><dd><p>Explicitly defines the size of the color map of the resulting gif image. Usually the image will be bicolor with fg as color 1, unless [-f] is explicitly given in case the color map size will be big enough to hold it. However it is sometimes convenient to set the color map size to certain size while the fg color is small mainly so this image may be merged with another (images must match color map size).</p></dd><dt><span class="term">-f foreground</span></dt><dd><p> Select foreground index (background is always 0). By default it is one and therefore the image result is bicolored. if FG is set to n then color map will be created with 2^k entries where 2^k &gt; n for minimum k, assuming k &lt;= 8. This color map will be all zeros except this foreground index. This option is useful if this text image should be integrated into other image colormap using their colors.</p></dd><dt><span class="term">-c R G B</span></dt><dd><p> The color to use as the foreground color. White by default.</p></dd><dt><span class="term">-t text</span></dt><dd><p> One line of text can be provided on the command line. Note you must encapsulate the Text within quotes if it has spaces (The quotes themselves are not treated as part of the text). If no -t option is provided, stdin is read until end of file.</p></dd><dt><span class="term">-h</span></dt><dd><p> Print one line command line help, similar to Usage above.</p></dd></dl></div></div><div class="refsect1"><a id="id1339"></a><h2>Notes</h2><p>There is a hardcoded limit of 100 the number of lines.</p></div><div class="refsect1"><a id="id1340"></a><h2>Author</h2><p>Gershon Elber.</p></div></div></body></html>�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/giffilter.xml����������������������������������������������������������������������0000664�0001750�0001750�00000002320�15166751647�014404� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ <!ENTITY email "esr@thyrsus.com"> ]> <refentry id='giffilter.1'> <refentryinfo><date>2 May 2012</date></refentryinfo> <refmeta> <refentrytitle>giffilter</refentrytitle> <manvolnum>1</manvolnum> <refmiscinfo class="source">GIFLIB</refmiscinfo> <refmiscinfo class="manual">GIFLIB Documentation</refmiscinfo> </refmeta> <refnamediv id='name'> <refname>giffilter</refname> <refpurpose>expensive GIF copy, a model for filter utilities</refpurpose> </refnamediv> <refsynopsisdiv id='synopsis'> <cmdsynopsis> <command>giffilter</command> </cmdsynopsis> </refsynopsisdiv> <refsect1><title>Description</title> <para>This is an expensive way to copy a GIF. The source is included as a skeleton for more sophisticated filters. See the source in the util directory for details.</para> <para>Also has some utility as a test of the sequential GIF record I/O routines. The output should be bytewise identical to the input.</para> </refsect1> <refsect1><title>Author</title> <para>Eric S. Raymond <email>&email;</email></para> </refsect1> </refentry> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifhisto.1�������������������������������������������������������������������������0000664�0001750�0001750�00000005603�15166751647�013614� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: gifhisto .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFHISTO" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifhisto \- make a color histogram from GIF color frequencies .SH "SYNOPSIS" .HP \w'\fBgifhisto\fR\ 'u \fBgifhisto\fR [\-v] [\-t] [\-s\ \fIwidth\fR\ \fIheight\fR] [\-n\ \fIimage\-number\fR] [\-b] [\-h] [\fIgif\-file\fR] .SH "DESCRIPTION" .PP A program to create histogram of number of pixels using each color\&. The output can be formatted into a GIF histogram file, or as text file \- both go to stdout\&. .PP If no GIF file is given, gifhisto will try to read a GIF file from stdin\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-t .RS 4 Force output to be text file of the following form: (colormap size) lines each containing two integers: number of times color appeared, and color index\&. Lines are in increasing color index order\&. This output can be fed directly to a sort program if ordering by color frequency is desired\&. .sp The colormap picked is the one to be used for the image to generate histogram for, as defined in GIF format\&. .RE .PP \-s width height .RS 4 Size of GIF histogram file\&. The height of the histogram should be power of 2 divisible by number of colors in colormap\&. .sp Width sets the resolution (accuracy if you like) of the histogram as the maximum histogram bar is scaled to fit it\&. .RE .PP \-n image\-number .RS 4 Image number to test\&. Default is one\&. .RE .PP \-b .RS 4 Zeros the background color count\&. As only linear scale bars are supported and usually the background appears much more often then other colors, deleting the background count will improve the scaling of other colors\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .SH "AUTHOR" .PP Gershon Elber �����������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/giffilter.1������������������������������������������������������������������������0000664�0001750�0001750�00000003276�15166751647�013757� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: giffilter .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFFILTER" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" giffilter \- expensive GIF copy, a model for filter utilities .SH "SYNOPSIS" .HP \w'\fBgiffilter\fR\ 'u \fBgiffilter\fR .SH "DESCRIPTION" .PP This is an expensive way to copy a GIF\&. The source is included as a skeleton for more sophisticated filters\&. See the source in the util directory for details\&. .PP Also has some utility as a test of the sequential GIF record I/O routines\&. The output should be bytewise identical to the input\&. .SH "AUTHOR" .PP Eric S\&. Raymond <esr@thyrsus\&.com> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/giftool.1��������������������������������������������������������������������������0000664�0001750�0001750�00000012153�15166751647�013441� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: giftool .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 3 June 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFTOOL" "1" "3 June 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" giftool \- GIF transformation tool .SH "SYNOPSIS" .HP \w'\fBgiftool\fR\ 'u \fBgiftool\fR [\-a\ \fIaspect\fR] [\-b\ \fIbgcolor\fR] [\-d\ \fIdelaytime\fR] [\-i\ \fIinterlacing\fR] [\-n\ \fIimagelist\fR] [\-p\ \fIleft,top\fR] [\-s\ \fIwidth,height\fR] [\-t\ \fItranscolor\fR] [\-u\ \fIsort\-flag\fR] [\-x\ \fIdisposal\fR] [\-z\ \fIsort\-flag\fR] .SH "DESCRIPTION" .PP A filter for transforming GIFS\&. With no options, it\*(Aqs an expensive copy of a GIF in standard input to standard output\&. Options specify filtering operations and are performed in the order specified on the command line\&. .PP The \-n option selects images, allowing the tool to act on a subset of images in a multi\-image GIF\&. This option takes a comma\-separated list of decimal integers which are interpreted as 1\-origin image indices; these are the images that will be acted on\&. If no \-n option is specified, the tool will select and transform all images\&. .PP The \-b option takes a decimal integer argument and uses it to set the (0\-origin) screen background color index\&. .PP The \-f option accepts a printf\-style format string and substitutes into it the values of image\-descriptor and graphics\-control fields\&. The string is formatted and output once for each selected image\&. Normal C\-style escapes \eb, \ef, \en, \er, \et\&. \ev, and \exNN are interpreted; also \ee produces ESC (ASCII 0x1b)\&. The following format cookies are substituted: .PP %a .RS 4 Pixel aspect byte\&. .RE .PP %b .RS 4 Screen background color\&. .RE .PP %d .RS 4 Image delay time .RE .PP %h .RS 4 Image height (y dimension) .RE .PP %n .RS 4 Image index .RE .PP %p .RS 4 Image position (as an x,y pair) .RE .PP %s .RS 4 Screen size (as an x,y pair) .RE .PP %t .RS 4 Image transparent\-color index .RE .PP %u .RS 4 Image user\-input flag (boolean) .RE .PP %v .RS 4 GIF version string .RE .PP %w .RS 4 Image width (x dimension) .RE .PP %x .RS 4 Image GIF89 disposal mode .RE .PP %z .RS 4 Image\*(Aqs color table sort flag (boolean, false if no local color map) .RE .PP Boolean substitutions may take a prefix to modify how they are displayed: .PP 1 .RS 4 "1" or "0" .RE .PP o .RS 4 "on" or "off" .RE .PP t .RS 4 "t" or "f" .RE .PP y .RS 4 "yes" or "no" .RE .PP Thus, for example, "%oz" displays image sort flags using the strings "on" and "off"\&. The default with no prefix is numeric\&. .PP The \-a option takes an unsigned decimal integer argument and uses it to set the aspect\-ratio bye in the logical screen descriptor block\&. .PP The \-b option takes an unsigned decimal integer argument and uses it to set the background color index in the logical screen descriptor block\&. .PP The \-d option takes a decimal integer argument and uses it to set a delay time, in hundredths of a second, on selected images\&. .PP The \-i option sets or clears interlacing in selected images\&. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f" .PP The \-p option takes a (0\-origin) x,y coordinate\-pair and sets it as the preferred upper\-left\-corner coordinates of selected images\&. .PP The \-s option takes a (0\-origin) x,y coordinate\-pair and sets it as the expected display screen size\&. .PP The \-t option takes a decimal integer argument and uses it to set the (0\-origin) index of the transparency color in selected images\&. .PP The \-u option sets or clears the user\-input flag in selected images\&. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f"\&. .PP The \-x option takes a decimal integer argument and uses it to set the GIF89 disposal mode in selected images\&. .PP The \-z option sets or clears the color\-table sort flag in selected images\&. Acceptable arguments are "1", "0", "yes", "no", "on", "off", "t", "f"\&. .PP Note that the \-a, \-b, \-p, \-s, and \-z options are included to complete the ability to modify all fields defined in the GIF standard, but should have no effect on how an image renders on browsers or modern viewers\&. .SH "AUTHOR" .PP Eric S\&. Raymond\&. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/index.html�������������������������������������������������������������������������0000664�0001750�0001750�00000007333�15166751647�013715� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html> <head> <link rev='made' href='mailto:esr@snark.thyrsus.com' /> <meta name='MSSmartTagsPreventParsing' content='TRUE' /> <title>The GIFLIB project</title> <script type="text/javascript"> // JavaScript to generate a compact date representation // // format date as yyyy-mm-dd // function date_ddmmmyyyy(date) { var d = date.getDate(); var m = date.getMonth() + 1; var y = date.getFullYear(); return "" + y + "-" + (m<10?"0"+m:m) + "-" + (d<10?"0"+d:d); } // // get last modified date of the // current document. // function date_lastmodified() { var lmd = document.lastModified; var s = "Unknown"; var d1; // check if we have a valid date // before proceeding if(0 != (d1=Date.parse(lmd))) { s = "" + date_ddmmmyyyy(new Date(d1)); } return s; } // End </script> </head> <body> <table width='100%' cellpadding='0' summary='Canned page header' bgcolor="#ddd"> <tr> <td><h2>The GIFLIB project</h2></td> <td align="center"><img src="giflib-logo.gif"></td> <td align='right'><script type="text/javascript"> document.write(date_lastmodified()); </script></td> </tr> </table> <p>The GIFLIB project maintains the giflib service library, which has been pulling images out of GIFs since 1989. It is deployed everywhere you can think of and some places you probably can't - graphics applications and web browsers on multiple operating systems, game consoles, smartphones, and likely your ATM too.</p> <p>Yes, this code is he reason GIFs were in Mosaic, the first web browser that could do inline graphics; it is the implementation Andreesen and Bina used.</p> <p>This is very mature, stable, small-footprint code with minimal dependencies (suitable for use in embedded deployments) that needs only occasional very minor bugfixes. Test reports from odd platforms and better regression tests are particularly welcome. Don't try to redesign it, applications beyond counting would break if you did.</p> <p>It's "GIFLIB" in caps as a nod to the code's origins in the dark and backward abysm of MS-DOS, but Unix hackers are encouraged to spell it "giflib" in deference to local conventions. :-) <p>You can read GIFLIB's documentation <a href="intro.html">here</a> and a very detailed description of GIF <a href="whatsinagif/index.html">here</a>. People to thank for this code: Gershon Elber, Eric S. Raymond, Toshio Kuratomi.</p> <p>Before October 2006 the GIF format was encumbered by patents on the LZW compression it uses. This first became an issue in 1993 when the patent-holders made ambiguous noises about requiring royalties. For some time a subset of this code travelled as "libungif", supporting decompression but not compression. You can read a more detailed history <a href="history.html">here</a>.</p> <p>Note: The 5.x versions change the API slightly in a way that isn't compatible with older shared libraries. This was required to fix some known problems with the extensions API and with thread-safety.</p> <p>If you require shared-library compatibility back to ancient versions, build from 4.2. 4.2 and the 5.0 version are behaviorally almost identical; the few differences are explained <a href="gif_lib.html#compatibility">here</a>. <p>The SourceForge summary page (where you can download the source, review the project, find links to the bugtracker and mailing list pages, or ask to join the project as a developer) is <a href="https://sourceforge.net/projects/giflib/">here</a>. <p>If you appreciate this project, and especially if you make money from it, please <a href="https://www.patreon.com/esr">support continuing maintainance on Patreon</a>.</p> </body> </html> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifwedge.xml�����������������������������������������������������������������������0000664�0001750�0001750�00000004144�15166751647�014220� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> <refentry id='gifwedge.1'> <refentryinfo><date>2 May 2012</date></refentryinfo> <refmeta> <refentrytitle>gifwedge</refentrytitle> <manvolnum>1</manvolnum> <refmiscinfo class="source">GIFLIB</refmiscinfo> <refmiscinfo class="manual">GIFLIB Documentation</refmiscinfo> </refmeta> <refnamediv id='name'> <refname>gifwedge</refname> <refpurpose>create a GIF test pattern</refpurpose> </refnamediv> <refsynopsisdiv id='synopsis'> <cmdsynopsis> <command>gifwedge</command> <arg choice='opt'>-v</arg> <arg choice='opt'>-l <replaceable>levels</replaceable></arg> <arg choice='opt'>-s <replaceable>sizex</replaceable> <replaceable>sizey</replaceable></arg> <arg choice='opt'>-h</arg> <arg choice='opt'><replaceable>gif-file</replaceable></arg> </cmdsynopsis> </refsynopsisdiv> <refsect1><title>Description</title> <para>A program to create a test GIF image with intensity levels of the RGB colors YCM colors and white.</para> </refsect1> <refsect1><title>Options</title> <variablelist> <varlistentry> <term>-v</term> <listitem> <para>Verbose mode (show progress). Enables printout of running scan lines. </para> </listitem> </varlistentry> <varlistentry> <term>-l levels</term> <listitem> <para>Set number of intensity levels per color. This number must be power of two up to 32, as Gif format can only have 256 color simultaneously and 7 basic colors are to be displayed.</para> </listitem> </varlistentry> <varlistentry> <term>-s sizex sizey</term> <listitem> <para>Force image size to be SizeX by SizeY pixels. Image size will be rounded down to be a multiple of number of intensities horizontally, and 7 (colors) vertically.</para> </listitem> </varlistentry> <varlistentry> <term>-h</term> <listitem> <para>Print one line command line help, similar to Usage above.</para> </listitem> </varlistentry> </variablelist> </refsect1> <refsect1><title>Author</title> <para>Gershon Elber.</para> </refsect1> </refentry> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/doc/gifcolor.1�������������������������������������������������������������������������0000664�0001750�0001750�00000004506�15166751647�013605� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'\" t .\" Title: gifcolor .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB .\" Language: English .\" .TH "GIFCOLOR" "1" "2 May 2012" "GIFLIB" "GIFLIB Documentation" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" gifcolor \- generate color test\-pattern GIFs .SH "SYNOPSIS" .HP \w'\fBgifcolor\fR\ 'u \fBgifcolor\fR [\-v] [\-b\ \fIbackground\fR] [\-h] [\fIcolormap\-file\fR] .SH "DESCRIPTION" .PP A program to generate color test patterns\&. Feed it a color map file (as generated, say, by the \-s option of gifclrmp) and it will generate a GIF containing lines of the form\&. .sp .if n \{\ .RS 4 .\} .nf Color %\-3d: [%\-3d, %\-3d, %\-3d]: .fi .if n \{\ .RE .\} .PP where the first number is the zero\-based color index, and the triple is the index\*(Aqs [Red, Green, Blue] value\&. There will be one such line for each color\&. Each line will be set in a simple 8x8 font in the color it describes; thus, any lines corresponding to the GIF\*(Aqs background color will be blank\&. .SH "OPTIONS" .PP \-v .RS 4 Verbose mode (show progress)\&. Enables printout of running scan lines\&. .RE .PP \-b .RS 4 Set the image\*(Aqs backround color to a given numeric index\&. .RE .PP \-h .RS 4 Print one line of command line help, similar to Usage above\&. .RE .PP If no colormap file is specified, the color map will be read from stdin\&. .SH "AUTHOR" .PP Gershon Elber\&. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/giftool.c������������������������������������������������������������������������������0000664�0001750�0001750�00000032331�15166751647�012756� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** giftool.c - GIF transformation tool. ****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond <esr@thyrsus.com> #include <fcntl.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "getarg.h" #include "getopt.h" #include "gif_lib.h" #define PROGRAM_NAME "giftool" #define MAX_OPERATIONS 256 #define MAX_IMAGES 2048 enum boolmode { numeric, onoff, tf, yesno }; char *putbool(bool flag, enum boolmode mode) { if (flag) { switch (mode) { case numeric: return "1"; break; case onoff: return "on"; break; case tf: return "true"; break; case yesno: return "yes"; break; } } else { switch (mode) { case numeric: return "0"; break; case onoff: return "off"; break; case tf: return "false"; break; case yesno: return "no"; break; } } return "FAIL"; /* should never happen */ } bool getbool(char *from) { struct valmap { char *name; bool val; } boolnames[] = { {"yes", true}, {"on", true}, {"1", true}, {"t", true}, {"no", false}, {"off", false}, {"0", false}, {"f", false}, {NULL, false}, }, *sp; // cppcheck-suppress nullPointerRedundantCheck for (sp = boolnames; sp->name; sp++) { if (strcmp(sp->name, from) == 0) { return sp->val; } } (void)fprintf(stderr, "giftool: %s is not a valid boolean argument.\n", from); exit(EXIT_FAILURE); } struct operation { enum { aspect, delaytime, background, info, interlace, position, screensize, transparent, userinput, disposal, } mode; union { GifByteType numerator; int delay; int color; int dispose; char *format; bool flag; struct { int x, y; } p; }; }; int main(int argc, char **argv) { extern char *optarg; /* set by getopt */ extern int optind; /* set by getopt */ struct operation operations[MAX_OPERATIONS]; struct operation *top = operations; int selected[MAX_IMAGES], nselected = 0; bool have_selection = false; char *cp; int i, status, ErrorCode; GifFileType *GifFileIn, *GifFileOut = (GifFileType *)NULL; struct operation *op; /* * Gather operations from the command line. We use regular * getopt(3) here rather than Gershom's argument getter because * preserving the order of operations is important. */ while ((status = getopt(argc, argv, "a:b:d:f:i:n:p:s:u:x:")) != EOF) { if (top >= operations + MAX_OPERATIONS) { (void)fprintf(stderr, "giftool: too many operations."); exit(EXIT_FAILURE); } switch (status) { case 'a': top->mode = aspect; top->numerator = (GifByteType)atoi(optarg); break; case 'b': top->mode = background; top->color = atoi(optarg); break; case 'd': top->mode = delaytime; top->delay = atoi(optarg); break; case 'f': top->mode = info; top->format = optarg; break; case 'i': top->mode = interlace; top->flag = getbool(optarg); break; case 'n': have_selection = true; nselected = 0; cp = optarg; for (;;) { size_t span = strspn(cp, "0123456789"); if (span > 0) { selected[nselected++] = atoi(cp) - 1; cp += span; if (*cp == '\0') { break; } else if (*cp == ',') { continue; } } (void)fprintf(stderr, "giftool: bad selection.\n"); exit(EXIT_FAILURE); } break; case 'p': case 's': if (status == 'p') { top->mode = position; } else { top->mode = screensize; } cp = strchr(optarg, ','); if (cp == NULL) { (void)fprintf(stderr, "giftool: missing comma " "in coordinate pair.\n"); exit(EXIT_FAILURE); } top->p.x = atoi(optarg); top->p.y = atoi(cp + 1); if (top->p.x < 0 || top->p.y < 0) { (void)fprintf( stderr, "giftool: negative coordinate.\n"); exit(EXIT_FAILURE); } break; case 'u': top->mode = userinput; top->flag = getbool(optarg); break; case 'x': top->mode = disposal; top->dispose = atoi(optarg); break; default: fprintf(stderr, "usage: giftool [-b color] [-d delay] [-iI] " "[-t color] -[uU] [-x disposal]\n"); break; } ++top; } /* read in a GIF */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } if (DGifSlurp(GifFileIn) == GIF_ERROR) { PrintGifError(GifFileIn->Error); exit(EXIT_FAILURE); } if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* if the selection is defaulted, compute it; otherwise bounds-check it */ if (!have_selection) { for (i = nselected = 0; i < GifFileIn->ImageCount; i++) { selected[nselected++] = i; } } else { for (i = 0; i < nselected; i++) { if (selected[i] >= GifFileIn->ImageCount || selected[i] < 0) { (void)fprintf(stderr, "giftool: selection " "index out of bounds.\n"); exit(EXIT_FAILURE); } } } /* perform the operations we've gathered */ for (op = operations; op < top; op++) { switch (op->mode) { case background: GifFileIn->SBackGroundColor = op->color; break; case delaytime: for (i = 0; i < nselected; i++) { GraphicsControlBlock gcb; DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); gcb.DelayTime = op->delay; EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]); } break; case info: for (i = 0; i < nselected; i++) { SavedImage *ip = &GifFileIn->SavedImages[selected[i]]; GraphicsControlBlock gcb; for (cp = op->format; *cp; cp++) { if (*cp == '\\') { char c; switch (*++cp) { case 'b': (void)putchar('\b'); break; case 'e': (void)putchar(0x1b); break; case 'f': (void)putchar('\f'); break; case 'n': (void)putchar('\n'); break; case 'r': (void)putchar('\r'); break; case 't': (void)putchar('\t'); break; case 'v': (void)putchar('\v'); break; case 'x': switch (*++cp) { case '0': c = (char)0x00; break; case '1': c = (char)0x10; break; case '2': c = (char)0x20; break; case '3': c = (char)0x30; break; case '4': c = (char)0x40; break; case '5': c = (char)0x50; break; case '6': c = (char)0x60; break; case '7': c = (char)0x70; break; case '8': c = (char)0x80; break; case '9': c = (char)0x90; break; case 'A': case 'a': c = (char)0xa0; break; case 'B': case 'b': c = (char)0xb0; break; case 'C': case 'c': c = (char)0xc0; break; case 'D': case 'd': c = (char)0xd0; break; case 'E': case 'e': c = (char)0xe0; break; case 'F': case 'f': c = (char)0xf0; break; default: return -1; } switch (*++cp) { case '0': c += 0x00; break; case '1': c += 0x01; break; case '2': c += 0x02; break; case '3': c += 0x03; break; case '4': c += 0x04; break; case '5': c += 0x05; break; case '6': c += 0x06; break; case '7': c += 0x07; break; case '8': c += 0x08; break; case '9': c += 0x09; break; case 'A': case 'a': c += 0x0a; break; case 'B': case 'b': c += 0x0b; break; case 'C': case 'c': c += 0x0c; break; case 'D': case 'd': c += 0x0d; break; case 'E': case 'e': c += 0x0e; break; case 'F': case 'f': c += 0x0f; break; default: return -2; } putchar(c); break; default: putchar(*cp); break; } } else if (*cp == '%') { enum boolmode boolfmt; SavedImage *sp = &GifFileIn->SavedImages[i]; if (cp[1] == 't') { boolfmt = tf; ++cp; } else if (cp[1] == 'o') { boolfmt = onoff; ++cp; } else if (cp[1] == 'y') { boolfmt = yesno; ++cp; } else if (cp[1] == '1') { boolfmt = numeric; ++cp; } else { boolfmt = numeric; } switch (*++cp) { case '%': putchar('%'); break; case 'a': (void)printf( "%d", GifFileIn ->AspectByte); break; case 'b': (void)printf( "%d", GifFileIn ->SBackGroundColor); break; case 'd': DGifSavedExtensionToGCB( GifFileIn, selected[i], &gcb); (void)printf( "%d", gcb.DelayTime); break; case 'h': (void)printf( "%d", ip->ImageDesc .Height); break; case 'n': (void)printf( "%d", selected[i] + 1); break; case 'p': (void)printf( "%d,%d", ip->ImageDesc.Left, ip->ImageDesc.Top); break; case 's': (void)printf( "%d,%d", GifFileIn->SWidth, GifFileIn->SHeight); break; case 'w': (void)printf( "%d", ip->ImageDesc .Width); break; case 't': DGifSavedExtensionToGCB( GifFileIn, selected[i], &gcb); (void)printf( "%d", gcb.TransparentColor); break; case 'u': DGifSavedExtensionToGCB( GifFileIn, selected[i], &gcb); (void)printf( "%s", putbool( gcb.UserInputFlag, boolfmt)); break; case 'v': fputs(EGifGetGifVersion( GifFileIn), stdout); break; case 'x': DGifSavedExtensionToGCB( GifFileIn, selected[i], &gcb); (void)printf( "%d", gcb.DisposalMode); break; case 'z': (void)printf( "%s", putbool( sp->ImageDesc .ColorMap && sp->ImageDesc .ColorMap ->SortFlag, boolfmt)); break; default: (void)fprintf( stderr, "giftool: bad " "format %%%c\n", *cp); } } else { (void)putchar(*cp); } } } exit(EXIT_SUCCESS); break; case interlace: for (i = 0; i < nselected; i++) { GifFileIn->SavedImages[selected[i]] .ImageDesc.Interlace = op->flag; } break; case position: for (i = 0; i < nselected; i++) { GifFileIn->SavedImages[selected[i]] .ImageDesc.Left = op->p.x; GifFileIn->SavedImages[selected[i]] .ImageDesc.Top = op->p.y; } break; case screensize: GifFileIn->SWidth = op->p.x; GifFileIn->SHeight = op->p.y; break; case transparent: for (i = 0; i < nselected; i++) { GraphicsControlBlock gcb; DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); gcb.TransparentColor = op->color; EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]); } break; case userinput: for (i = 0; i < nselected; i++) { GraphicsControlBlock gcb; DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); gcb.UserInputFlag = op->flag; EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]); } break; case disposal: for (i = 0; i < nselected; i++) { GraphicsControlBlock gcb; DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); gcb.DisposalMode = op->dispose; EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]); } break; default: (void)fprintf(stderr, "giftool: unknown operation mode\n"); exit(EXIT_FAILURE); } } /* write out the results */ GifFileOut->SWidth = GifFileIn->SWidth; GifFileOut->SHeight = GifFileIn->SHeight; GifFileOut->SColorResolution = GifFileIn->SColorResolution; GifFileOut->SBackGroundColor = GifFileIn->SBackGroundColor; if (GifFileIn->SColorMap != NULL) { GifFileOut->SColorMap = GifMakeMapObject(GifFileIn->SColorMap->ColorCount, GifFileIn->SColorMap->Colors); } for (i = 0; i < GifFileIn->ImageCount; i++) { (void)GifMakeSavedImage(GifFileOut, &GifFileIn->SavedImages[i]); } if (EGifSpew(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); } else if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); } return 0; } /* end */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/gifcolor.c�����������������������������������������������������������������������������0000664�0001750�0001750�00000012202�15166751647�013112� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** gifcolor - generate color test-pattern GIFs *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifcolor" #define LINE_LEN 40 #define IMAGEWIDTH LINE_LEN *GIF_FONT_WIDTH static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- b%-Background!d h%-"; static int BackGround = 0; static void QuitGifError(GifFileType *GifFile); static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, int BufferWidth, int ForeGroundIndex); /****************************************************************************** Interpret the command line and generate the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, l, GifNoisyPrint, ColorMapSize, ErrorCode; bool Error, BackGroundFlag = false, HelpFlag = false; char Line[LINE_LEN]; GifRowType RasterBuffer[GIF_FONT_HEIGHT]; ColorMapObject *ColorMap; GifFileType *GifFile; GifColorType ScratchMap[256]; int red, green, blue; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &BackGroundFlag, &BackGround, &HelpFlag)) != false) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* Allocate the raster buffer for GIF_FONT_HEIGHT scan lines. */ for (i = 0; i < GIF_FONT_HEIGHT; i++) { if ((RasterBuffer[i] = (GifRowType)malloc( sizeof(GifPixelType) * IMAGEWIDTH)) == NULL) { GIF_EXIT( "Failed to allocate memory required, aborted."); } } /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Read the color map in ColorFile into this color map: */ ColorMapSize = 0; while (fscanf(stdin, "%*3d %3d %3d %3d\n", &red, &green, &blue) == 3) { if (ColorMapSize < 256) { ScratchMap[ColorMapSize].Red = red; ScratchMap[ColorMapSize].Green = green; ScratchMap[ColorMapSize].Blue = blue; ColorMapSize++; } else { GIF_EXIT("Too many color map triples, aborting."); } } if ((ColorMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ScratchMap)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } if (EGifPutScreenDesc( GifFile, IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT, GifBitSize(ColorMapSize), BackGround, ColorMap) == GIF_ERROR) { QuitGifError(GifFile); } /* Dump out the image descriptor: */ if (EGifPutImageDesc(GifFile, 0, 0, IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT, false, NULL) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); for (i = l = 0; i < ColorMap->ColorCount; i++) { (void)snprintf( Line, sizeof(Line), "Color %-3d: [%-3d, %-3d, %-3d] ", i, ColorMap->Colors[i].Red, ColorMap->Colors[i].Green, ColorMap->Colors[i].Blue); GenRasterTextLine(RasterBuffer, Line, IMAGEWIDTH, i); for (j = 0; j < GIF_FONT_HEIGHT; j++) { if (EGifPutLine(GifFile, RasterBuffer[j], IMAGEWIDTH) == GIF_ERROR) { QuitGifError(GifFile); } GifQprintf("\b\b\b\b%-4d", l++); } } if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } return 0; } /****************************************************************************** Close output file (if open), and exit. ******************************************************************************/ static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, int BufferWidth, int ForeGroundIndex) { unsigned char Byte, Mask; int i, j, k, CharPosX, Len = strlen(TextLine); for (i = 0; i < BufferWidth; i++) for (j = 0; j < GIF_FONT_HEIGHT; j++) RasterBuffer[j][i] = BackGround; for (i = CharPosX = 0; i < Len; i++, CharPosX += GIF_FONT_WIDTH) { unsigned char c = TextLine[i]; for (j = 0; j < GIF_FONT_HEIGHT; j++) { Byte = GifAsciiTable8x8[(unsigned short)c][j]; for (k = 0, Mask = 128; k < GIF_FONT_WIDTH; k++, Mask >>= 1) if (Byte & Mask) RasterBuffer[j][CharPosX + k] = ForeGroundIndex; } } } /****************************************************************************** Close output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFile) { if (GifFile != NULL) { PrintGifError(GifFile->Error); EGifCloseFile(GifFile, NULL); } exit(EXIT_FAILURE); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/gifinto.c������������������������������������������������������������������������������0000664�0001750�0001750�00000013330�15166751647�012750� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** gifinto - save GIF on stdin to file if size over set threshold *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include <ctype.h> #include <fcntl.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _WIN32 #include <io.h> #else #include <unistd.h> #endif /* _WIN32 */ #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifinto" #define STRLEN 512 #define DEFAULT_MIN_FILE_SIZE 14 /* More than GIF stamp + screen desc. */ #define DEFAULT_OUT_NAME "GifInto.Gif" #define DEFAULT_TMP_NAME "TempInto.XXXXXX" static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- s%-MinFileSize!d h%- GifFile!*s"; static int MinFileSize = DEFAULT_MIN_FILE_SIZE; #ifndef _WIN32 #define IS_PATH_SEP(c) ((c) == '/') #else #define IS_PATH_SEP(c) ((c) == '/' || (c) == '\\') #endif static bool IsUnsafePath(const char *path) { const unsigned char *p = (const unsigned char *)path; if (path == NULL || *path == '\0') { return true; } /* Absolute paths or drive-qualified paths are not allowed. */ if (IS_PATH_SEP(p[0])) { return true; } if (isalpha(p[0]) && p[1] == ':') { return true; } /* Reject any ".." path segment. */ for (p = (const unsigned char *)path; *p != '\0'; p++) { if (p[0] == '.' && p[1] == '.' && (p == (const unsigned char *)path || IS_PATH_SEP(p[-1])) && (p[2] == '\0' || IS_PATH_SEP(p[2]))) { return true; } } return false; } #ifdef _WIN32 #include <errno.h> #include <sys/stat.h> int mkstemp(char *tpl) { int fd = -1; char *p; int e = errno; errno = 0; p = _mktemp(tpl); if (*p && errno == 0) { errno = e; fd = _open(p, _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY, _S_IREAD | _S_IWRITE); } return fd; } #endif /****************************************************************************** This is simply: read until EOF, then close the output, test its length, and if non zero then rename it. ******************************************************************************/ int main(int argc, char **argv) { int FD; int NumFiles; bool Error, MinSizeFlag = false, HelpFlag = false, GifNoisyPrint = false; char **FileName = NULL, FoutTmpName[STRLEN + 1], FullPath[STRLEN + 1], *p; FILE *Fin, *Fout; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &MinSizeFlag, &MinFileSize, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles != 1) { GIF_MESSAGE("Error in command line parsing - one GIF " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } /* Open the stdin in binary mode and increase its buffer size: */ #ifdef _WIN32 _setmode(0, O_BINARY); /* Make sure it is in binary mode. */ #endif Fin = fdopen(0, "rb"); /* Make it into a stream: */ if (Fin == NULL) { GIF_EXIT("Failed to open input."); } /* Isolate the directory where our destination is, and set tmp file name */ /* in the very same directory. This code is isecure because it creates */ /* predictable names, but it's not worth the effort and risk to fix. */ if (*FileName == NULL) { GIF_EXIT("No valid Filename given."); } if (IsUnsafePath(*FileName)) { GIF_EXIT("Unsafe filename (absolute path or traversal)."); } if (strlen(*FileName) > STRLEN - 1) { GIF_EXIT("Filename too long."); } memset(FullPath, '\0', sizeof(FullPath)); strncpy(FullPath, *FileName, STRLEN); if ((p = strrchr(FullPath, '/')) != NULL || (p = strrchr(FullPath, '\\')) != NULL) { p[1] = 0; } else if ((p = strrchr(FullPath, ':')) != NULL) { p[1] = 0; } else { FullPath[0] = 0; /* No directory or disk specified. */ } if (strlen(FullPath) > STRLEN - 1) { GIF_EXIT("Filename too long."); } strncpy(FoutTmpName, FullPath, STRLEN); /* First setup the Path */ /* then add a name for the tempfile */ if ((strlen(FoutTmpName) + strlen(DEFAULT_TMP_NAME)) > STRLEN - 1) { GIF_EXIT("Filename too long."); } strcat(FoutTmpName, DEFAULT_TMP_NAME); #ifdef _WIN32 char *tmpFN = _mktemp(FoutTmpName); if (tmpFN) { FD = open(tmpFN, O_CREAT | O_EXCL | O_WRONLY); } else { FD = -1; } #else FD = mkstemp(FoutTmpName); /* returns filedescriptor */ #endif if (FD == -1) { GIF_EXIT("Failed to open output."); } Fout = fdopen(FD, "wb"); /* returns a stream with FD */ if (Fout == NULL) { GIF_EXIT("Failed to open output."); } while (1) { int c = getc(Fin); if (feof(Fin)) { break; } if (putc(c, Fout) == EOF) { GIF_EXIT("Failed to write output."); } } fclose(Fin); if (ftell(Fout) >= (long)MinFileSize) { fclose(Fout); unlink(*FileName); if (rename(FoutTmpName, *FileName) != 0) { char DefaultName[STRLEN + 1]; memset(DefaultName, '\0', sizeof(DefaultName)); if ((strlen(FullPath) + strlen(DEFAULT_OUT_NAME)) > STRLEN - 1) { GIF_EXIT("Filename too long."); } strncpy(DefaultName, FullPath, STRLEN); strcat(DefaultName, DEFAULT_OUT_NAME); if (rename(FoutTmpName, DefaultName) == 0) { char s[STRLEN]; snprintf( s, STRLEN, "Failed to rename out file - left as %s.", DefaultName); GIF_MESSAGE(s); } else { unlink(FoutTmpName); GIF_MESSAGE( "Failed to rename out file - deleted."); } } } else { fclose(Fout); unlink(FoutTmpName); GIF_MESSAGE("File too small - not renamed."); } return 0; } /* end */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/gif2rgb.c������������������������������������������������������������������������������0000664�0001750�0001750�00000042277�15166751647�012647� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** gif2rgb - convert GIF to 24-bit RGB pixel triples or vice-versa *****************************************************************************/ /*************************************************************************** Toshio Kuratomi had written this in a comment about the rgb2gif code: 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. I (ESR) took this off the main to-do list in 2012 because I don't think the GIFLIB project actually needs to be in the converters-and-tools business. Plenty of hackers do that; our job is to supply stable library capability with our utilities mainly interesting as test tools. ***************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include <ctype.h> #include <fcntl.h> #include <limits.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _WIN32 #include <io.h> #endif /* _WIN32 */ #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gif2rgb" static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- c%-#Colors!d s%-Width|Height!d!d 1%- o%-OutFileName!s h%- GifFile!*s"; static void LoadRGB(char *FileName, int OneFileFlag, GifByteType **RedBuffer, GifByteType **GreenBuffer, GifByteType **BlueBuffer, int Width, int Height); static void SaveGif(GifByteType *OutputBuffer, int Width, int Height, int ExpColorMapSize, ColorMapObject *OutputColorMap); /****************************************************************************** Load RGB file into internal frame buffer. ******************************************************************************/ static void LoadRGB(char *FileName, int OneFileFlag, GifByteType **RedBuffer, GifByteType **GreenBuffer, GifByteType **BlueBuffer, int Width, int Height) { int i; unsigned long Size; GifByteType *RedP, *GreenP, *BlueP; FILE *rgbfp[3]; Size = ((long)Width) * Height * sizeof(GifByteType); if ((*RedBuffer = (GifByteType *)malloc((unsigned int)Size)) == NULL || (*GreenBuffer = (GifByteType *)malloc((unsigned int)Size)) == NULL || (*BlueBuffer = (GifByteType *)malloc((unsigned int)Size)) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } RedP = *RedBuffer; GreenP = *GreenBuffer; BlueP = *BlueBuffer; if (FileName != NULL) { if (OneFileFlag) { if ((rgbfp[0] = fopen(FileName, "rb")) == NULL) { GIF_EXIT("Can't open input file name."); } } else { static const char *Postfixes[] = {".R", ".G", ".B"}; char OneFileName[80]; for (i = 0; i < 3; i++) { strncpy(OneFileName, FileName, sizeof(OneFileName) - 1); strncat(OneFileName, Postfixes[i], sizeof(OneFileName) - 1 - strlen(OneFileName)); if ((rgbfp[i] = fopen(OneFileName, "rb")) == NULL) { GIF_EXIT("Can't open input file name."); } } } } else { OneFileFlag = true; #ifdef _WIN32 _setmode(0, O_BINARY); #endif /* _WIN32 */ rgbfp[0] = stdin; } GifQprintf("\n%s: RGB image: ", PROGRAM_NAME); if (OneFileFlag) { GifByteType *Buffer, *BufferP; if ((Buffer = (GifByteType *)malloc(Width * 3)) == NULL) { GIF_EXIT( "Failed to allocate memory required, aborted."); } for (i = 0; i < Height; i++) { int j; GifQprintf("\b\b\b\b%-4d", i); if (fread(Buffer, Width * 3, 1, rgbfp[0]) != 1) { GIF_EXIT( "Input file(s) terminated prematurly."); } for (j = 0, BufferP = Buffer; j < Width; j++) { *RedP++ = *BufferP++; *GreenP++ = *BufferP++; *BlueP++ = *BufferP++; } } free((char *)Buffer); fclose(rgbfp[0]); } else { for (i = 0; i < Height; i++) { GifQprintf("\b\b\b\b%-4d", i); if (fread(RedP, Width, 1, rgbfp[0]) != 1 || fread(GreenP, Width, 1, rgbfp[1]) != 1 || fread(BlueP, Width, 1, rgbfp[2]) != 1) { GIF_EXIT( "Input file(s) terminated prematurly."); } RedP += Width; GreenP += Width; BlueP += Width; } fclose(rgbfp[0]); fclose(rgbfp[1]); fclose(rgbfp[2]); } } /****************************************************************************** Save the GIF resulting image. ******************************************************************************/ static void SaveGif(GifByteType *OutputBuffer, int Width, int Height, int ExpColorMapSize, ColorMapObject *OutputColorMap) { int i, Error; GifFileType *GifFile; GifByteType *Ptr = OutputBuffer; /* Open stdout for the output file: */ if ((GifFile = EGifOpenFileHandle(1, &Error)) == NULL) { PrintGifError(Error); exit(EXIT_FAILURE); } if (EGifPutScreenDesc(GifFile, Width, Height, ExpColorMapSize, 0, OutputColorMap) == GIF_ERROR || EGifPutImageDesc(GifFile, 0, 0, Width, Height, false, NULL) == GIF_ERROR) { PrintGifError(Error); exit(EXIT_FAILURE); } GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top, GifFile->Image.Width, GifFile->Image.Height); for (i = 0; i < Height; i++) { if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR) { exit(EXIT_FAILURE); } GifQprintf("\b\b\b\b%-4d", Height - i - 1); Ptr += Width; } if (EGifCloseFile(GifFile, &Error) == GIF_ERROR) { PrintGifError(Error); exit(EXIT_FAILURE); } } /****************************************************************************** Close output file (if open), and exit. ******************************************************************************/ static void RGB2GIF(bool OneFileFlag, int NumFiles, char *FileName, int ExpNumOfColors, int Width, int Height) { int ColorMapSize; GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL, *OutputBuffer = NULL; ColorMapObject *OutputColorMap = NULL; ColorMapSize = 1 << ExpNumOfColors; if (NumFiles == 1) { LoadRGB(FileName, OneFileFlag, &RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height); } else { LoadRGB(NULL, OneFileFlag, &RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height); } if ((OutputColorMap = GifMakeMapObject(ColorMapSize, NULL)) == NULL || (OutputBuffer = (GifByteType *)malloc( Width * Height * sizeof(GifByteType))) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } if (GifQuantizeBuffer(Width, Height, &ColorMapSize, RedBuffer, GreenBuffer, BlueBuffer, OutputBuffer, OutputColorMap->Colors) == GIF_ERROR) { free((char *)RedBuffer); free((char *)GreenBuffer); free((char *)BlueBuffer); free((char *)OutputBuffer); GifFreeMapObject(OutputColorMap); exit(EXIT_FAILURE); } free((char *)RedBuffer); free((char *)GreenBuffer); free((char *)BlueBuffer); SaveGif(OutputBuffer, Width, Height, ExpNumOfColors, OutputColorMap); free((char *)OutputBuffer); GifFreeMapObject(OutputColorMap); } /****************************************************************************** The real screen dumping routine. ******************************************************************************/ static void DumpScreen2RGB(char *FileName, int OneFileFlag, ColorMapObject *ColorMap, const GifRowType *ScreenBuffer, int ScreenWidth, int ScreenHeight) { int i, j; GifRowType GifRow; GifColorType *ColorMapEntry; FILE *rgbfp[3]; if (FileName != NULL) { if (OneFileFlag) { if ((rgbfp[0] = fopen(FileName, "wb")) == NULL) { GIF_EXIT("Can't open input file name."); } } else { static char *Postfixes[] = {".R", ".G", ".B"}; char OneFileName[80]; for (i = 0; i < 3; i++) { snprintf(OneFileName, sizeof(OneFileName), "%s%s", FileName, Postfixes[i]); if ((rgbfp[i] = fopen(OneFileName, "wb")) == NULL) { GIF_EXIT("Can't open input file name."); } } } } else { OneFileFlag = true; #ifdef _WIN32 _setmode(1, O_BINARY); #endif /* _WIN32 */ rgbfp[0] = stdout; } if (ColorMap == NULL) { fprintf(stderr, "Color map pointer is NULL.\n"); exit(EXIT_FAILURE); } if (OneFileFlag) { unsigned char *Buffer, *BufferP; if ((Buffer = (unsigned char *)malloc(ScreenWidth * 3)) == NULL) { GIF_EXIT( "Failed to allocate memory required, aborted."); } for (i = 0; i < ScreenHeight; i++) { GifRow = ScreenBuffer[i]; GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); for (j = 0, BufferP = Buffer; j < ScreenWidth; j++) { /* Check if color is within color palete */ if (GifRow[j] >= ColorMap->ColorCount) { GIF_EXIT(GifErrorString( D_GIF_ERR_IMAGE_DEFECT)); } ColorMapEntry = &ColorMap->Colors[GifRow[j]]; *BufferP++ = ColorMapEntry->Red; *BufferP++ = ColorMapEntry->Green; *BufferP++ = ColorMapEntry->Blue; } if (fwrite(Buffer, ScreenWidth * 3, 1, rgbfp[0]) != 1) { GIF_EXIT("Write to file(s) failed."); } } free((char *)Buffer); fclose(rgbfp[0]); } else { unsigned char *Buffers[3]; if ((Buffers[0] = (unsigned char *)malloc(ScreenWidth)) == NULL || (Buffers[1] = (unsigned char *)malloc(ScreenWidth)) == NULL || (Buffers[2] = (unsigned char *)malloc(ScreenWidth)) == NULL) { GIF_EXIT( "Failed to allocate memory required, aborted."); } for (i = 0; i < ScreenHeight; i++) { GifRow = ScreenBuffer[i]; GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); for (j = 0; j < ScreenWidth; j++) { /* Check if color is within color palete */ if (GifRow[j] >= ColorMap->ColorCount) { GIF_EXIT(GifErrorString( D_GIF_ERR_IMAGE_DEFECT)); } ColorMapEntry = &ColorMap->Colors[GifRow[j]]; Buffers[0][j] = ColorMapEntry->Red; Buffers[1][j] = ColorMapEntry->Green; Buffers[2][j] = ColorMapEntry->Blue; } if (fwrite(Buffers[0], ScreenWidth, 1, rgbfp[0]) != 1 || fwrite(Buffers[1], ScreenWidth, 1, rgbfp[1]) != 1 || fwrite(Buffers[2], ScreenWidth, 1, rgbfp[2]) != 1) { GIF_EXIT("Write to file(s) failed."); } } free((char *)Buffers[0]); free((char *)Buffers[1]); free((char *)Buffers[2]); fclose(rgbfp[0]); fclose(rgbfp[1]); fclose(rgbfp[2]); } } static void GIF2RGB(int NumFiles, char *FileName, bool OneFileFlag, char *OutFileName) { int i, j, Size, Row, Col, Width, Height, ExtCode, Count; GifRecordType RecordType; GifByteType *Extension; GifRowType *ScreenBuffer; GifFileType *GifFile; static const int InterlacedOffset[] = { 0, 4, 2, 1}; /* The way Interlaced image should. */ static const int InterlacedJumps[] = { 8, 8, 4, 2}; /* be read - offsets and jumps... */ int ImageNum = 0; ColorMapObject *ColorMap; if (NumFiles == 1) { int Error; if ((GifFile = DGifOpenFileName(FileName, &Error)) == NULL) { PrintGifError(Error); exit(EXIT_FAILURE); } } else { int Error; /* Use stdin instead: */ if ((GifFile = DGifOpenFileHandle(0, &Error)) == NULL) { PrintGifError(Error); exit(EXIT_FAILURE); } } if (GifFile->SHeight == 0 || GifFile->SWidth == 0) { fprintf(stderr, "Image of width or height 0\n"); exit(EXIT_FAILURE); } /* * Allocate the screen as vector of column of rows. Note this * screen is device independent - it's the screen defined by the * GIF file parameters. */ if ((ScreenBuffer = (GifRowType *)malloc(GifFile->SHeight * sizeof(GifRowType))) == NULL) { GIF_EXIT("Failed to allocate memory required, aborted."); } Size = GifFile->SWidth * sizeof(GifPixelType); /* Size in bytes one row.*/ if ((ScreenBuffer[0] = (GifRowType)malloc(Size)) == NULL) { /* First row. */ GIF_EXIT("Failed to allocate memory required, aborted."); } for (i = 0; i < GifFile->SWidth; i++) { /* Set its color to BackGround. */ ScreenBuffer[0][i] = GifFile->SBackGroundColor; } for (i = 1; i < GifFile->SHeight; i++) { /* Allocate the other rows, and set their color to background * too: */ if ((ScreenBuffer[i] = (GifRowType)malloc(Size)) == NULL) { GIF_EXIT( "Failed to allocate memory required, aborted."); } memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); } /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } Row = GifFile->Image .Top; /* Image Position relative to Screen. */ Col = GifFile->Image.Left; Width = GifFile->Image.Width; Height = GifFile->Image.Height; GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth || GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) { fprintf(stderr, "Image %d is not confined to screen " "dimension, aborted.\n", ImageNum); exit(EXIT_FAILURE); } if (GifFile->Image.Interlace) { /* Need to perform 4 passes on the images: */ for (Count = i = 0; i < 4; i++) { for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) { GifQprintf("\b\b\b\b%-4d", Count++); if (DGifGetLine( GifFile, &ScreenBuffer[j][Col], Width) == GIF_ERROR) { PrintGifError( GifFile->Error); exit(EXIT_FAILURE); } } } } else { for (i = 0; i < Height; i++) { GifQprintf("\b\b\b\b%-4d", i); if (DGifGetLine( GifFile, &ScreenBuffer[Row++][Col], Width) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } while (Extension != NULL) { if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { PrintGifError(GifFile->Error); exit(EXIT_FAILURE); } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Lets dump it - set the global variables required and do it: */ ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap); if (ColorMap == NULL) { fprintf(stderr, "Gif Image does not have a colormap\n"); exit(EXIT_FAILURE); } /* check that the background color isn't garbage (SF bug #87) */ if (GifFile->SBackGroundColor < 0 || GifFile->SBackGroundColor >= ColorMap->ColorCount) { fprintf(stderr, "Background color out of range for colormap\n"); exit(EXIT_FAILURE); } DumpScreen2RGB(OutFileName, OneFileFlag, ColorMap, ScreenBuffer, GifFile->SWidth, GifFile->SHeight); for (i = 0; i < GifFile->SHeight; i++) { (void)free(ScreenBuffer[i]); } (void)free(ScreenBuffer); { int Error; if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) { PrintGifError(Error); exit(EXIT_FAILURE); } } } /****************************************************************************** * Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { bool Error, OutFileFlag = false, ColorFlag = false, SizeFlag = false, GifNoisyPrint = false; int NumFiles, Width = 0, Height = 0, ExpNumOfColors = 8; char *OutFileName, **FileName = NULL; static bool OneFileFlag = false, HelpFlag = false; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &ColorFlag, &ExpNumOfColors, &SizeFlag, &Width, &Height, &OneFileFlag, &OutFileFlag, &OutFileName, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles > 1) { GIF_MESSAGE("Error in command line parsing - one input " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (!OutFileFlag) { OutFileName = NULL; } if (SizeFlag) { if ((Width <= 0 || Height <= 0) || (Height > INT_MAX / Width)) { GIF_MESSAGE( "Image size would be overflow, zero or negative"); exit(EXIT_FAILURE); } RGB2GIF(OneFileFlag, NumFiles, *FileName, ExpNumOfColors, Width, Height); } else { GIF2RGB(NumFiles, *FileName, OneFileFlag, OutFileName); } return 0; } /* end */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/history.adoc���������������������������������������������������������������������������0000664�0001750�0001750�00000007131�15166751647�013500� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������= History of GIFLIB = GIF (Graphics Interchange Format) was originally developed on the CompuServe timesharing service in the late 1980s. It was described by a GIF standard issued in 1987 and revised in 1989. A copy of the GIF89 standard is included in the doc/ directory. This code originated as a linkable library for DOS programs, together with command-line tools for generating and viewing and analyzing GIF images. The DOS code was written by Gershon Elber using Borland C under MS-DOS sometime between the issue of GIF87 and mid-1989 (1.0 was dated 14 June 1989; one portion, getarg.c, was dated 11 Mar 88). At some time no later than the end of 1989 Eric S. Raymond (aka "ESR") ported this DOS version to System V Unix. Between 1989 and 1992 ESR reworked various portions of the API, improving and simplifying the code's interface. ESR's 2.1 version was the first to include the DGifSlurp()/EGifSpew() function pair for enabling non-sequential operations on GIF images (also the tools icon2gif, gifovly, and gifcompose; the last was removed in 5.0). ESR's Unix port was incorporated into the NCSA Mosaic browser in 1994, which is how GIF became (with JPEG) one of the two most popular image formats on the early Web. Beginning around 1993, patent claims by Unisys over the LZW compression method used in GIF theatened adverse legal consequences for users and developers of programs incorporating the format. The threats became serious in 1999, with Unisys demanding license fees for any software using the format. One response to this was the development of PNG in 1995. Another was that ESR sought a lead developer outside the U.S. to hand the project off to, and passed it to Toshio Kuratomi. ESR remembers this as happening in 1994, but that date could be wrong as some headers imply 3.0 was issued under ESR's name in 1996. But other files do date Toshio's first release to 1994. Toshio shipped 4.0 in December 1998. Subsequently, the project shipped for some time as "libungif" with support for compressed GIFs removed to avoid the LZW patent issues. Compression support was merged back in after the last blocking patent expired in 2004; this became release 4.0.0. After that merge the code was again known as giflib. By 2006, support for PNGs was sufficiently universal that GIF could be described as a legacy format. Anything you can do with it GIF could probably be better done with PNG. Nevertheless (and despite efforts like "Burn All GIFs Day" in November 1999) the GIF format has remained widely popular. In April 2012 ESR rejoined the project to do some code cleanups and auditing, and Toshio Kuratomi asked him to take back the lead. ESR released version 4.2 in May 2012. Version 5.0, released in June 2012, fulfilled almost all the to-do items from 18 years of backlog. It made the library thread-safe, added direct support for GIF89 graphics control blocks, and tossed out large amounts of obsolete utility code. More recent version of the code (5.1.0 and onwards) have been hardened by both static analysis and fuzz testing. While these failed to turn up bugs in normal rendering cases, they did uncover some crash and corruption bugs that could be tickled by carefully crafted malformed GIFs. This code is very old, very stable, and *everywhere* - browsers game consoles, smartphones, pretty much everything that opens an HTTP port and does graphics uses it. The utilities in this source tree were important as GIF production tools early in the format's history, but have been superseded by multi-format viewers and editors. Most installable binary packages shipped as 'giflib' include the library and header file only. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/local.dic������������������������������������������������������������������������������0000664�0001750�0001750�00000004775�15166751647�012735� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AddExtensionBlock ApplyTranslation BNF BitSize ByteType ColorCount ColorIn ColorIndex ColorMap ColorMapObject ColorTransIn ColorUnion CtrlStr DGIF DGif DGifClose DGifCloseFile DGifGetCode DGifGetCodeNext DGifGetExtension DGifGetExtensionNext DGifGetGifVersion DGifGetImageDesc DGifGetLZCodes DGifGetLine DGifGetPixel DGifGetRecordType DGifGetScreenDesc DGifOpen DGifOpenFileHandle DGifOpenFileName DGifSavedExtensionToGCB DGifSlurp DSCR EGIF EGif EGifClose EGifCloseFile EGifGCBToSavedExtension EGifGetGifVersion EGifOpen EGifOpenFileHandle EGifOpenFileName EGifPutCode EGifPutCodeNext EGifPutComment EGifPutExtension EGifPutExtensionBlock EGifPutExtensionFirst EGifPutExtensionLast EGifPutExtensionLeader EGifPutExtensionNext EGifPutExtensionTrailer EGifPutLine EGifPutPixel EGifPutScreenDesc EGifSetGifVersion EGifSlurp EGifSpew EOF ESC Elber ErrorCode ExtensionBlock ExtensionRecordType FG FileHandle FreeExtension FreeMapObject FreeSavedImages GAGetArgs GAPrintErrMsg GAPrintHowTo GCB GFLIB GIF's GIFLIB GIFLIB's GIFS GIFs Gershon Gif GifAddExtensionBlock GifApplyTranslation GifAsciiTable GifAttachImage GifBitSize GifCode GifCodeBlock GifCodeSize GifColorType GifComment GifDrawBox GifDrawBoxedText GifDrawRectangle GifDrawText GifError GifErrorString GifExtCode GifExtLen GifExtension GifFile GifFileHandle GifFileName GifFileType GifFreeExtensions GifFreeMapObject GifFreeSavedImages GifLastError GifLine GifLineLen GifMakeMapObject GifMakeSavedImage GifPixel GifPixelType GifPos GifRecordType GifTestExistance GifText GifType GifUnionColorMap GraphicsControlBlock IMAG ImageDescRecordType ImageMagick InputFunc Kuratomi LSDB LZ Lempel-Ziv MakeMapObject MakeSavedImage MinFileSize OutFileName OutputFunc PixelType PrintGifError RGB RGB-to-GIF RGBRGB RLE SCRN SavedImage SavedImages ScreenDescRecordType SizeX SizeY Suárez Toshio TrailerRecordType UndefinedRecordType UnionColorMap VoidPtr YCM argc argv ascii attemp backround bg bgcolor bicolored bool bytewise colormap colormap-file colormap-size colormaps const deallocate deallocating deconverter delaytime dgif egif errorname fg getarg gif gif-file gifalloc gifbg gifbuild gifclip gifclrmap gifclrmp gifcolor gifecho giffilter giffix gifhisto gifinto giflib gifpos gifsponge giftext giftool gifwedge hardcoded html imagelist libgif little-endian maintainership mapfile minsize misdesigned netscape outfile plaintext pointer-to-GifFileType printf-style readFunc reentrant rgb signedness sizex sizey sm stderr stdin stdout subblock subblocks toolkits transcolor undump userPtr util writeFunc xNN ���giflib-6.1.3/Makefile�������������������������������������������������������������������������������0000664�0001750�0001750�00000015336�15166751647�012615� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Top-level Unix makefile for the GIFLIB package # Should work for all Unix versions # # If your platform has the OpenBSD reallocarray(3) call, you may # add -DHAVE_REALLOCARRAY to CFLAGS to use that, saving a bit # of code space in the shared library. # # SPDX-FileCopyrightText: Copyright (C) Eric S. Raymond <esr@thyrsus.com> # SPDX-License-Identifier: MIT PREFIX ?= /usr/local BINDIR = $(PREFIX)/bin INCDIR = $(PREFIX)/include LIBDIR = $(PREFIX)/lib MANDIR = $(PREFIX)/share/man DOCDIR = $(PREFIX)/share/doc/giflib CC ?= gcc OFLAGS = -g -fno-inline #-fsanitize=address OFLAGS = -O2 CFLAGS += -std=gnu99 -fPIC -Wall $(OFLAGS) #LDFLAGS += -fsanitize=address SHELL = /bin/sh TAR = tar INSTALL = install # No user-serviceable parts below this line VERSION:=$(shell ./getversion) LIBMAJOR=7 LIBMINOR=2 LIBPOINT=0 LIBVER=$(LIBMAJOR).$(LIBMINOR).$(LIBPOINT) SOURCES = dgif_lib.c egif_lib.c gifalloc.c gif_err.c gif_font.c \ gif_hash.c openbsd-reallocarray.c quantize.c HEADERS = gif_hash.h gif_lib.h gif_lib_private.h OBJECTS = $(SOURCES:.c=.o) USOURCES = qprintf.c getarg.c UHEADERS = getarg.h UOBJECTS = $(USOURCES:.c=.o) UNAME:=$(shell uname) # Rules .PHONY: all distcheck check reflow cppcheck spellcheck .PHONY: install install-bin install-include ibnstall-lib install-man install-doc .PHONY: uninstall uninstall-bin uninstall-include uninstall-lib uninstall-man uninstall-doc .PHONY: version dist release refresh # Build # Some utilities are installed INSTALLABLE = \ gifbuild \ giffix \ giftext \ giftool \ gifclrmp # Some utilities are only used internally for testing. # There is a parallel list in doc/Makefile. # These are all candidates for removal in future releases. UTILS = $(INSTALLABLE) \ gifbg \ gifcolor \ gifecho \ giffilter \ gifhisto \ gifinto \ gifsponge \ gifwedge \ gif2rgb LDLIBS=libgif.a -lm MANUAL_PAGES_1 = \ doc/gifbuild.xml \ doc/gifclrmp.xml \ doc/giffix.xml \ doc/giftext.xml \ doc/giftool.xml MANUAL_PAGES_7 = \ doc/giflib.xml MANUAL_PAGES = $(MANUAL_PAGES_1) $(MANUAL_PAGES_7) MANUAL_PAGES_1_MAN = $(MANUAL_PAGES_1:%.xml=%.1) MANUAL_PAGES_7_MAN = $(MANUAL_PAGES_7:%.xml=%.7) SOEXTENSION = so LIBGIFSO = libgif.$(SOEXTENSION) LIBGIFSOMAJOR = libgif.$(SOEXTENSION).$(LIBMAJOR) LIBGIFSOVER = libgif.$(SOEXTENSION).$(LIBVER) LIBUTILSO = libutil.$(SOEXTENSION) LIBUTILSOMAJOR = libutil.$(SOEXTENSION).$(LIBMAJOR) ifeq ($(UNAME), Darwin) SOEXTENSION = dylib LIBGIFSO = libgif.$(SOEXTENSION) LIBGIFSOMAJOR = libgif.$(LIBMAJOR).$(SOEXTENSION) LIBGIFSOVER = libgif.$(LIBVER).$(SOEXTENSION) LIBUTILSO = libutil.$(SOEXTENSION) LIBUTILSOMAJOR = libutil.$(LIBMAJOR).$(SOEXTENSION) endif SHARED_LIBS = $(LIBGIFSO) $(LIBUTILSO) STATIC_LIBS = libgif.a libutil.a all: shared-lib static-lib $(UTILS) ifeq ($(UNAME), Darwin) else $(MAKE) -C doc endif $(UTILS):: $(STATIC_LIBS) shared-lib: $(SHARED_LIBS) static-lib: $(STATIC_LIBS) $(LIBGIFSO): $(OBJECTS) $(HEADERS) ifeq ($(UNAME), Darwin) $(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(OBJECTS) -o $(LIBGIFSO) else $(CC) $(CFLAGS) $(CPPFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBGIFSOMAJOR) -o $(LIBGIFSO) $(OBJECTS) endif libgif.a: $(OBJECTS) $(HEADERS) $(AR) rcs libgif.a $(OBJECTS) $(LIBUTILSO): $(UOBJECTS) $(UHEADERS) ifeq ($(UNAME), Darwin) $(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(UOBJECTS) -o $(LIBUTILSO) else $(CC) $(CFLAGS) $(CPPLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBUTILSOMAJOR) -o $(LIBUTILSO) $(UOBJECTS) endif libutil.a: $(UOBJECTS) $(UHEADERS) $(AR) rcs libutil.a $(UOBJECTS) clean: rm -f $(UTILS) $(OBSOLETE_UTILS) $(TARGET) libgetarg.a $(SHARED_LIBS) $(STATIC_LIBS) *.o rm -f $(LIBGIFSOVER) rm -f $(LIBGIFSOMAJOR) $(MAKE) --quiet -C doc clean # Validate check: all $(MAKE) -C tests reflow: @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") obsolete-utils: $(OBSOLETE_UTILS) # cppcheck should run clean cppcheck: @cppcheck --quiet --inline-suppr --template gcc --enable=all --suppress=unusedFunction --suppress=missingInclude --force *.[ch] spellcheck: @spellcheck local.dic doc/*.xml # Install/uninstall ifeq ($(UNAME), Darwin) install: all install-bin install-include install-lib else install: all install-bin install-include install-lib install-man install-doc endif install-bin: $(INSTALLABLE) $(INSTALL) -d "$(DESTDIR)$(BINDIR)" $(INSTALL) $^ "$(DESTDIR)$(BINDIR)" install-include: $(INSTALL) -d "$(DESTDIR)$(INCDIR)" $(INSTALL) -m 644 gif_lib.h "$(DESTDIR)$(INCDIR)" install-static-lib: $(INSTALL) -d "$(DESTDIR)$(LIBDIR)" $(INSTALL) -m 644 libgif.a "$(DESTDIR)$(LIBDIR)/libgif.a" install-shared-lib: $(INSTALL) -d "$(DESTDIR)$(LIBDIR)" $(INSTALL) -m 755 $(LIBGIFSO) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOVER)" ln -sf $(LIBGIFSOVER) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOMAJOR)" ln -sf $(LIBGIFSOMAJOR) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSO)" install-lib: install-static-lib install-shared-lib install-man: $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" "$(DESTDIR)$(MANDIR)/man7" $(INSTALL) -m 644 $(MANUAL_PAGES_1_MAN) "$(DESTDIR)$(MANDIR)/man1" $(INSTALL) -m 644 $(MANUAL_PAGES_7_MAN) "$(DESTDIR)$(MANDIR)/man7" install-doc: $(MAKE) -C doc allhtml $(INSTALL) -d "$(DESTDIR)$(DOCDIR)/html" cd doc && $(INSTALL) -m 644 $$(echo *.html) "$(DESTDIR)$(DOCDIR)/html" @if [ -f doc/giflib-logo.gif ]; then \ $(INSTALL) -m 644 doc/giflib-logo.gif "$(DESTDIR)$(DOCDIR)/html"; \ fi uninstall: uninstall-man uninstall-include uninstall-lib uninstall-bin uninstall-bin: cd "$(DESTDIR)$(BINDIR)" && rm -f $(INSTALLABLE) uninstall-include: rm -f "$(DESTDIR)$(INCDIR)/gif_lib.h" uninstall-lib: cd "$(DESTDIR)$(LIBDIR)" && \ rm -f libgif.a $(LIBGIFSO) $(LIBGIFSOMAJOR) $(LIBGIFSOVER) uninstall-man: cd "$(DESTDIR)$(MANDIR)/man1" && rm -f $(shell cd doc >/dev/null && echo *.1) cd "$(DESTDIR)$(MANDIR)/man7" && rm -f $(shell cd doc >/dev/null && echo *.7) uninstall-doc: rm -rf "$(DESTDIR)$(DOCDIR)/html" # Export # # We include all of the XML, and also generated manual pages # so people working from the distribution tarball won't need xmlto. # Check that getversion hasn't gone pear-shaped. version: @echo $(VERSION) EXTRAS = NEWS \ TODO \ COPYING \ getversion \ ChangeLog \ control \ local.dic ALL = Makefile *.[ch] *.adoc doc tests pic $(EXTRAS) giflib-$(VERSION).tar.gz: $(ALL) mkdir giflib-$(VERSION) cp -r $(ALL) giflib-$(VERSION) tar -czf giflib-$(VERSION).tar.gz giflib-$(VERSION) rm -fr giflib-$(VERSION) ls -l giflib-$(VERSION).tar.gz dist: giflib-$(VERSION).tar.gz # release using the shipper tool release: all giflib-$(VERSION).tar.gz $(MAKE) -C doc website shipper --no-stale version=$(VERSION) | sh -e -x rm -fr doc/staging # Refresh the website refresh: all $(MAKE) -C doc website shipper --no-stale -w version=$(VERSION) | sh -e -x rm -fr doc/staging # end ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/�����������������������������������������������������������������������������������0000775�0001750�0001750�00000000000�15166751647�011720� 5����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/solid2.gif�������������������������������������������������������������������������0000664�0001750�0001750�00000044247�15166751647�013616� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a���������������������������������������������������������������������������~~�||�{{�yy�ww�uu�ss�rr�pp�nn�ll�jj�ii�gg�ee�cc�aa�__�^^�\\�ZZ�XX�VV�UU�SS�QQ�OO�MM�LL�JJ�HH�FF�DD�CC�AA�??�==�;;�::�88�66�44�22�00�//�--�++�))�''�&&�$$�""� ����,������ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJի'הٺ˒Kp݊h lp=`KݻxI}(\*i+[eIJLeb]U՚v ъSbװckOr|L>̐?xFU֏#^μڜX³(i;WTc,ɝ_Ϟ"^P+Z"v /eEb$ň"]߁pUQPk-C}E(ᄖyW ̍PDwpGXQB $X=l:R<`�:<Qk!IjPA (p &p"*(€a8yhhRH$ACTp[hl`CB - *BTZyb$.z \ C!J >榜v :<7P 3 [0ŸZRVy%]Dqd#&첕J@é1:+Z(U*k\v pxijF+ó0-*ڭ +i`KkɒҚʯj+'*n,.I|C8A q0$j(?rZlXX3S k,,1KQxs;ێي"ҿ2vԐEr׳Fm͵^ p,]2H(殜�nnzloߝ^J80䱟C1G/lu0Ÿ~v72�w<V*ރg3\Pgխ <Dz'shao ߬'>)KC]: Ԇ` u ? n/[\�x0* }$<Be DȐ4=P �Dp}Ct50|b {?nЊҖ..qLj 9<&)fЍU v0Fomwd_ PaA7̤ g86Tl78p/i<W,4I&ʐOؽ7֪B[¸()/D4",e@i|.ݤK.2Ё&@X &0y<&sM IhN60&$ Pu0XA:J}}g+Xϊ2@$5}%$! H8Ā) T2hA hLJM,S@bT+D I0B'}Tԥ9xЃ41K8DJtxdONJƟc8pQ 0OTy ;xA vҫ_DIЬԥ^pO}\z#|4Ӫ_OXN a3&RG@BşUS`Y&@A&UM>vrPh{F6vF5mlK*@K MN oqkZ {s{ [R ]vJ`e@+и5mT9Ԗt l&D Y0;@nu{_~ YL4\*"0pաA6\h$*/~pd#- grvT,\L# a N3 ´.̸h<-KT_2l29k 1pS<aϘ>50A04լEwt$ 4O7Xkrӛ#Kx( rwPuhcp֙5w ,E){>< # %`QUk2DY`;]$pxC>7X|W4cjߴw^V"h.U'pMz7-^O͵=pf Nf$hA̗>s\Zsr$VWKuANW5=>Rm^>0t11$< qvltR֋0xf"f+hJuk艩Nk[37~M]l')*G @&}O>_,<Aҡ{Χd_|&;o-@f>v>\T `w$B/zЂ~o'2?7r 07@RzwFWmQ1HWMS;Ag?$DpD@Ł~C jZOA|(Bbǂ@XOVvCq~v>BM!V=B'wAK0tKQFT6XĄևn5pfKQP/qZ8BKUZ2/H;C(,lfLp8A/Gf|Js`HbD�G0FPoXkt|xr|W|x!s-1KIHxȇ/ɧH *A* 7�tҁx`x7AJp00PV7FwxC8؈@O}LNS'YyH7G=@wTؐyCmf9$+XFi9G$wȒgx#2IX;!9wE165x7=i}BC!0%S=e4.VystLG<g N  ,�q^|eU0m6A'0CrI�)1 TBeb&-՗YP/X;+m?)37:`*yiPٗDLdA $9PU</y*Y{y~RZHqhiiFp3TĜ)E[ؙ;P4!9(Ae蹜霔ٞ iɂHIKA.\44*ʩ: h璵4e @wE}":zщ%ZWФ@oiG`EP4驣٣$'*!tIo5ɑ' դN6: ;*`\Zy)o?? RkZ7Jڜq #twt9Vyhx(L H@PjnzWj*qiXЖ ԩMRڡoj<zOA~A~L Ṉ*Mꩠʦsj*:\2٬.A Q�OԺ:Ur܊@`FsŢ?L5aQ@ʮ*J멭Z9 2/J/pU@S튫 ZJB:~ 9p;HY + [ګ(*˨*.:@296QUHVKmڰ)D :B %[@;{蝹^,{f*kLK%x)k%]ж:k#A Za{ة,4=X\불۳Ys۵j>y*ky;؁zaๆ[< {F\(m}Q�2acp{ʵB[XꨪۖiyKxP!ы[ kCY:DyKX3Ufӫp۾r+{ۋd}ɋN =iқoL +;?RrW˸ #<OPQ?a8l  "?,Z=Z-P}Yf@MLO<۸:L$l?lЃ*"Y|pjpfhP9LnəW̒aʂɚi)}ۻ8 +yLbDЃF =gL'[J?y[Ѓ!�|yM˚L;ȷ ,,E<Ѓ ~,=<˜l,m,;|\\Q@;{ ȴ7\ `.YN�JyPϛ\t̐>gsU|G&}1|,UL� ju UX}\!}`%N\˞Sl .3]ӯNŇrgl +llFH9A܃6sNQ-Ub�^ZX=ZM]MoLE2IPsRz/~s]w\ҟ׷FIUTؑMMv[m~ț͙?L t=pxک-٬זMˣ<?)k�v=_WAڑW?۫׭=!\lFR9lvPɲÌԍw.prړטMk �yR� 콈^� -m@@`mނ ppȢN`iGw[ݔ_~XтY#_(8y_1⏝&N̜==Q3-(�OV=NܕD|IX9>uы R|>@> >6ntpz+orteE-=8ptXċHkvوX'>vי-a^ӌט'Kwq(^.y^I[U겖@%^n돎ެ 2A>wYP 4ihy\` ݺ8T}E Pg8 {.낚r}nwPِYieV|.K=ޏ  vt u?fWGM ~ א( Qah.O2nbnu�w,x1?4_=ߑ}QIW_ }+kIb}n꯷ېrrz y;kv/ac`.O VoP抱SZm.KOC. lߘ70_X?`Q}^dn qOSNZp۞|P;b�4BMx>S^ "lp�|qob1KSkhdb`^\ZXVTSRPONLKJIIHGFEDCBBA@@??>==<<;:98768ANeebHbÇ#JH�7lD #BL1cȔ1sM5kشqN9sv.;G>~1ӧPYXիXZGԯNI`ÊKٳhӪ]˶۷pʝK;=+R^|�˸cEZJ˔icC!|=dZlWu)7f]xo_#(<X|xL8j,̼砸Qc7HkiZn[ƅIw]zs35jV҆Z ?$ߍ}KxG(`݁BrAft6$U- m.ݩR[,\2US^8SA8qDIQ`<FRoDJp! cm(e.^W"lXskx9暇p )tfh$@$ 5KTGk'De g.QQ>禜bp):vꪠ)UL4cj|pðRƱFK곜rjFgp"긁]zksԷ fPk kUqf`o!1dH.&#:a4wwHeFlC� ̭`4ɱ 3l+KZJo(K�?rTlѣ<egV<ĭ]i5&1tHmv&J\*ܧRRms`t~Prr-x|pņh ^vr<qwޘ׫b]8F04ԏVR_Tkיbrl, %ۭzW>o:Cc[[x-׎7]0||qydq?rJ7֩S`gjQY&ȣs_A"a~pAHRI 20D�lk̡s %Dp@K qB CbD  uH ˝v0@0v#PϚHFp P\JUX !ЄELp 95h "+sܛE&=.x["IJ�@,Z�mFC <al IP X)1<@,@<;Pj|'"j~\Wَ DA37ɘ} 7J5ّ l!^7pSFp@ɉL z;8N(H pOmP?7 1 t<$`@A,,fC'і q�>rN@@kA`~tRgA,PTi UӛXE&rְ 9 th {rabU9Qf�ah)�eZ @! m )E}uw@&Kؕj#8IUJn KZFp X@,EKHC-^*Kˆ'X~ -p1+6,/pn,f`FM+i z?qdk.)@VV-'pw%MXAb}7੷0pot[μwd +Y V/,|^w;"*#N02@a Bg-\T pE b7VoJX.^4c fF 0D6[De M.n�(WxLBǛطFr}>c/2E+8bl A8`gziya43axvfaA=fj#h=A<a T`u[ұ栗s]H.Tphb{{o5lW3F( >>S;׻lBx~q{>y^vn~=hND`({ Ⱦ+wlu0nEZmM-`,oHox)M&4ʏIhC�/On�t[w}炻зi3>R#hDx.n\9q7(m \{MClfgJЛ8e- λ޽c:(@7ߑ8 jo:͡ qmv ,`<卌z BB4gmzXU;?[;pAl�-߽#!47ӇWerCeϿ#V&|wqVzn62g2L~%'}bՇ!@@wPL|G~(p&E̕2 p(]ئm+}*wx lsf*vr_bp5GrmqsXILn�X@(*w0DHFx炃mm3J: �t:h7weF`\s_X$w|c8eo-h[G@2.3J K@9(z㇇pxUM8*7XvH}@*Єm�E@ 8XXoxTetuRG`vvSцf* HXxvQƋyr(gx}¶F?(hLJgō߸XxW@;pGUq!xz?@E"uj#P)\P YsWXlpT ُHXy$@&yh/0F` ɐ IH2Y~"Z69;ɓ<ّ?9}ԅ`dhJ+);hn=8VwYȕzz^<u[bia5?PELٔ-ٖ}SxS9lGUwy{ٗ~SvP@9َ)i՘X[əfC�"i i3@DRwHzqH_$PE.ٜn 1iWxYQj LiDd{0%pI?ɜ),v8XȟX:>i�iNH"Pנ_S50C𹚋9Y<?!# Zb P?/ 4:7Zq)7ZgBjZE%(&,ʠP-p7 Uj+OYYɃwgneZgڏi8hv9 Тs&>2:{m )3yn5F?�& $#,©ABZ6ڧl9/lTIVF*uAP#" :yJj:jAjךԶZYfK6)p@ j*7)9lK8gEg`A2 {ښʬ:zأS{ w![rlڦ *˲O->0 ;Zʧ8[;;=?4p?w6G:_@r*a4pW ۰۵슥eg$MjKm  @yy5!x#;X2˵:[ѩ9p tI[ l+%[bUԹ3@= Y[6[ʺQy<vZp"GJUK'0ț|k{ JꥰԱ i^gJdv#0.0;;K۩45қ˳6r kR< b hh䈊 w{P-9<۷ΛK;͊_Z,Ož@3< \ ܭA7"$6El *#<~Zc{*\|FdZ ^\ \r Io9A++0;E;v W*ʺۥiŃ|AY|Țp|_<a,``@K@|7&* =q t\1x Odž;d;Ki35L9%|ιˎ`L> L/Wq,s̼|ʧ7K ˬGi`<ь qZt< `0dI(0`Iĥ<_a כs$|<H�m`)5.2�(@  `(�4f:ӠʢwLƪ`[9YIΗ@2M#KK򕢅�Sj"Wmf .e Hp]-Aqgj<{8{'B=~ W%JM؅˖ ? T"V~?!,y!p+5?mMӣĀsͣ\@B״|*`c۹]m7̻L40(LP)3@ߞ0ݣ Х]ͧt{ meb0�ޡۺ ]Ijߑ-/9''HA>,J4 >6iݟݤm}:~yz]@t&nW]i߂L�3#3NfO^:+p%GK+|z~SU>oY9KMHn~9p榞j.l%a 뼞a8�<G|Ě"}dj@~<@Gpn~N _-B N> Ŝʈ -� ھkfΜ="�Ne�ce1^~܏N.?~W>];M}Эzʽ@H~L?Pk�`1/>�,03Paq)zho.5֕N9<|sx˽xIKM/PI�#km@ Dh@>(!`_b?n/>TV劣ۜ@]ngJ��$p>A݌W?EpIp:ߕi@f)o/OqZ^}bzjti[x0_3<*<8789:;<>@CEGILC ;KC;::986¾<==>>?@@ABCCDDEFGGLBPA%0iĉ'O@E)SPbʕ+Xlɓ(S\ɲ˗0cʜI rܹϟ?*ԁѣH*Ei(zKC(I(96;vٳ:E%f+_׮Qw5ך/ܺ GN9t~s/<!? LÈ+^̸ǐwjʞM4(PD nT3~:7j1B(Ux@ ˽;pVq!{O? ӕh1<dTf<݃gEc@!AP!B 9DYFyh(⋼EoE܍G5Չ?sUQt[U vY@IwLޓiyW ]م0uIߗŷ%6 Ɵ5dLfe nƙ6hᆩyQ!Fj)ċ>h#8I E rSyUtZQg/,䩘@qlQY%e˘ti>c͙nVgfrvgvf!AZmf͡E 6(H�v Gd) tF^WEP꾕 ^S\ W ۰+b fkO.PDZqFܶ(١E#+no.�Dةs 3=aK<AE`tԖV*S Tai* _ù>LkĶjZ z rYrlE$,13p94F!6W tYM?Tnեy.=ٸ=&ډ)lD6e˽1 ɬw'|RVFԟ83SX8HW~yUm4NcYۼ[d-NmhX.V c O3X笑EkZ'c Pz6׻=GqQ\P(r6}_U}o?Пy6׽.v� (&Wc 9@v8 ҇�1 VȂ{2@t0 C+;R8\ .,_ 3OuG@0>'^ DVF%֧g{Ģ wp fySȷQ! h,QB5 =cyBZ1SD9Bz! "F@JVҒ) ~(4i "Eyx08F.lDlyK҄!Wx)h |d8d֐}, +p DPk&M0t9u;t~ [;#NT:Kj|Ԍm?ґA/t+&~ 6D+dTV˚Gai$-i!NRLNd'yǦŔMO /./~JuDB͎*ͱFyp(4a ?sЬ0G$WU>ic}KYmrsLjE[$B,x)Y١*ġȝxˎDmcԣ ``Y]Vgѕ&pU擪ڏfLklo0iՀpM[9[ҺȊW+ži{H0:f2eb2vԅ,R]r G"+Q"0O-m{Cz#mk/4RZzp]׉8ϔPvY@!Ga g�@a'xW#*VE^H| <h1(^lZ%ycEǺ8p<`7Bl&([e׻\"D=e 4aUC ^hrs? P' _πtm3Ih(@/fZJ$Obi"҆K[[[Ȧ�*-Ҳk47ժ>g(^"*Q8BEqN\@׻-k<F6C7DmλxOBMB}6~�p1OMtzJf{t~ݖ<|of0.ڤd!nٌ^x&8!FoOBO+NՒtcXR\xCЅ,XA OPg aмj+Xas Zףȿ}th*'U|mw SA=ៈ!j ѮvcZY"Q嫹;Y.,7= 31:܊L9)yӓ$ѸF L~ -9!e?{hz͡[ \hWy,۫5[y{_&SWpW P|}2}R`֗}}Z#l}dTEL >)j4=�3xF{g{6_'h*Ul_[vSPB}f0Tg3K(kP"PPTAbLI#ЂA5D2 H@87R7{=ƃ7W>S(J'L'\ Q{HS6ZyS eT8Vx}ᒅ:_Ѕ_HkP'h47P/v k:lwPTt$ŷE782Y׈aQ�*0UXX>lPuGPU%xL>.gx*^hco8LJGh\ k@\Ȍ88}]uriVbHh5L2Xw;8hII?xW8`WDhN 8-wy x#ajݸfY Ly /  %}wycCBvВIJT4*qqXmu9IP9P= T> ](GДi)&27HcsXuxǕfpbhV ȖiLj8ʸPp=Iz .n&y6�`gUo눃9;Xqe5| K7V�LjsPy3,Prf 0P9O0 tΩ_(҉pHw.n*Y)P@y!C`rp¹�pWYَD*t [~ג|ڄ(}j:Dz &:1 P+/wo0ȟ{}g}9ڃףGJ&AIɄo JJG�&$Pp4 Uy*]N)gQb X4zy Wl@Qp\vJx2 .0$ '10$`*:?c 2ڟf�ʜy'ɣzvڪz NJh{)P2)ɪJcjҺlx*:d> ')vm*ښ骮N0ﺁ@2RIq/کiWd�H|ZJS =6Yr:OdJڡڱ;P$@ %گ|1k35뇻Xr$ҳT6B`Dd QPU]"+ORV˯Jtɵ{ᵠ*icNcG�Kj۳hq uiNM `eeP$X;,hڵ CV̦ [9۹E#PKe ~; / 6d:JT;<Rīun~ʼr {k|[ 罬�+[-[:_ ۻۙKhp˚+- :iu˥  ,: b{tI@kz$\  пJ˱41,[68\Zk+$a ZBr^M<ʼLV|K/<] ' Lʎg|ikBA`r<u I)-{D0† P:1ƯȬ [̻1Ely맦dl 0ȥ;Ȱ\Ȇ|Llˮ7˒i%%,̹Ex_C|ǭR˲| 0YÜed}rAD{ʠK ZǴ bд;5TѺ{ї<WPomۧլ1Lº* ͬ˔5mK@6ޤ/ @]&gpG=gw,M' ЭP!3W7 ,_ bw<LLA֏a:ךdx& )-J0!EPV}1 c|-ѐ7@fb8'Km#Ԩפtk0Ҵmث ۋ 7؏]ڕɻ*-m|MC[Ҽףa,+͜P]| ݋]{1|h?œ^0q�VpL\( =!,|B۷ ]ֵm}๭Bgh@Pev0ԩD=[1׍ngm ;a 9)zޢ-mM!>0 "M" R5TVNIh1n@}Xb~c^$KP!q:qݧuɚQ@DMۼ:>lSp+aNʥߏ^!m>WHߜ3 XpPAU^.~ۀξ`�氾*![zCNI!H�C.Y gr Np%!\Ͼ:/偞Api�~ck.kG@pn^A>^ %ipFZKN=d?( ?QM_E#p t%$0v@S;|. JJ^|At.19�~NL e /iRݶ3[@m`_*{R<?EEYMj0p@HX"z_pI�_+W__[]| P(m 5 }$e4 NhNY96<m ;Vm i>. EpB!XP-cm�[VI;76DI[dm��aPOONNMMLKJJIHHGFED1?Nnmd[iDJZ2D4qIHŋ3jlf._ c"/2fIAZ5lشUGfrе[H@gc8m(U§PPd1mʵׯ`Îj㑗`F3y3\3Ɔx݌%| Lh9b+aØ QT@8De'̹Ϡzv$IclQR\Db͛w- ML NUl.mzIoY~ 36!Cn]v 4xߍӫ_ϞV+gEj~;3q^L�x5F]'|Vt,Ma'0p#^{m X,޳(4h}@a\r}h]Ca6pb77bPÏTVi|8$l y<ti睜aŅf}uCxfVp礔VjD{|i<Jp Jh2tC@f*무i]vRJ?jA0jY; &kGZ]fJ,@�B7l Fʸ}.jIl O+ދlAOj)毣ۯF1%w1gn8QҼ ~+Z .4׼QTx'C|o˯0Fb6'Ҳ`j]`2`kkcnWlq[amwN]>gßEܲHčOw'cڔSlo׳Ŝwy{xS=[1l=ϣǎpO4|[̲/|?y tosW_kN<^oǦ{Y?ߺ][oAz(m5.ύI|7'!Lпlq\֪mN̠Qj� IJ(LĠݒUBO8yo˃&h ѡH:Pw^8C|L̢& R7ohLfҀvuͫ:+{C78PP"IȍA |t$E0(jc$#07H򓠬G5e CV G(eJ Ε%*KENuIb␾d&]fјЌ')fR@P)nFiFX$#]͟<қ4f茰;U(_: M4$AOE~F MˌX[|YE΃`(4߀ Fy,FGJ;|a <IҖ2S(-Қ ONO[8A JTbrHE ��;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/porsche.gif������������������������������������������������������������������������0000664�0001750�0001750�00000014000�15166751647�014045� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a@������fD3UUU��"��3DDU"f""w""�3333D3D3DDUDUwffݙDf�U�U"�̻DDD333""",����@�� dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ .P@0  L="H 2jGBh†\>t ŋ>ʜIM"0dB(tC (]ʴS|@ル$ygP%&tP]˶m� x4*bzɯC>-*+^̘qQǶKrݻxjI`  @ J�n:1p)W.hԽ ~A4 |tqn_]A@s"kduya7c>@ '=z,?n/u4yCo6p"z ߄^x SD f `p�8ߌ4h5B8`HJ*b"eކE)cf_@R;dZChP�qMl9z]\HR@ IAbd}-&ƹi1&w_bt^ꉞ_s2IhvpYJ a &zZ p֠lE魰}sH?Y{&#b ֩)^F+6;\ԒR)VDwᨩ)[zksCuH79ڗ쬚J{-,Om݆KKh& .p&1~bi!$@"blO<k|+-p�63q̏):L3!ct5\Ty$J`3+Uw9%fq# 5nZ2`|F-rpG\Q޽!%*@�D:� �p1Ǿ)jzE^o[1۬yd@pw]s�f/GJ 0%~f觯UY>o?:0X)}sty\B&M|AG-)c�B5i� n<ЙP0a �~ZIwXA#U`g^ Jp.% k‘D$MH*ZXԈHE萇`S%hLxEpo.�Ba () @>~Ḧ́25:x#%r1 qNz[bU6:jHD�3Nwl#$N&UHKB>̄\@ IL�'LER~AXBɁ�+lLAft I:Lg:)4`(Њi¼*bDd0$b;0&|a! ZN\'C'JbEy(0ᲊ~4d7*MANt�\v&Wh?G8p'T'D;같\R& H� rK8O"58R(z` k\"6-G^SMm@RU P܍b `1F, 8"/b83q 0#},d_DzMjU<.jb+/5#8IȥO'dDS"ՉM?[*W)`0KZtyJ_2&&Hݩ {�>nj\<rQBR3>dɣ`JWNL&D};c ̫\YPf�[wҸB,yʉ٫خ 8αw=/'{-`ti�Mf �,~4Ā=汘L2m� x\mQZ{%/KCV9p&ߑ� x[3ѐ63�^-*C4gh#]e=׀@ GvwfTMёε=msʹ$`r.(_Tkء�rAMa3TZ5D7tvMrƪr�Af?ۆV[Fu$.0o .d#mv^A\Yn<ns[<cnAfCƞ-;#,d�p_S$\< n⾸qFvxH2#0yo�ˮ{=ḢĭwK|~p׸C;Au/'8Jg:A]+aWnZn ڊ4|fs3}rk-^8>�^!V>w񪿼=j:;wӟ1{lAB5=8#y|ệm'x6ۃZdWE</?N} =63Pa>E?hs3}h"W#G'uiԀ%,Ct!oEr{ׁhRvb}ey �!>BqW,6G~h70R',"NaGU_ HxG8EB*wL�X~ |7"$g|0hnGJaQ68!#`b&7<~'A3Ko8wA'=xMagHnVs$"pȅX78a(,6`em2lxg{Sw*!�� Qmdtь=U#0 ay񋃱Xa},y^@#>(mX…\o�a}؂!?xq n3xrv Ut+h\+(8W9Q�!:<IP#W4I*()*ɒr9E\.`lPuX8Fo1 �X9WpMa�=p ?+0nƕ`0e}g9VU88)>LBHuh"5a.or@)|z$7tqJO$%C9�*o+9 s)QSiԕȋF KrQ�q&{P!#Q_8"9Yy򸐋蕴Yٙ鐍#gFYjDM�i(u^"@ڡtÐpѠJ/aN'h\ugeGٜY~# p@)@,IqB} ACzEH*�JrФO.)ia9>H >2#0xAy)'H21wǧbkYqɦc (r$Sy|Kʨܑ%:٪lK B#P pʙ"uYj@�שG C!��)ji-:3<Zʙz:zy;jn�i yoYR<*ǃ)%8cS+%0H<:b: 9{c@au!ivtFк({ rӪ{2$+ ˰ @ ;^~KX$dxo7(9K";%P|}H'Y#dy1�|Bp<{a:pڀ%е_ac[gk+  �@ekQNȸ}+WK*�1{@A$[�(; [[}j'Bڸ۶˻k+[X jG+{RZOK"+כ[+�*Yxw9+鋿%ZL \ ;WE (,",$,Z(* pGX%@X8p <%lA,K: si=PVlM ;, QH|`Lwz3\^1hW f-{Zm.x%9g\0w#ǂ<Ȅ%}L0l%ȞB4/.l٧}v}ɜɞWv1l0lɃs, X/l w Sʵp,84pv\tΜz&p;L('\#t(ɜl>&'̄q|ΝzLΧk,rT;>?]Ǜβ3m1a]!5+@ч;&% &-3&,02=/)4}3):>@B=D]F}H�LNPR=JV}XZ\^MӬ<b=d]f}g-lnp$\v}xz|{M~؂=؄]؆}ؓ ؈،؎؏ؐ=ٔ]ٖ}ٜٞג٢=ڤ][>=AyM:hbΚ&6ښע,Iɼیٻ-Vܿmi ˭=ס-.:R*M/)sڍ+ ۍ*<ѽ~=w̍=Lމ-Fzvߴm߿c-~ >ᜭu-"^#,֬,4} ;:⁚<.v.>LN}*'M@D|M M&."N vfD -\7~^%txMu.MΫx=瀾sNڔN5l<)n>@D3 ~:n뿾Wj)NN-m]~]N> ~~nٕG ^?_F k0\wZXʢ.0*,1_'o3)_3,@5V7o9ϵDO182M0-JT/=O!��;giflib-6.1.3/pic/treescap-interlaced.gif������������������������������������������������������������0000664�0001750�0001750�00000000633�15166751647�016327� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a(�(���.]���QVnnn�s_�f������������������,����(�(�@IxI1A( %yb"nq ׯ|Hؚ:E Z[9x0w"Jw-&ަ^nB0O_e)$bo(f'& Lu<&(++l5s}ssrACQxyJtv>VHEZ7W�[B؄߹N^Lu-$)f*mJZQO}Ψ@'&$B4HUUGPx˖H8غ_,9tהfIh::kV!PVLcљPJ]ZũLXZI0AG`:2G�;�����������������������������������������������������������������������������������������������������giflib-6.1.3/pic/gifgrid.gif������������������������������������������������������������������������0000664�0001750�0001750�00000001636�15166751647�014030� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89ad�d�������������!�����,����d�d��(0@8}ৄHIp SL7- 5 ׎5k=ӆDVUXƢ6on fɳz+f];|Auz~NRdEs|Tw]_ GilrP">yCanZ-ɚq<DZxٕӶJTGГ)>pݳ >fёXb1dBq$0BǓ/Qg!ǘf|8&9?e6TɲuHtȔP !�XjʵWT&m`ٳfEvmڲn�H&ٸrmWڹ:{ */[gEnͱCū0elj \91gΘGz$3eq9 꾧/>űSfwȇwh]87Ԡgϰ9nW?}e캥_c^{wmۼgo<S  ^wuVv4%R5rf]-(|޽[ ab!w)_%1XK95Cx<�9bZBF�PfeN>%ShTSOz\B9hy"bH"k&~4"Jɤ=j',rН6y^XNYAYFѧ&<e:]LJ׎)xZ z**=*P+' {,c@iв9)xXmg h|ގ롵1[Ҽ^k/N6* .)KR+/% ;-Ĥ)좒��;��������������������������������������������������������������������������������������������������giflib-6.1.3/pic/treescap.gif�����������������������������������������������������������������������0000664�0001750�0001750�00000000627�15166751647�014222� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF87a(�(���.]���QVnnn�s_�f������������������,����(�(��Ix;.Bdih Jp,Z8|Z$0t Y\o M ҳ7.)�/ŭ2\ڙ6y[Shs^jwm5>Hsrg Nij =xr}@G q@nU=g<q;V>դuujjҤ;m`iTpxА^| �@ўPM *@�`fyU Fdx 0ɳMBIt襟@u\ʓd9uyAWXUlׯ`Â��;���������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/fire.gif���������������������������������������������������������������������������0000664�0001750�0001750�00000051440�15166751647�013340� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a�<���ބ{cB{JR:)έBťc:cֵRZ1!s:Z{BsZ1c!!R)Bck!��kR:ŔBsRJJ)k)s)cJ1)cc){J{1J1!R:!Υ:cťJ::!�{!֭JZ)�)��Z:s:sR!R!{)B!ZJJ�Ŕ1sJJ�c:kB{1JŜJsc:�s{c1{:B1:ŜBcťR1:!!RΥcR1�!�c:cBֽRkBsJ)!B)B1::1Zk��B)cBsB{B�c1k:cB!)!ZZ{R){:1Ŝ)R)�)kΥJR��Z1c:kJJ:!Z)Z:!Jc)�ssέRs)1Z�B�{{Z:{c:{BťBΥB1!{{ZZέZ֭RR1Z1�!s:޽R޽Zs:sBkR1sR){ZZ!c){!J1BZk!k�޽cJ1R1:BŔ:sJ{J{RB!�J!�J)�c)k)k1s1cB)cJ))1cc{Z1Z){B{1B1!ť1ŜR1�1�:�:�:ss!έJεJR)�R)!��!�Z1Z:k:�k:kJ)sJ!{J{R!Rs){1s):)B!RJ�����)1kB�sBB�c1cB!s:ksZ:�sc:B){{!{RJ1�!�c:ֵZkJkR))B)! NETSCAPE2.0���! �!��,�����<�G� H SΜÄڱ0|D$C%K`'ABƉ!;ÂKɬ%cZNDV_2"]̗;v"D"7P8!dGdN(9M`F=%+F;.st<Rۆʅp +ο-kڽ u� JWѥJ=V2g^in) MNA2h3<x߿O j*_μ\[)6kg },(o;8$dXdhX;K"}:Sw U<y52 HـHDViqvQL<Ѵ) (%C2$ZTJ-ՔRm[ TM-"Q=xn zJ9"a9‘8QCڑ(SQ9!&2�6a qda ݕM`)UT8R>5g`{}^W2'Ty2FfdqZ[2g(]U7Z]&fuVK8{ L]㙟)mPWR@g!QM M8zcᥕ!]6"z K66XRI d7nX ;05""8RnHI"vm4lN1 #92V)F8X ) :ےJlbE's#.LHZ&ߤ(.mZSPV{*yg_s2V!й[meXC)W@�!��,�����<�G� H*\ȰAsQg9#f4b8YIK>YCeˁ* iS(\۶Y8HK$Sܸ@UrhEhbׯ_Kه`c^-E+92m_W-eHui֎zQ݀iAx>}FGVqӨS͡5ǎ`j(6o[PG !Nܬ!ߒ#G*MA`| zy} ^yZ["yXK " kV _ qA4FnY!lВ[nWȹ&$h≩%'(ZWe[i0:aB3fquvrYeU)cnD\"J)Qis֘g5v[y`6jzQ> )R_|(yb-ָx(xŝ5ݶ{_$N8) PDwa?{7A(jq6R_M6l.Rgojsqٟ(OWߟpEɤY 2Վ6?Lϳ,f9P>VZyaCu�!��,�����<�G� H*\Ȱr"JDh.GD ^PƑ0*|aI 9RȸR74Ex40z&M`ha4q#uhq #FUҨ$F%jhׯ`ÂzlYsJ˚ldURnq++:C7<E.AK6۪^U& 2;u „XӨS^ͺVF4}PbYqHжnu[i:krW}A cJ&OpLVnFN5e=Vfqn;5#Ԉ \a@1L6Fi]JeiJau ($hjamdl(Y4Fco2UaF~ gpՅΥooe#%\r_d,"މ $gUQb =e'gv0Exd zr6%TIjRD#NA]gLXUR}]m-``/ЂW7@ � G?g_PC deYDo Cΰ)5mTͳ^e0gi,YؕCr5k7�!��,�����<�G� H*\Ȑas3g;v.f qqSm]4Y~ZO *e̢"ū#A>s#S!Cu# p(A$8qrHѦٳ&-g۷pFKM`=]jr8h'>UG:t*/:`ʊ"Μ"!"%mJn 9rJPmr@Mab N\st#XYͮhsH F+Mش_OD!0_:N)+{Ms ;ZL_1Fi 8<JB@5 O l2IKݔWN lyF9$_MPXqD5y 9}Fv<t^ :WZQD)Vq@)DiHc=TN1r5DhYԔtS]gu95v%Ue|RŗHz1RJ(PSZB�J%y=6K RF^bMu穔t|XQ٧Z((a?/Ȳ 7L*`h44:5I,ZbnlSyA'(tfgG҆aԢIY%`و臥FlڀƦXyhf3Ń]XL[Z|e\m4eDX)%N$Szd�!��,�����<�G� H*\Ȑ-Hю;q&J�A q!S`,`AJ)]^S.N!CFÄL.d*hYpRm2AT.!B34`D*Cfs#Žh zlȶ۷p?JjsHexbԔgM;\ӧ^ȴbAC36 SuVU �BPJزMTV뤸4Wu6B˻{{r7^Knd513ޝڧE RdUL) ±(S¿4ȑf}=ƬTWSեL4Ed�%h31]Ri'8\h@HxDDű&{[F&ݤnC`F@Ʊ5\pDiH&DdP"q)gD8ѕ TT@\B5^H b"}QMǜ#m vD & nyz&LܝguI5U{uM^VVH`bXzꭗ)K-M鄉~թQX {(KE)5SS RL׀Td&0V+f:WU4z�]eEXM]l %NƹlhMcnzWU.Ї]'iQV>XyBg#E!7Cv㣏:B1P@�!��,�����<�G� H*\09"Zha3̦YTRMK*9xt٨Q`{&5/_QEƐ$qDv64ʙ:řFz*fU-Z J%sQbۇpʝK.\&2A"@iFau<+PV/uEa,N (Pc Qf.yy*I#@gH%NdgoߠAi3v8YУ;gX)So:{~bJԠrL3]gϠvC_۴MjTL9lb3Ńδ�V i8 (Owz@4̓ȸ�XHJOSv[v#> (Τ$-H҆lF[X6(j`6;2BfR9=Td]54]9vҕihlIe\9^b)fBbfguWr}MlmIH[L`=5(3$TeJh`Yc} 4`gmYh n9VmZ M 맣XGA8g9j8SXOmyEHbRM}$DEŃ:Τ7-�m(i�ʎ; c($ZBqaj^{X0ʈ>6±暏e+$_X[)q7"Z|Q\QE<lξƋd(VigɿѢKKd}yuM}0BeQؕ dg9^z1DIwAV �!��,�����<�G� H*,B 3g)ڔUhT&(8dԩbl9?Uذav,L1Q\3rJ᠍C\mUP9;:Hٳh#\˳lO!cі2(CvqJevJ>5s2H͸*s\A-#h.GBeu=Rh!+Qk .mS>{۸qC(xr贤;Fv!ԉvcDԱܸaN~곣,clؾAUu8&Zq)' s̖ kadOubdƸKI&X9FH/?࢑G Mga .`/JO7JiV vJ&aTc i&Y�<@#1D$pyVId~D֤ &i PQf$i'Q Vp9Fy.FE`OPrG u+N%|](tCY]EL淦Jl7bصdҭő2ITLu1_xe)cW Fq$`h%C* u~FR(?�r@"Om̅ blUFHar0CLh$u6vǕ+Z،!$UbՆFڸf Xf9#v9q q.*\`EbQ䦐 �!��,�����<�G� H*,haÅYt4f-۸9r$A\Ș!G-dȦĈC"=V,[$YEr'M"I9OJdN(1b~=%N2 !jʵW)>:p#V0WJ6 i;mv$DiԒٹtCzȒ_@"5'ҲNlbfS0ϠCQXfsp[ګDhmfqߍ9:J[4Z.y\8sMI+˗"=тpidEWcM-,ē/5t|PdK}4)RT{4VȑY˦7;Bn QX]&VhfH!`fiJIefDQ``I%4uR V0n3pxwƛLjI[ȤxBZ$lL}$xuxJ}L2"ə#pD✑}Hf]d{x- 3FXNYׇ;jf7~ \N(5h$gR&M|!=0fؒ4XTRes;ըgSHE j'V&W}Hf;Q/xQg+${}ؠ!�!��,�����<�G� H*\0G)4g΂E!:H^8D`HfƂ ng.\ ys'\ tX90)P(ݤӧPJedb@fIUnAByL'Jm&DIѢ(4J@OERJgʩ#KL!Eb^?8d>` **ǒ!lRܐ1Elɳ\WD$@d8iU = 8:L98E_A{u_ߺAޔT`iO_^OdgXy|>'UlG}{^Aj6*ecum#gɦ9F'T5>t#H'͸G`Ѓ;"*qA%DtcUmyWE E^8iYOg [']:_pLY$Z)vE'YVX#rUeN�!��,�����<�G� H*,h`sH\H9  |TY(Мɐ,r&R4'\J0C >8 @P0Ĝ9dqc7@MXjfP)T54Ŕ8|`Nϐdo@1(lF%ǎ$*RFpخ3kެ٤AAc-R| -МȔL> =Yr@ hb Mc?&9\wE+'өI^/7nNxqrt9nխ6J 14je96ٔP_RV%ق 6F(aIuWgP}@"JnxHfdAnЖjdG_75jpw[NM*t^`Oo^h$UW{!R�60@c9NMfujU�LtGtdSV[kƁ|MTKq{ Tyb]x{RTaOEڔ$;&SANx8P\0g,[R ?ꗛ1؊b j#\U tPj - E�!��,�����<�G� H*\ȰÇ"k(ѡD Iӧ{2bW1arD�@\wO_|'#>ɳϟ@HTŋ-UX|H}#N<l`n m|Zu ]˶۷p-\IK-J''Wibȩ|D$v>/ʆSh"% 0)lМ y-bg 6]xF`a i Nȓ+_.\BەNnܼ)GN燂a,-Ww 㽱U;t/lXn%pEvݳ8Q8 AN0lL>=9Pp 8 %tɑ l"Ce7:!_nI7]2T@�!��,�����<�G� H*\ȰÇ s4W\s`p xJ<"9A Ƅp1h�4 >/! JѣH^-,ȱ4AGNF$ƫ` |ذ9#G٤x˷_KIB.a9w;bϭ,Nb` ֌v,@@{#.łs# r4PyA V4d3ȱFpNgHZPuŋ7سkνb"eVӼa%{c-W|Rj(_"=v\RqEN&2g,xAf hU,lpjeOH#pSN:3VgxAmQ7SpB\haRLTEq2p"RHDH$XˑGF4@UieeMQ�!��,�����<�G� H*\ȰAsB4'q%ʑcGE 0i0bE;vPP4_?9& bhM14iҬPxl\OJJի˙3V#>ݺ*(cKJ;ܚrGѢ6۴eS fY_(Q£K͑J˘3[ jBUk(Uؒm`Q v#PH&ݱj%Y^[zmiǎ&*_<rŦh-}rHӱ%O<]ϿWYea54WN Qh[tTmht&`(B kZB9mgjmm`E&C?;[q4A9^J*!Sv2syNqy]_Lt(YwvM?4^*7r,mBR] DdLM (6YTնM|z('x}fNh(mJgה%]*'q!B�!��,�����<�G� H*\Ȱ!9(9 0&be#+fv(NL1G;qrAce^B.- UdxkK-l(`SħPJJ0KJV~*N*e^2g>KтӉX1ŗW"6ұR@Y8Z]̸ǐ%ޭ "$s3`(BS!dCBXh.ilɅK{:mТH/n+ck3nwJJN#,)v˟O;Ʈ!vRՆ$wftg(Ōa'1s{if^kC-jQWE(-ђ$ @K,Jцiu sHP,w{Et=\Lm"╖ldpMp  %J$32H!!X$=[<Cp[ĒX 6YN{%ҝƣudixaHXSQ{!U�!��,�����<�G� H*\ȰBsI19 c BN C b<9Y_X ‘#_pI R"DrS^(U'-:JիXCyɪ+AF6\dg9""$_~eBЄF8["`HƬI9RJL˓D9E)Gð:b6m0x0,H60Y.\1 bE [Zj' rləF۸@Ef/GH}Ql2O Dw9l`̞h@[̿�(h`D>I})z 2`i}g̐hAB3RGٰƌHa~ %TvI ae!qomR6.|Ǣ@,)nt&pE`dDDZRLKյWL:~\$M^T#4u5xN&dzG-9N1yE I%ZuXjġl!37ʡFYgR�!��,�����<�G� H*\Ȱ!BsBL#2gǜ`xEŭ[ꬹӑbŁbG2H4DErZ4bLp@d_}N{bbDXjʵUr kUc̣q򩋄R:4zW ęq  ǎ1+QN`@Fla9Aʹ^3&QCb'٘U&fbf1v O(@ٽ6[N{|Lxs;c8nQ=j'Kx] ; .1^wߗ 9i6qVAݦUiF(b`9 V:dj}VgqaxCgI�UBbq/,dMdXOuF2Lo.0a[)QX1}hMkp<qR]Mqlӕqp 7ĭXNQ/f-.'*VF]#EMLNJGqxMos t}w0 hud`6JLpe`�S4D"Y*f@zq5%+8Db qfv|H) Ä6dL}xXPcEDŘX)]1@�!��,�����<�G� H*\МC # |8B,L3ԧ!Cpi|qPJ̖(I2 e9ʱ)0a t%8HqSJjʵEs唈:MGJ@En3fchE= 1cRhG!< ԯPbdr#G(VCMpᶔ¶-B=ǖ02t:rh X �.~(|mD,-MOP%A'ި)R`rGf4EgUuڂ 6F(UIhn3 g9TCRрek`Y^gqZ!l.yQHPrn pbHbh@IAF}d%�w lAHi~8"t3x9QvL#!4[YVFl>!fx6Ak:`''i _%5DPiYqfyfPbQ C*` MMzL>91g;[9Z쮿5 b8Z@�!��,�����<�G� H*\ȰAs9rHq0P0i -Qn͟?ęfa#E BYN]S4h@B̺8q`FHJihƢEI[eKX%Nʵׄ.6tia0(9sFeKs]je9-Ksb!53D)!RsrA3 F_S^ͺ5C\z 40Gsm[o>$ 3?TKQiPsYF3mn8f4_}EA+Ё YӧLr gaT&AāTr4Ut`fGD9ġUnFh(,[lydه-эEwP$ⶡYJ.!$W@m("9:(Ѵi]z!NrBET_ki]g'dIkdvYg~]9D0EPU tz9ZTS"h}Ņ(HBR{WJ.Qe܌A7: Z`pP&L"؄HPB46lN&fUY54Q(`dFdbf`v8eġVb(P܈Yb#R�!��,�����<�G� H*\C"FB 2Z!a.Yȧ;lI4g[ځʉ7Nt%fǁ]/Iܠiȣ tׯ` ~`Q3#[Ӗ6f41G#1f_N|Z{i2rϭ_)$Iv$Eqf:jV"NYfeheφ]ͺڕ̋>f]$;wLvfqGL%e'; QlmMA(v[&םH-Vw{I8I)HUYimVNw8a6锄}Qle8AYۇ ($h"y*VGxe{h6Uh\DFsUdQziMi4[lIu{P]hkM X.%O<݇L t'F^`da,';%XzEސ.9TO!x;SO@M KDt$zJ\fS\1YO|YKĩB_aiB9UsY!I{3ά8͓&ѕb8Y'әlGw""RbP'�!��,�����<�G� H*\ȰBs#Z0Wb9 EJ88NxH峀1cAbcG|ٱ3)1[ B>)as̊FtHիX2S 3f8|b1!L qgG/)pGw(As9dr$IDmq)ybÜR"w"Eʤk̹ϠCs݈v%Ћ4ʌC6$Q]Q9tKΜ_8li4GR4SH‰ 327f8kkJN7x ꘔ3(3c!�(h hF^j VYHAJxDeYtH}Dad)j `oܑW,q[`)z4 !xa%ub/h6xd  K cۘ!)6@aɤށSw]vmj1S "Dgv'],M#GZs``N ?98Py§;7Y>.cv!xfVe9P@�!��,�����<�G� H*\C9a@N .*CB`1#X֨1NͽLQ7nr.JRfė9TI%'5f, C=F,ï`Ê 1W0b580c!ѡ4p\1:(֌q8pCB {?-0\T`er,O zV0GS^Z!ҳdJUȯ[GNԋRň ")94TM83Uqr2e…Ȅ)u%^b}T;|4kq r `pdIm9l!kyQWqVAц&$h(8VW"e!kvXa$ǍxVqiad'Y[] dv$4.$Ǥk嘖M*%K 7nm7 }kĝdJq kAw)tqх}ɴv@{p#O,nFLxB['MV_zy$0.`xe]^c xlFsC sUFf`G4q.q~c3HYY)p 7HYEZ%uceY W2ɢ@AV[(*�!��,�����<�G� H*\p`'Ne.2ʢe-NI*_8. >NZcsEH5dZhjg…yS%-@ASE qBlSسhä|+a8ewR 93ܙ3VXL3̬y3g9o! Gnk,,6p]R& O\(Ue۸sލP*L k.H7D?5]FVFlK˅,{Ɂ RD%1LN^nLUfݪXp&`mQ,]E,qXS]IYgpGl1\]7'p 2qVTBI 5\VV@)䐼V^DcW^)vDwbp wR8iT]|Kfל]_|qR59\}m՗ n.Mr6R>H `TwLuWU{!`hEgEghP-Q=⢢;rW9萡mwY9ga }?Y#TQiݖt F V aNf-]E΂㍖,v*Wie"l-o;י/U%SR%UuGeHNMe9$=H�!��,�����<�G� H*,c@s"aǎ9sh!Df ӥKL ah!ǏC&: 9jeˇRQa8ӨG1b-a$lJV'#bHٳh^471Z cam‹k֬/:jU'AC'ʟd6b*@%NM]9Þ*0R,F̽{Ŵ St۸s>gB Fk{,[jW9m F N_'=(i8sljɣ0fU.Q8W%U.PF[PY*QtU}2QXQDa&?5C?۵ D9q9r8__ ~uFd@X֍dېDiH&yGFFqƝI jEdGr2a9ۈ! ʤK3p5WKXr(?S,cU DTaNї l?IRNA'^;m6MQ4"7H2iUvQǥu8O(B}bhUTM\ SPنM+Kՙ~[_U1yNX<^hhHTڎVf("LˬP-:Q4](C+vT(UCku֝*_Ac.̲HH$QFRw!ȫr{% I�!��,�����<�G� H`s\Ȱ9;J2g9s6|xQY e(떍 &̡J;ʘj2h3e./j4xfuAդ t%JsNRR1A]tc֒j* 72cmP7TY3,U ʝK\ dTJN-@ó( P"B_uj,T%̓˖vdj59<iD63MK p]8k))niN̝|`Q3?w6?JQ AbV~Zi)UN$zű% u סƙC>PiuCIReA}`tQ *\SGKV]O(YJVQY �%{pd3YZj]GC[O5'\ Nie\M\SVFL$rvfic30%Yb x13fwE n-ЉeVRT yYnY }(U5 ֣QfU5K:ש h:\Yg`,bG]4-ݪ9SDjiщ1aZG%V]|!E&# +QZQ2>-GH_)i"0UMxZDA5![7gǸh@�f%QI q6I[PhX6mV Κ[i~ip-etpfz�!��,�����<�G� H`9s3Ȱ@RáTرÁ+9+ZTPFVecbAs6rPF_fL@5Í2e8hܘOUvaM1=`1StIβy-ڂ9 A1#aOc>Y16uj8ce&3XsgÔI�Z@L60KJb֗$f$\ {;mωkI]ԛէ˄htNݿU|*&+c8dKw5ϧ塗oJ;dHQ5P1 شTT7LČa1_m�6Dpe5FUIf 7xHׇ=qM 'dYRWp6@tA$ORoq'q49ёeZ1D +űTE$p+~B2őM,F$Xi]b ^<k铘XegYsH�cd'L"u:FevL0#gNdĩ~AƠR88K>d2yw*QpPWYݐ2%u/Tz�QR)n>(j5ai$S=%�½z#+[L1[ʦyiZqaiKzvUKbr)%AJhVs^29Q>f4�!��,�����<�G� H*,#BsBlXEZ|X\*f Hʜ#2h+xLu"Ł*!`C,WFyC1vLe'\sj\Y(tפ_Ê&A&ɑ7#,xdW8bt^-XH�V<HfY9X0=3S֜RS^Z傕IXbDK3K-_̯BT!f˞[13;\kP b0 Z=jMK.R>w*ō*Te\9=`{SQE]WJQGZ[kfv_-Ww1Ek9dZp*Vt]x[ӽؖ(dIxA2TWS EXW2URI ɔZ<wF^Zy%wIL1t$anX3VF@25^ gt^}c!oWr]*N_,x3%XV='hyw]ўTRUKLLIbaGeD#\ hPSX3c EV-9И&4B6VeQ6Id>RG*MG"Y!�!��,�����<�G� H*\МÇ bb XnC;-(&\ňSO`�6 Ϭ3rR,rٙ3 Qplc"E NJUȑc'é,*[ɗeK=hNlD�,DYsԔ#?;ÆZ< LlSW3k̹sA^7)թ`yhc?t5jg")K3۸%Q3g9W|z>թZ 4_c6lK=8l>4lv�(h`fy}mX\u6X}Sr\GQXYR]| 9%&UB-CSv8dpA&4e-3K[W VDI-crʎ1LȠuu]Q0|iV`ߩSv-^PFՋ^89\MeC[╗zl&i}&GeeՅc gGm;9u yYby U�!��,�����<�G� H*\М9 tH#rxc9sZì$3z&zThI<dr&_ذr,1Ã\Hhᆋ<xt29PcXjʵDsDǯ2džM̶X1 *Cbs7NNY~TŌUp,'. ʹϠUFܬ5h RtY+fE! eI9 )yWLY59yM2as0»vgϯNdMƺծ G3#NJǩBeTBV%ڂ 6Fm}VqJeh V`kTx&b+'%رSq}XUHWRpSBef?UWa<?^ldePs1ŵfL29W/HU)w#VLk\=v<6,'.WZ֐*[NSN~f]l%}Kp\F!9v{†vU^F$١֓ګCz&P �!��,�����<�G� H*,h#Jt0$6<#všGYc0; hB* C;#x0^<{PMaRh0Dž`Ê"7--<i9”TV'eQIU>lM<J+@ ,/z$*A qpm3VKӨKfV֮_1 uWL\e6OqC c#Ȓ>j5?b3ѲTgN rVڕ(A&t9w™x"LiA/7jZdN{VxTQ2ajv ([զjAIt&"C63(l0bW3 fckA7.Ho\'F'="lofϵ7َ3D-桴'A7ZL4RNءT$9RXOoYN9A9p�VIaW T KmU`lqaj4co9GGsK|rTņ"gd$)z4JeAȁg[zܖ0ǖD("V1IW"X~%Va�!��,�����<�G� H*,*CJ9s2"gGs=8'~JR0;z,1c>d²EQp= Rh!t "7DMLAVKY%8KSKg#ү=L\ t08pãMdZuPr/K#39fˆX.i 2k̶װck0Ta#ZfQ&^5oJ.RȌd< {2 .\o;i*U01:ɑT.n~*=&n5!0RO?^=pZ2 KE=]G4R9M]TG"Yk5$ۋ0(4hRA4Qn 9tZZZraZ1Yb)iONt&čw5o%gdV^h]>Tw]uS vXPEY/vPmeS69^)D|">^:1y_ґzS4I\uI[_`OA%@zp(T'P.m"S7,T\D؏QwѺwMFIdApO䪓&+QRMQ4Qul=#l�!��,�����<�G� H*\Ȱ!As,( cKmʔE`\| ;zaD%ʋ,/d)Pcrr3i!2"I# ݦH l[qmmG@h*ӖFÊK@vQ/G#9kK/xhC$K QY23V[識RTWsv̦pHi[gmAM[r݆-Qr.\e)ٷې*\zk(c5yA%\(xI;i)*T^ҌkuJ2ʠ�.VS&Xg]4S$ DVlQS9]UJ.ysG &[(&4h8h9T9<:OaI1 [i۬_ ť\ɴTIQitb5eBq&U.,5cg#Z<wy!AH=IT.hK ehuu`)@MZ{&fDgO ڔN92B$TMٴb`vHbE]F)n)sL)$Q{1ӬSI�:pR^aHbVYr -DMY%a$J]@uFBRJ-%ZITw�!��,�����<�G� H*\(М9j0f!G,@xoG<fӦuLuB!.[6mBO9tcj ANբg6\cMbbiSYȰ۷p\PxwTƌRŁuc`(^U}˽x&x8qRR0eqdN0!,<{"rhÌ`8@Kr*_μs2j#xK=j#(#uL,)`b duZ-J3HauKEAjM "T!j*qhQ0 �S8ͷ*MfQVQS "_%d9Okm3 "c(R-ZYtP*mGiDiܙhlfsl5L(WZqqTBy]VzvUwPx hY%J_=&I qRrv4 Bb`9UG]dLc `_eTM4K]NQSZc:a nȠ%U"ljQġ9deF_-bQUv)L�VNRMU+”*oSu(Fb$ASn)^e&u0kCCEp$suLUqؚY�ڮri/9 3)b9 WuAvt TΆElΛh �!��,�����<�G� H*Th΂C&LYĂs08ʦM5"|6BsP%HejuѬtk 38Lٲ;I7)cB8*S gfYasl\(LxꝉQގK|k6YZa15EA.LxĈZ[ZȨ#ΦԌ Ljn @joMC*Z&߼i&B+Wo˖~r^r3Nu_{NBnWMAX̆k`j՚܈{D54+)WЭ`']F9gCWU3C4r1VwaN:6R7 q2Lx2C|#IM!EQWLԨ݌ Պ /%[ӨG܆[IfmRL !mTS3?* Cs$Wket9#&w׵p)'BIbaZP5eAu 9TJbtE)r"pfv*T2aVP5L7Qj)i91yHR՗A:p9~ap%V95h{l'"}hb-Ru|�sX[fHXO*/^qfg~6`jtf7US;C7j(N%N\v;mMYM^l.qFrk3H(mO, L.ݫ^iZ(L;%Io(j㆛aC%pݩ9I`E$%SPmƥ2SAgSx饄52)g1_sZ^�!7Don't flame me! polder@xs4all.nl (c) 1996 Demon Systems�;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/x-trans.gif������������������������������������������������������������������������0000664�0001750�0001750�00000002131�15166751647�014000� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89ad�d���f3�̙f3�f3�ffffff3f�3333f333�����f�3��f3�̙f3�̙̙̙̙f̙3̙�ffffff3f�3333f333�����f�3��̙f3�̙̙f3�̙f3�ff̙ffff3f�33̙33f333���̙��f�3��ffffff3f�fff̙fff3f�ffffff3f�fffffffffff3ff�f3f3f3f3ff33f3�f�f�f�f�ff�3f��3333f333�333̙3f333�3333f333�3f3f3f3ff3f33f�33333333f33333�3�3�3�3�f3�33������f�3�����̙�f�3������f�3���f�f�f�ff�f3�f��3�3�3�3f�33�3���������f��3���!Made with GIMP�! ���,����d�d�@�H*\ȰÇ#JHŋ3jȱǏ ^I$’!S>,ʗY li͖ iִɳϟ@ JѣH*]ʔΑ"q6tΩzQ\sjju԰hӪ]˶۷pʝKݻ ['Q\,^fGݫ8|Gflk`rOϠCMӨS^ͺװc˞Mm%s^ZL0辣ǚN.gϡ_m}%<gͧ.v ߞOϿ@�;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/pic/sample.ico�������������������������������������������������������������������������0000664�0001750�0001750�00000002710�15166751647�013675� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Example icon file # screen width 640 screen height 480 screen colors 16 screen background 0 screen map rgb 0 0 0 is . # Black rgb 0 0 170 is 1 # Blue rgb 0 170 0 is 2 # Green rgb 0 170 170 is 3 # Cyan rgb 170 0 0 is 4 # Red rgb 170 0 170 is 5 # Magenta rgb 170 170 0 is 6 # Brown rgb 170 170 170 is 7 # LightGray rgb 85 85 85 is X # DarkGray rgb 85 85 255 is 9 # LightBlue rgb 85 255 85 is A # LightGreen rgb 85 255 255 is # # LightCyan rgb 255 85 85 is C # LightRed rgb 255 85 255 is D # LightMagenta rgb 255 255 85 is E # Yellow rgb 255 255 255 is F # White end # # Shield # image image top 30 image left 50 image bits 16 by 16 ################ ################ ##XXX######XXX## ##XXXXXXXXXXXX## ###XXXXXXXXXX### ###XXXXXXXXXX### ###XXXXXXXXXX### ###XXXXXXXXXX### ###XXXXXXXXXX### ###XXXXXXXXXX### ###XXXXXXXXXX### ####XXXXXXXX#### #####XXXXXX##### ######XXXX###### ################ ################ comment This is a klugey way of embedding a comment in a GIF. end # # Questionmark # image image top 30 image left 500 image bits 16 by 16 ......XXXXX..... .....XXXXXXX.... ....XXX..XXXX... ...XXX....XXXX.. ...XXX....XXXX.. ....XX...XXXX... ........XXXX.... .......XXXX..... ......XXXX...... ......XXXX...... ......XXXX...... ................ .......XX....... ......XXXX...... ......XXXX...... .......XX....... # The following sets edit modes for GNU EMACS # Local Variables: # mode:picture # truncate-lines:t # End: ��������������������������������������������������������giflib-6.1.3/pic/welcome2.gif�����������������������������������������������������������������������0000664�0001750�0001750�00000107740�15166751647�014135� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GIF89a"0������JJJ������RRR������ bbbsss{{{ZZZ��999)))jjj͋Ŵլ��AAA��111j11{11RR))��s11RAARR99))AA{ZZAA11b��ZZ11JJ99ެbbդRRAA͜))RR{RR))))Ń119911{bb b11͋AA{{RRՔ��sJJ ŔJJ{{JJssJJ�� 99ss99{99��jRRRR99̓ZZs))ssޜ9999sZZ))9911լJJ{{{))RR椤JJՋZ99ZZRRZAA99RR{{ 99sRR{��11Ջ))jJJbbbb{jj{{朜ޤ{{ss JJjZZ))jjjjŤssAAJJ))AAޔʹj��11սAA{ AA99{JJZZAARR{AA11ssbbbbsbbRRjAAss11s��欬ssŋ洴bbAAj99{{ {{攔 b99ދjjss՜JJbJJ))RRbbs99 ZZ! NETSCAPE2.0�! d���,����"0��H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴS*TXP"Hi `BXXDس::�, 4`ٻ`=.!/ p`z{B @tجAAB勡/Rز220[)j!C *sf4H�y Olgۻ@._^o·nBK`gxo_ʗi\VczFim@0BAD@Y( LA Fm!s5Lip+ɰm-㑇 \ q0,A!Pf \v٥ @ �]~Y9&Nf $gL@d8fġ^ĢģO$H64A EtG'4 PrCl1#Fj+;kWF�8Z$l`ف�|묱@%B @ɳĀ0@%8+ܘE$ >`K] S{l0#dt*qЫ*j8`@ e:|* (r W ,%2\ #3AB"E|8ADRMPG"?Tmu5{zKHCo>hv7 @p~DAx}>W`0)X,O,15 IZhl2 *Z$Q(w9aC97β]pT,!&|2AN*8@W`;/.BtQvt=#ϰ}@ާ\EEW8p"�azߐ}<~j @K=aD3Gp`/#*cD3ȫF!#d@,�pm` @l*r ^80 z`t%P%3$0D@�Q0 (xwS*Xf @sF$�#"K&Ё'.Z9D,vT@VC\LAtąpMbUdB0.@@H�0ѥp"` h&2DH Ft pB8e�^(T )Ul<k A `3n9K@;,`*yCl�F 200\" ü@LJ\&CH �, BL=:Ń\ "h� s%Nz O "HEpbNZC\s)+F � �k*CT^H@.@v6��1/<U A0(x! @Щ  ĺ' tb%-Jʤpz:& CvF3"EDA!`A,q]9b� 2֞K L�ȬV2~ye4@ 45]xE0ժj#|!M6m~E`3'T"&Ձg�]8 < ` p�L�NV\r d(C�*h;�` *s>B &(X V7  t�RYmu'R!Enl ӈyEؖy JJ�S:�+X&P�*[H�*q/9(Uki|3? P JB: Sc c˳BXX^xEbr- DЀ- `(^ N @~Yď빗`aZArCH`�^92(dG6 p@0a $[ 5@ p%pҵtH }b !ʁ-rz"A˚\�@J< 0Bz&�緗Cȸ3^b5uM[uV\lNn�p9# +5sF�K:Kޢk. w"t �wͫ@$Fz~|!H:# E Sú dd3�p=6� ŵ Bg{ Idz9+| U0zl",Kdk%g * / P/pQltɀn] ]H|毸t (|A\Dlh!�1.}0�<z�}F{x2H?uDa%zzL{)[R ljd�p1|5?}Ad7"�PBp .=XEsNns%B0=AEZ &pp/@sp;qlD@0�O>st �Q8�� X% :t*v;`Tpdu 4q^=X8�Z>G�W 8@K�5=tR" tpa."/P[wlq/"NmP0vxы&*E p*RmjtKuπ*pLXX^5<�wP.}�ζ 2=5=.�2-oS@/`Td/`[N " `0֋ !UTT`�[p*vVh  (:9@.1"#4* 0D`ѱbLXw' � T�70`910d9 �3Lcc Pdi Pg ae@ 0 / ` `gymo0 GR C/I#K5)*Vw��^<P{](:I�PB;EЛY ``� ]?�X3t `a^ҹU9/]@vg)/B#^@ ҞY0e0y?*br�P2@Vu  uU:2 @֙6FԲ�9BWPu)F .*,2P# 'P6z8sE*z>*0DZC mÅ4 FZ0R:0I4*�ځ (e �j�(]$+Par:qZ � `<6'16�P@<c1 Dyᓎ� #p<gy%<m˄4"6%&݃%#b=i�b@%0Q"3` !�ʺЬЊ~Oڬ ѬԺܺƺvڭtE %r0Zڮzگ�;[{ ۰;[{�! d��,����"0������� �����1�ZJJ)���9�����R�����J���A���j��� RZ�9�)1�s�b�9A��bRR��1�s ��Ճ R�AA19ZZsbAA))b�s{ޔ)js sbb{JJޜRR1j{ Ŵ))99s�Z� )��{{j�sjjbZZJ)1�RZZ Ŕ j{{99)1{{��99 1ŽA�j11 ��11Z ) RR{�b{� )jj99)1ދ�RJJJJZZJ�լ{99{�JJs�{))))���bZRR �jj欬jj)) jj 1��s{ss j)){99jbb��{{A ZJR)�jJJs ս�Zb��)�� ޽� )Ճ{{11bRZ ��sZZbJJ��9���R���99{���J��j��)RA��s���� H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIMr*RgΟ8hX3abC&-L醫PIMYiWӞ]۳LHյi:E�ձdͲ< s_{P)ؽx[hjԸ Zc6 R!֥7H<ְ 1ݢM>ףCg`<94&^-yCxhû;1ߝ:p~W]P~}'  P௉]iOPWH7P4`7l@'n"K`7& ('AB1ʃD؉#ƨ8J' f D&*(K7 ; #bz.(Pv#h |1l)K.PCHȘi|Y:Hn>t@8£"j41!B:$#À"ģ~D:JwQ�~k@>ꡑ% 8骹*j#I0B *;*B2!)/O@G0`Xj:+ A/R |*  $Pt(,K$ bBH' L>�r$(覲 4AЛ/ t$ZZD-MOG/;H4ǀ�oG$OAM4e633CKQ8`FЊ/-GPB/5<uER L�GoPF ~L҆jm ㆾa1B�y)y1("~|� !L@F _f@BDdTOG-X?谂 \p8[ PlCpQ0G2~* w;⃹/96 8gT` E/ZA<pDA*齣|!�w,V X *c " .>(UpPk\01qBȢ]; 1 *A6x@( dT`G>b]3%5P*Zh򕰜T�_a _~;&Dx9J }^,/x? ma$j՛.P3ܟ rq   Rq`s?E~QsPMD0�3 =v2ub @QP%,hFSqcG rF0$`2x\ G8 8-ZK,@oB2: YXxZ�Ř�(LͪV*"` OsNʢbb@?�,XzXj#ڈصx 6AQ=2䀮]aE@B9Uy'8! $C#YR[ $ e=4 �6 HA UF KF! npAc B& 1 7 0&^�Yr'Z@zAD((G3 y=!FrHfk堀�p |Hp jB HAo%C&w Ae̠Ÿ/kC0g <$4TP=,Ā@vlaB@r$Hؔ%!` ^A`ߙ*{|\LxnC : 10aށ`L B ʈ4܂ F0&;Dzb�W¼kB)\ B_tb 5%FMjR+C1 $8}E +Df\I8xxvЃbh"x!/>Aj[D d �!_t y @` R@B`_)z@'l2 A5_rhE4qF7 ՋC| `p]8T Ђ`i68p B~ r"@}N:d�#}@a`S)&LmGP]hO{bn @ b 4lS(mnv,c 0x6ipq6�<kЀ 4bG/L5h0�Nhj 0Ehrc!Dnp>RJBI~qK_*xAC+@~[H.d~A]c]! Dmz<v v[ns0_p xU l.Fyx_ (_ xYE 1veS0AFd@ O8aDYg=Vyo8Zpy6~W~w~8'KDPptdl9 /rN@b+hUUua(:&d #d}q0}_p@P W`&؄x~~pt:E @tpuWO`I9�vbw FUi�uK`0rP<-byc_pkP0VI?@F bw@$O]`FE@LS�`"�@ecD(vŠ xM(MhS�RHPt Z{PUAC�Kx *%Wi `\pJ�9 :v`X_Pp` {؇�7PWb~~X Uε(@a8pTN+ 4pYFrFIQ[p0F?hs�N CYF|cW@q{bP`@V PE 3� zFF�ye `3P? @~ų u'8V~OS�f`{ � %|y ًF9_D|uH )^PƉ ȉ w TPWz@afP :9[i $pP 虞0`F�rs/f7N 繞p�s �%9 @6visY QrWo'vsW7?y�Т.*O2I'R7 o_Ƨn_Yk_TWЋV:0 E0 wБ ;L7 *u ҉f7Z(V4p *Н[0 G0PzENi?06�ph)z0#p�y�d YcG~I @ 5gg 7ŊP=7Z�C 0 ~ gGڬz*@ " (VIN_"kpiS EP7PU_{0p9g_`Pנ^ڢFPF  )ˉ \ QRrj~a{i0P `в..O@-+0J^R*벨 d(&{P~{ oˊ>�̀y֗A7&*Zh3l۶n@�*)apa |_{ SRE@ W _08wFv_xp i%ڥ; u JOpbq9 g*|JY O84.=J�Ű`PF.� J V�MR  + Zxp ?a۵ <,pp[uO,KEP_KkڠF__oPP{�woW *"\�G00�56c"a G  -<@1 ya`H�b{ K` 96dj.+AHb]: I PN{ˆЖPzi^+@yyYJ: | ɞ` `l\qzp# ڐC0 5 &xťpixj e܀0 Iw؜|M~)uIH` P%!, b^J�Y!= `/-&R lU "J]B&] ;:LˆbrPP@ u |?q@&ſ&(#Jz8MzɠuaP4 zd[h�  _@ @ 0i }`1Gjoݼ ) g�Xq<4� MםBJ @`�CS.y؏)/ j\hv؞P4) 7 y{K(Us# UWC0 ЫpipY|0͵\% im v� L@E+P3<!_p XG_@ p `Mdm t } P`>|CT`:v P@ (U 7B#nBL1XN?1&�XP&4' s I g�E0 91*S,P0Ka vZ. vV(9-?__Zp <`x�S۝4 pg' �Υ 2PZ.sa � :~rp C!fuPPMB>L�c@ % ~~뷐^L+ݠ5NE`�' pCU�[ g3SZVn'~݌K7`"TdIy T U5_@ A`)}࣯6 \@p  7aK0 C* P (85$b /C y)o+/ qp7cP1A/+T=6bA Qp[# eDד)C 噇s yW/ 3: <19R$-`u0_�TY)_`i�D� f]Vpi``0PDJs?}ΰ(oaK+MP. -bp*@`ALFk2q�*ί }dS  ZഔPL0D\- >ϋd vZQ (9Fp@Port�Q1g,Be >1bpHt <~`%N(qY4\|LS0.|#$^Eԋ#rGk&\GQ\L\4kϞ_yQّ m/aKW#q;v2uf|gN*x F  ƍ3F@dj62eѬ_&gdj 9k@Dh8LUU4hRcotz=:'խM2EH:OH$2c(2gNW()c H" (@j NQ/?s`p eC'p3X7R-W\11-#VJ$1o,4,9~,f*< ) S!k4h0-Mq"~ .OJ"d>dM7d!=Sd(H 4 )-aG,H!b=P -$`)4W_5VX)9'5HxR~6Xa]NRB`;Z6Zi6tpSPB bx;4!\s==Ȅ $!J aaA?# M!B2` R:z!XL*5J #G&dSG(3O<)?9A0d % !S>YjR H Q;1&aGZ�ittE[e0QZIŔA"l>;HO IGG\jaS|y{Hf` s#K2)F(BD*y$ s3,;BHQG A$U3Z! &Dպ3<DF0te(O2mHEK ΧTXm$᧻`�k)i% V8@ÀHDC K_|�@VЂ\ G5JHE(Jd0 A!!+dȊʐnL & ( J$bNO$hEL fDq ԃd<!lHA@ p3`A-^x`. ; ^1U~* xdAxHO E e!,A(E9Pa`)aOT ? Rr($!9PbBj BA.kJ]T� X |2dq@/I*0acJa+Q0t (D%& a,1 $=M("W=I H�y-R`+Q D2T"=�6|HGJ<< Rԧ?}i(bz}/'.ЀsQ@uP� Sa թOTj N ֧ +$`3hE^' \0͎~p�*h(QX]t՞�Hj]s6 X0;*pDk] Gv@D t!um"7Pc)Y-V#hr]:%[i\DensGڪӕpw2w#@\Yź B~*PjU#]žjVgq!`j /nYwuOQ-1@-lS'FqyG롔EtcX=7R㸪>FeƊ,ǘՈTxHp6HU|Iidlr7DU fWWڈ1ZI<=Jwǀ!o0:(-NNẇ.4,][?ӧ^,Q5ѦF<8mh 'ҘsaC֩&Pjxz4"C-B!4yjPZЧų\[#[ۢrm5a0sEUnYԴͶykzڷn3ɷ͜o=;Av8}r^]&ns\(�yA;8xRQ"5>sW!yus?zЅ>tGGzҕt7Ozԥ>uWWzֵ�! d���,����"0��H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴS*TXP"Hi `BXXDس::�, 4`ٻ`=.!/ p`z{B @tجAAB勡/Rز220[)j!C *sf4H�y Olgۻ@._^o·nBK`gxo_ʗi\VczFim@0BAD@Y( LA Fm!s5Lip+ɰm-㑇 \ q0,A!Pf \v٥ @ �]~Y9&Nf $gL@d8fġ^ĢģO$H64A EtG'4 PrCl1#Fj+;kWF�8Z$l`ف�|묱@%B @ɳĀ0@%8+ܘE$ >`K] S{l0#dt*qЫ*j8`@ e:|* (r W ,%2\ #3AB"E|8ADRMPG"?Tmu5{zKHCo>hv7 @p~DAx}>W`0)X,O,15 IZhl2 *Z$Q(w9aC97β]pT,!&|2AN*8@W`;/.BtQvt=#ϰ}@ާ\EEW8p"�azߐ}<~j @K=aD3Gp`/#*cD3ȫF!#d@,�pm` @l*r ^80 z`t%P%3$0D@�Q0 (xwS*Xf @sF$�#"K&Ё'.Z9D,vT@VC\LAtąpMbUdB0.@@H�0ѥp"` h&2DH Ft pB8e�^(T )Ul<k A `3n9K@;,`*yCl�F 200\" ü@LJ\&CH �, BL=:Ń\ "h� s%Nz O "HEpbNZC\s)+F � �k*CT^H@.@v6��1/<U A0(x! @Щ  ĺ' tb%-Jʤpz:& CvF3"EDA!`A,q]9b� 2֞K L�ȬV2~ye4@ 45]xE0ժj#|!M6m~E`3'T"&Ձg�]8 < ` p�L�NV\r d(C�*h;�` *s>B &(X V7  t�RYmu'R!Enl ӈyEؖy JJ�S:�+X&P�*[H�*q/9(Uki|3? P JB: Sc c˳BXX^xEbr- DЀ- `(^ N @~Yď빗`aZArCH`�^92(dG6 p@0a $[ 5@ p%pҵtH }b !ʁ-rz"A˚\�@J< 0Bz&�緗Cȸ3^b5uM[uV\lNn�p9# +5sF�K:Kޢk. w"t �wͫ@$Fz~|!H:# E Sú dd3�p=6� ŵ Bg{ Idz9+| U0zl",Kdk%g * / P/pQltɀn] ]H|毸t (|A\Dlh!�1.}0�<z�}F{x2H?uDa%zzL{)[R ljd�p1|5?}Ad7"�PBp .=XEsNns%B0=AEZ &pp/@sp;qlD@0�O>st �Q8�� X% :t*v;`Tpdu 4q^=X8�Z>G�W 8@K�5=tR" tpa."/P[wlq/"NmP0vxы&*E p*RmjtKuπ*pLXX^5<�wP.}�ζ 2=5=.�2-oS@/`Td/`[N " `0֋ !UTT`�[p*vVh  (:9@.1"#4* 0D`ѱbLXw' � T�70`910d9 �3Lcc Pdi Pg ae@ 0 / ` `gymo0 GR C/I#K5)*Vw��^<P{](:I�PB;EЛY ``� ]?�X3t `a^ҹU9/]@vg)/B#^@ ҞY0e0y?*br�P2@Vu  uU:2 @֙6FԲ�9BWPu)F .*,2P# 'P6z8sE*z>*0DZC mÅ4 FZ0R:0I4*�ځ (e �j�(]$+Par:qZ � `<6'16�P@<c1 Dyᓎ� #p<gy%<m˄4"6%&݃%#b=i�b@%0Q"3` !�ʺЬЊ~Oڬ ѬԺܺƺvڭtE %r0Zڮzگ�;[{ ۰;[{�! d��,����"0������� �����1�ZJJ)���9�����R�����J���A���j��� RZ�9�)1�s�b�9A��bRR��1�s ��Ճ R�AA19ZZsbAA))b�s{ޔ)js sbb{JJޜRR1j{ Ŵ))99s�Z� )��{{j�sjjbZZJ)1�RZZ Ŕ j{{99)1{{��99 1ŽA�j11 ��11Z ) RR{�b{� )jj99)1ދ�RJJJJZZJ�լ{99{�JJs�{))))���bZRR �jj欬jj)) jj 1��s{ss j)){99jbb��{{A ZJR)�jJJs ս�Zb��)�� ޽� )Ճ{{11bRZ ��sZZbJJ��9���R���99{���J��j��)RA��s���� H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIMr*RgΟ8hX3abC&-L醫PIMYiWӞ]۳LHյi:E�ձdͲ< s_{P)ؽx[hjԸ Zc6 R!֥7H<ְ 1ݢM>ףCg`<94&^-yCxhû;1ߝ:p~W]P~}'  P௉]iOPWH7P4`7l@'n"K`7& ('AB1ʃD؉#ƨ8J' f D&*(K7 ; #bz.(Pv#h |1l)K.PCHȘi|Y:Hn>t@8£"j41!B:$#À"ģ~D:JwQ�~k@>ꡑ% 8骹*j#I0B *;*B2!)/O@G0`Xj:+ A/R |*  $Pt(,K$ bBH' L>�r$(覲 4AЛ/ t$ZZD-MOG/;H4ǀ�oG$OAM4e633CKQ8`FЊ/-GPB/5<uER L�GoPF ~L҆jm ㆾa1B�y)y1("~|� !L@F _f@BDdTOG-X?谂 \p8[ PlCpQ0G2~* w;⃹/96 8gT` E/ZA<pDA*齣|!�w,V X *c " .>(UpPk\01qBȢ]; 1 *A6x@( dT`G>b]3%5P*Zh򕰜T�_a _~;&Dx9J }^,/x? ma$j՛.P3ܟ rq   Rq`s?E~QsPMD0�3 =v2ub @QP%,hFSqcG rF0$`2x\ G8 8-ZK,@oB2: YXxZ�Ř�(LͪV*"` OsNʢbb@?�,XzXj#ڈصx 6AQ=2䀮]aE@B9Uy'8! $C#YR[ $ e=4 �6 HA UF KF! npAc B& 1 7 0&^�Yr'Z@zAD((G3 y=!FrHfk堀�p |Hp jB HAo%C&w Ae̠Ÿ/kC0g <$4TP=,Ā@vlaB@r$Hؔ%!` ^A`ߙ*{|\LxnC : 10aށ`L B ʈ4܂ F0&;Dzb�W¼kB)\ B_tb 5%FMjR+C1 $8}E +Df\I8xxvЃbh"x!/>Aj[D d �!_t y @` R@B`_)z@'l2 A5_rhE4qF7 ՋC| `p]8T Ђ`i68p B~ r"@}N:d�#}@a`S)&LmGP]hO{bn @ b 4lS(mnv,c 0x6ipq6�<kЀ 4bG/L5h0�Nhj 0Ehrc!Dnp>RJBI~qK_*xAC+@~[H.d~A]c]! Dmz<v v[ns0_p xU l.Fyx_ (_ xYE 1veS0AFd@ O8aDYg=Vyo8Zpy6~W~w~8'KDPptdl9 /rN@b+hUUua(:&d #d}q0}_p@P W`&؄x~~pt:E @tpuWO`I9�vbw FUi�uK`0rP<-byc_pkP0VI?@F bw@$O]`FE@LS�`"�@ecD(vŠ xM(MhS�RHPt Z{PUAC�Kx *%Wi `\pJ�9 :v`X_Pp` {؇�7PWb~~X Uε(@a8pTN+ 4pYFrFIQ[p0F?hs�N CYF|cW@q{bP`@V PE 3� zFF�ye `3P? @~ų u'8V~OS�f`{ � %|y ًF9_D|uH )^PƉ ȉ w TPWz@afP :9[i $pP 虞0`F�rs/f7N 繞p�s �%9 @6visY QrWo'vsW7?y�Т.*O2I'R7 o_Ƨn_Yk_TWЋV:0 E0 wБ ;L7 *u ҉f7Z(V4p *Н[0 G0PzENi?06�ph)z0#p�y�d YcG~I @ 5gg 7ŊP=7Z�C 0 ~ gGڬz*@ " (VIN_"kpiS EP7PU_{0p9g_`Pנ^ڢFPF  )ˉ \ QRrj~a{i0P `в..O@-+0J^R*벨 d(&{P~{ oˊ>�̀y֗A7&*Zh3l۶n@�*)apa |_{ SRE@ W _08wFv_xp i%ڥ; u JOpbq9 g*|JY O84.=J�Ű`PF.� J V�MR  + Zxp ?a۵ <,pp[uO,KEP_KkڠF__oPP{�woW *"\�G00�56c"a G  -<@1 ya`H�b{ K` 96dj.+AHb]: I PN{ˆЖPzi^+@yyYJ: | ɞ` `l\qzp# ڐC0 5 &xťpixj e܀0 Iw؜|M~)uIH` P%!, b^J�Y!= `/-&R lU "J]B&] ;:LˆbrPP@ u |?q@&ſ&(#Jz8MzɠuaP4 zd[h�  _@ @ 0i }`1Gjoݼ ) g�Xq<4� MםBJ @`�CS.y؏)/ j\hv؞P4) 7 y{K(Us# UWC0 ЫpipY|0͵\% im v� L@E+P3<!_p XG_@ p `Mdm t } P`>|CT`:v P@ (U 7B#nBL1XN?1&�XP&4' s I g�E0 91*S,P0Ka vZ. vV(9-?__Zp <`x�S۝4 pg' �Υ 2PZ.sa � :~rp C!fuPPMB>L�c@ % ~~뷐^L+ݠ5NE`�' pCU�[ g3SZVn'~݌K7`"TdIy T U5_@ A`)}࣯6 \@p  7aK0 C* P (85$b /C y)o+/ qp7cP1A/+T=6bA Qp[# eDד)C 噇s yW/ 3: <19R$-`u0_�TY)_`i�D� f]Vpi``0PDJs?}ΰ(oaK+MP. -bp*@`ALFk2q�*ί }dS  ZഔPL0D\- >ϋd vZQ (9Fp@Port�Q1g,Be >1bpHt <~`%N(qY4\|LS0.|#$^Eԋ#rGk&\GQ\L\4kϞ_yQّ m/aKW#q;v2uf|gN*x F  ƍ3F@dj62eѬ_&gdj 9k@Dh8LUU4hRcotz=:'խM2EH:OH$2c(2gNW()c H" (@j NQ/?s`p eC'p3X7R-W\11-#VJ$1o,4,9~,f*< ) S!k4h0-Mq"~ .OJ"d>dM7d!=Sd(H 4 )-aG,H!b=P -$`)4W_5VX)9'5HxR~6Xa]NRB`;Z6Zi6tpSPB bx;4!\s==Ȅ $!J aaA?# M!B2` R:z!XL*5J #G&dSG(3O<)?9A0d % !S>YjR H Q;1&aGZ�ittE[e0QZIŔA"l>;HO IGG\jaS|y{Hf` s#K2)F(BD*y$ s3,;BHQG A$U3Z! &Dպ3<DF0te(O2mHEK ΧTXm$᧻`�k)i% V8@ÀHDC K_|�@VЂ\ G5JHE(Jd0 A!!+dȊʐnL & ( J$bNO$hEL fDq ԃd<!lHA@ p3`A-^x`. ; ^1U~* xdAxHO E e!,A(E9Pa`)aOT ? Rr($!9PbBj BA.kJ]T� X |2dq@/I*0acJa+Q0t (D%& a,1 $=M("W=I H�y-R`+Q D2T"=�6|HGJ<< Rԧ?}i(bz}/'.ЀsQ@uP� Sa թOTj N ֧ +$`3hE^' \0͎~p�*h(QX]t՞�Hj]s6 X0;*pDk] Gv@D t!um"7Pc)Y-V#hr]:%[i\DensGڪӕpw2w#@\Yź B~*PjU#]žjVgq!`j /nYwuOQ-1@-lS'FqyG롔EtcX=7R㸪>FeƊ,ǘՈTxHp6HU|Iidlr7DU fWWڈ1ZI<=Jwǀ!o0:(-NNẇ.4,][?ӧ^,Q5ѦF<8mh 'ҘsaC֩&Pjxz4"C-B!4yjPZЧų\[#[ۢrm5a0sEUnYԴͶykzڷn3ɷ͜o=;Av8}r^]&ns\(�yA;8xRQ"5>sW!yus?zЅ>tGGzҕt7Ozԥ>uWWzֵ�! d���,����"0��H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴS*TXP"Hi `BXXDس::�, 4`ٻ`=.!/ p`z{B @tجAAB勡/Rز220[)j!C *sf4H�y Olgۻ@._^o·nBK`gxo_ʗi\VczFim@0BAD@Y( LA Fm!s5Lip+ɰm-㑇 \ q0,A!Pf \v٥ @ �]~Y9&Nf $gL@d8fġ^ĢģO$H64A EtG'4 PrCl1#Fj+;kWF�8Z$l`ف�|묱@%B @ɳĀ0@%8+ܘE$ >`K] S{l0#dt*qЫ*j8`@ e:|* (r W ,%2\ #3AB"E|8ADRMPG"?Tmu5{zKHCo>hv7 @p~DAx}>W`0)X,O,15 IZhl2 *Z$Q(w9aC97β]pT,!&|2AN*8@W`;/.BtQvt=#ϰ}@ާ\EEW8p"�azߐ}<~j @K=aD3Gp`/#*cD3ȫF!#d@,�pm` @l*r ^80 z`t%P%3$0D@�Q0 (xwS*Xf @sF$�#"K&Ё'.Z9D,vT@VC\LAtąpMbUdB0.@@H�0ѥp"` h&2DH Ft pB8e�^(T )Ul<k A `3n9K@;,`*yCl�F 200\" ü@LJ\&CH �, BL=:Ń\ "h� s%Nz O "HEpbNZC\s)+F � �k*CT^H@.@v6��1/<U A0(x! @Щ  ĺ' tb%-Jʤpz:& CvF3"EDA!`A,q]9b� 2֞K L�ȬV2~ye4@ 45]xE0ժj#|!M6m~E`3'T"&Ձg�]8 < ` p�L�NV\r d(C�*h;�` *s>B &(X V7  t�RYmu'R!Enl ӈyEؖy JJ�S:�+X&P�*[H�*q/9(Uki|3? P JB: Sc c˳BXX^xEbr- DЀ- `(^ N @~Yď빗`aZArCH`�^92(dG6 p@0a $[ 5@ p%pҵtH }b !ʁ-rz"A˚\�@J< 0Bz&�緗Cȸ3^b5uM[uV\lNn�p9# +5sF�K:Kޢk. w"t �wͫ@$Fz~|!H:# E Sú dd3�p=6� ŵ Bg{ Idz9+| U0zl",Kdk%g * / P/pQltɀn] ]H|毸t (|A\Dlh!�1.}0�<z�}F{x2H?uDa%zzL{)[R ljd�p1|5?}Ad7"�PBp .=XEsNns%B0=AEZ &pp/@sp;qlD@0�O>st �Q8�� X% :t*v;`Tpdu 4q^=X8�Z>G�W 8@K�5=tR" tpa."/P[wlq/"NmP0vxы&*E p*RmjtKuπ*pLXX^5<�wP.}�ζ 2=5=.�2-oS@/`Td/`[N " `0֋ !UTT`�[p*vVh  (:9@.1"#4* 0D`ѱbLXw' � T�70`910d9 �3Lcc Pdi Pg ae@ 0 / ` `gymo0 GR C/I#K5)*Vw��^<P{](:I�PB;EЛY ``� ]?�X3t `a^ҹU9/]@vg)/B#^@ ҞY0e0y?*br�P2@Vu  uU:2 @֙6FԲ�9BWPu)F .*,2P# 'P6z8sE*z>*0DZC mÅ4 FZ0R:0I4*�ځ (e �j�(]$+Par:qZ � `<6'16�P@<c1 Dyᓎ� #p<gy%<m˄4"6%&݃%#b=i�b@%0Q"3` !�ʺЬЊ~Oڬ ѬԺܺƺvڭtE %r0Zڮzگ�;[{ ۰;[{�! d��,����"0������� �����1�ZJJ)���9�����R�����J���A���j��� RZ�9�)1�s�b�9A��bRR��1�s ��Ճ R�AA19ZZsbAA))b�s{ޔ)js sbb{JJޜRR1j{ Ŵ))99s�Z� )��{{j�sjjbZZJ)1�RZZ Ŕ j{{99)1{{��99 1ŽA�j11 ��11Z ) RR{�b{� )jj99)1ދ�RJJJJZZJ�լ{99{�JJs�{))))���bZRR �jj欬jj)) jj 1��s{ss j)){99jbb��{{A ZJR)�jJJs ս�Zb��)�� ޽� )Ճ{{11bRZ ��sZZbJJ��9���R���99{���J��j��)RA��s���� H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIMr*RgΟ8hX3abC&-L醫PIMYiWӞ]۳LHյi:E�ձdͲ< s_{P)ؽx[hjԸ Zc6 R!֥7H<ְ 1ݢM>ףCg`<94&^-yCxhû;1ߝ:p~W]P~}'  P௉]iOPWH7P4`7l@'n"K`7& ('AB1ʃD؉#ƨ8J' f D&*(K7 ; #bz.(Pv#h |1l)K.PCHȘi|Y:Hn>t@8£"j41!B:$#À"ģ~D:JwQ�~k@>ꡑ% 8骹*j#I0B *;*B2!)/O@G0`Xj:+ A/R |*  $Pt(,K$ bBH' L>�r$(覲 4AЛ/ t$ZZD-MOG/;H4ǀ�oG$OAM4e633CKQ8`FЊ/-GPB/5<uER L�GoPF ~L҆jm ㆾa1B�y)y1("~|� !L@F _f@BDdTOG-X?谂 \p8[ PlCpQ0G2~* w;⃹/96 8gT` E/ZA<pDA*齣|!�w,V X *c " .>(UpPk\01qBȢ]; 1 *A6x@( dT`G>b]3%5P*Zh򕰜T�_a _~;&Dx9J }^,/x? ma$j՛.P3ܟ rq   Rq`s?E~QsPMD0�3 =v2ub @QP%,hFSqcG rF0$`2x\ G8 8-ZK,@oB2: YXxZ�Ř�(LͪV*"` OsNʢbb@?�,XzXj#ڈصx 6AQ=2䀮]aE@B9Uy'8! $C#YR[ $ e=4 �6 HA UF KF! npAc B& 1 7 0&^�Yr'Z@zAD((G3 y=!FrHfk堀�p |Hp jB HAo%C&w Ae̠Ÿ/kC0g <$4TP=,Ā@vlaB@r$Hؔ%!` ^A`ߙ*{|\LxnC : 10aށ`L B ʈ4܂ F0&;Dzb�W¼kB)\ B_tb 5%FMjR+C1 $8}E +Df\I8xxvЃbh"x!/>Aj[D d �!_t y @` R@B`_)z@'l2 A5_rhE4qF7 ՋC| `p]8T Ђ`i68p B~ r"@}N:d�#}@a`S)&LmGP]hO{bn @ b 4lS(mnv,c 0x6ipq6�<kЀ 4bG/L5h0�Nhj 0Ehrc!Dnp>RJBI~qK_*xAC+@~[H.d~A]c]! Dmz<v v[ns0_p xU l.Fyx_ (_ xYE 1veS0AFd@ O8aDYg=Vyo8Zpy6~W~w~8'KDPptdl9 /rN@b+hUUua(:&d #d}q0}_p@P W`&؄x~~pt:E @tpuWO`I9�vbw FUi�uK`0rP<-byc_pkP0VI?@F bw@$O]`FE@LS�`"�@ecD(vŠ xM(MhS�RHPt Z{PUAC�Kx *%Wi `\pJ�9 :v`X_Pp` {؇�7PWb~~X Uε(@a8pTN+ 4pYFrFIQ[p0F?hs�N CYF|cW@q{bP`@V PE 3� zFF�ye `3P? @~ų u'8V~OS�f`{ � %|y ًF9_D|uH )^PƉ ȉ w TPWz@afP :9[i $pP 虞0`F�rs/f7N 繞p�s �%9 @6visY QrWo'vsW7?y�Т.*O2I'R7 o_Ƨn_Yk_TWЋV:0 E0 wБ ;L7 *u ҉f7Z(V4p *Н[0 G0PzENi?06�ph)z0#p�y�d YcG~I @ 5gg 7ŊP=7Z�C 0 ~ gGڬz*@ " (VIN_"kpiS EP7PU_{0p9g_`Pנ^ڢFPF  )ˉ \ QRrj~a{i0P `в..O@-+0J^R*벨 d(&{P~{ oˊ>�̀y֗A7&*Zh3l۶n@�*)apa |_{ SRE@ W _08wFv_xp i%ڥ; u JOpbq9 g*|JY O84.=J�Ű`PF.� J V�MR  + Zxp ?a۵ <,pp[uO,KEP_KkڠF__oPP{�woW *"\�G00�56c"a G  -<@1 ya`H�b{ K` 96dj.+AHb]: I PN{ˆЖPzi^+@yyYJ: | ɞ` `l\qzp# ڐC0 5 &xťpixj e܀0 Iw؜|M~)uIH` P%!, b^J�Y!= `/-&R lU "J]B&] ;:LˆbrPP@ u |?q@&ſ&(#Jz8MzɠuaP4 zd[h�  _@ @ 0i }`1Gjoݼ ) g�Xq<4� MםBJ @`�CS.y؏)/ j\hv؞P4) 7 y{K(Us# UWC0 ЫpipY|0͵\% im v� L@E+P3<!_p XG_@ p `Mdm t } P`>|CT`:v P@ (U 7B#nBL1XN?1&�XP&4' s I g�E0 91*S,P0Ka vZ. vV(9-?__Zp <`x�S۝4 pg' �Υ 2PZ.sa � :~rp C!fuPPMB>L�c@ % ~~뷐^L+ݠ5NE`�' pCU�[ g3SZVn'~݌K7`"TdIy T U5_@ A`)}࣯6 \@p  7aK0 C* P (85$b /C y)o+/ qp7cP1A/+T=6bA Qp[# eDד)C 噇s yW/ 3: <19R$-`u0_�TY)_`i�D� f]Vpi``0PDJs?}ΰ(oaK+MP. -bp*@`ALFk2q�*ί }dS  ZഔPL0D\- >ϋd vZQ (9Fp@Port�Q1g,Be >1bpHt <~`%N(qY4\|LS0.|#$^Eԋ#rGk&\GQ\L\4kϞ_yQّ m/aKW#q;v2uf|gN*x F  ƍ3F@dj62eѬ_&gdj 9k@Dh8LUU4hRcotz=:'խM2EH:OH$2c(2gNW()c H" (@j NQ/?s`p eC'p3X7R-W\11-#VJ$1o,4,9~,f*< ) S!k4h0-Mq"~ .OJ"d>dM7d!=Sd(H 4 )-aG,H!b=P -$`)4W_5VX)9'5HxR~6Xa]NRB`;Z6Zi6tpSPB bx;4!\s==Ȅ $!J aaA?# M!B2` R:z!XL*5J #G&dSG(3O<)?9A0d % !S>YjR H Q;1&aGZ�ittE[e0QZIŔA"l>;HO IGG\jaS|y{Hf` s#K2)F(BD*y$ s3,;BHQG A$U3Z! &Dպ3<DF0te(O2mHEK ΧTXm$᧻`�k)i% V8@ÀHDC K_|�@VЂ\ G5JHE(Jd0 A!!+dȊʐnL & ( J$bNO$hEL fDq ԃd<!lHA@ p3`A-^x`. ; ^1U~* xdAxHO E e!,A(E9Pa`)aOT ? Rr($!9PbBj BA.kJ]T� X |2dq@/I*0acJa+Q0t (D%& a,1 $=M("W=I H�y-R`+Q D2T"=�6|HGJ<< Rԧ?}i(bz}/'.ЀsQ@uP� Sa թOTj N ֧ +$`3hE^' \0͎~p�*h(QX]t՞�Hj]s6 X0;*pDk] Gv@D t!um"7Pc)Y-V#hr]:%[i\DensGڪӕpw2w#@\Yź B~*PjU#]žjVgq!`j /nYwuOQ-1@-lS'FqyG롔EtcX=7R㸪>FeƊ,ǘՈTxHp6HU|Iidlr7DU fWWڈ1ZI<=Jwǀ!o0:(-NNẇ.4,][?ӧ^,Q5ѦF<8mh 'ҘsaC֩&Pjxz4"C-B!4yjPZЧų\[#[ۢrm5a0sEUnYԴͶykzڷn3ɷ͜o=;Av8}r^]&ns\(�yA;8xRQ"5>sW!yus?zЅ>tGGzҕt7Ozԥ>uWWzֵ�!This animated GIF is created by Fairy Suryana http://members.aol.com/BeatFacto/ http://www.dewa.com/ Fairy Suryana DJ paling jago se dunia!!!!!!�! GIFCONnb1.0� ����������� new-6.gif� ����������� New-5.gif� �� ��������� new-6.gif� �� ��������� New-5.gif� �� ��������� new-6.gif��;��������������������������������giflib-6.1.3/pic/NOTES������������������������������������������������������������������������������0000664�0001750�0001750�00000000442�15166751647�012533� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Gershon wrote: Only one of the images on .\pic was actually generated by me - solid2.gif, which is binary image rendered using a solid modeller I have developed named IRIT. The other two were released to usenet few month ago. I do not think so, but let me know if I violate anything here. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������giflib-6.1.3/gifhisto.c�����������������������������������������������������������������������������0000664�0001750�0001750�00000021121�15166751647�013122� 0����������������������������������������������������������������������������������������������������ustar �esr�����������������������������esr��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** gifhisto - make a color histogram from image color frequencies *****************************************************************************/ // SPDX-License-Identifier: MIT // SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber #include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "getarg.h" #include "gif_lib.h" #define PROGRAM_NAME "gifhisto" #define DEFAULT_HISTO_WIDTH 100 /* Histogram image diemnsions. */ #define DEFAULT_HISTO_HEIGHT 256 #define HISTO_BITS_PER_PIXEL 2 /* Size of bitmap for histogram GIF. */ static char *VerStr = PROGRAM_NAME VERSION_COOKIE __DATE__ ", " __TIME__ "\n"; static char *CtrlStr = PROGRAM_NAME " v%- t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s"; static int ImageWidth = DEFAULT_HISTO_WIDTH, ImageHeight = DEFAULT_HISTO_HEIGHT, ImageN = 1; static GifColorType HistoColorMap[] = {/* Constant bit map for histograms: */ {0, 0, 0}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}}; static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); /****************************************************************************** Interpret the command line and scan the given GIF file. ******************************************************************************/ int main(int argc, char **argv) { int i, j, ErrorCode, NumFiles, ExtCode, CodeSize, NumColors = 2, ImageNum = 0; bool Error, TextFlag = false, SizeFlag = false, ImageNFlag = false, BackGroundFlag = false, HelpFlag = false, GifNoisyPrint; long Histogram[256]; GifRecordType RecordType; GifByteType *Extension, *CodeBlock; char **FileName = NULL; GifRowType Line; GifFileType *GifFileIn = NULL, *GifFileOut = NULL; /* Same image dimension vars for both Image & ImageN as only one allowed */ if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &TextFlag, &SizeFlag, &ImageWidth, &ImageHeight, &ImageNFlag, &ImageN, &BackGroundFlag, &HelpFlag, &NumFiles, &FileName)) != false || (NumFiles > 1 && !HelpFlag)) { if (Error) { GAPrintErrMsg(Error); } else if (NumFiles > 1) { GIF_MESSAGE("Error in command line parsing - one GIF " "file please."); } GAPrintHowTo(CtrlStr); exit(EXIT_FAILURE); } if (HelpFlag) { (void)fprintf(stderr, VerStr, GIFLIB_MAJOR, GIFLIB_MINOR); GAPrintHowTo(CtrlStr); exit(EXIT_SUCCESS); } if (NumFiles == 1) { if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } else { /* Use stdin instead: */ if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } for (i = 0; i < 256; i++) { Histogram[i] = 0; /* Reset counters. */ } /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } if (GifFileIn->Image.ColorMap) { NumColors = GifFileIn->Image.ColorMap->ColorCount; } else if (GifFileIn->SColorMap) { NumColors = GifFileIn->SColorMap->ColorCount; } else { GIF_EXIT("Neither Screen nor Image color map " "exists."); } if ((ImageHeight / NumColors) * NumColors != ImageHeight) { GIF_EXIT("Image height specified not dividable " "by #colors."); } if (++ImageNum == ImageN) { /* This is the image we should make histogram * for: */ Line = (GifRowType)malloc(GifFileIn->Image.Width * sizeof(GifPixelType)); GifQprintf( "\n%s: Image %d at (%d, %d) [%dx%d]: ", PROGRAM_NAME, ImageNum, GifFileIn->Image.Left, GifFileIn->Image.Top, GifFileIn->Image.Width, GifFileIn->Image.Height); for (i = 0; i < GifFileIn->Image.Height; i++) { if (DGifGetLine( GifFileIn, Line, GifFileIn->Image.Width) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } for (j = 0; j < GifFileIn->Image.Width; j++) { Histogram[Line[j]]++; } GifQprintf("\b\b\b\b%-4d", i); } free((char *)Line); } else { /* Skip the image: */ /* Now read image itself in decoded form as we * dont */ /* really care what is there, and this is much * faster. */ if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } while (CodeBlock != NULL) { if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } while (Extension != NULL) { if (DGifGetExtensionNext( GifFileIn, &Extension) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* We requested suppression of the background count: */ if (BackGroundFlag) { Histogram[GifFileIn->SBackGroundColor] = 0; } if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* We may required to dump out the histogram as text file: */ if (TextFlag) { for (i = 0; i < NumColors; i++) { printf("%12ld %3d\n", Histogram[i], i); } } else { int Color, Count; long Scaler; /* Open stdout for the histogram output file: */ if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } /* Dump out screen descriptor to fit histogram dimensions: */ if (EGifPutScreenDesc(GifFileOut, ImageWidth, ImageHeight, HISTO_BITS_PER_PIXEL, 0, GifMakeMapObject(4, HistoColorMap)) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Dump out image descriptor to fit histogram dimensions: */ if (EGifPutImageDesc(GifFileOut, 0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } /* Prepare scan line for histogram file, and find scaler to * scale */ /* histogram to be between 0 and ImageWidth: */ Line = (GifRowType)malloc(ImageWidth * sizeof(GifPixelType)); for (Scaler = 0, i = 0; i < NumColors; i++) { if (Histogram[i] > Scaler) { Scaler = Histogram[i]; } } Scaler /= ImageWidth; if (Scaler == 0) { Scaler = 1; /* In case maximum is less than width. */ } /* Dump out the image itself: */ for (Count = ImageHeight, i = 0, Color = 1; i < NumColors; i++) { int Size; if ((Size = Histogram[i] / Scaler) > ImageWidth) { Size = ImageWidth; } for (j = 0; j < Size; j++) { Line[j] = Color; } for (j = Size; j < ImageWidth; j++) { Line[j] = GifFileOut->SBackGroundColor; } /* Move to next color: */ if (++Color >= (1 << HISTO_BITS_PER_PIXEL)) { Color = 1; } /* Dump this histogram entry as many times as required: */ for (j = 0; j < ImageHeight / NumColors; j++) { if (EGifPutLine(GifFileOut, Line, ImageWidth) == GIF_ERROR) { QuitGifError(GifFileIn, GifFileOut); } GifQprintf("\b\b\b\b%-4d", Count--); } } if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { PrintGifError(ErrorCode); exit(EXIT_FAILURE); } } return 0; } /****************************************************************************** Close both input and output file (if open), and exit. ******************************************************************************/ static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) { if (GifFileIn != NULL) { PrintGifError(GifFileIn->Error); EGifCloseFile(GifFileIn, NULL); } if (GifFileOut != NULL) { PrintGifError(GifFileOut->Error); EGifCloseFile(GifFileOut, NULL); } exit(EXIT_FAILURE); } /* end */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������