diff -Nru giflib-5.2.1/Makefile giflib-5.2.2/Makefile --- giflib-5.2.1/Makefile 2019-06-24 16:08:57.000000000 +0000 +++ giflib-5.2.2/Makefile 2024-02-19 01:01:50.000000000 +0000 @@ -37,6 +37,8 @@ UHEADERS = getarg.h UOBJECTS = $(USOURCES:.c=.o) +UNAME:=$(shell uname) + # Some utilities are installed INSTALLABLE = \ gif2rgb \ @@ -61,35 +63,78 @@ LDLIBS=libgif.a -lm -all: libgif.so libgif.a libutil.so libutil.a $(UTILS) +MANUAL_PAGES = \ + doc/gif2rgb.xml \ + doc/gifbuild.xml \ + doc/gifclrmp.xml \ + doc/giffix.xml \ + doc/giflib.xml \ + doc/giftext.xml \ + doc/giftool.xml + +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 + +all: $(LIBGIFSO) libgif.a $(LIBUTILSO) libutil.a $(UTILS) +ifeq ($(UNAME), Darwin) +else $(MAKE) -C doc +endif $(UTILS):: libgif.a libutil.a -libgif.so: $(OBJECTS) $(HEADERS) - $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libgif.so.$(LIBMAJOR) -o libgif.so $(OBJECTS) +$(LIBGIFSO): $(OBJECTS) $(HEADERS) +ifeq ($(UNAME), Darwin) + $(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(OBJECTS) -o $(LIBGIFSO) +else + $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBGIFSOMAJOR) -o $(LIBGIFSO) $(OBJECTS) +endif libgif.a: $(OBJECTS) $(HEADERS) $(AR) rcs libgif.a $(OBJECTS) -libutil.so: $(UOBJECTS) $(UHEADERS) - $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libutil.so.$(LIBMAJOR) -o libutil.so $(UOBJECTS) +$(LIBUTILSO): $(UOBJECTS) $(UHEADERS) +ifeq ($(UNAME), Darwin) + $(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(OBJECTS) -o $(LIBUTILSO) +else + $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBUTILMAJOR) -o $(LIBUTILSO) $(UOBJECTS) +endif libutil.a: $(UOBJECTS) $(UHEADERS) $(AR) rcs libutil.a $(UOBJECTS) clean: - rm -f $(UTILS) $(TARGET) libgetarg.a libgif.a libgif.so libutil.a libutil.so *.o - rm -f libgif.so.$(LIBMAJOR).$(LIBMINOR).$(LIBPOINT) - rm -f libgif.so.$(LIBMAJOR) + rm -f $(UTILS) $(TARGET) libgetarg.a libgif.a $(LIBGIFSO) libutil.a $(LIBUTILSO) *.o + rm -f $(LIBGIFSOVER) + rm -f $(LIBGIFSOMAJOR) rm -fr doc/*.1 *.html doc/staging check: all $(MAKE) -C tests +reflow: + @clang-format --style="{IndentWidth: 8, UseTab: ForIndentation}" -i $$(find . -name "*.[ch]") + # Installation/uninstallation +ifeq ($(UNAME), Darwin) +install: all install-bin install-include install-lib +else install: all install-bin install-include install-lib install-man +endif + install-bin: $(INSTALLABLE) $(INSTALL) -d "$(DESTDIR)$(BINDIR)" $(INSTALL) $^ "$(DESTDIR)$(BINDIR)" @@ -99,12 +144,12 @@ install-lib: $(INSTALL) -d "$(DESTDIR)$(LIBDIR)" $(INSTALL) -m 644 libgif.a "$(DESTDIR)$(LIBDIR)/libgif.a" - $(INSTALL) -m 755 libgif.so "$(DESTDIR)$(LIBDIR)/libgif.so.$(LIBVER)" - ln -sf libgif.so.$(LIBVER) "$(DESTDIR)$(LIBDIR)/libgif.so.$(LIBMAJOR)" - ln -sf libgif.so.$(LIBMAJOR) "$(DESTDIR)$(LIBDIR)/libgif.so" + $(INSTALL) -m 755 $(LIBGIFSO) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOVER)" + ln -sf $(LIBGIFSOVER) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOMAJOR)" + ln -sf $(LIBGIFSOMAJOR) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSO)" install-man: $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" - $(INSTALL) -m 644 doc/*.1 "$(DESTDIR)$(MANDIR)/man1" + $(INSTALL) -m 644 $(MANUAL_PAGES) "$(DESTDIR)$(MANDIR)/man1" uninstall: uninstall-man uninstall-include uninstall-lib uninstall-bin uninstall-bin: cd "$(DESTDIR)$(BINDIR)" && rm -f $(INSTALLABLE) @@ -112,9 +157,10 @@ rm -f "$(DESTDIR)$(INCDIR)/gif_lib.h" uninstall-lib: cd "$(DESTDIR)$(LIBDIR)" && \ - rm -f libgif.a libgif.so libgif.so.$(LIBMAJOR) libgif.so.$(LIBVER) + 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) # Make distribution tarball # @@ -134,7 +180,7 @@ doc/gifstandard \ DSOURCES = Makefile *.[ch] -DOCS = doc/*.xml doc/*.1 doc/*.html doc/index.html.in doc/00README doc/Makefile +DOCS = doc/*.xml doc/*.1 doc/*.7 doc/*.html doc/index.html.in doc/00README doc/Makefile ALL = $(DSOURCES) $(DOCS) tests pic $(EXTRAS) giflib-$(VERSION).tar.gz: $(ALL) $(TAR) --transform='s:^:giflib-$(VERSION)/:' -czf giflib-$(VERSION).tar.gz $(ALL) @@ -151,7 +197,7 @@ # cppcheck should run clean cppcheck: - cppcheck --inline-suppr --template gcc --enable=all --suppress=unusedFunction --force *.[ch] + cppcheck --quiet --inline-suppr --template gcc --enable=all --suppress=unusedFunction --suppress=missingInclude --force *.[ch] # Verify the build distcheck: all diff -Nru giflib-5.2.1/NEWS giflib-5.2.2/NEWS --- giflib-5.2.1/NEWS 2019-06-24 16:14:17.000000000 +0000 +++ giflib-5.2.2/NEWS 2024-02-19 07:32:44.000000000 +0000 @@ -1,10 +1,72 @@ GIFLIB NEWS +Repository head +=============== + +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: [PATCH] Limit installed man pages to binaries, move giflib to section 7 + +* Address SF issue #147 [PATCH] 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 dome a release while imn surgical recovery" release. +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. @@ -20,7 +82,7 @@ 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-transformmation tools +error or have been obsolesced by modern image-transformation tools like ImageMagick convert. They may be removed entirely in a future release. @@ -44,7 +106,7 @@ Version 5.1.8 ============= -* Address SF bug #119: MemorySanitizer: FPE on unknown address +* 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 diff -Nru giflib-5.2.1/debian/changelog giflib-5.2.2/debian/changelog --- giflib-5.2.1/debian/changelog 2022-06-12 16:32:15.000000000 +0000 +++ giflib-5.2.2/debian/changelog 2024-04-05 08:31:09.000000000 +0000 @@ -1,3 +1,46 @@ +giflib (5.2.2-1ubuntu1) noble; urgency=medium + + * d/p/snprintf.patch: + - cherry pick a patch from Adam Sampson to fix incorrect length arg + to snprintf (LP:#2060282). + + -- Nathan Pratta Teodosio Fri, 05 Apr 2024 10:31:09 +0200 + +giflib (5.2.2-1) unstable; urgency=medium + + [ Debian Janitor] + * Update standards version to 4.6.1, no changes needed. + * Remove obsolete fields Contact, Name from debian/upstream/metadata + (already present in machine-readable debian/copyright). + * Use secure URI in Homepage field. + + [ Andreas Metzler ] + * debian/patches: + + Drop patches applied upstream (fix-get-args-segment-violation.patch + fix-spelling-errors-on-doc-pages.patch recover-giffilter-docs.patch + add-gifsponge-docs.patch) + + Drop superseded patch (install-only-distributed-binaries-manuals.patch). + + Unfuzzz patches + + Features fixes for CVE-2023-48161, CVE-2022-28506. + * Cherry-pick Correct-document-page-install.patch to install manpages + instead of xml source. + * Install giflib.7 manpage. + * Update symbol file (added DGifDecreaseImageCounter@Base). + * Cherry-pick Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch to + fix CVE-2021-40633. + * Add lintian overrides for html files built from xml (source-is-missing). + + [ David Suárez ] + * New upstream version; + Closes: #1024988, #988151, #1014586, #1045040, 1049653 + * Update email to debian domain. + * Wrap and sort. + * Add 'dont-build-html-pages-images' patch. + * Acknowledges NMU's uploads. + * Add 'salsa-ci.yml'. + + -- David Suárez Sun, 25 Feb 2024 17:44:51 +0000 + giflib (5.2.1-2.5) unstable; urgency=medium * Non-maintainer upload @@ -76,12 +119,7 @@ [ Andreas Metzler ] * AUTHORS file not shipped anymore, update debian/*.docs. * Uses straight make instead of autotools, adapt debian/rules accordingly. - - [ Debian Janitor ] - * Bump debhelper from old 10 to 12. - * Set debhelper-compat version in Build-Depends. - - [ Andreas Metzler ] + * Use dh 12 compat level. + Update debian/copyright, add Format specifier. [ David Suárez ] @@ -101,7 +139,7 @@ Applied upstream. - Add 'install-only-distributed-binaries-manuals' patch. - Add 'revert-GifQuantizeBuffer-remove-from-lib' patch. - * d/rules: + * d/rules - Don't force the rebuilding of manpages, the clean rule does the job. - Remove the txt docs from giflib-tools; Not distributed. - Remove 'dh_strip --dbgsym-migration'; Not needed anymore. diff -Nru giflib-5.2.1/debian/control giflib-5.2.2/debian/control --- giflib-5.2.1/debian/control 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/control 2024-04-05 08:31:09.000000000 +0000 @@ -1,10 +1,11 @@ Source: giflib Section: libs Priority: optional -Maintainer: David Suárez +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: David Suárez Build-Depends: debhelper-compat (= 13), xmlto -Standards-Version: 4.6.0 -Homepage: http://giflib.sourceforge.net/ +Standards-Version: 4.6.1 +Homepage: https://giflib.sourceforge.net/ Vcs-Git: https://salsa.debian.org/debian/giflib.git Vcs-Browser: https://salsa.debian.org/debian/giflib Rules-Requires-Root: no @@ -12,10 +13,9 @@ Package: giflib-tools Section: utils Architecture: any -Depends: - libperl4-corelibs-perl | perl (<< 5.12.3-7), - ${misc:Depends}, - ${shlibs:Depends} +Depends: libperl4-corelibs-perl | perl (<< 5.12.3-7), + ${misc:Depends}, + ${shlibs:Depends} Provides: libungif-bin Description: library for GIF images (utilities) GIFLIB is a package of portable tools and library routines for working with diff -Nru giflib-5.2.1/debian/copyright giflib-5.2.2/debian/copyright --- giflib-5.2.1/debian/copyright 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/copyright 2024-02-24 20:38:56.000000000 +0000 @@ -26,11 +26,7 @@ Files: debian/* Copyright: (C) 2006-2009 Daniel Baumann - (C) 2010 Thibaut GRIDEL - (C) 2019 David Suárez - (C) 2021-2022 Mattia Rizzolo - (C) 2021-2022 Vasyl Gello + 2019 David Suárez License: MIT License: MIT diff -Nru giflib-5.2.1/debian/gbp.conf giflib-5.2.2/debian/gbp.conf --- giflib-5.2.1/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/gbp.conf 2024-02-24 20:38:56.000000000 +0000 @@ -0,0 +1,10 @@ +[DEFAULT] +debian-branch = debian/latest +upstream-branch = upstream/latest +pristine-tar=True + +[buildpackage] +export-dir = ../build-area/ + +[import-orig] +filter=[ '.gitignore', '.travis.yml', '.git*' ] diff -Nru giflib-5.2.1/debian/giflib-dbg.docs giflib-5.2.2/debian/giflib-dbg.docs --- giflib-5.2.1/debian/giflib-dbg.docs 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/giflib-dbg.docs 2024-02-24 20:38:56.000000000 +0000 @@ -0,0 +1,2 @@ +NEWS +TODO diff -Nru giflib-5.2.1/debian/giflib-tools.manpages giflib-5.2.2/debian/giflib-tools.manpages --- giflib-5.2.1/debian/giflib-tools.manpages 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/giflib-tools.manpages 2024-02-24 20:38:56.000000000 +0000 @@ -1 +1,2 @@ usr/share/man/man1/*.1* +usr/share/man/man7/*.7* diff -Nru giflib-5.2.1/debian/libgif7.symbols giflib-5.2.2/debian/libgif7.symbols --- giflib-5.2.1/debian/libgif7.symbols 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/libgif7.symbols 2024-02-24 20:38:56.000000000 +0000 @@ -1,14 +1,15 @@ libgif.so.7 libgif7 #MINVER# * Build-Depends-Package: libgif-dev DGifCloseFile@Base 5.1 + DGifDecreaseImageCounter@Base 5.2.2 DGifExtensionToGCB@Base 5.1 DGifGetCode@Base 5.1 DGifGetCodeNext@Base 5.1 DGifGetExtension@Base 5.1 DGifGetExtensionNext@Base 5.1 - DGifGetGifVersion@Base 5.1.7 + DGifGetGifVersion@Base 5.1.9 DGifGetImageDesc@Base 5.1 - DGifGetImageHeader@Base 5.1.7 + DGifGetImageHeader@Base 5.1.9 DGifGetLZCodes@Base 5.1 DGifGetLine@Base 5.1 DGifGetPixel@Base 5.1 @@ -60,4 +61,4 @@ _ExistsHashTable@Base 5.1 _InitHashTable@Base 5.1 _InsertHashTable@Base 5.1 - openbsd_reallocarray@Base 5.1.7 + openbsd_reallocarray@Base 5.1.9 diff -Nru giflib-5.2.1/debian/patches/30_link_utils_dynamically.diff giflib-5.2.2/debian/patches/30_link_utils_dynamically.diff --- giflib-5.2.1/debian/patches/30_link_utils_dynamically.diff 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/30_link_utils_dynamically.diff 2024-02-24 20:38:56.000000000 +0000 @@ -2,65 +2,52 @@ Author: Andreas Metzler Origin: vendor Bug: https://sourceforge.net/p/giflib/bugs/123/ -Last-Update: 2019-03-17 +Last-Update: 2024-02-24 --- a/Makefile +++ b/Makefile -@@ -59,7 +59,7 @@ +@@ -59,11 +59,11 @@ UTILS = $(INSTALLABLE) \ + gifhisto \ + gifinto \ gifsponge \ gifwedge -LDLIBS=libgif.a -lm +LDLIBS=-lm - MANUAL_PAGES = \ - doc/gif2rgb.1 \ -@@ -77,16 +77,28 @@ - all: libgif.so libgif.a libutil.so libutil.a $(UTILS) + MANUAL_PAGES_1 = \ + doc/gif2rgb.xml \ + doc/gifbuild.xml \ + doc/gifclrmp.xml \ +@@ -95,19 +95,22 @@ all: $(LIBGIFSO) libgif.a $(LIBUTILSO) l + ifeq ($(UNAME), Darwin) + else $(MAKE) -C doc - + endif + -$(UTILS):: libgif.a libutil.a -+$(UTILS):: libutil.a libgif.so ++$(UTILS):: $(LIBGIFSOMAJOR) libutil.a --libgif.so: $(OBJECTS) $(HEADERS) -- $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libgif.so.$(LIBMAJOR) -o libgif.so $(OBJECTS) -+libgif.so.$(LIBVER): $(OBJECTS) $(HEADERS) -+ $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libgif.so.$(LIBMAJOR) -o $@ $(OBJECTS) -+ -+libgif.so.$(LIBMAJOR): libgif.so.$(LIBVER) + $(LIBGIFSO): $(OBJECTS) $(HEADERS) + ifeq ($(UNAME), Darwin) + $(CC) $(CFLAGS) -dynamiclib -current_version $(LIBVER) $(OBJECTS) -o $(LIBGIFSO) + else + $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,$(LIBGIFSOMAJOR) -o $(LIBGIFSO) $(OBJECTS) + endif + ++$(LIBGIFSOMAJOR): $(LIBGIFSO) + ln -s $< $@ + -+libgif.so: libgif.so.$(LIBMAJOR) -+ ln -s $< $@ - libgif.a: $(OBJECTS) $(HEADERS) $(AR) rcs libgif.a $(OBJECTS) --libutil.so: $(UOBJECTS) $(UHEADERS) -- $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libutil.so.$(LIBMAJOR) -o libutil.so $(UOBJECTS) -+libutil.so.$(LIBVER): $(UOBJECTS) $(UHEADERS) libgif.so -+ $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname -Wl,libutil.so.$(LIBMAJOR) -o $@ $(UOBJECTS) libgif.so -+ -+libutil.so.$(LIBMAJOR): libutil.so.$(LIBVER) -+ ln -s $< $@ -+ -+libutil.so: libutil.so.$(LIBMAJOR) -+ ln -s $< $@ - - libutil.a: $(UOBJECTS) $(UHEADERS) - $(AR) rcs libutil.a $(UOBJECTS) -@@ -112,7 +124,7 @@ - install-lib: - $(INSTALL) -d "$(DESTDIR)$(LIBDIR)" - $(INSTALL) -m 644 libgif.a "$(DESTDIR)$(LIBDIR)/libgif.a" -- $(INSTALL) -m 755 libgif.so "$(DESTDIR)$(LIBDIR)/libgif.so.$(LIBVER)" -+ $(INSTALL) -m 755 libgif.so.$(LIBVER) "$(DESTDIR)$(LIBDIR)/libgif.so.$(LIBVER)" - ln -sf libgif.so.$(LIBVER) "$(DESTDIR)$(LIBDIR)/libgif.so.$(LIBMAJOR)" - ln -sf libgif.so.$(LIBMAJOR) "$(DESTDIR)$(LIBDIR)/libgif.so" - install-man: + $(LIBUTILSO): $(UOBJECTS) $(UHEADERS) + ifeq ($(UNAME), Darwin) --- a/tests/makefile +++ b/tests/makefile -@@ -3,6 +3,8 @@ +@@ -1,10 +1,12 @@ + # Regression-test suite for the giflib library and tools + # All utilities have tests except gifbg, gifcolor, and gifhisto. .SUFFIXES: .gif .rgb @@ -69,3 +56,5 @@ # This is what to do by default test: render-regress \ gifbuild-regress \ + gifclrmp-regress \ + gifecho-regress \ diff -Nru giflib-5.2.1/debian/patches/Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch giflib-5.2.2/debian/patches/Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch --- giflib-5.2.1/debian/patches/Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/patches/Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch 2024-02-24 20:38:56.000000000 +0000 @@ -0,0 +1,30 @@ +From ccbc956432650734c91acb3fc88837f7b81267ff Mon Sep 17 00:00:00 2001 +From: "Eric S. Raymond" +Date: Wed, 21 Feb 2024 18:55:00 -0500 +Subject: [PATCH] Clean up memory better at end of run (CVE-2021-40633) + +--- + gif2rgb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gif2rgb.c b/gif2rgb.c +index d51226d..fc2e683 100644 +--- a/gif2rgb.c ++++ b/gif2rgb.c +@@ -515,10 +515,13 @@ static void GIF2RGB(int NumFiles, char *FileName, bool OneFileFlag, + } + + 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) { +-- +2.43.0 + diff -Nru giflib-5.2.1/debian/patches/Correct-document-page-install.patch giflib-5.2.2/debian/patches/Correct-document-page-install.patch --- giflib-5.2.1/debian/patches/Correct-document-page-install.patch 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/patches/Correct-document-page-install.patch 2024-02-24 20:38:56.000000000 +0000 @@ -0,0 +1,58 @@ +From 61f375082c80ee479eb8ff03189aea691a6a06aa Mon Sep 17 00:00:00 2001 +From: "Eric S. Raymond" +Date: Wed, 21 Feb 2024 08:33:51 -0500 +Subject: [PATCH] Correct document page install. + +--- + Makefile | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index 87966a9..f4ecb24 100644 +--- a/Makefile ++++ b/Makefile +@@ -61,19 +61,23 @@ UTILS = $(INSTALLABLE) \ + gifsponge \ + gifwedge + + LDLIBS=libgif.a -lm + +-MANUAL_PAGES = \ ++MANUAL_PAGES_1 = \ + doc/gif2rgb.xml \ + doc/gifbuild.xml \ + doc/gifclrmp.xml \ + doc/giffix.xml \ +- doc/giflib.xml \ + doc/giftext.xml \ + doc/giftool.xml + ++MANUAL_PAGES_7 = \ ++ doc/giflib.xml ++ ++MANUAL_PAGES = $(MANUAL_PAGES_1) $(MANUAL_PAGES_7) ++ + SOEXTENSION = so + LIBGIFSO = libgif.$(SOEXTENSION) + LIBGIFSOMAJOR = libgif.$(SOEXTENSION).$(LIBMAJOR) + LIBGIFSOVER = libgif.$(SOEXTENSION).$(LIBVER) + LIBUTILSO = libutil.$(SOEXTENSION) +@@ -146,12 +150,13 @@ install-lib: + $(INSTALL) -m 644 libgif.a "$(DESTDIR)$(LIBDIR)/libgif.a" + $(INSTALL) -m 755 $(LIBGIFSO) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOVER)" + ln -sf $(LIBGIFSOVER) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSOMAJOR)" + ln -sf $(LIBGIFSOMAJOR) "$(DESTDIR)$(LIBDIR)/$(LIBGIFSO)" + install-man: +- $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" +- $(INSTALL) -m 644 $(MANUAL_PAGES) "$(DESTDIR)$(MANDIR)/man1" ++ $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" "$(DESTDIR)$(MANDIR)/man7" ++ $(INSTALL) -m 644 $(MANUAL_PAGES_1:xml=1) "$(DESTDIR)$(MANDIR)/man1" ++ $(INSTALL) -m 644 $(MANUAL_PAGES_7:xml=7) "$(DESTDIR)$(MANDIR)/man7" + 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" +-- +2.43.0 + diff -Nru giflib-5.2.1/debian/patches/add-gifsponge-docs.patch giflib-5.2.2/debian/patches/add-gifsponge-docs.patch --- giflib-5.2.1/debian/patches/add-gifsponge-docs.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/add-gifsponge-docs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -Description: Add gifsponge docs -Author: David Suárez -Origin: vendor -Bug: https://sourceforge.net/p/giflib/bugs/155/ -Last-Update: 2020-12-20 - ---- a/Makefile -+++ b/Makefile -@@ -71,6 +71,7 @@ - doc/giffix.1 \ - doc/gifinto.1 \ - doc/giflib.1 \ -+ doc/gifsponge.1 \ - doc/giftext.1 \ - doc/giftool.1 - ---- a/doc/Makefile -+++ b/doc/Makefile -@@ -26,6 +26,7 @@ - giffix.xml \ - gifinto.xml \ - giflib.xml \ -+ gifsponge.xml \ - giftext.xml \ - giftool.xml - XMLINTERNAL = \ ---- /dev/null -+++ b/doc/gifsponge.xml -@@ -0,0 +1,40 @@ -+ -+ -+]> -+ -+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; -+ -+ -+ diff -Nru giflib-5.2.1/debian/patches/dont-build-html-pages-images.diff giflib-5.2.2/debian/patches/dont-build-html-pages-images.diff --- giflib-5.2.1/debian/patches/dont-build-html-pages-images.diff 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/patches/dont-build-html-pages-images.diff 2024-02-25 17:30:46.000000000 +0000 @@ -0,0 +1,18 @@ +Description: Don't build the site HTML pages images. + It saves us to have ImageMagick as a b-depend. +Author: David Suárez +Origin: vendor +Last-Update: 2024-03-24 +Forwarded: not-needed + +--- a/doc/Makefile ++++ b/doc/Makefile +@@ -46,7 +46,7 @@ + convert $^ -resize 50x50 $@ + + # Philosophical choice: the website gets the internal manual pages +-allhtml: $(XMLALL:.xml=.html) giflib-logo.gif ++allhtml: $(XMLALL:.xml=.html) + + manpages: $(XMLMAN1:.xml=.1) $(XMLMAN7:.xml=.7) $(XMLINTERNAL:.xml=.1) + diff -Nru giflib-5.2.1/debian/patches/fix-get-args-segment-violation.patch giflib-5.2.2/debian/patches/fix-get-args-segment-violation.patch --- giflib-5.2.1/debian/patches/fix-get-args-segment-violation.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/fix-get-args-segment-violation.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -Description: Fix segmentation faults due to non correct checking for args -Author: David Suárez -Origin: vendor -Bug: https://sourceforge.net/p/giflib/bugs/153/ -Bug-Debian: https://bugs.debian.org/715963 -Bug-Debian: https://bugs.debian.org/715964 -Bug-Debian: https://bugs.debian.org/715967 -Last-Update: 2020-12-20 - ---- a/getarg.c -+++ b/getarg.c -@@ -305,6 +305,12 @@ - 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", diff -Nru giflib-5.2.1/debian/patches/fix-spelling-errors-on-doc-pages.patch giflib-5.2.2/debian/patches/fix-spelling-errors-on-doc-pages.patch --- giflib-5.2.1/debian/patches/fix-spelling-errors-on-doc-pages.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/fix-spelling-errors-on-doc-pages.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Description: Fix some typos on the html documentation and man pages -Author: David Suárez -Origin: vendor -Bug: https://sourceforge.net/p/giflib/bugs/152/ -Bug-Debian: https://bugs.debian.org/857609 -Last-Update: 2020-12-20 - ---- a/doc/gif_lib.xml -+++ b/doc/gif_lib.xml -@@ -280,7 +280,7 @@ - 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 iff they didn't exist before. ColorTransIn2 maps -+ColorIn2 are copied if they didn't exist before. ColorTransIn2 maps - the old ColorIn2 into ColorUnion color map table. - - ---- a/doc/gifinto.xml -+++ b/doc/gifinto.xml -@@ -28,7 +28,7 @@ - - Description - --A program to save stdin into a file with given name, iff the -+A program to save stdin into a file with given name, 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. diff -Nru giflib-5.2.1/debian/patches/giflib_quantize-header.patch giflib-5.2.2/debian/patches/giflib_quantize-header.patch --- giflib-5.2.1/debian/patches/giflib_quantize-header.patch 2022-06-12 16:32:10.000000000 +0000 +++ giflib-5.2.2/debian/patches/giflib_quantize-header.patch 2024-02-24 20:38:56.000000000 +0000 @@ -1,28 +1,35 @@ Description: Move declaration of GifQuantizeBuffer() back to gif_lib.h Bug-Debian: https://bugs.debian.org/1011705 -Author: Graham Inggs -Last-Update: 2022-06-12 +Author: Graham Inggs , Andreas Metzler +Last-Update: 2024-02-24 --- a/gif_lib.h +++ b/gif_lib.h -@@ -215,6 +215,14 @@ +@@ -210,10 +210,19 @@ int DGifGetCode(GifFileType *GifFile, in + int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock); int DGifGetLZCodes(GifFileType *GifFile, int *GifCode); const char *DGifGetGifVersion(GifFileType *GifFile); -+/****************************************************************************** -+ Color table quantization (deprecated) + /****************************************************************************** ++ Color table quantization +******************************************************************************/ +int GifQuantizeBuffer(unsigned int Width, unsigned int Height, -+ int *ColorMapSize, GifByteType * RedInput, -+ GifByteType * GreenInput, GifByteType * BlueInput, -+ GifByteType * OutputBuffer, -+ GifColorType * OutputColorMap); - - /****************************************************************************** ++ int *ColorMapSize, const GifByteType *RedInput, ++ const GifByteType *GreenInput, ++ const GifByteType *BlueInput, ++ GifByteType *OutputBuffer, GifColorType *OutputColorMap); ++ ++/****************************************************************************** Error handling and reporting. + ******************************************************************************/ + extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */ + + /***************************************************************************** --- a/getarg.h +++ b/getarg.h -@@ -34,15 +34,6 @@ +@@ -31,18 +31,10 @@ void GAPrintHowTo(char *CtrlStr); + From qprintf.c + ******************************************************************************/ extern void GifQprintf(char *Format, ...); extern void PrintGifError(int ErrorCode); @@ -30,11 +37,12 @@ - Color table quantization -******************************************************************************/ -int GifQuantizeBuffer(unsigned int Width, unsigned int Height, -- int *ColorMapSize, GifByteType * RedInput, -- GifByteType * GreenInput, GifByteType * BlueInput, -- GifByteType * OutputBuffer, -- GifColorType * OutputColorMap); +- int *ColorMapSize, GifByteType *RedInput, +- GifByteType *GreenInput, GifByteType *BlueInput, +- GifByteType *OutputBuffer, GifColorType *OutputColorMap); - /* 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); } + #define GIF_EXIT(Msg) \ + { \ + GIF_MESSAGE(Msg); \ diff -Nru giflib-5.2.1/debian/patches/giflib_quantize.patch giflib-5.2.2/debian/patches/giflib_quantize.patch --- giflib-5.2.1/debian/patches/giflib_quantize.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/giflib_quantize.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -Description: Move quantize.c back into libgif.so -Origin: other, fedora https://src.fedoraproject.org/rpms/giflib/c/109bf038d703a471b857aba44af673be103d7079 -Bug: https://sourceforge.net/p/giflib/bugs/142/ -Bug-Debian: https://bugs.debian.org/935088 - -diff -rupN giflib-5.2.1/Makefile giflib-5.2.1-new/Makefile ---- giflib-5.2.1/Makefile 2019-06-24 18:08:57.000000000 +0200 -+++ giflib-5.2.1-new/Makefile 2019-10-01 13:02:33.227952230 +0200 -@@ -29,11 +29,11 @@ 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 -+ 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 quantize.c getarg.c -+USOURCES = qprintf.c getarg.c - UHEADERS = getarg.h - UOBJECTS = $(USOURCES:.c=.o) - diff -Nru giflib-5.2.1/debian/patches/install-only-distributed-binaries-manuals.patch giflib-5.2.2/debian/patches/install-only-distributed-binaries-manuals.patch --- giflib-5.2.1/debian/patches/install-only-distributed-binaries-manuals.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/install-only-distributed-binaries-manuals.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Description: Only install the manuals for installed binaries -Author: David Suárez -Origin: vendor -Bug: https://sourceforge.net/p/giflib/bugs/145/ -Last-Update: 2019-11-25 - ---- a/Makefile -+++ b/Makefile -@@ -62,6 +62,17 @@ - - LDLIBS=libgif.a -lm - -+MANUAL_PAGES = \ -+ doc/gif2rgb.1 \ -+ doc/gifbuild.1 \ -+ doc/gifclrmp.1 \ -+ doc/gifecho.1 \ -+ doc/giffix.1 \ -+ doc/gifinto.1 \ -+ doc/giflib.1 \ -+ doc/giftext.1 \ -+ doc/giftool.1 -+ - all: libgif.so libgif.a libutil.so libutil.a $(UTILS) - $(MAKE) -C doc - -@@ -105,7 +116,7 @@ - ln -sf libgif.so.$(LIBMAJOR) "$(DESTDIR)$(LIBDIR)/libgif.so" - install-man: - $(INSTALL) -d "$(DESTDIR)$(MANDIR)/man1" -- $(INSTALL) -m 644 doc/*.1 "$(DESTDIR)$(MANDIR)/man1" -+ $(INSTALL) -m 644 $(MANUAL_PAGES) "$(DESTDIR)$(MANDIR)/man1" - uninstall: uninstall-man uninstall-include uninstall-lib uninstall-bin - uninstall-bin: - cd "$(DESTDIR)$(BINDIR)" && rm -f $(INSTALLABLE) diff -Nru giflib-5.2.1/debian/patches/recover-giffilter-docs.patch giflib-5.2.2/debian/patches/recover-giffilter-docs.patch --- giflib-5.2.1/debian/patches/recover-giffilter-docs.patch 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/patches/recover-giffilter-docs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -Description: Recover the giffilter manual page -Author: David Suárez -Origin: vendor -Bug: https://sourceforge.net/p/giflib/bugs/154/ -Last-Update: 2020-12-20 - ---- /dev/null -+++ b/doc/giffilter.xml -@@ -0,0 +1,42 @@ -+ -+ -+]> -+ -+2 May 2012 -+ -+giffilter -+1 -+GIFLIB -+GIFLIB Documentation -+ -+ -+giffilter -+expensive GIF copy, a model for filter utilities -+ -+ -+ -+ -+ -+ 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 &email; -+ -+ -+ ---- a/Makefile -+++ b/Makefile -@@ -67,6 +67,7 @@ - doc/gifbuild.1 \ - doc/gifclrmp.1 \ - doc/gifecho.1 \ -+ doc/giffilter.1 \ - doc/giffix.1 \ - doc/gifinto.1 \ - doc/giflib.1 \ ---- a/doc/Makefile -+++ b/doc/Makefile -@@ -22,6 +22,7 @@ - gifbuild.xml \ - gifclrmp.xml \ - gifecho.xml \ -+ giffilter.xml \ - giffix.xml \ - gifinto.xml \ - giflib.xml \ diff -Nru giflib-5.2.1/debian/patches/revert-GifQuantizeBuffer-remove-from-lib.patch giflib-5.2.2/debian/patches/revert-GifQuantizeBuffer-remove-from-lib.patch --- giflib-5.2.1/debian/patches/revert-GifQuantizeBuffer-remove-from-lib.patch 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/patches/revert-GifQuantizeBuffer-remove-from-lib.patch 2024-02-24 20:38:56.000000000 +0000 @@ -0,0 +1,28 @@ +Description: Revert the remove of GifQuantizeBuffer symbol from the main lib. + It is needed for some applications (exactimage, mplayer-gui, mplayer, qutemol and xplanet). + . + This patch is temporary to allow switch to the new ABI, the change + is trivial, the symbol is moved to libutil, so the packages will + need to links against it. +Author: David Suárez +Origin: vendor +Last-Update: 2024-03-24 +Bug: https://sourceforge.net/p/giflib/bugs/142/ +Bug-Debian: https://bugs.debian.org/935088 + +--- a/Makefile ++++ b/Makefile +@@ -29,11 +29,11 @@ + 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 ++ 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 quantize.c getarg.c ++USOURCES = qprintf.c getarg.c + UHEADERS = getarg.h + UOBJECTS = $(USOURCES:.c=.o) + diff -Nru giflib-5.2.1/debian/patches/series giflib-5.2.2/debian/patches/series --- giflib-5.2.1/debian/patches/series 2022-06-12 16:30:10.000000000 +0000 +++ giflib-5.2.2/debian/patches/series 2024-04-05 08:31:09.000000000 +0000 @@ -1,9 +1,8 @@ -fix-get-args-segment-violation.patch -install-only-distributed-binaries-manuals.patch -fix-spelling-errors-on-doc-pages.patch -recover-giffilter-docs.patch -add-gifsponge-docs.patch +dont-build-html-pages-images.diff +Correct-document-page-install.patch +revert-GifQuantizeBuffer-remove-from-lib.patch 30_link_utils_dynamically.diff -giflib_quantize.patch dont-spoil-tests-with-stderr.patch giflib_quantize-header.patch +Clean-up-memory-better-at-end-of-run-CVE-2021-40633.patch +snprintf.patch diff -Nru giflib-5.2.1/debian/patches/snprintf.patch giflib-5.2.2/debian/patches/snprintf.patch --- giflib-5.2.1/debian/patches/snprintf.patch 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/patches/snprintf.patch 2024-04-05 08:31:09.000000000 +0000 @@ -0,0 +1,24 @@ +Description: Fix incorrect length args to snprintf +Author: Adam Sampson +Bug: https://sourceforge.net/p/giflib/bugs/170/ + +--- giflib-5.2.2/giftext.c 2024-02-19 03:01:28.000000000 +0000 ++++ giflib-5.2.2/giftext.c 2024-04-04 19:20:51.474029582 +0100 +@@ -442,7 +442,7 @@ + for (i = 1; i <= Len; i++) { + (void)snprintf(&HexForm[CrntPlace * 3], 3, " %02x", + Extension[i]); +- (void)snprintf(&AsciiForm[CrntPlace], 3, "%c", ++ (void)snprintf(&AsciiForm[CrntPlace], 2, "%c", + MAKE_PRINTABLE(Extension[i])); + if (++CrntPlace == 16) { + HexForm[CrntPlace * 3] = 0; +@@ -488,7 +488,7 @@ + for (i = 0; i < Len; i++) { + (void)snprintf(&HexForm[CrntPlace * 3], 3, " %02x", + PixelBlock[i]); +- (void)snprintf(&AsciiForm[CrntPlace], 3, "%c", ++ (void)snprintf(&AsciiForm[CrntPlace], 2, "%c", + MAKE_PRINTABLE(PixelBlock[i])); + if (++CrntPlace == 16) { + HexForm[CrntPlace * 3] = 0; diff -Nru giflib-5.2.1/debian/rules giflib-5.2.2/debian/rules --- giflib-5.2.1/debian/rules 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/rules 2024-02-25 17:38:52.000000000 +0000 @@ -1,5 +1,7 @@ #!/usr/bin/make -f +export DH_ALWAYS_EXCLUDE=CVS:.idea + # Include /usr/share/dpkg/pkg-info.mk to get DEB_{SOURCE,VERSION} include /usr/share/dpkg/pkg-info.mk diff -Nru giflib-5.2.1/debian/salsa-ci.yml giflib-5.2.2/debian/salsa-ci.yml --- giflib-5.2.1/debian/salsa-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/debian/salsa-ci.yml 2023-03-03 18:09:29.000000000 +0000 @@ -0,0 +1,4 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml diff -Nru giflib-5.2.1/debian/source/lintian-overrides giflib-5.2.2/debian/source/lintian-overrides --- giflib-5.2.1/debian/source/lintian-overrides 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/source/lintian-overrides 2024-02-24 20:38:56.000000000 +0000 @@ -1,2 +1,20 @@ # don't use the redirector giflib source: debian-watch-lacks-sourceforge-redirector +# all of these are built from xml files in the same directory. +giflib source: source-is-missing [doc/gif2rgb.html] +giflib source: source-is-missing [doc/gif_lib.html] +giflib source: source-is-missing [doc/gifbg.html] +giflib source: source-is-missing [doc/gifbuild.html] +giflib source: source-is-missing [doc/gifclrmp.html] +giflib source: source-is-missing [doc/gifcolor.html] +giflib source: source-is-missing [doc/gifecho.html] +giflib source: source-is-missing [doc/giffilter.html] +giflib source: source-is-missing [doc/giffix.html] +giflib source: source-is-missing [doc/gifhisto.html] +giflib source: source-is-missing [doc/gifinto.html] +giflib source: source-is-missing [doc/giflib.html] +giflib source: source-is-missing [doc/gifsponge.html] +giflib source: source-is-missing [doc/giftext.html] +giflib source: source-is-missing [doc/giftool.html] +giflib source: source-is-missing [doc/gifwedge.html] +giflib source: source-is-missing [doc/intro.html] diff -Nru giflib-5.2.1/debian/upstream/metadata giflib-5.2.2/debian/upstream/metadata --- giflib-5.2.1/debian/upstream/metadata 2022-06-12 16:26:45.000000000 +0000 +++ giflib-5.2.2/debian/upstream/metadata 2024-02-24 19:59:38.000000000 +0000 @@ -1,7 +1,5 @@ --- Archive: Sourceforge Bug-Database: https://sourceforge.net/p/giflib/bugs/ -Contact: https://sourceforge.net/p/giflib/discussion/ -Name: giflib Repository: https://git.code.sf.net/p/giflib/code Repository-Browse: https://sourceforge.net/p/giflib/code/ci/master/tree/ diff -Nru giflib-5.2.1/dgif_lib.c giflib-5.2.2/dgif_lib.c --- giflib-5.2.1/dgif_lib.c 2019-06-24 07:23:29.000000000 +0000 +++ giflib-5.2.2/dgif_lib.c 2024-02-19 03:01:28.000000000 +0000 @@ -10,11 +10,11 @@ *****************************************************************************/ -#include +#include #include #include -#include #include +#include #include #ifdef _WIN32 @@ -27,22 +27,23 @@ #include "gif_lib_private.h" /* compose unsigned little endian value */ -#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8)) +#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)); + // 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(GifPrefixType *Prefix, int Code, int ClearCode); +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); @@ -52,20 +53,19 @@ 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; - } +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; + GifFile = DGifOpenFileHandle(FileHandle, Error); + return GifFile; } /****************************************************************************** @@ -73,484 +73,487 @@ 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; - } +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; - /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType)); + 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 */ + _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* _WIN32 */ + + f = fdopen(FileHandle, "rb"); /* Make it into a stream: */ - 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@*/ - /*@-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; - } + /* 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; + GifFile->Error = 0; - /* What version of GIF? */ - Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); + /* What version of GIF? */ + Private->gif89 = (Buf[GIF_VERSION_POS + 1] == '9'); - return GifFile; + 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; - } +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)); - GifFile->Error = 0; + /* Belt and suspenders, in case the null pointer isn't zero */ + GifFile->SavedImages = NULL; + GifFile->SColorMap = NULL; - /* What version of GIF? */ - Private->gif89 = (Buf[GIF_VERSION_POS] == '9'); + 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; - return GifFile; + 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; +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]; - } - } +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; + Private->PixelCount = + (long)GifFile->Image.Width * (long)GifFile->Image.Height; - /* Reset decompress algorithm parameters. */ - return DGifSetupDecompress(GifFile); + /* 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; +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++; + GifFile->ImageCount++; - return GIF_OK; + 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 ((Private->PixelCount -= LineLen) > 0xffff0000UL) { - GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - - 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; +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 ((Private->PixelCount -= LineLen) > 0xffff0000UL) { + GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + + 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 > 0xffff0000UL) - { - GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; - return GIF_ERROR; - } - - 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; +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 > 0xffff0000UL) { + GifFile->Error = D_GIF_ERR_DATA_TOO_BIG; + return GIF_ERROR; + } + + 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; + } } /****************************************************************************** @@ -560,28 +563,28 @@ 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); +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); + return DGifGetExtensionNext(GifFile, Extension); } /****************************************************************************** @@ -589,32 +592,32 @@ 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); +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; + return GIF_OK; } /****************************************************************************** @@ -622,120 +625,126 @@ ******************************************************************************/ 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; + 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; + 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; +int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex, + GraphicsControlBlock *GCB) { + int i; - if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) - return GIF_ERROR; + 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; - 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); - } + 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; + 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; - } +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; + } - 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; + 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; - } +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; + *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]); + return GIF_OK; } /****************************************************************************** @@ -745,20 +754,18 @@ 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; - } +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; + *CodeSize = Private->BitsPerPixel; - return DGifGetCodeNext(GifFile, CodeBlock); + return DGifGetCodeNext(GifFile, CodeBlock); } /****************************************************************************** @@ -766,77 +773,79 @@ 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. */ - } +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; + 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. */ - 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; +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; + return GIF_OK; } /****************************************************************************** @@ -845,127 +854,149 @@ 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; - } - } +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; + Private->LastCode = LastCode; + Private->StackPtr = StackPtr; - return GIF_OK; + return GIF_OK; } /****************************************************************************** @@ -974,55 +1005,55 @@ If image is defective, we might loop here forever, so we limit the loops to the maximum possible if image O.k. - LZ_MAX_CODE times. ******************************************************************************/ -static int -DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode) -{ - int i = 0; - - while (Code > ClearCode && i++ <= LZ_MAX_CODE) { - if (Code > LZ_MAX_CODE) { - return NO_SUCH_CODE; - } - Code = Prefix[Code]; - } - return Code; +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; - } +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; + return GIF_OK; } /****************************************************************************** @@ -1031,52 +1062,48 @@ 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; +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; } /****************************************************************************** @@ -1085,37 +1112,56 @@ 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]--; - } +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; +} - 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); + } + + // 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; + } } /****************************************************************************** @@ -1123,119 +1169,144 @@ 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)) { - return GIF_ERROR; - } - ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; - - if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) { - return GIF_ERROR; - } - sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize, - sizeof(GifPixelType)); - - if (sp->RasterBits == NULL) { - return GIF_ERROR; - } - - if (sp->ImageDesc.Interlace) { - int i, j; - /* - * The way an interlaced image should be read - - * offsets and jumps... - */ - int InterlacedOffset[] = { 0, 4, 2, 1 }; - int InterlacedJumps[] = { 8, 8, 4, 2 }; - /* Need to perform 4 passes on the image */ - for (i = 0; i < 4; i++) - for (j = InterlacedOffset[i]; - j < sp->ImageDesc.Height; - j += InterlacedJumps[i]) { - if (DGifGetLine(GifFile, - sp->RasterBits+j*sp->ImageDesc.Width, - sp->ImageDesc.Width) == GIF_ERROR) - return GIF_ERROR; - } - } - else { - if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR) - return (GIF_ERROR); - } - - 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 (ExtData != NULL) - 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); - } +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); + return (GIF_OK); } /* end */ diff -Nru giflib-5.2.1/doc/Makefile giflib-5.2.2/doc/Makefile --- giflib-5.2.1/doc/Makefile 2019-03-28 17:05:25.000000000 +0000 +++ giflib-5.2.2/doc/Makefile 2024-02-18 18:15:05.000000000 +0000 @@ -1,4 +1,4 @@ -.SUFFIXES: .xml .html .txt .adoc .1 +.SUFFIXES: .xml .html .txt .adoc .1 .7 .xml.html: xmlto xhtml-nochunks $< @@ -6,6 +6,9 @@ .xml.1: xmlto man $< +.xml.7: + xmlto man $< + .xml.txt: xmlto txt $< @@ -17,34 +20,40 @@ # 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. -XMLMAN = \ +XMLMAN1 = \ gif2rgb.xml \ gifbuild.xml \ gifclrmp.xml \ - gifecho.xml \ + giffilter.xml \ giffix.xml \ - gifinto.xml \ - giflib.xml \ + gifsponge.xml \ giftext.xml \ giftool.xml +XMLMAN7 = \ + giflib.xml XMLINTERNAL = \ gifbg.xml \ gifcolor.xml \ + gifecho.xml \ + gifinto.xml \ gifhisto.xml \ gifwedge.xml XMLDOC = intro.xml gif_lib.xml -XMLALL = $(XMLMAN) $(XMLINTERNAL) $(XMLDOC) +XMLALL = $(XMLMAN1) $(XMLMAN7) $(XMLINTERNAL) $(XMLDOC) + +# Logo image file for HTML docs +giflib-logo.gif: ../pic/gifgrid.gif + convert $^ -resize 50x50 $@ # Philosophical choice: the website gets the internal manual pages -allhtml: $(XMLALL:.xml=.html) $(XMLINTERNAL:.xml=.html) +allhtml: $(XMLALL:.xml=.html) giflib-logo.gif -manpages: $(XMLMAN:.xml=.1) $(XMLINTERNAL:.xml=.1) +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 rm -fr staging; mkdir staging; - cp -r $(XMLALL:.xml=.html) gifstandard whatsinagif staging + cp -r $(XMLALL:.xml=.html) gifstandard whatsinagif giflib-logo.gif staging cp index.html.in staging/index.html - convert ../pic/gifgrid.gif -resize 50x50 staging/giflib-logo.gif asciidoc - <../history.adoc >staging/history.html diff -Nru giflib-5.2.1/doc/gif2rgb.1 giflib-5.2.2/doc/gif2rgb.1 --- giflib-5.2.1/doc/gif2rgb.1 2019-06-24 16:16:38.000000000 +0000 +++ giflib-5.2.2/doc/gif2rgb.1 2024-02-19 01:05:24.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: gif2rgb .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB @@ -67,6 +67,9 @@ 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\&. diff -Nru giflib-5.2.1/doc/gif2rgb.html giflib-5.2.2/doc/gif2rgb.html --- giflib-5.2.1/doc/gif2rgb.html 2019-02-09 11:38:28.000000000 +0000 +++ giflib-5.2.2/doc/gif2rgb.html 2024-02-18 02:02:17.000000000 +0000 @@ -1,5 +1,5 @@ -gif2rgb

Name

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

Synopsis

gif2rgb [-v] [-1] [-c colors] [-s +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, @@ -12,4 +12,6 @@ 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.

Author

Gershon Elber.

\ No newline at end of file +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.

\ No newline at end of file diff -Nru giflib-5.2.1/doc/gif2rgb.xml giflib-5.2.2/doc/gif2rgb.xml --- giflib-5.2.1/doc/gif2rgb.xml 2016-04-02 15:34:00.000000000 +0000 +++ giflib-5.2.2/doc/gif2rgb.xml 2024-02-18 01:24:30.000000000 +0000 @@ -88,6 +88,13 @@ 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. diff -Nru giflib-5.2.1/doc/gif_lib.html giflib-5.2.2/doc/gif_lib.html --- giflib-5.2.1/doc/gif_lib.html 2019-03-28 17:13:50.000000000 +0000 +++ giflib-5.2.2/doc/gif_lib.html 2024-02-18 19:07:04.000000000 +0000 @@ -1,5 +1,5 @@ -The GIFLIB Library

The GIFLIB Library

Eric Steven Raymond

+The GIFLIB Library

The GIFLIB Library

Eric Steven Raymond


Introduction

The Graphics Interchange Format(c) is the Copyright property of @@ -113,7 +113,7 @@

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 iff they didn't exist before. ColorTransIn2 maps +ColorIn2 are copied 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 @@ -148,9 +148,10 @@ will create a new leading extension block.

Error Handling (gif_err.c)

 int GifErrorString(int ErrCode)
 

Returns a sting 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 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 +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(
diff -Nru giflib-5.2.1/doc/gif_lib.xml giflib-5.2.2/doc/gif_lib.xml
--- giflib-5.2.1/doc/gif_lib.xml	2019-03-28 17:05:25.000000000 +0000
+++ giflib-5.2.2/doc/gif_lib.xml	2024-02-18 18:15:05.000000000 +0000
@@ -280,7 +280,7 @@
 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 iff they didn't exist before.  ColorTransIn2 maps
+ColorIn2 are copied if they didn't exist before.  ColorTransIn2 maps
 the old ColorIn2 into ColorUnion color map table.
 
 
@@ -340,9 +340,10 @@
 
 The GIF Utility Font
 
-The 8x8 utility font used in 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 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.
diff -Nru giflib-5.2.1/doc/gifbg.1 giflib-5.2.2/doc/gifbg.1
--- giflib-5.2.1/doc/gifbg.1	2019-06-24 16:16:41.000000000 +0000
+++ giflib-5.2.2/doc/gifbg.1	2024-02-19 01:05:26.000000000 +0000
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: gifbg
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
 .\"      Date: 2 May 2012
 .\"    Manual: GIFLIB Documentation
 .\"    Source: GIFLIB
diff -Nru giflib-5.2.1/doc/gifbuild.1 giflib-5.2.2/doc/gifbuild.1
--- giflib-5.2.1/doc/gifbuild.1	2019-06-24 16:16:38.000000000 +0000
+++ giflib-5.2.2/doc/gifbuild.1	2024-02-19 01:05:24.000000000 +0000
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: gifbuild
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
 .\"      Date: 2 May 2012
 .\"    Manual: GIFLIB Documentation
 .\"    Source: GIFLIB
diff -Nru giflib-5.2.1/doc/gifclrmp.1 giflib-5.2.2/doc/gifclrmp.1
--- giflib-5.2.1/doc/gifclrmp.1	2019-06-24 16:16:38.000000000 +0000
+++ giflib-5.2.2/doc/gifclrmp.1	2024-02-19 01:05:25.000000000 +0000
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: gifclrmp
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
 .\"      Date: 2 May 2012
 .\"    Manual: GIFLIB Documentation
 .\"    Source: GIFLIB
diff -Nru giflib-5.2.1/doc/gifcolor.1 giflib-5.2.2/doc/gifcolor.1
--- giflib-5.2.1/doc/gifcolor.1	2019-06-24 16:16:41.000000000 +0000
+++ giflib-5.2.2/doc/gifcolor.1	2024-02-19 01:05:27.000000000 +0000
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: gifcolor
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
 .\"      Date: 2 May 2012
 .\"    Manual: GIFLIB Documentation
 .\"    Source: GIFLIB
diff -Nru giflib-5.2.1/doc/gifecho.1 giflib-5.2.2/doc/gifecho.1
--- giflib-5.2.1/doc/gifecho.1	2019-06-24 16:16:39.000000000 +0000
+++ giflib-5.2.2/doc/gifecho.1	2024-02-19 01:05:27.000000000 +0000
@@ -1,7 +1,7 @@
 '\" t
 .\"     Title: gifecho
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1 
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
 .\"      Date: 2 May 2012
 .\"    Manual: GIFLIB Documentation
 .\"    Source: GIFLIB
diff -Nru giflib-5.2.1/doc/giffilter.1 giflib-5.2.2/doc/giffilter.1
--- giflib-5.2.1/doc/giffilter.1	1970-01-01 00:00:00.000000000 +0000
+++ giflib-5.2.2/doc/giffilter.1	2024-02-19 01:05:25.000000000 +0000
@@ -0,0 +1,43 @@
+'\" t
+.\"     Title: giffilter
+.\"    Author: [see the "Author" section]
+.\" Generator: DocBook XSL Stylesheets vsnapshot 
+.\"      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
+
diff -Nru giflib-5.2.1/doc/giffilter.html giflib-5.2.2/doc/giffilter.html
--- giflib-5.2.1/doc/giffilter.html	1970-01-01 00:00:00.000000000 +0000
+++ giflib-5.2.2/doc/giffilter.html	2024-02-17 23:24:03.000000000 +0000
@@ -0,0 +1,5 @@
+
+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

\ No newline at end of file diff -Nru giflib-5.2.1/doc/giffilter.xml giflib-5.2.2/doc/giffilter.xml --- giflib-5.2.1/doc/giffilter.xml 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/doc/giffilter.xml 2024-02-17 23:07:45.000000000 +0000 @@ -0,0 +1,42 @@ + + +]> + +2 May 2012 + +giffilter +1 +GIFLIB +GIFLIB Documentation + + +giffilter +expensive GIF copy, a model for filter utilities + + + + + + 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 &email; + + + diff -Nru giflib-5.2.1/doc/giffix.1 giflib-5.2.2/doc/giffix.1 --- giflib-5.2.1/doc/giffix.1 2019-06-24 16:16:39.000000000 +0000 +++ giflib-5.2.2/doc/giffix.1 2024-02-19 01:05:25.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: giffix .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB diff -Nru giflib-5.2.1/doc/gifhisto.1 giflib-5.2.2/doc/gifhisto.1 --- giflib-5.2.1/doc/gifhisto.1 2019-06-24 16:16:41.000000000 +0000 +++ giflib-5.2.2/doc/gifhisto.1 2024-02-19 01:05:28.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: gifhisto .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB diff -Nru giflib-5.2.1/doc/gifinto.1 giflib-5.2.2/doc/gifinto.1 --- giflib-5.2.1/doc/gifinto.1 2019-06-24 16:16:39.000000000 +0000 +++ giflib-5.2.2/doc/gifinto.1 2024-02-19 01:05:27.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: gifinto .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB @@ -34,7 +34,7 @@ \fBgifinto\fR [\-v] [\-s\ \fIminsize\fR] [\-h] [\fIoutfile\fR] .SH "DESCRIPTION" .PP -A program to save stdin into a file with given name, iff 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\&. +A program to save stdin into a file with given name, 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" diff -Nru giflib-5.2.1/doc/gifinto.html giflib-5.2.2/doc/gifinto.html --- giflib-5.2.1/doc/gifinto.html 2019-02-09 11:38:29.000000000 +0000 +++ giflib-5.2.2/doc/gifinto.html 2024-02-17 23:24:03.000000000 +0000 @@ -1,5 +1,5 @@ -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, iff the +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 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). diff -Nru giflib-5.2.1/doc/gifinto.xml giflib-5.2.2/doc/gifinto.xml --- giflib-5.2.1/doc/gifinto.xml 2014-05-16 10:46:53.000000000 +0000 +++ giflib-5.2.2/doc/gifinto.xml 2024-02-17 22:48:39.000000000 +0000 @@ -28,7 +28,7 @@ Description -A program to save stdin into a file with given name, iff the +A program to save stdin into a file with given name, 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. diff -Nru giflib-5.2.1/doc/giflib.1 giflib-5.2.2/doc/giflib.1 --- giflib-5.2.1/doc/giflib.1 2019-06-24 16:16:40.000000000 +0000 +++ giflib-5.2.2/doc/giflib.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -'\" t -.\" Title: giflib -.\" Author: [see the "Authors" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 3 June 2012 -.\" Manual: GIFLIB Documentation -.\" Source: GIFLIB -.\" Language: English -.\" -.TH "GIFLIB" "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" -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 -\fBgif2raw\fR(1), -\fBgif2rgb\fR(1), -\fBgifbuild\fR(1), -\fBgifecho\fR(1), -\fBgiffix\fR(1), -\fBgifinto\fR(1), -\fBgiftext\fR(1), -\fBgiftool\fR(1), -\fBgifclrmap\fR(1)\&. -.SH "AUTHORS" -.PP -Gershon Elber, Eric S\&. Raymond, Toshio Kuratomi\&. diff -Nru giflib-5.2.1/doc/giflib.7 giflib-5.2.2/doc/giflib.7 --- giflib-5.2.1/doc/giflib.7 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/doc/giflib.7 2024-02-18 19:07:04.000000000 +0000 @@ -0,0 +1,49 @@ +'\" 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 +\fBgif2rgb\fR(1), +\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\&. diff -Nru giflib-5.2.1/doc/giflib.html giflib-5.2.2/doc/giflib.html --- giflib-5.2.1/doc/giflib.html 2019-02-11 02:27:31.000000000 +0000 +++ giflib-5.2.2/doc/giflib.html 2024-02-18 19:07:04.000000000 +0000 @@ -1,5 +1,5 @@ -giflib

Name

giflib — GIFLIB utilities

Description

GIFLIB is a linkable service library and a set of utilities for +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 @@ -8,13 +8,10 @@ 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

-gif2raw(1), gif2rgb(1), gifbuild(1), -gifecho(1), giffix(1), -gifinto(1), giftext(1), giftool(1), gifclrmap(1). -

Authors

Gershon Elber, Eric S. Raymond, Toshio Kuratomi.

\ No newline at end of file +

Authors

Gershon Elber, Eric S. Raymond, Toshio Kuratomi.

\ No newline at end of file diff -Nru giflib-5.2.1/doc/giflib.xml giflib-5.2.2/doc/giflib.xml --- giflib-5.2.1/doc/giflib.xml 2019-02-10 22:36:27.000000000 +0000 +++ giflib-5.2.2/doc/giflib.xml 2024-02-18 18:15:05.000000000 +0000 @@ -4,11 +4,11 @@ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ ]> - + 3 June 2012 giflib -1 +7 GIFLIB GIFLIB Documentation @@ -37,12 +37,9 @@ See Also -gif2raw1, gif2rgb1, gifbuild1, -gifecho1, giffix1, -gifinto1, giftext1, giftool1, gifclrmap1. diff -Nru giflib-5.2.1/doc/gifsponge.1 giflib-5.2.2/doc/gifsponge.1 --- giflib-5.2.1/doc/gifsponge.1 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/doc/gifsponge.1 2024-02-19 01:05:26.000000000 +0000 @@ -0,0 +1,41 @@ +'\" 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 + diff -Nru giflib-5.2.1/doc/gifsponge.html giflib-5.2.2/doc/gifsponge.html --- giflib-5.2.1/doc/gifsponge.html 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/doc/gifsponge.html 2024-02-17 23:24:03.000000000 +0000 @@ -0,0 +1,5 @@ + +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

\ No newline at end of file diff -Nru giflib-5.2.1/doc/gifsponge.xml giflib-5.2.2/doc/gifsponge.xml --- giflib-5.2.1/doc/gifsponge.xml 1970-01-01 00:00:00.000000000 +0000 +++ giflib-5.2.2/doc/gifsponge.xml 2024-02-17 23:06:30.000000000 +0000 @@ -0,0 +1,40 @@ + + +]> + +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; + + + diff -Nru giflib-5.2.1/doc/giftext.1 giflib-5.2.2/doc/giftext.1 --- giflib-5.2.1/doc/giftext.1 2019-06-24 16:16:40.000000000 +0000 +++ giflib-5.2.2/doc/giftext.1 2024-02-19 01:05:26.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: giftext .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB diff -Nru giflib-5.2.1/doc/giftool.1 giflib-5.2.2/doc/giftool.1 --- giflib-5.2.1/doc/giftool.1 2019-06-24 16:16:40.000000000 +0000 +++ giflib-5.2.2/doc/giftool.1 2024-02-19 01:05:26.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: giftool .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 3 June 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB diff -Nru giflib-5.2.1/doc/gifwedge.1 giflib-5.2.2/doc/gifwedge.1 --- giflib-5.2.1/doc/gifwedge.1 2019-06-24 16:16:42.000000000 +0000 +++ giflib-5.2.2/doc/gifwedge.1 2024-02-19 01:05:28.000000000 +0000 @@ -1,7 +1,7 @@ '\" t .\" Title: gifwedge .\" Author: [see the "Author" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2 May 2012 .\" Manual: GIFLIB Documentation .\" Source: GIFLIB diff -Nru giflib-5.2.1/doc/intro.html giflib-5.2.2/doc/intro.html --- giflib-5.2.1/doc/intro.html 2019-03-28 17:13:49.000000000 +0000 +++ giflib-5.2.2/doc/intro.html 2024-02-18 19:07:04.000000000 +0000 @@ -1,8 +1,8 @@ -Introduction to GIFLIB

Introduction to GIFLIB

Eric Steven Raymond

+Introduction to GIFLIB

Introduction to GIFLIB

Eric Steven Raymond


GIFLIB is a package of portable tools and library routines for +    


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 @@ -25,15 +25,16 @@ 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.

Conversion Utilities

gif2rgb

convert images saved as GIF to 24-bit RGB image(s) or vice-versa

Test Pattern Generators

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

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

gifhisto

generate color-frequency histogram from a GIF

GIF Composition Tools

gifbuild

converter/deconverter to/from an editable text format

gifecho

generate GIF images out of regular text in 8x8 font

gifinto

end-of-pipe fitting for GIF-processing pipelines

giftool

GIF transformation tool

Library Functions

The library contains two groups of C functions. One group does +in increasing order.

Conversion Utilities

gif2rgb

convert images saved as GIF to 24-bit RGB image(s) or vice-versa

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.

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 +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 http://catb.org/~esr/.

GIFLIB is not under active development, but bug fixes are being accepted.

\ No newline at end of file diff -Nru giflib-5.2.1/doc/intro.xml giflib-5.2.2/doc/intro.xml --- giflib-5.2.1/doc/intro.xml 2019-03-28 17:05:25.000000000 +0000 +++ giflib-5.2.2/doc/intro.xml 2024-02-18 18:15:05.000000000 +0000 @@ -88,95 +88,99 @@ -Test Pattern Generators +Image Manipulation Components -gifbg +gifclrmp -generate a single-color test pattern GIF +modify GIF image colormaps -gifcolor +giffix -generate color test patterns +clumsily attempts to fix truncated GIF images + + + +Report Generators + + -gifwedge +giftext -create a test GIF image resembling a color monitor test pattern +print (text only) general information about a GIF -Image Manipulation Components +GIF Composition Tools -gifclrmp +gifbuild -modify GIF image colormaps +converter/deconverter to/from an editable text format -giffix +giftool -clumsily attempts to fix truncated GIF images +GIF transformation tool -Report Generators +Obsolete utilities + +These are used for testing by the GFLIB developers and no longer +installed by a normal build. -giftext +gifbg -print (text only) general information about a GIF +generate a single-color test pattern GIF -gifhisto +gifcolor -generate color-frequency histogram from a GIF +generate color test patterns - - - -GIF Composition Tools - - -gifbuild +gifwedge -converter/deconverter to/from an editable text format +create a test GIF image resembling a color monitor test pattern -gifecho +gifhisto -generate GIF images out of regular text in 8x8 font +generate color-frequency histogram from a GIF -gifinto +gifecho -end-of-pipe fitting for GIF-processing pipelines +generate GIF images out of regular text in 8x8 font -giftool +gifinto -GIF transformation tool +end-of-pipe fitting for GIF-processing pipelines + Library Functions diff -Nru giflib-5.2.1/doc/whatsinagif/animation_and_transparency.html giflib-5.2.2/doc/whatsinagif/animation_and_transparency.html --- giflib-5.2.1/doc/whatsinagif/animation_and_transparency.html 2014-05-16 10:46:53.000000000 +0000 +++ giflib-5.2.2/doc/whatsinagif/animation_and_transparency.html 2024-02-17 23:06:30.000000000 +0000 @@ -275,7 +275,7 @@ A3 19 82 - 45 + 47 02 00 3B diff -Nru giflib-5.2.1/doc/whatsinagif/bits_and_bytes.html giflib-5.2.2/doc/whatsinagif/bits_and_bytes.html --- giflib-5.2.1/doc/whatsinagif/bits_and_bytes.html 2014-05-16 10:46:53.000000000 +0000 +++ giflib-5.2.2/doc/whatsinagif/bits_and_bytes.html 2024-02-17 23:19:08.000000000 +0000 @@ -221,7 +221,7 @@

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 filed is N, the number of +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; @@ -134,13 +132,13 @@ 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 immediatly follow the colors; however -it is possible to specify a larger LWZ minimum code size which may leave +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 summarizaed in the following table.

- + @@ -226,14 +224,16 @@ K. [Step 6].

LWZ Min Code
Size
Color
Codes
Clear
Code
EOI
Code
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
- + - + + + @@ -1055,7 +1055,7 @@

You can see in the first byte that was returned (8C) that the lowest three bits (because that was -our first code size) contain 110 which is the binary value of 4 so +our first code size) contain 010 which is the binary value of 6 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 Binary files /tmp/tmp5sybf4h0/rYcsqJBSDt/giflib-5.2.1/doc/whatsinagif/sample_2_animation.gif and /tmp/tmp5sybf4h0/_bTQqh5DoO/giflib-5.2.2/doc/whatsinagif/sample_2_animation.gif differ diff -Nru giflib-5.2.1/egif_lib.c giflib-5.2.2/egif_lib.c --- giflib-5.2.1/egif_lib.c 2019-06-24 07:23:37.000000000 +0000 +++ giflib-5.2.2/egif_lib.c 2024-02-19 03:01:28.000000000 +0000 @@ -10,17 +10,17 @@ *****************************************************************************/ +#include #include -#include #include +#include #include -#include #ifdef _WIN32 #include #else -#include #include +#include #endif /* _WIN32 */ #include @@ -29,22 +29,20 @@ /* 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 -}; +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, GifPixelType * Line, - int LineLen); -static int EGifCompressOutput(GifFileType * GifFile, int Code); -static int EGifBufferedOutput(GifFileType * GifFile, GifByteType * Buf, - int c); +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) +#define LOBYTE(x) ((x)&0xff) +#define HIBYTE(x) (((x) >> 8) & 0xff) #ifndef S_IREAD #define S_IREAD S_IRUSR @@ -59,29 +57,31 @@ 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; +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; } /****************************************************************************** @@ -91,462 +91,458 @@ 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; - } +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 */ + _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* _WIN32 */ - f = fdopen(FileHandle, "wb"); /* Make it into a stream: */ + 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; + 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) */ + Private->Write = (OutputFunc)0; /* No user write routine (MRB) */ + GifFile->UserData = (void *)NULL; /* No user write handle (MRB) */ - GifFile->Error = 0; + GifFile->Error = 0; - return GifFile; + 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; +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->Write = writeFunc; /* User write routine (MRB) */ + GifFile->UserData = userData; /* User write handle (MRB) */ - Private->gif89 = false; /* initially, write GIF87 */ + Private->gif89 = false; /* initially, write GIF87 */ - GifFile->Error = 0; + GifFile->Error = 0; - return GifFile; + 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; +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 + 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; +void EGifSetGifVersion(GifFileType *GifFile, const bool gif89) { + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - Private->gif89 = gif89; + 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); +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; - GifFile->SColorMap = NULL; - - 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) { - GifFile->SColorMap = GifMakeMapObject(ColorMap->ColorCount, - ColorMap->Colors); - if (GifFile->SColorMap == NULL) { - GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; - return GIF_ERROR; - } - } else - GifFile->SColorMap = NULL; - - /* - * 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); +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; + GifFile->SColorMap = NULL; + + 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; + } - /* 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; - } - } - } + 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) { + GifFile->SColorMap = + GifMakeMapObject(ColorMap->ColorCount, ColorMap->Colors); + if (GifFile->SColorMap == NULL) { + GifFile->Error = E_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + } else { + GifFile->SColorMap = NULL; + } - /* Mark this file as has screen descriptor, and no pixel written yet: */ - Private->FileState |= FILE_STATE_SCREEN; + /* + * 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; + } + } + } - return GIF_OK; + /* 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; +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; - } - } else { - GifFile->Image.ColorMap = NULL; } - } + 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 { + 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); + /* 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; + } - /* 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; + /* 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); + /* Reset compress algorithm parameters. */ + (void)EGifSetupCompress(GifFile); - return GIF_OK; + 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; +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); + 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]; +int EGifPutPixel(GifFileType *GifFile, GifPixelType Pixel) { + GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; - return EGifCompressLine(GifFile, &Pixel, 1); + 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; +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; } /****************************************************************************** @@ -554,69 +550,63 @@ 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); +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; + 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); +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; + return GIF_OK; } /****************************************************************************** Put a terminating block (see GIF manual) into a GIF file. ******************************************************************************/ -int -EGifPutExtensionTrailer(GifFileType *GifFile) { +int EGifPutExtensionTrailer(GifFileType *GifFile) { - GifByteType Buf; - GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; + 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); + if (!IS_WRITEABLE(Private)) { + /* This file was NOT open for writing: */ + GifFile->Error = E_GIF_ERR_NOT_WRITEABLE; + return GIF_ERROR; + } - return GIF_OK; + /* Write the block terminator */ + Buf = 0; + InternalWrite(GifFile, &Buf, 1); + + return GIF_OK; } /****************************************************************************** @@ -625,34 +615,31 @@ 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); +int EGifPutExtension(GifFileType *GifFile, const int ExtCode, const int ExtLen, + const void *Extension) { - return GIF_OK; + 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; } /****************************************************************************** @@ -660,49 +647,52 @@ ******************************************************************************/ 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; + 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); +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; + } + } - 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); } /****************************************************************************** @@ -712,27 +702,26 @@ 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; - * } - */ +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); + return EGifPutCodeNext(GifFile, CodeBlock); } /****************************************************************************** @@ -740,146 +729,142 @@ 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. */ - } +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; + 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 { - //cppcheck-suppress nullPointerRedundantCheck - File = Private->File; +int EGifCloseFile(GifFileType *GifFile, int *ErrorCode) { + GifByteType Buf; + GifFilePrivateType *Private; + FILE *File; - Buf = TERMINATOR_INTRODUCER; - InternalWrite(GifFile, &Buf, 1); + if (GifFile == NULL) { + return GIF_ERROR; + } - if (GifFile->Image.ColorMap) { - GifFreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; + 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; + } } - if (GifFile->SColorMap) { - GifFreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - } - if (Private) { - 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; + 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; +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; +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; } /****************************************************************************** @@ -888,86 +873,91 @@ This routine can be called a few times (one per scan line, for example), in order to complete the whole image. ******************************************************************************/ -static int -EGifCompressLine(GifFileType *GifFile, - GifPixelType *Line, - 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; - } - } +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; + return GIF_OK; } /****************************************************************************** @@ -976,46 +966,49 @@ 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; - } +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; + return retval; } /****************************************************************************** @@ -1024,37 +1017,35 @@ 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; - } +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; + return GIF_OK; } /****************************************************************************** @@ -1062,104 +1053,111 @@ 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) +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 i, j; + + if (EGifPutScreenDesc(GifFileOut, GifFileOut->SWidth, + GifFileOut->SHeight, GifFileOut->SColorResolution, + GifFileOut->SBackGroundColor, + GifFileOut->SColorMap) == 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 i, j; - - if (EGifPutScreenDesc(GifFileOut, - GifFileOut->SWidth, - GifFileOut->SHeight, - GifFileOut->SColorResolution, - GifFileOut->SBackGroundColor, - GifFileOut->SColorMap) == GIF_ERROR) { - return (GIF_ERROR); - } - - 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) - return (GIF_ERROR); - - if (EGifPutImageDesc(GifFileOut, - sp->ImageDesc.Left, - sp->ImageDesc.Top, - SavedWidth, - SavedHeight, - sp->ImageDesc.Interlace, - sp->ImageDesc.ColorMap) == GIF_ERROR) - return (GIF_ERROR); - - if (sp->ImageDesc.Interlace) { - /* - * The way an interlaced image should be written - - * offsets and jumps... - */ - int InterlacedOffset[] = { 0, 4, 2, 1 }; - int InterlacedJumps[] = { 8, 8, 4, 2 }; - int k; - /* Need to perform 4 passes on the images: */ - for (k = 0; k < 4; k++) - for (j = InterlacedOffset[k]; - j < SavedHeight; - j += InterlacedJumps[k]) { - if (EGifPutLine(GifFileOut, - sp->RasterBits + j * SavedWidth, - SavedWidth) == GIF_ERROR) + } + + 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) { return (GIF_ERROR); } - } else { - for (j = 0; j < SavedHeight; j++) { - if (EGifPutLine(GifFileOut, - sp->RasterBits + j * SavedWidth, - SavedWidth) == GIF_ERROR) - return (GIF_ERROR); - } - } - } - - if (EGifWriteExtensions(GifFileOut, - GifFileOut->ExtensionBlocks, - GifFileOut->ExtensionBlockCount) == GIF_ERROR) - return (GIF_ERROR); - if (EGifCloseFile(GifFileOut, NULL) == GIF_ERROR) - return (GIF_ERROR); + if (EGifPutImageDesc(GifFileOut, sp->ImageDesc.Left, + sp->ImageDesc.Top, SavedWidth, SavedHeight, + sp->ImageDesc.Interlace, + sp->ImageDesc.ColorMap) == GIF_ERROR) { + return (GIF_ERROR); + } + + 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) { + return (GIF_ERROR); + } + } + } + } else { + for (j = 0; j < SavedHeight; j++) { + if (EGifPutLine(GifFileOut, + sp->RasterBits + j * SavedWidth, + SavedWidth) == GIF_ERROR) { + return (GIF_ERROR); + } + } + } + } + + if (EGifWriteExtensions(GifFileOut, GifFileOut->ExtensionBlocks, + GifFileOut->ExtensionBlockCount) == GIF_ERROR) { + return (GIF_ERROR); + } + + if (EGifCloseFile(GifFileOut, NULL) == GIF_ERROR) { + return (GIF_ERROR); + } - return (GIF_OK); + return (GIF_OK); } /* end */ diff -Nru giflib-5.2.1/getarg.c giflib-5.2.2/getarg.c --- giflib-5.2.1/getarg.c 2019-06-24 07:23:51.000000000 +0000 +++ giflib-5.2.2/getarg.c 2024-02-19 03:01:27.000000000 +0000 @@ -106,18 +106,18 @@ **************************************************************************/ -#include +#include +#include #include +#include #include -#include -#include - + #include "getarg.h" -#define MAX_PARAM 100 /* maximum number of parameters allowed. */ -#define CTRL_STR_MAX_LEN 1024 +#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 SPACE_CHAR '|' /* The character not to print using HowTo. */ #define ARG_OK false @@ -126,255 +126,267 @@ /* 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, char **argv_end, - char ***argv, void *Parameters[MAX_PARAM], - int *ParamCount); -static bool GAUpdateParameters(void *Parameters[], int *ParamCount, - char *Option, char *CtrlStrCopy, char *CtrlStr, - char **argv_end, char ***argv); +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(char *CtrlStr, int Max, int *ParamCount); -static bool GAOptionExists(char **argv_end, char **argv); + 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) { +static void *xmalloc(unsigned size) { - void *p; + void *p; - if ((p = malloc(size)) != NULL) - return p; + if ((p = malloc(size)) != NULL) { + return p; + } - fprintf(stderr, "Not enough memory, exit.\n"); - exit(2); + fprintf(stderr, "Not enough memory, exit.\n"); + exit(2); - return NULL; /* Makes warning silent. */ + 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... + 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]; - char **argv_end = 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 < argv_end) { - bool Error = false; - if (!GAOptionExists(argv_end, argv)) - break; /* The loop. */ - char *Option = *argv++; - if ((Error = GAUpdateParameters(Parameters, &ParamCount, Option, - CtrlStrCopy, CtrlStr, argv_end, - &argv)) != false) - return Error; - } - /* Check for results and update trail of command line: */ - return GATestAllSatis(CtrlStrCopy, CtrlStr, argv_end, &argv, Parameters, - &ParamCount) != ARG_OK; +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 !- + 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. + 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, - char **argv_end, - 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)++] = *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; - } +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; + return ARG_OK; } /*************************************************************************** Routine to update the parameters according to the given Option: **************************************************************************/ -static bool -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); +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]))) { - 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! */ - } +static int GAGetParmeters(void *Parameters[], int *ParamCount, + char *CtrlStrCopy, char *Option, char **argv_end, + char ***argv) { + + int i = 0, ScanRes; + + while (!(ISSPACE(CtrlStrCopy[i]))) { - return ARG_OK; + 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; } /*************************************************************************** @@ -385,110 +397,113 @@ 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; +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; } /*************************************************************************** @@ -500,140 +515,156 @@ and one for pointer to block pointers. Note ALL variables are passed by address and so of fixed size (address). ***************************************************************************/ -static void -GASetParamCount(char *CtrlStr, - int Max, - int *ParamCount) { - int i; - - *ParamCount = 0; - for (i = 0; i < Max; i++) - if (ISCTRLCHAR(CtrlStr[i])) { - if (CtrlStr[i + 1] == '*') - *ParamCount += 2; - else - (*ParamCount)++; - } +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(char **argv_end, - char **argv) { - - while (argv < argv_end) - if ((*argv++)[0] == '-') - return true; - return false; +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) { +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); + 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) { +void GAPrintHowTo(char *CtrlStr) { - int i = 0; - bool SpaceFlag; + 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"); + 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 */ diff -Nru giflib-5.2.1/getarg.h giflib-5.2.2/getarg.h --- giflib-5.2.1/getarg.h 2019-06-24 07:32:56.000000000 +0000 +++ giflib-5.2.2/getarg.h 2024-02-19 02:20:00.000000000 +0000 @@ -4,7 +4,7 @@ SPDX-License-Identifier: MIT -**************************************************************************/ + **************************************************************************/ #ifndef _GETARG_H #define _GETARG_H @@ -15,13 +15,13 @@ #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. */ + 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); @@ -30,7 +30,6 @@ /****************************************************************************** From qprintf.c ******************************************************************************/ -extern bool GifNoisyPrint; extern void GifQprintf(char *Format, ...); extern void PrintGifError(int ErrorCode); @@ -38,14 +37,17 @@ Color table quantization ******************************************************************************/ int GifQuantizeBuffer(unsigned int Width, unsigned int Height, - int *ColorMapSize, GifByteType * RedInput, - GifByteType * GreenInput, GifByteType * BlueInput, - GifByteType * OutputBuffer, - GifColorType * OutputColorMap); + int *ColorMapSize, GifByteType *RedInput, + GifByteType *GreenInput, GifByteType *BlueInput, + GifByteType *OutputBuffer, GifColorType *OutputColorMap); /* 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); } +#define GIF_EXIT(Msg) \ + { \ + GIF_MESSAGE(Msg); \ + exit(-3); \ + } #endif /* _GETARG_H */ diff -Nru giflib-5.2.1/gif2rgb.c giflib-5.2.2/gif2rgb.c --- giflib-5.2.1/gif2rgb.c 2019-06-24 07:24:27.000000000 +0000 +++ giflib-5.2.2/gif2rgb.c 2024-02-19 03:01:28.000000000 +0000 @@ -22,517 +22,559 @@ ***************************************************************************/ -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include #ifdef _WIN32 #include #endif /* _WIN32 */ -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "gif2rgb" +#define PROGRAM_NAME "gif2rgb" -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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); +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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."); +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."); } - else { - static 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; + + 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); + _setmode(0, O_BINARY); #endif /* _WIN32 */ - rgbfp[0] = stdin; - } + rgbfp[0] = stdin; + } - GifQprintf("\n%s: RGB image: ", PROGRAM_NAME); + GifQprintf("\n%s: RGB image: ", PROGRAM_NAME); - if (OneFileFlag) { - GifByteType *Buffer, *BufferP; + if (OneFileFlag) { + GifByteType *Buffer, *BufferP; - if ((Buffer = (GifByteType *) malloc(Width * 3)) == NULL) - GIF_EXIT("Failed to allocate memory required, aborted."); + 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++; - } - } + 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; - } + 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]); - } + 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); - } +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) - exit(EXIT_FAILURE); - free((char *) RedBuffer); - free((char *) GreenBuffer); - free((char *) BlueBuffer); + 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); + } - SaveGif(OutputBuffer, Width, Height, ExpNumOfColors, OutputColorMap); + 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) { + exit(EXIT_FAILURE); + } + free((char *)RedBuffer); + free((char *)GreenBuffer); + free((char *)BlueBuffer); + + SaveGif(OutputBuffer, Width, Height, ExpNumOfColors, OutputColorMap); } /****************************************************************************** The real screen dumping routine. ******************************************************************************/ static void DumpScreen2RGB(char *FileName, int OneFileFlag, - ColorMapObject *ColorMap, - 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++) { - strncpy(OneFileName, FileName, sizeof(OneFileName)-1); - strncat(OneFileName, Postfixes[i], - sizeof(OneFileName) - 1 - strlen(OneFileName)); - - if ((rgbfp[i] = fopen(OneFileName, "wb")) == NULL) { - GIF_EXIT("Can't open input file name."); - } - } - } - } else { - OneFileFlag = true; + 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++) { + strncpy(OneFileName, FileName, + sizeof(OneFileName) - 1); + strncat(OneFileName, Postfixes[i], + sizeof(OneFileName) - 1 - + strlen(OneFileName)); + + if ((rgbfp[i] = fopen(OneFileName, "wb")) == + NULL) { + GIF_EXIT("Can't open input file name."); + } + } + } + } else { + OneFileFlag = true; #ifdef _WIN32 - _setmode(1, O_BINARY); + _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++) { - 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++) { - 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; - int - InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ - InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ - int ImageNum = 0; - ColorMapObject *ColorMap; - int Error; - - 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); - } + 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."); } } - 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); + + 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++) { + 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); } - while (Extension != NULL) { - if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + } 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); - } } - 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); - - (void)free(ScreenBuffer); - - if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) { - PrintGifError(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); + + (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; - 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, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); - GAPrintHowTo(CtrlStr); - exit(EXIT_SUCCESS); - } - if (!OutFileFlag) OutFileName = NULL; - - if (SizeFlag && Width > 0 && Height > 0) - RGB2GIF(OneFileFlag, NumFiles, *FileName, - ExpNumOfColors, Width, Height); - else - GIF2RGB(NumFiles, *FileName, OneFileFlag, OutFileName); + * 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, VersionStr, 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; + return 0; } /* end */ diff -Nru giflib-5.2.1/gif_err.c giflib-5.2.2/gif_err.c --- giflib-5.2.1/gif_err.c 2019-06-24 07:26:07.000000000 +0000 +++ giflib-5.2.2/gif_err.c 2024-02-19 02:24:57.000000000 +0000 @@ -14,86 +14,84 @@ /***************************************************************************** Return a string description of the last GIF error *****************************************************************************/ -const char * -GifErrorString(int ErrorCode) -{ - const char *Err; +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; + 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 */ diff -Nru giflib-5.2.1/gif_font.c giflib-5.2.2/gif_font.c --- giflib-5.2.1/gif_font.c 2019-06-24 07:27:04.000000000 +0000 +++ giflib-5.2.2/gif_font.c 2024-02-19 03:01:28.000000000 +0000 @@ -1,13 +1,13 @@ /***************************************************************************** - + gif_font.c - utility font handling and simple drawing for the GIF library - + SPDX-License-Identifier: MIT ****************************************************************************/ -#include #include +#include #include "gif_lib.h" @@ -22,240 +22,240 @@ */ /*@+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 */ + {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@*/ -void -GifDrawText8x8(SavedImage *Image, - const int x, const int y, - const char *legend, - const int color) -{ - int i, j; - const char *cp; - - for (i = 0; i < GIF_FONT_HEIGHT; i++) { - int base = Image->ImageDesc.Width * (y + i) + x; - - for (cp = legend; *cp; cp++) - for (j = 0; j < GIF_FONT_WIDTH; j++) { - if (GifAsciiTable8x8[(short)(*cp)][i] & (1 << (GIF_FONT_WIDTH - j))) - Image->RasterBits[base] = color; - base++; - } - } +void GifDrawText8x8(SavedImage *Image, const int x, const int y, + const char *legend, const int color) { + int i, j; + const char *cp; + + for (i = 0; i < GIF_FONT_HEIGHT; i++) { + int base = Image->ImageDesc.Width * (y + i) + x; + + for (cp = legend; *cp; cp++) { + for (j = 0; j < GIF_FONT_WIDTH; j++) { + if (GifAsciiTable8x8[(short)(*cp)][i] & + (1 << (GIF_FONT_WIDTH - j))) { + Image->RasterBits[base] = color; + } + base++; + } + } + } } -void -GifDrawBox(SavedImage *Image, - const int x, const int y, - const int w, const int d, - const int color) -{ - int j, base = Image->ImageDesc.Width * y + x; - - for (j = 0; j < w; j++) - Image->RasterBits[base + j] = - Image->RasterBits[base + (d * Image->ImageDesc.Width) + j] = color; - - for (j = 0; j < d; j++) - Image->RasterBits[base + j * Image->ImageDesc.Width] = - Image->RasterBits[base + j * Image->ImageDesc.Width + w] = color; +void GifDrawBox(SavedImage *Image, const int x, const int y, const int w, + const int d, const int color) { + int j, base = Image->ImageDesc.Width * y + x; + + for (j = 0; j < w; j++) { + Image->RasterBits[base + j] = + Image->RasterBits[base + (d * Image->ImageDesc.Width) + j] = + color; + } + + for (j = 0; j < d; j++) { + Image->RasterBits[base + j * Image->ImageDesc.Width] = + Image->RasterBits[base + j * Image->ImageDesc.Width + w] = + color; + } } -void -GifDrawRectangle(SavedImage *Image, - const int x, const int y, - const int w, const int d, - const int color) -{ - unsigned char *bp = Image->RasterBits + Image->ImageDesc.Width * y + x; - int i; - - for (i = 0; i < d; i++) - memset(bp + (i * Image->ImageDesc.Width), color, (size_t)w); +void GifDrawRectangle(SavedImage *Image, const int x, const int y, const int w, + const int d, const int color) { + unsigned char *bp = Image->RasterBits + Image->ImageDesc.Width * y + x; + int i; + + for (i = 0; i < d; i++) { + memset(bp + (i * Image->ImageDesc.Width), color, (size_t)w); + } } -void -GifDrawBoxedText8x8(SavedImage *Image, - const int x, const int y, - const char *legend, - const int border, - const int bg, const int fg) -{ - int j = 0, LineCount = 0, TextWidth = 0; - const char *cp; - char *dup; - - /* compute size of text to box */ - for (cp = legend; *cp; cp++) - if (*cp == '\r') { - 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; - - /* draw the text */ - dup = malloc(strlen(legend)+1); - /* FIXME: should return bad status, but that would require API change */ - if (dup != NULL) { - int i = 0; - /* fill the box */ - GifDrawRectangle(Image, x + 1, y + 1, - border + TextWidth * GIF_FONT_WIDTH + border - 1, - border + LineCount * GIF_FONT_HEIGHT + border - 1, bg); - (void)strcpy(dup, (char *)legend); - char *lasts; - cp = strtok_r(dup, "\r\n", &lasts); - do { - int leadspace = 0; - - if (cp[0] == '\t') - leadspace = (TextWidth - strlen(++cp)) / 2; - - GifDrawText8x8(Image, x + border + (leadspace * GIF_FONT_WIDTH), - y + border + (GIF_FONT_HEIGHT * i++), cp, fg); - cp = strtok_r(NULL, "\r\n", &lasts); - } while (cp); - (void)free((void *)dup); - - /* outline the box */ - GifDrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border, - border + LineCount * GIF_FONT_HEIGHT + border, fg); - } +void GifDrawBoxedText8x8(SavedImage *Image, const int x, const int y, + const char *legend, const int border, const int bg, + const int fg) { + int j = 0, LineCount = 0, TextWidth = 0; + const char *cp; + char *dup; + + /* compute size of text to box */ + for (cp = legend; *cp; cp++) { + if (*cp == '\r') { + 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; + } + + /* draw the text */ + dup = malloc(strlen(legend) + 1); + /* FIXME: should return bad status, but that would require API change */ + if (dup != NULL) { + int i = 0; + /* fill the box */ + GifDrawRectangle( + Image, x + 1, y + 1, + border + TextWidth * GIF_FONT_WIDTH + border - 1, + border + LineCount * GIF_FONT_HEIGHT + border - 1, bg); + (void)strcpy(dup, (char *)legend); + char *lasts; + cp = strtok_r(dup, "\r\n", &lasts); + do { + int leadspace = 0; + + if (cp[0] == '\t') { + leadspace = (TextWidth - strlen(++cp)) / 2; + } + + GifDrawText8x8( + Image, x + border + (leadspace * GIF_FONT_WIDTH), + y + border + (GIF_FONT_HEIGHT * i++), cp, fg); + cp = strtok_r(NULL, "\r\n", &lasts); + } while (cp); + (void)free((void *)dup); + + /* outline the box */ + GifDrawBox(Image, x, y, + border + TextWidth * GIF_FONT_WIDTH + border, + border + LineCount * GIF_FONT_HEIGHT + border, fg); + } } /* end */ diff -Nru giflib-5.2.1/gif_hash.c giflib-5.2.2/gif_hash.c --- giflib-5.2.1/gif_hash.c 2019-06-24 07:27:16.000000000 +0000 +++ giflib-5.2.2/gif_hash.c 2024-02-19 03:01:27.000000000 +0000 @@ -13,96 +13,94 @@ *****************************************************************************/ -#include -#include #include +#include #include +#include #include -#include "gif_lib.h" #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 */ +#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; +GifHashTableType *_InitHashTable(void) { + GifHashTableType *HashTable; - if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType))) - == NULL) - return NULL; + if ((HashTable = (GifHashTableType *)malloc( + sizeof(GifHashTableType))) == NULL) { + return NULL; + } - _ClearHashTable(HashTable); + _ClearHashTable(HashTable); - return 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)); +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; +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) { + while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE - NumberOfMisses++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ - HKey = (HKey + 1) & HT_KEY_MASK; - } - HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code); + 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; +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) { + while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) { #ifdef DEBUG_HIT_RATE - NumberOfMisses++; + NumberOfMisses++; #endif /* DEBUG_HIT_RATE */ - if (Key == HTKey) return HT_GET_CODE(HTable[HKey]); - HKey = (HKey + 1) & HT_KEY_MASK; - } + if (Key == HTKey) { + return HT_GET_CODE(HTable[HKey]); + } + HKey = (HKey + 1) & HT_KEY_MASK; + } - return -1; + return -1; } /****************************************************************************** @@ -112,22 +110,19 @@ 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; +static int KeyItem(uint32_t Item) { + return ((Item >> 12) ^ Item) & HT_KEY_MASK; } -#ifdef DEBUG_HIT_RATE +#ifdef DEBUG_HIT_RATE /****************************************************************************** Debugging routine to print the hit ratio - number of times the hash table * was tested per operation. This routine was used to test the KeyItem routine * ******************************************************************************/ -void HashTablePrintHitRatio(void) -{ - printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", - NumberOfMisses, NumberOfTests, - NumberOfMisses * 100 / NumberOfTests); +void HashTablePrintHitRatio(void) { + printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", NumberOfMisses, + NumberOfTests, NumberOfMisses * 100 / NumberOfTests); } -#endif /* DEBUG_HIT_RATE */ +#endif /* DEBUG_HIT_RATE */ /* end */ diff -Nru giflib-5.2.1/gif_hash.h giflib-5.2.2/gif_hash.h --- giflib-5.2.1/gif_hash.h 2019-06-24 07:27:26.000000000 +0000 +++ giflib-5.2.2/gif_hash.h 2024-02-19 02:28:45.000000000 +0000 @@ -9,26 +9,28 @@ #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. */ +#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) +#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]; + uint32_t HTable[HT_SIZE]; } GifHashTableType; GifHashTableType *_InitHashTable(void); diff -Nru giflib-5.2.1/gif_lib.h giflib-5.2.2/gif_lib.h --- giflib-5.2.1/gif_lib.h 2019-06-24 16:16:13.000000000 +0000 +++ giflib-5.2.2/gif_lib.h 2024-02-19 07:35:14.000000000 +0000 @@ -1,7 +1,7 @@ /****************************************************************************** - + gif_lib.h - service library for decoding and encoding GIF images - + SPDX-License-Identifier: MIT *****************************************************************************/ @@ -15,19 +15,19 @@ #define GIFLIB_MAJOR 5 #define GIFLIB_MINOR 2 -#define GIFLIB_RELEASE 1 +#define GIFLIB_RELEASE 2 -#define GIF_ERROR 0 -#define GIF_OK 1 +#define GIF_ERROR 0 +#define GIF_OK 1 -#include #include +#include -#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ +#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. */ +#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; @@ -36,88 +36,88 @@ typedef int GifWord; typedef struct GifColorType { - GifByteType Red, Green, Blue; + GifByteType Red, Green, Blue; } GifColorType; typedef struct ColorMapObject { - int ColorCount; - int BitsPerPixel; - bool SortFlag; - GifColorType *Colors; /* on malloc(3) heap */ + 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 */ + 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) */ + 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 */ + 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! */ + 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) +#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 ';' */ + 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); +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); +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 + 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; /****************************************************************************** @@ -129,49 +129,44 @@ 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 EGifSpew(GifFileType *GifFile); const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */ int EGifCloseFile(GifFileType *GifFile, int *ErrorCode); -#define E_GIF_SUCCEEDED 0 -#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */ -#define E_GIF_ERR_WRITE_FAILED 2 -#define E_GIF_ERR_HAS_SCRN_DSCR 3 -#define E_GIF_ERR_HAS_IMAG_DSCR 4 -#define E_GIF_ERR_NO_COLOR_MAP 5 -#define E_GIF_ERR_DATA_TOO_BIG 6 +#define E_GIF_SUCCEEDED 0 +#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */ +#define E_GIF_ERR_WRITE_FAILED 2 +#define E_GIF_ERR_HAS_SCRN_DSCR 3 +#define E_GIF_ERR_HAS_IMAG_DSCR 4 +#define E_GIF_ERR_NO_COLOR_MAP 5 +#define E_GIF_ERR_DATA_TOO_BIG 6 #define E_GIF_ERR_NOT_ENOUGH_MEM 7 -#define E_GIF_ERR_DISK_IS_FULL 8 -#define E_GIF_ERR_CLOSE_FAILED 9 -#define E_GIF_ERR_NOT_WRITEABLE 10 +#define E_GIF_ERR_DISK_IS_FULL 8 +#define E_GIF_ERR_CLOSE_FAILED 9 +#define E_GIF_ERR_NOT_WRITEABLE 10 /* 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, +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, +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 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 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 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); +int EGifPutCodeNext(GifFileType *GifFile, const GifByteType *GifCodeBlock); /****************************************************************************** GIF decoding routines @@ -180,24 +175,25 @@ /* 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 +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 +#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); @@ -215,11 +211,10 @@ 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 */ +extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */ /***************************************************************************** Everything below this point is new after version 1.2, supporting `slurp @@ -231,26 +226,26 @@ ******************************************************************************/ extern ColorMapObject *GifMakeMapObject(int ColorCount, - const GifColorType *ColorMap); + const GifColorType *ColorMap); extern void GifFreeMapObject(ColorMapObject *Object); extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1, - const ColorMapObject *ColorIn2, - GifPixelType ColorTransIn2[]); + const ColorMapObject *ColorIn2, + GifPixelType ColorTransIn2[]); extern int GifBitSize(int n); /****************************************************************************** - Support for the in-core structures allocation (slurp mode). + Support for the in-core structures allocation (slurp mode). ******************************************************************************/ -extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]); +extern void GifApplyTranslation(SavedImage *Image, + const GifPixelType Translation[]); extern int GifAddExtensionBlock(int *ExtensionBlock_Count, - ExtensionBlock **ExtensionBlocks, - int Function, - unsigned int Len, unsigned char ExtData[]); + ExtensionBlock **ExtensionBlocks, int Function, + unsigned int Len, unsigned char ExtData[]); extern void GifFreeExtensions(int *ExtensionBlock_Count, - ExtensionBlock **ExtensionBlocks); + ExtensionBlock **ExtensionBlocks); extern SavedImage *GifMakeSavedImage(GifFileType *GifFile, - const SavedImage *CopyFrom); + const SavedImage *CopyFrom); extern void GifFreeSavedImages(GifFileType *GifFile); /****************************************************************************** @@ -258,42 +253,36 @@ ******************************************************************************/ int DGifExtensionToGCB(const size_t GifExtensionLength, - const GifByteType *GifExtension, - GraphicsControlBlock *GCB); + const GifByteType *GifExtension, + GraphicsControlBlock *GCB); size_t EGifGCBToExtension(const GraphicsControlBlock *GCB, - GifByteType *GifExtension); + GifByteType *GifExtension); -int DGifSavedExtensionToGCB(GifFileType *GifFile, - int ImageIndex, - GraphicsControlBlock *GCB); -int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, - GifFileType *GifFile, - int ImageIndex); +int DGifSavedExtensionToGCB(GifFileType *GifFile, int ImageIndex, + GraphicsControlBlock *GCB); +int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, + GifFileType *GifFile, int ImageIndex); /****************************************************************************** - The library's internal utility font + The library's internal utility font ******************************************************************************/ -#define GIF_FONT_WIDTH 8 +#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); +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 } diff -Nru giflib-5.2.1/gif_lib_private.h giflib-5.2.2/gif_lib_private.h --- giflib-5.2.1/gif_lib_private.h 2019-06-24 07:28:13.000000000 +0000 +++ giflib-5.2.2/gif_lib_private.h 2024-02-19 02:29:13.000000000 +0000 @@ -9,55 +9,57 @@ #ifndef _GIF_LIB_PRIVATE_H #define _GIF_LIB_PRIVATE_H -#include "gif_lib.h" #include "gif_hash.h" +#include "gif_lib.h" #ifndef SIZE_MAX - #define SIZE_MAX UINTPTR_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 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) +#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; + 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 diff -Nru giflib-5.2.1/gifalloc.c giflib-5.2.2/gifalloc.c --- giflib-5.2.1/gifalloc.c 2019-06-24 07:24:37.000000000 +0000 +++ giflib-5.2.2/gifalloc.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,415 +6,420 @@ ****************************************************************************/ -#include #include +#include #include #include "gif_lib.h" #include "gif_lib_private.h" -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** - Miscellaneous utility functions + 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); +int GifBitSize(int n) { + register int i; + + for (i = 1; i <= 8; i++) { + if ((1 << i) >= n) { + break; + } + } + return (i); } /****************************************************************************** - Color map object functions + Color map object functions ******************************************************************************/ /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ -ColorMapObject * -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)); - } +ColorMapObject *GifMakeMapObject(int ColorCount, const GifColorType *ColorMap) { + ColorMapObject *Object; - return (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 + Free a color map object *******************************************************************************/ -void -GifFreeMapObject(ColorMapObject *Object) -{ - if (Object != NULL) { - (void)free(Object->Colors); - (void)free(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"); - } - } +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 + 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 (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; - } - } +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 (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; + ColorUnion->ColorCount = RoundUpTo; + ColorUnion->BitsPerPixel = NewGifBitSize; - return (ColorUnion); + return (ColorUnion); } /******************************************************************************* Apply a given color translation to the raster bits of an image *******************************************************************************/ -void -GifApplyTranslation(SavedImage *Image, 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]]; +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 + 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; +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 + 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. - */ +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 + * Append an image block to the SavedImages array */ -SavedImage * -GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom) -{ - 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. - */ - - /* 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) { - sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL, - CopyFrom->ExtensionBlockCount, - sizeof(ExtensionBlock)); - if (sp->ExtensionBlocks == NULL) { - FreeLastSavedImage(GifFile); - return (SavedImage *)(NULL); - } - memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, - sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); - } - } - 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; +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. + */ + + /* 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) { + sp->ExtensionBlocks = + (ExtensionBlock *)reallocarray( + NULL, CopyFrom->ExtensionBlockCount, + sizeof(ExtensionBlock)); + if (sp->ExtensionBlocks == NULL) { + FreeLastSavedImage(GifFile); + return (SavedImage *)(NULL); + } + memcpy(sp->ExtensionBlocks, + CopyFrom->ExtensionBlocks, + sizeof(ExtensionBlock) * + CopyFrom->ExtensionBlockCount); + } + } 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 */ diff -Nru giflib-5.2.1/gifbg.c giflib-5.2.2/gifbg.c --- giflib-5.2.1/gifbg.c 2019-06-24 07:24:52.000000000 +0000 +++ giflib-5.2.2/gifbg.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,344 +6,384 @@ *****************************************************************************/ -#include #include -#include #include +#include #include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "gifbg" +#define PROGRAM_NAME "gifbg" -#define DEFAULT_WIDTH 640 -#define DEFAULT_HEIGHT 350 +#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 - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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; +#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 *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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; - 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); - } +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, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); - GAPrintHowTo(CtrlStr); - exit(EXIT_SUCCESS); - } - - /* 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]); + if (HelpFlag) { + (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); + GAPrintHowTo(CtrlStr); + exit(EXIT_SUCCESS); + } - switch(DirectionStr[0]) { + /* 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; + 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; + break; case 'R': /* Right or East */ case 'E': - Direction = DIR_RIGHT; - break; + 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; + if (strlen(DirectionStr) < 2) { + Direction = DIR_BOT; FlipDir = true; - break; + } 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; + 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; + Direction = DIR_LEFT; + FlipDir = true; break; - case DIR_LEFT: + } + 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; - 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); - } + /* 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]."); + } - /* 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) + /* 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); - 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) + + /* Dump out the image descriptor: */ + if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, + NULL) == 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; + + 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."); } - /* 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); - } + 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; + } + } + } + } - return 0; + 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); +static void QuitGifError(GifFileType *GifFile) { + if (GifFile != NULL) { + PrintGifError(GifFile->Error); + EGifCloseFile(GifFile, NULL); + } + exit(EXIT_FAILURE); } /* end */ diff -Nru giflib-5.2.1/gifbuild.c giflib-5.2.2/gifbuild.c --- giflib-5.2.1/gifbuild.c 2019-06-24 12:49:43.000000000 +0000 +++ giflib-5.2.2/gifbuild.c 2024-02-19 03:05:16.000000000 +0000 @@ -6,935 +6,1016 @@ *****************************************************************************/ -#include -#include -#include -#include #include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" + +#define PROGRAM_NAME "gifbuild" -#define PROGRAM_NAME "gifbuild" +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Eric Raymond, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1992 Eric Raymond.\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 char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Eric Raymond, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1992 Eric Raymond.\n"; -static char - *CtrlStr = - PROGRAM_NAME - " v%- d%- t%-Characters!s h%- GifFile(s)!*s"; - -static char KeyLetters[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:<=>?@[\\]^_`{|}~"; -#define PRINTABLES (sizeof(KeyLetters) - 1) - -static void Icon2Gif(char *FileName, FILE *txtin, int fdout); -static void Gif2Icon(char *FileName, - int fdin, int fdout, - char NameTable[]); +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; - 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, VersionStr, 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, 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]); +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 (DisasmFlag) - { - printf("#\n# GIF information from %s\n", FileNames[i]); - Gif2Icon(FileNames[i], -1, 1, TextLineFlag ? TextLines[0] : KeyLetters); - } - else - { - Icon2Gif(FileNames[i], fp, 1); - } + if (HelpFlag) { + (void)fprintf(stderr, VersionStr, 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); + (void)fclose(fp); + } } - } - return 0; + return 0; } /****************************************************************************** Parse image directives ******************************************************************************/ -#define PARSE_ERROR(str) (void) fprintf(stderr,"%s:%d: %s\n",FileName,LineNum,str); +#define PARSE_ERROR(str) \ + (void)fprintf(stderr, "%s:%d: %s\n", FileName, LineNum, str); -static void Icon2Gif(char *FileName, FILE *txtin, 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; +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; - ++LineNum; + if ((GifFileOut = EGifOpenFileHandle(fdout, &ErrorCode)) == NULL) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); + } - /* - * Skip lines consisting only of whitespace and comments - */ - for (cp = buf; isspace((int)(*cp)); cp++) - continue; - if (*cp == '#' || *cp == '\0') - continue; + /* 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'; - } + /* + * 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 - */ + /* + * Explicit header declarations + */ - if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == 1) - continue; + if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == + 1) { + continue; + } - else if (sscanf(buf, "screen height %d\n", &GifFileOut->SHeight) == 1) - continue; + else if (sscanf(buf, "screen height %d\n", + &GifFileOut->SHeight) == 1) { + 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); - } + else if (sscanf(buf, "screen colors %d\n", &n) == 1) { + int ResBits = GifBitSize(n); - GifFileOut->SColorResolution = ResBits; - continue; - } + if (n > 256 || n < 0 || n != (1 << ResBits)) { + PARSE_ERROR("Invalid color resolution value."); + exit(EXIT_FAILURE); + } - else if (sscanf(buf, - "screen background %d\n", - &GifFileOut->SBackGroundColor) == 1) - continue; + GifFileOut->SColorResolution = ResBits; + continue; + } - else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) { - GifFileOut->AspectByte = (GifByteType)(intval & 0xff); - continue; - } + else if (sscanf(buf, "screen background %d\n", + &GifFileOut->SBackGroundColor) == 1) { + continue; + } - /* - * Color table parsing - */ + else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) { + GifFileOut->AspectByte = (GifByteType)(intval & 0xff); + continue; + } - 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); - } + /* + * 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)); - } + 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); - } + 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)); - } + 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) - { - ColorMap[ColorMapSize].Red = red; - ColorMap[ColorMapSize].Green = green; - ColorMap[ColorMapSize].Blue = blue; - ColorMapSize++; - } + 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); + } + 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) - { - 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 on\n") == 0) { + SortFlag = true; + } - else if (strcmp(buf, " sort flag off\n") == 0) - SortFlag = false; + else if (strcmp(buf, " sort flag off\n") == 0) { + SortFlag = false; + } - else if (strcmp(buf, "end\n") == 0) - { - ColorMapObject *NewMap; + 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 = 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; + NewMap->SortFlag = SortFlag; - if (NewImage) - NewImage->ImageDesc.ColorMap = NewMap; - else - GifFileOut->SColorMap = NewMap; - } + 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) - { - int ErrorCode; - bool DoTranslation; - GifPixelType Translation[256]; + /* 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); + } - GifFileType *Inclusion; - SavedImage *CopyFrom; + 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); + } - if ((Inclusion = DGifOpenFileName(InclusionFile, &ErrorCode)) == NULL) { - PrintGifError(ErrorCode); - 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); + } - if (DGifSlurp(Inclusion) == GIF_ERROR) - { - PARSE_ERROR("Inclusion read failed."); - if (Inclusion != NULL) { - PrintGifError(Inclusion->Error); - DGifCloseFile(Inclusion, NULL); - } - if (GifFileOut != NULL) { - EGifCloseFile(GifFileOut, NULL); - }; - exit(EXIT_FAILURE); - } + GifFreeMapObject(GifFileOut->SColorMap); + GifFileOut->SColorMap = UnionMap; + } - //cppcheck-suppress nullPointerRedundantCheck - if ((DoTranslation = (GifFileOut->SColorMap!=(ColorMapObject*)NULL))) - { - ColorMapObject *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); + } - //cppcheck-suppress nullPointerRedundantCheck - UnionMap = GifUnionColorMap(GifFileOut->SColorMap, Inclusion->SColorMap, Translation); + (void)DGifCloseFile(Inclusion, NULL); + } - if (UnionMap == NULL) - { - PARSE_ERROR("Inclusion failed --- global map conflict."); - //cppcheck-suppress nullPointerRedundantCheck - PrintGifError(GifFileOut->Error); - if (Inclusion != NULL) DGifCloseFile(Inclusion, NULL); - if (GifFileOut != NULL) EGifCloseFile(GifFileOut, NULL); - exit(EXIT_FAILURE); - } - - GifFreeMapObject(GifFileOut->SColorMap); - GifFileOut->SColorMap = UnionMap; - } - - //cppcheck-suppress nullPointerRedundantCheck - for (CopyFrom = Inclusion->SavedImages; - //cppcheck-suppress nullPointerRedundantCheck - CopyFrom < Inclusion->SavedImages + Inclusion->ImageCount; - CopyFrom++) - { - SavedImage *NewImage; - if ((NewImage = GifMakeSavedImage(GifFileOut, CopyFrom)) == NULL) - { - PARSE_ERROR("Inclusion failed --- out of memory."); - //cppcheck-suppress nullPointerRedundantCheck - PrintGifError(GifFileOut->Error); - 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); - } + /* + * 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); + } - (void) DGifCloseFile(Inclusion, NULL); - } + } 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); + } - /* - * 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; + } 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); + } + } + } + } - 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); - } + /* + * 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; } - } - 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."); + /* + * 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); - } } - } - 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)) + /* + * Accept image attributes + */ + else if (sscanf(buf, "image top %d\n", + &NewImage->ImageDesc.Top) == 1) { 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)) + } + + else if (sscanf(buf, "image left %d\n", + &NewImage->ImageDesc.Left) == 1) { continue; - if (sscanf(tp, "transparent index %d\n", - &gcb.TransparentColor)) + } + + else if (strcmp(buf, "image interlaced\n") == 0) { + NewImage->ImageDesc.Interlace = true; 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; + 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); + + /* coverity[overflow_sink] */ + if ((Raster = (GifPixelType *)malloc( + sizeof(GifPixelType) * + NewImage->ImageDesc.Width * + NewImage->ImageDesc.Height)) == 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); + } - 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."); + NewImage->RasterBits = (unsigned char *)Raster; + } else { + (void)fputs(buf, stderr); + PARSE_ERROR("Syntax error in image description."); exit(EXIT_FAILURE); - } } } - /* - * Explicit image declarations - */ + /* connect trailing extension blocks */ + GifFileOut->ExtensionBlockCount = LeadingExtensionBlockCount; + GifFileOut->ExtensionBlocks = LeadingExtensionBlocks; + // LeadingExtensionBlockCount = 0; + LeadingExtensionBlocks = NULL; - 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); - } + EGifSpew(GifFileOut); +} - /* 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; - } +static void VisibleDumpBuffer(GifByteType *buf, int len) +/* Visibilize a given string */ +{ + GifByteType *cp; - /* - * 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); + 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); + } } +} - /* - * Accept image attributes - */ - else if (sscanf(buf, "image top %d\n", &NewImage->ImageDesc.Top) == 1) - continue; +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"); + } + } +} - else if (sscanf(buf, "image left %d\n", &NewImage->ImageDesc.Left)== 1) - continue; +static void Gif2Icon(char *FileName, int fdin, int fdout, char NameTable[]) { + int ErrorCode, im, i, j, ColorCount = 0; + GifFileType *GifFile; + + 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); + } + } - 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, *cp; - int c; - bool hex = (strstr(buf, "hex") != NULL); - - /* coverity[overflow_sink] */ - if ((Raster = (GifPixelType *) malloc(sizeof(GifPixelType) * NewImage->ImageDesc.Width * NewImage->ImageDesc.Height)) - == NULL) { - PARSE_ERROR("Failed to allocate raster block, aborted."); + if (DGifSlurp(GifFile) == GIF_ERROR) { + PrintGifError(GifFile->Error); 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); + printf("screen width %d\nscreen height %d\n", GifFile->SWidth, + GifFile->SHeight); - cp = Raster; - for (i = 0; i < NewImage->ImageDesc.Height; i++) { + 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) { + 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"); + } - char *dp; + for (im = 0; im < GifFile->ImageCount; im++) { + SavedImage *image = &GifFile->SavedImages[im]; - 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); - *cp++ = (hi << 4) | lo; - } - else if ((dp = strchr(KeyTable, c))) - *cp++ = (dp - KeyTable); - else { - PARSE_ERROR("Invalid ASCII pixel key."); - exit(EXIT_FAILURE); - } + DumpExtensions(GifFile, image->ExtensionBlockCount, + image->ExtensionBlocks); - 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; - - EGifSpew(GifFileOut); -} + 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"); + } -static void VisibleDumpBuffer(GifByteType *buf, int len) -/* Visibilize a given string */ -{ - GifByteType *cp; + if (image->ImageDesc.ColorMap) { + printf("image map\n"); - 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); - } -} + 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++) { + 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"); + } -static void DumpExtensions(GifFileType *GifFileOut, - int ExtensionBlockCount, - ExtensionBlock *ExtensionBlocks) -{ - ExtensionBlock *ep; + /* 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; + } - 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); + 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'); - } - 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"); + + 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); } - } -} -static void Gif2Icon(char *FileName, - int fdin, int fdout, - char NameTable[]) -{ - int ErrorCode, im, i, j, ColorCount = 0; - GifFileType *GifFile; + /* + * Sanity checks. + */ - 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) - 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++) - 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); - } + /* 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; + 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; - } + 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); + return (tp - StartAddr); } /* end */ - diff -Nru giflib-5.2.1/gifclrmp.c giflib-5.2.2/gifclrmp.c --- giflib-5.2.1/gifclrmp.c 2019-06-24 07:25:44.000000000 +0000 +++ giflib-5.2.2/gifclrmp.c 2024-02-19 03:01:27.000000000 +0000 @@ -6,43 +6,32 @@ *****************************************************************************/ -#include -#include +#include #include -#include +#include #include +#include #include -#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "gifclrmp" +#define PROGRAM_NAME "gifclrmp" -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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 char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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); @@ -50,312 +39,377 @@ /****************************************************************************** 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; - 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); - } +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, VersionStr, 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 (HelpFlag) { - (void)fprintf(stderr, VersionStr, 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) { + 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); - } } - 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) + } + /* 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); + } + } - 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) + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == 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) + } + + 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); } - 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; + 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++) { - NewMap->Colors[i] = ColorMap->Colors[Translation[i]]; - } - - return(NewMap); - } - else - { - GIF_EXIT("Nothing to do!"); - return(ColorMap); - } +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++) { + 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); +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 */ diff -Nru giflib-5.2.1/gifcolor.c giflib-5.2.2/gifcolor.c --- giflib-5.2.1/gifcolor.c 2019-06-24 07:25:51.000000000 +0000 +++ giflib-5.2.2/gifcolor.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,165 +6,162 @@ *****************************************************************************/ -#include -#include #include -#include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "gifcolor" +#define PROGRAM_NAME "gifcolor" -#define LINE_LEN 40 -#define IMAGEWIDTH LINE_LEN*GIF_FONT_WIDTH +#define LINE_LEN 40 +#define IMAGEWIDTH LINE_LEN *GIF_FONT_WIDTH -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\n"; -static char - *CtrlStr = PROGRAM_NAME " v%- b%-Background!d h%-"; +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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); + 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); - } +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, VersionStr, 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); - } + if (HelpFlag) { + (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); + GAPrintHowTo(CtrlStr); + exit(EXIT_SUCCESS); + } - /* 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) + /* 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); - GifQprintf("\b\b\b\b%-4d", l++); } - } - if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) - { - PrintGifError(ErrorCode); - exit(EXIT_FAILURE); - } + /* 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++); + } + } - return 0; + 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; + 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); +static void QuitGifError(GifFileType *GifFile) { + if (GifFile != NULL) { + PrintGifError(GifFile->Error); + EGifCloseFile(GifFile, NULL); + } + exit(EXIT_FAILURE); } diff -Nru giflib-5.2.1/gifecho.c giflib-5.2.2/gifecho.c --- giflib-5.2.1/gifecho.c 2019-06-24 07:25:59.000000000 +0000 +++ giflib-5.2.2/gifecho.c 2024-02-19 03:01:27.000000000 +0000 @@ -6,204 +6,223 @@ *****************************************************************************/ -#include -#include #include -#include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" + +#define PROGRAM_NAME "gifecho" -#define PROGRAM_NAME "gifecho" +#define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */ -#define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */ +#define LINE_LEN 256 /* Maximum length of one text line. */ -#define LINE_LEN 256 /* Maximum length of one text line. */ +#define DEFAULT_FG_INDEX 1 /* Text foreground index. */ -#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 -#define DEFAULT_COLOR_RED 255 /* Text foreground color. */ -#define DEFAULT_COLOR_GREEN 255 -#define DEFAULT_COLOR_BLUE 255 - -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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 char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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); + 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; - 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); - } +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, VersionStr, 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) - 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); - } + if (HelpFlag) { + (void)fprintf(stderr, VersionStr, 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) { + GIF_EXIT( + "Failed to allocate memory required, aborted."); + } + } - /* 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) + /* 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); - GifQprintf("\b\b\b\b%-4d", l++); } - } - if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) - { - PrintGifError(ErrorCode); - exit(EXIT_FAILURE); - } + /* 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); + } - return 0; + 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; + 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); + * 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 */ diff -Nru giflib-5.2.1/giffilter.c giflib-5.2.2/giffilter.c --- giflib-5.2.1/giffilter.c 2019-06-24 07:26:43.000000000 +0000 +++ giflib-5.2.2/giffilter.c 2024-02-19 03:01:28.000000000 +0000 @@ -1,6 +1,6 @@ /****************************************************************************** - -giffilter.c - skeleton file for generic GIF `filter' program + +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 @@ -20,135 +20,154 @@ ******************************************************************************/ +#include #include #include #include -#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "giffilter" +#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); +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); - } +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); - } + /* 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) + /* 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); - 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; + 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 */ diff -Nru giflib-5.2.1/giffix.c giflib-5.2.2/giffix.c --- giflib-5.2.1/giffix.c 2019-06-24 07:26:51.000000000 +0000 +++ giflib-5.2.2/giffix.c 2024-02-19 03:01:27.000000000 +0000 @@ -6,213 +6,239 @@ *****************************************************************************/ -#include -#include #include -#include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "giffix" +#define PROGRAM_NAME "giffix" -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\n"; -static char - *CtrlStr = - PROGRAM_NAME - " v%- h%- GifFile!*s"; +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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; - 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); - } +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, VersionStr, 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); - } + if (HelpFlag) { + (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); + GAPrintHowTo(CtrlStr); + exit(EXIT_SUCCESS); + } - /* 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; - } + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == + NULL) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); } - - /* 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); + } else { + /* Use stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); } + } - 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) + /* 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); - 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; + 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); +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 */ diff -Nru giflib-5.2.1/gifhisto.c giflib-5.2.2/gifhisto.c --- giflib-5.2.1/gifhisto.c 2019-06-24 07:27:35.000000000 +0000 +++ giflib-5.2.2/gifhisto.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,254 +6,293 @@ *****************************************************************************/ -#include -#include #include -#include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "gifhisto" +#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 - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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 } - }; +#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 *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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; - 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); - } +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, VersionStr, 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); + } + } - if (HelpFlag) { - (void)fprintf(stderr, VersionStr, 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) + 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); - 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) + 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); } - 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); - } + /* 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--); + } + } - /* 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); + if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); + } } - } - return 0; + 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); +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 */ diff -Nru giflib-5.2.1/gifinto.c giflib-5.2.2/gifinto.c --- giflib-5.2.1/gifinto.c 2019-06-24 07:27:45.000000000 +0000 +++ giflib-5.2.2/gifinto.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,12 +6,12 @@ *****************************************************************************/ +#include #include +#include #include #include -#include #include -#include #ifdef _WIN32 #include @@ -19,51 +19,40 @@ #include #endif /* _WIN32 */ -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" + +#define PROGRAM_NAME "gifinto" -#define PROGRAM_NAME "gifinto" +#define STRLEN 512 -#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" -#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 - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\n"; -static char - *CtrlStr = - PROGRAM_NAME - " v%- s%-MinFileSize!d h%- GifFile!*s"; +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\n"; +static char *CtrlStr = PROGRAM_NAME " v%- s%-MinFileSize!d h%- GifFile!*s"; -static int - MinFileSize = DEFAULT_MIN_FILE_SIZE; +static int MinFileSize = DEFAULT_MIN_FILE_SIZE; #ifdef _WIN32 #include #include -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; +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 @@ -71,121 +60,138 @@ 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; - 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, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); - GAPrintHowTo(CtrlStr); - exit(EXIT_SUCCESS); - } +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, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR); + GAPrintHowTo(CtrlStr); + exit(EXIT_SUCCESS); + } - /* Open the stdin in binary mode and increase its buffer size: */ + /* Open the stdin in binary mode and increase its buffer size: */ #ifdef _WIN32 - _setmode(0, O_BINARY); /* Make sure it is in binary mode. */ + _setmode(0, O_BINARY); /* Make sure it is in binary mode. */ #endif - Fin = fdopen(0, "rb"); /* Make it into a stream: */ + Fin = fdopen(0, "rb"); /* Make it into a stream: */ + + if (Fin == NULL) { + GIF_EXIT("Failed to open input."); + } - 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 ( 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); + /* 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 (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; + char *tmpFN = _mktemp(FoutTmpName); + if (tmpFN) { + FD = open(tmpFN, O_CREAT | O_EXCL | O_WRONLY); + } else { + FD = -1; + } #else - FD = mkstemp(FoutTmpName); /* returns filedescriptor */ + 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 { + 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("Failed to rename out file - deleted."); - } + GIF_MESSAGE("File too small - not renamed."); } - } - else { - fclose(Fout); - unlink(FoutTmpName); - GIF_MESSAGE("File too small - not renamed."); - } - return 0; + return 0; } /* end */ diff -Nru giflib-5.2.1/gifsponge.c giflib-5.2.2/gifsponge.c --- giflib-5.2.1/gifsponge.c 2019-06-24 07:28:45.000000000 +0000 +++ giflib-5.2.2/gifsponge.c 2024-02-19 03:01:28.000000000 +0000 @@ -20,68 +20,71 @@ ****************************************************************************/ +#include #include #include #include -#include -#include "gif_lib.h" #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) == GIF_ERROR) - PrintGifError(GifFileOut->Error); +#define PROGRAM_NAME "gifsponge" - if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) - PrintGifError(ErrorCode); +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) == GIF_ERROR) { + PrintGifError(GifFileOut->Error); + } + + if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { + PrintGifError(ErrorCode); + } - return 0; + return 0; } /* end */ diff -Nru giflib-5.2.1/giftext.c giflib-5.2.2/giftext.c --- giflib-5.2.1/giftext.c 2019-06-24 07:28:55.000000000 +0000 +++ giflib-5.2.2/giftext.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,36 +6,30 @@ *****************************************************************************/ -#include -#include #include #include #include +#include +#include #ifdef _WIN32 #include #endif /* _WIN32 */ -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" -#define PROGRAM_NAME "giftext" +#define PROGRAM_NAME "giftext" -#define MAKE_PRINTABLE(c) (isprint(c) ? (c) : ' ') +#define MAKE_PRINTABLE(c) (isprint(c) ? (c) : ' ') -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\n"; -static char - *CtrlStr = - PROGRAM_NAME - " v%- c%- e%- z%- p%- r%- h%- GifFile!*s"; +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\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 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); @@ -43,268 +37,320 @@ /****************************************************************************** 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; - 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, VersionStr, 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; +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, VersionStr, 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 && 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"); + _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 && 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"); } - } } + } - 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) { + do { + if (DGifGetRecordType(GifFile, &RecordType) == 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"); + } + 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 APPLICATION_EXT_FUNC_CODE: - printf("GIF89 application block"); + 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; - default: - printf("Extension record of unknown type"); + case TERMINATE_RECORD_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) + default: /* Should be trapped by DGifGetRecordType */ break; - PrintExtBlock(Extension, false); } - break; - case TERMINATE_RECORD_TYPE: - break; - default: /* Should be trapped by DGifGetRecordType */ - break; - } - } - while (RecordType != TERMINATE_RECORD_TYPE); + } while (RecordType != TERMINATE_RECORD_TYPE); - if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { - PrintGifError(ErrorCode); - exit(EXIT_FAILURE); - } + if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); + } - if (!RawFlag) printf("\nGIF file terminated normally.\n"); + if (!RawFlag) { + printf("\nGIF file terminated normally.\n"); + } - return 0; + return 0; } /****************************************************************************** @@ -312,46 +358,56 @@ 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; - } - - 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; - } +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; + } + } } /****************************************************************************** @@ -359,44 +415,45 @@ 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], 3, - " %02x", Extension[i]); - (void)snprintf(&AsciiForm[CrntPlace], 3, - "%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; +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], 3, " %02x", + Extension[i]); + (void)snprintf(&AsciiForm[CrntPlace], 3, "%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; + } + } } - } } /****************************************************************************** @@ -404,63 +461,69 @@ 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], 3, - " %02x", PixelBlock[i]); - (void)snprintf(&AsciiForm[CrntPlace], 3, - "%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; +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], 3, " %02x", + PixelBlock[i]); + (void)snprintf(&AsciiForm[CrntPlace], 3, "%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); +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 */ diff -Nru giflib-5.2.1/giftool.c giflib-5.2.2/giftool.c --- giflib-5.2.1/giftool.c 2019-06-24 07:29:02.000000000 +0000 +++ giflib-5.2.2/giftool.c 2024-02-19 03:01:28.000000000 +0000 @@ -6,574 +6,645 @@ ****************************************************************************/ +#include +#include #include #include #include -#include -#include +#include "getarg.h" #include "getopt.h" #include "gif_lib.h" -#include "getarg.h" -#define PROGRAM_NAME "giftool" +#define PROGRAM_NAME "giftool" -#define MAX_OPERATIONS 256 -#define MAX_IMAGES 2048 +#define MAX_OPERATIONS 256 +#define MAX_IMAGES 2048 -enum boolmode {numeric, onoff, tf, yesno}; +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; +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 */ + 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; - - 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", - sp->name); - exit(EXIT_FAILURE); +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; + } + } + + if (sp == NULL) { + (void)fprintf(stderr, + "giftool: %s is not a valid boolean argument.\n", + // cppcheck-suppress nullPointerRedundantCheck + sp->name); + } + 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; - }; + 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"); +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; - if (span > 0) - { - selected[nselected++] = atoi(cp)-1; - cp += span; - if (*cp == '\0') + default: + fprintf(stderr, + "usage: giftool [-b color] [-d delay] [-iI] " + "[-t color] -[uU] [-x disposal]\n"); break; - else if (*cp == ',') - continue; } - (void) fprintf(stderr, "giftool: bad selection.\n"); - exit(EXIT_FAILURE); - } - break; + ++top; + } - 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"); + /* read in a GIF */ + if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) { + PrintGifError(ErrorCode); 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"); + } + if (DGifSlurp(GifFileIn) == GIF_ERROR) { + PrintGifError(GifFileIn->Error); + exit(EXIT_FAILURE); + } + if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) { + PrintGifError(ErrorCode); 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); + } + } + } - /* 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; - /* 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 delaytime: - for (i = 0; i < nselected; i++) - { - GraphicsControlBlock gcb; + 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; - 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 interlace: + for (i = 0; i < nselected; i++) { + GifFileIn->SavedImages[selected[i]] + .ImageDesc.Interlace = op->flag; + } + break; - case transparent: - for (i = 0; i < nselected; i++) - { - GraphicsControlBlock gcb; + 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; - DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); - gcb.TransparentColor = op->color; - EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]); - } - break; + case screensize: + GifFileIn->SWidth = op->p.x; + GifFileIn->SHeight = op->p.y; + break; - case userinput: - for (i = 0; i < nselected; i++) - { - GraphicsControlBlock gcb; + 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; - DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb); - gcb.UserInputFlag = op->flag; - 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; + 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); + } + } - 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) == GIF_ERROR) - PrintGifError(GifFileOut->Error); - else if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) - PrintGifError(ErrorCode); + /* 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) == GIF_ERROR) { + PrintGifError(GifFileOut->Error); + } else if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) { + PrintGifError(ErrorCode); + } - return 0; + return 0; } /* end */ diff -Nru giflib-5.2.1/gifwedge.c giflib-5.2.2/gifwedge.c --- giflib-5.2.1/gifwedge.c 2019-06-24 07:29:10.000000000 +0000 +++ giflib-5.2.2/gifwedge.c 2024-02-19 03:01:27.000000000 +0000 @@ -6,138 +6,148 @@ *****************************************************************************/ -#include -#include #include -#include #include +#include +#include +#include -#include "gif_lib.h" #include "getarg.h" +#include "gif_lib.h" + +#define PROGRAM_NAME "gifwedge" -#define PROGRAM_NAME "gifwedge" +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 350 -#define DEFAULT_WIDTH 640 -#define DEFAULT_HEIGHT 350 +#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */ -#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */ +static char *VersionStr = PROGRAM_NAME VERSION_COOKIE + " Gershon Elber, " __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber.\n"; +static char *CtrlStr = PROGRAM_NAME " v%- l%-#Lvls!d s%-Width|Height!d!d h%-"; -static char - *VersionStr = - PROGRAM_NAME - VERSION_COOKIE - " Gershon Elber, " - __DATE__ ", " __TIME__ "\n" - "(C) Copyright 1989 Gershon Elber.\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; +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; - GifRowType Line; - ColorMapObject *ColorMap; - 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, VersionStr, 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); - } - - /* 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) { +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; + ColorMapObject *ColorMap; + 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, VersionStr, 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); + } + + /* Dump out the image descriptor: */ + if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, false, + NULL) == GIF_ERROR) { + PrintGifError(GifFile->Error); exit(EXIT_FAILURE); - } - GifQprintf("\b\b\b\b%-4d", Count++); } - } - if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { - PrintGifError(ErrorCode); - 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++); + } + } + + if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) { + PrintGifError(ErrorCode); + exit(EXIT_FAILURE); + } - return 0; + return 0; } /* end */ diff -Nru giflib-5.2.1/openbsd-reallocarray.c giflib-5.2.2/openbsd-reallocarray.c --- giflib-5.2.1/openbsd-reallocarray.c 2019-06-24 07:31:35.000000000 +0000 +++ giflib-5.2.2/openbsd-reallocarray.c 2024-02-19 01:15:19.000000000 +0000 @@ -3,24 +3,22 @@ * SPDX-License-Identifier: MIT */ -#include #include #include #include +#include #ifndef SIZE_MAX - #define SIZE_MAX UINTPTR_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)) +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) -void * -openbsd_reallocarray(void *optr, size_t nmemb, size_t size) -{ +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; @@ -68,7 +66,8 @@ * fuzzing on one platform may not detect zero-size allocation * problems on other platforms. */ - if (size == 0 || nmemb == 0) - return NULL; + if (size == 0 || nmemb == 0) { + return NULL; + } return realloc(optr, size * nmemb); } diff -Nru giflib-5.2.1/qprintf.c giflib-5.2.2/qprintf.c --- giflib-5.2.1/qprintf.c 2019-06-24 07:29:51.000000000 +0000 +++ giflib-5.2.2/qprintf.c 2024-02-19 03:01:28.000000000 +0000 @@ -3,15 +3,14 @@ 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 *****************************************************************************/ - -#include -#include #include +#include +#include #include "gif_lib.h" @@ -20,29 +19,28 @@ /***************************************************************************** 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); - } +void GifQprintf(char *Format, ...) { + va_list ArgPtr; + + va_start(ArgPtr, Format); - va_end(ArgPtr); + 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); +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 */ diff -Nru giflib-5.2.1/quantize.c giflib-5.2.2/quantize.c --- giflib-5.2.1/quantize.c 2019-06-24 07:30:17.000000000 +0000 +++ giflib-5.2.2/quantize.c 2024-02-19 03:01:27.000000000 +0000 @@ -13,34 +13,36 @@ ******************************************************************************/ -#include #include +#include + #include "gif_lib.h" #include "gif_lib_private.h" -#define ABS(x) ((x) > 0 ? (x) : (-(x))) +#define ABS(x) ((x) > 0 ? (x) : (-(x))) #define COLOR_ARRAY_SIZE 32768 #define BITS_PER_PRIM_COLOR 5 -#define MAX_PRIM_COLOR 0x1f +#define MAX_PRIM_COLOR 0x1f static int SortRGBAxis; typedef struct QuantizedColorType { - GifByteType RGB[3]; - GifByteType NewColorIndex; - long Count; - struct QuantizedColorType *Pnext; + 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; + 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, +static int SubdivColorMap(NewColorMapType *NewColorSubdiv, unsigned int ColorMapSize, unsigned int *NewColorMapSize); static int SortCmpRtn(const void *Entry1, const void *Entry2); @@ -57,136 +59,150 @@ 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, - GifByteType * RedInput, - GifByteType * GreenInput, - 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]); - } +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]); + fprintf(stderr, + "Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n", + MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]); #endif /* DEBUG */ - free((char *)ColorArrayEntries); + free((char *)ColorArrayEntries); - *ColorMapSize = NewColorMapSize; + *ColorMapSize = NewColorMapSize; - return GIF_OK; + return GIF_OK; } /****************************************************************************** @@ -195,138 +211,147 @@ 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 = 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; +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]; + NewColorSubdiv[Index].RGBWidth[SortRGBAxis] = + MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis]; - (*NewColorMapSize)++; - } + (*NewColorMapSize)++; + } - return GIF_OK; + 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]; +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; + return hash1 - hash2; } /* end */

Step Action Index Stream New Code Table Row Code Stream
0 Init