编译uos-amd64版本的giflib库

This commit is contained in:
luoliangyi 2022-07-12 11:19:36 +08:00
parent ba40c13cdf
commit 7f15550da1
32 changed files with 9950 additions and 0 deletions

View File

@ -20,6 +20,7 @@
<Add directory="../../../third_party/zlib/uos/amd64/include" /> <Add directory="../../../third_party/zlib/uos/amd64/include" />
<Add directory="../../../third_party/libpng/uos/amd64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/amd64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/amd64/include" /> <Add directory="../../../third_party/libtiff/uos/amd64/include" />
<Add directory="../../../third_party/giflib/uos/amd64/include" />
<Add directory="../../../third_party/libzip/uos/amd64/include" /> <Add directory="../../../third_party/libzip/uos/amd64/include" />
<Add directory="../../../third_party/tinyxml2/uos/amd64/include" /> <Add directory="../../../third_party/tinyxml2/uos/amd64/include" />
<Add directory="../../../third_party/pdflib/uos/amd64/include" /> <Add directory="../../../third_party/pdflib/uos/amd64/include" />
@ -30,6 +31,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/amd64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/amd64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/amd64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/amd64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/amd64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/amd64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/amd64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/amd64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/amd64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/amd64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/amd64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/amd64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/amd64/lib -lz" />
@ -50,6 +52,7 @@
<Add directory="../../../third_party/zlib/uos/amd64/include" /> <Add directory="../../../third_party/zlib/uos/amd64/include" />
<Add directory="../../../third_party/libpng/uos/amd64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/amd64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/amd64/include" /> <Add directory="../../../third_party/libtiff/uos/amd64/include" />
<Add directory="../../../third_party/giflib/uos/amd64/include" />
<Add directory="../../../third_party/libzip/uos/amd64/include" /> <Add directory="../../../third_party/libzip/uos/amd64/include" />
<Add directory="../../../third_party/tinyxml2/uos/amd64/include" /> <Add directory="../../../third_party/tinyxml2/uos/amd64/include" />
<Add directory="../../../third_party/pdflib/uos/amd64/include" /> <Add directory="../../../third_party/pdflib/uos/amd64/include" />
@ -61,6 +64,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/amd64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/amd64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/amd64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/amd64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/amd64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/amd64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/amd64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/amd64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/amd64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/amd64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/amd64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/amd64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/amd64/lib -lz" />
@ -81,6 +85,7 @@
<Add directory="../../../third_party/zlib/uos/aarch64/include" /> <Add directory="../../../third_party/zlib/uos/aarch64/include" />
<Add directory="../../../third_party/libpng/uos/aarch64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/aarch64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/aarch64/include" /> <Add directory="../../../third_party/libtiff/uos/aarch64/include" />
<Add directory="../../../third_party/giflib/uos/aarch64/include" />
<Add directory="../../../third_party/libzip/uos/aarch64/include" /> <Add directory="../../../third_party/libzip/uos/aarch64/include" />
<Add directory="../../../third_party/tinyxml2/uos/aarch64/include" /> <Add directory="../../../third_party/tinyxml2/uos/aarch64/include" />
<Add directory="../../../third_party/pdflib/uos/aarch64/include" /> <Add directory="../../../third_party/pdflib/uos/aarch64/include" />
@ -91,6 +96,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/aarch64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/aarch64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/aarch64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/aarch64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/aarch64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/aarch64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/aarch64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/aarch64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/aarch64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/aarch64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/aarch64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/aarch64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/aarch64/lib -lz" />
@ -111,6 +117,7 @@
<Add directory="../../../third_party/zlib/uos/aarch64/include" /> <Add directory="../../../third_party/zlib/uos/aarch64/include" />
<Add directory="../../../third_party/libpng/uos/aarch64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/aarch64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/aarch64/include" /> <Add directory="../../../third_party/libtiff/uos/aarch64/include" />
<Add directory="../../../third_party/giflib/uos/aarch64/include" />
<Add directory="../../../third_party/libzip/uos/aarch64/include" /> <Add directory="../../../third_party/libzip/uos/aarch64/include" />
<Add directory="../../../third_party/tinyxml2/uos/aarch64/include" /> <Add directory="../../../third_party/tinyxml2/uos/aarch64/include" />
<Add directory="../../../third_party/pdflib/uos/aarch64/include" /> <Add directory="../../../third_party/pdflib/uos/aarch64/include" />
@ -122,6 +129,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/aarch64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/aarch64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/aarch64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/aarch64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/aarch64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/aarch64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/aarch64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/aarch64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/aarch64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/aarch64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/aarch64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/aarch64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/aarch64/lib -lz" />
@ -142,6 +150,7 @@
<Add directory="../../../third_party/zlib/uos/mips64/include" /> <Add directory="../../../third_party/zlib/uos/mips64/include" />
<Add directory="../../../third_party/libpng/uos/mips64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/mips64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/mips64/include" /> <Add directory="../../../third_party/libtiff/uos/mips64/include" />
<Add directory="../../../third_party/giflib/uos/mips64/include" />
<Add directory="../../../third_party/libzip/uos/mips64/include" /> <Add directory="../../../third_party/libzip/uos/mips64/include" />
<Add directory="../../../third_party/tinyxml2/uos/mips64/include" /> <Add directory="../../../third_party/tinyxml2/uos/mips64/include" />
<Add directory="../../../third_party/pdflib/uos/mips64/include" /> <Add directory="../../../third_party/pdflib/uos/mips64/include" />
@ -152,6 +161,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/mips64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/mips64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/mips64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/mips64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/mips64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/mips64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/mips64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/mips64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/mips64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/mips64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/mips64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/mips64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/mips64/lib -lz" />
@ -172,6 +182,7 @@
<Add directory="../../../third_party/zlib/uos/mips64/include" /> <Add directory="../../../third_party/zlib/uos/mips64/include" />
<Add directory="../../../third_party/libpng/uos/mips64/include/libpng16" /> <Add directory="../../../third_party/libpng/uos/mips64/include/libpng16" />
<Add directory="../../../third_party/libtiff/uos/mips64/include" /> <Add directory="../../../third_party/libtiff/uos/mips64/include" />
<Add directory="../../../third_party/giflib/uos/mips64/include" />
<Add directory="../../../third_party/libzip/uos/mips64/include" /> <Add directory="../../../third_party/libzip/uos/mips64/include" />
<Add directory="../../../third_party/tinyxml2/uos/mips64/include" /> <Add directory="../../../third_party/tinyxml2/uos/mips64/include" />
<Add directory="../../../third_party/pdflib/uos/mips64/include" /> <Add directory="../../../third_party/pdflib/uos/mips64/include" />
@ -183,6 +194,7 @@
<Add option="-L../../../third_party/libnsbmp/uos/mips64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/uos/mips64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/uos/mips64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/uos/mips64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/uos/mips64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/uos/mips64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/uos/mips64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/uos/mips64/lib -lzip" /> <Add option="-L../../../third_party/libzip/uos/mips64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/uos/mips64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/uos/mips64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/uos/mips64/lib -lz" /> <Add option="-L../../../third_party/zlib/uos/mips64/lib -lz" />
@ -203,6 +215,7 @@
<Add directory="../../../third_party/zlib/kylin/amd64/include" /> <Add directory="../../../third_party/zlib/kylin/amd64/include" />
<Add directory="../../../third_party/libpng/kylin/amd64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/amd64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/amd64/include" /> <Add directory="../../../third_party/libtiff/kylin/amd64/include" />
<Add directory="../../../third_party/giflib/kylin/amd64/include" />
<Add directory="../../../third_party/libzip/kylin/amd64/include" /> <Add directory="../../../third_party/libzip/kylin/amd64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/amd64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/amd64/include" />
<Add directory="../../../third_party/pdflib/kylin/amd64/include" /> <Add directory="../../../third_party/pdflib/kylin/amd64/include" />
@ -213,6 +226,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/amd64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/amd64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/amd64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/amd64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/amd64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/amd64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/amd64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/amd64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/amd64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/amd64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/amd64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/amd64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/amd64/lib -lz" />
@ -233,6 +247,7 @@
<Add directory="../../../third_party/zlib/kylin/amd64/include" /> <Add directory="../../../third_party/zlib/kylin/amd64/include" />
<Add directory="../../../third_party/libpng/kylin/amd64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/amd64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/amd64/include" /> <Add directory="../../../third_party/libtiff/kylin/amd64/include" />
<Add directory="../../../third_party/giflib/kylin/amd64/include" />
<Add directory="../../../third_party/libzip/kylin/amd64/include" /> <Add directory="../../../third_party/libzip/kylin/amd64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/amd64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/amd64/include" />
<Add directory="../../../third_party/pdflib/kylin/amd64/include" /> <Add directory="../../../third_party/pdflib/kylin/amd64/include" />
@ -244,6 +259,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/amd64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/amd64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/amd64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/amd64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/amd64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/amd64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/amd64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/amd64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/amd64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/amd64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/amd64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/amd64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/amd64/lib -lz" />
@ -264,6 +280,7 @@
<Add directory="../../../third_party/zlib/kylin/aarch64/include" /> <Add directory="../../../third_party/zlib/kylin/aarch64/include" />
<Add directory="../../../third_party/libpng/kylin/aarch64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/aarch64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/aarch64/include" /> <Add directory="../../../third_party/libtiff/kylin/aarch64/include" />
<Add directory="../../../third_party/giflib/kylin/aarch64/include" />
<Add directory="../../../third_party/libzip/kylin/aarch64/include" /> <Add directory="../../../third_party/libzip/kylin/aarch64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/aarch64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/aarch64/include" />
<Add directory="../../../third_party/pdflib/kylin/aarch64/include" /> <Add directory="../../../third_party/pdflib/kylin/aarch64/include" />
@ -274,6 +291,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/aarch64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/aarch64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/aarch64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/aarch64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/aarch64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/aarch64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/aarch64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/aarch64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/aarch64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/aarch64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/aarch64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/aarch64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/aarch64/lib -lz" />
@ -294,6 +312,7 @@
<Add directory="../../../third_party/zlib/kylin/aarch64/include" /> <Add directory="../../../third_party/zlib/kylin/aarch64/include" />
<Add directory="../../../third_party/libpng/kylin/aarch64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/aarch64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/aarch64/include" /> <Add directory="../../../third_party/libtiff/kylin/aarch64/include" />
<Add directory="../../../third_party/giflib/kylin/aarch64/include" />
<Add directory="../../../third_party/libzip/kylin/aarch64/include" /> <Add directory="../../../third_party/libzip/kylin/aarch64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/aarch64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/aarch64/include" />
<Add directory="../../../third_party/pdflib/kylin/aarch64/include" /> <Add directory="../../../third_party/pdflib/kylin/aarch64/include" />
@ -305,6 +324,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/aarch64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/aarch64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/aarch64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/aarch64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/aarch64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/aarch64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/aarch64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/aarch64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/aarch64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/aarch64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/aarch64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/aarch64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/aarch64/lib -lz" />
@ -325,6 +345,7 @@
<Add directory="../../../third_party/zlib/kylin/mips64/include" /> <Add directory="../../../third_party/zlib/kylin/mips64/include" />
<Add directory="../../../third_party/libpng/kylin/mips64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/mips64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/mips64/include" /> <Add directory="../../../third_party/libtiff/kylin/mips64/include" />
<Add directory="../../../third_party/giflib/kylin/mips64/include" />
<Add directory="../../../third_party/libzip/kylin/mips64/include" /> <Add directory="../../../third_party/libzip/kylin/mips64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/mips64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/mips64/include" />
<Add directory="../../../third_party/pdflib/kylin/mips64/include" /> <Add directory="../../../third_party/pdflib/kylin/mips64/include" />
@ -335,6 +356,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/mips64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/mips64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/mips64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/mips64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/mips64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/mips64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/mips64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/mips64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/mips64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/mips64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/mips64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/mips64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/mips64/lib -lz" />
@ -355,6 +377,7 @@
<Add directory="../../../third_party/zlib/kylin/mips64/include" /> <Add directory="../../../third_party/zlib/kylin/mips64/include" />
<Add directory="../../../third_party/libpng/kylin/mips64/include/libpng16" /> <Add directory="../../../third_party/libpng/kylin/mips64/include/libpng16" />
<Add directory="../../../third_party/libtiff/kylin/mips64/include" /> <Add directory="../../../third_party/libtiff/kylin/mips64/include" />
<Add directory="../../../third_party/giflib/kylin/mips64/include" />
<Add directory="../../../third_party/libzip/kylin/mips64/include" /> <Add directory="../../../third_party/libzip/kylin/mips64/include" />
<Add directory="../../../third_party/tinyxml2/kylin/mips64/include" /> <Add directory="../../../third_party/tinyxml2/kylin/mips64/include" />
<Add directory="../../../third_party/pdflib/kylin/mips64/include" /> <Add directory="../../../third_party/pdflib/kylin/mips64/include" />
@ -366,6 +389,7 @@
<Add option="-L../../../third_party/libnsbmp/kylin/mips64/lib -lnsbmp" /> <Add option="-L../../../third_party/libnsbmp/kylin/mips64/lib -lnsbmp" />
<Add option="-L../../../third_party/libpng/kylin/mips64/lib -lpng16" /> <Add option="-L../../../third_party/libpng/kylin/mips64/lib -lpng16" />
<Add option="-L../../../third_party/libtiff/kylin/mips64/lib -ltiff" /> <Add option="-L../../../third_party/libtiff/kylin/mips64/lib -ltiff" />
<Add option="-L../../../third_party/giflib/kylin/mips64/lib -lgiflib" />
<Add option="-L../../../third_party/libzip/kylin/mips64/lib -lzip" /> <Add option="-L../../../third_party/libzip/kylin/mips64/lib -lzip" />
<Add option="-L../../../third_party/tinyxml2/kylin/mips64/lib -ltinyxml2" /> <Add option="-L../../../third_party/tinyxml2/kylin/mips64/lib -ltinyxml2" />
<Add option="-L../../../third_party/zlib/kylin/mips64/lib -lz" /> <Add option="-L../../../third_party/zlib/kylin/mips64/lib -lz" />
@ -386,6 +410,8 @@
</Linker> </Linker>
<Unit filename="../../../modules/imgfmt/HGBmp.cpp" /> <Unit filename="../../../modules/imgfmt/HGBmp.cpp" />
<Unit filename="../../../modules/imgfmt/HGBmp.h" /> <Unit filename="../../../modules/imgfmt/HGBmp.h" />
<Unit filename="../../../modules/imgfmt/HGGif.cpp" />
<Unit filename="../../../modules/imgfmt/HGGif.h" />
<Unit filename="../../../modules/imgfmt/HGImgFmt.cpp" /> <Unit filename="../../../modules/imgfmt/HGImgFmt.cpp" />
<Unit filename="../../../modules/imgfmt/HGImgFmt.h" /> <Unit filename="../../../modules/imgfmt/HGImgFmt.h" />
<Unit filename="../../../modules/imgfmt/HGImgFmtErr.h" /> <Unit filename="../../../modules/imgfmt/HGImgFmtErr.h" />

1241
third_party/giflib/giflib/dgif_lib.c vendored Normal file

File diff suppressed because it is too large Load Diff

1165
third_party/giflib/giflib/egif_lib.c vendored Normal file

File diff suppressed because it is too large Load Diff

639
third_party/giflib/giflib/getarg.c vendored Normal file
View File

@ -0,0 +1,639 @@
/***************************************************************************
getarg.c - routines to grab the parameters from the command line:
Names of all the routines except the main one start with GA (Get
Arguments) to prevent conflicts.
The following routines are available in this module:
1. int GAGetArgs(argc, argv, CtrlStr, Variables...)
where argc, argv are received on entry.
CtrlStr is the contrl string (see below)
Variables are all the variables to be set according to CtrlStr.
Note that all the variables MUST be transfered by address.
Return 0 on correct parsing, otherwise error number (see GetArg.h).
2. GAPrintHowTo(CtrlStr)
Print the control string to stderr, in the correct format.
This feature is very useful in case of an error during GetArgs parsing.
Chars equal to SPACE_CHAR are not printed (regular spaces are NOT
allowed, and so using SPACE_CHAR you can create space in PrintHowTo).
3. GAPrintErrMsg(Error)
Describe the error to stderr, according to Error (usually returned by
GAGetArgs).
CtrlStr format:
The control string passed to GetArgs controls the way argv (argc) are
parsed. Each entry in this string must not have any spaces in it. The
First Entry is the name of the program, which is usually ignored except
when GAPrintHowTo is called. All the other entries (except the last one
which we will come back to later) must have the following format:
1. One letter which sets the option letter.
2. '!' or '%' to determines if this option is really optional ('%') or
required ('!')...
3. '-' must always be given.
4. Alphanumeric string, usually ignored, but used by GAPrintHowTo to
print the meaning of this option.
5. Sequences starts with '!' or '%'. Again if '!' then this sequence
must exist (only if its option flag is given of course), and if '%'
it is optional. Each sequence will continue with one or two
characters which defines the kind of the input:
a: d, x, o, u - integer is expected (decimal, hex, octal base or unsigned).
b: D, X, O, U - long integer is expected (same as above).
c: f - float number is expected.
d: F - double number is expected.
e: s - string is expected.
f: *? - any number of '?' kind (d, x, o, u, D, X, O, U, f, F, s)
will match this one. If '?' is numeric, it scans until
non-numeric input is given. If '?' is 's' then it scans
up to the next option or end of argv.
If the last parameter given in the CtrlStr, is not an option (i.e. the
second char is not in ['!', '%'] and the third one is not '-'), all what
remained from argv is linked to it.
The variables passed to GAGetArgs (starting from 4th parameter) MUST
match the order of the CtrlStr:
For each option, one integer address must be passed. This integer must
be initialized with 0. If that option is given in the command line, it will
be set.
In addition, the sequences that might follow an option require the
following parameters to pass:
1. d, x, o, u - pointer to integer (int *).
2. D, X, O, U - pointer to long (long *).
3. f - pointer to float (float *).
4. F - pointer to double (double *).
5. s - pointer to char (char *). NO allocation is needed!
6. *? - TWO variables are passed for each wild request. the first
one is (address of) integer, and it will return number of
parameters actually matched this sequence, and the second
one is a pointer to pointer to ? (? **), and will return an
address to a block of pointers to ? kind, terminated with
NULL pointer. NO pre-allocation is required. The caller is
responsible for freeing this memory, including the pointed to
memory.
Note that these two variables are pretty like the argv/argc pair...
Examples:
"Example1 i%-OneInteger!d s%-Strings!*s j%- k!-Float!f Files"
Will match: Example1 -i 77 -s String1 String2 String3 -k 88.2 File1 File2
or: Example1 -s String1 -k 88.3 -i 999 -j
but not: Example1 -i 77 78 (option i expects one integer, k must be).
Note the option k must exist, and that the order of the options is not
important. In the first examples File1 & File2 will match the Files
in the command line.
A call to GAPrintHowTo with this CtrlStr will print to stderr:
Example1 [-i OneIngeter] [-s Strings...] [-j] -k Float Files...
Notes:
1. This module assumes that all the pointers to all kind of data types
have the same length and format, i.e. sizeof(int *) == sizeof(char *).
SPDX-License-Identifier: MIT
**************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdarg.h>
#include "getarg.h"
#define MAX_PARAM 100 /* maximum number of parameters allowed. */
#define CTRL_STR_MAX_LEN 1024
#define SPACE_CHAR '|' /* The character not to print using HowTo. */
#define ARG_OK false
#define ISSPACE(x) ((x) <= ' ') /* Not conventional - but works fine! */
/* The two characters '%' and '!' are used in the control string: */
#define ISCTRLCHAR(x) (((x) == '%') || ((x) == '!'))
static char *GAErrorToken; /* On error, ErrorToken is set to point to it. */
static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr, 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 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);
/***************************************************************************
Allocate or die
***************************************************************************/
static void *
xmalloc(unsigned size) {
void *p;
if ((p = malloc(size)) != NULL)
return p;
fprintf(stderr, "Not enough memory, exit.\n");
exit(2);
return NULL; /* Makes warning silent. */
}
/***************************************************************************
Routine to access the command line argument and interpret them:
Return ARG_OK (0) is case of successful parsing, error code else...
***************************************************************************/
bool
GAGetArgs(int argc,
char **argv,
char *CtrlStr, ...) {
int i, ParamCount = 0;
void *Parameters[MAX_PARAM]; /* Save here parameter addresses. */
char CtrlStrCopy[CTRL_STR_MAX_LEN];
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;
}
/***************************************************************************
Routine to search for unsatisfied flags - simply scan the list for !-
sequence. Before this scan, this routine updates the rest of the command
line into the last two parameters if it is requested by the CtrlStr
(last item in CtrlStr is NOT an option).
Return ARG_OK if all satisfied, CMD_ERR_AllSatis error else.
***************************************************************************/
static int
GATestAllSatis(char *CtrlStrCopy,
char *CtrlStr,
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;
}
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);
}
/***************************************************************************
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! */
}
return ARG_OK;
}
/***************************************************************************
Routine to get a few parameters into one pointer such that the returned
pointer actually points on a block of pointers to the parameters...
For example *F means a pointer to pointers on floats.
Returns number of parameters actually read.
This routine assumes that all pointers (on any kind of scalar) has the
same size (and the union below is totally ovelapped bteween dif. arrays)
***************************************************************************/
static int
GAGetMultiParmeters(void *Parameters[],
int *ParamCount,
char *CtrlStrCopy,
char **argv_end,
char ***argv) {
int i = 0, ScanRes, NumOfPrm = 0;
void **Pmain, **Ptemp;
union TmpArray { /* Save here the temporary data before copying it to */
void *VoidArray[MAX_PARAM]; /* the returned pointer block. */
int *IntArray[MAX_PARAM];
long *LngArray[MAX_PARAM];
float *FltArray[MAX_PARAM];
double *DblArray[MAX_PARAM];
char *ChrArray[MAX_PARAM];
} TmpArray;
do {
switch (CtrlStrCopy[2]) { /* CtrlStr == '!*?' or '%*?' where ? is. */
case 'd': /* Format to read the parameters: */
TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%d",
(int *)TmpArray.IntArray[NumOfPrm++]);
break;
case 'u':
TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%u",
(unsigned int *)TmpArray.IntArray[NumOfPrm++]);
break;
case 'o':
TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%o",
(unsigned int *)TmpArray.IntArray[NumOfPrm++]);
break;
case 'x':
TmpArray.IntArray[NumOfPrm] = xmalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%x",
(unsigned int *)TmpArray.IntArray[NumOfPrm++]);
break;
case 'D':
TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%ld",
(long *)TmpArray.IntArray[NumOfPrm++]);
break;
case 'U':
TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lu",
(unsigned long *)TmpArray.
IntArray[NumOfPrm++]);
break;
case 'O':
TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lo",
(unsigned long *)TmpArray.
IntArray[NumOfPrm++]);
break;
case 'X':
TmpArray.LngArray[NumOfPrm] = xmalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lx",
(unsigned long *)TmpArray.
IntArray[NumOfPrm++]);
break;
case 'f':
TmpArray.FltArray[NumOfPrm] = xmalloc(sizeof(float));
ScanRes = sscanf(*((*argv)++), "%f",
// cppcheck-suppress invalidPointerCast
(float *)TmpArray.LngArray[NumOfPrm++]);
break;
case 'F':
TmpArray.DblArray[NumOfPrm] = xmalloc(sizeof(double));
ScanRes = sscanf(*((*argv)++), "%lf",
// cppcheck-suppress invalidPointerCast
(double *)TmpArray.LngArray[NumOfPrm++]);
break;
case 's':
while ((*argv < argv_end) && ((**argv)[0] != '-')) {
TmpArray.ChrArray[NumOfPrm++] = *((*argv)++);
}
ScanRes = 0; /* Force quit from do - loop. */
NumOfPrm++; /* Updated again immediately after loop! */
(*argv)++; /* "" */
break;
default:
ScanRes = 0; /* Make optimizer warning silent. */
}
}
while (ScanRes == 1); /* Exactly one parameter was read. */
(*argv)--;
NumOfPrm--;
/* Now allocate the block with the exact size, and set it: */
Ptemp = Pmain = xmalloc((unsigned)(NumOfPrm + 1) * sizeof(void *));
/* And here we use the assumption that all pointers are the same: */
for (i = 0; i < NumOfPrm; i++)
*Ptemp++ = TmpArray.VoidArray[i];
*Ptemp = NULL; /* Close the block with NULL pointer. */
/* That it save the number of parameters read as first parameter to
* return and the pointer to the block as second, and return: */
*(int *)Parameters[(*ParamCount)++] = NumOfPrm;
*(void ***)Parameters[(*ParamCount)++] = Pmain;
/* free(Pmain); -- can not free here as caller needs to access memory */
return NumOfPrm;
}
/***************************************************************************
Routine to scan the CtrlStr, up to Max and count the number of parameters
to that point:
1. Each option is counted as one parameter - boolean variable (int)
2. Within an option, each %? or !? is counted once - pointer to something
3. Within an option, %*? or !*? is counted twice - one for item count
and one for pointer to block pointers.
Note ALL variables are passed by address and so of fixed size (address).
***************************************************************************/
static void
GASetParamCount(char *CtrlStr,
int Max,
int *ParamCount) {
int i;
*ParamCount = 0;
for (i = 0; i < Max; i++)
if (ISCTRLCHAR(CtrlStr[i])) {
if (CtrlStr[i + 1] == '*')
*ParamCount += 2;
else
(*ParamCount)++;
}
}
/***************************************************************************
Routine to 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;
}
/***************************************************************************
Routine to print some error messages, for this module:
***************************************************************************/
void
GAPrintErrMsg(int Error) {
fprintf(stderr, "Error in command line parsing - ");
switch (Error) {
case 0:;
fprintf(stderr, "Undefined error");
break;
case CMD_ERR_NotAnOpt:
fprintf(stderr, "None option Found");
break;
case CMD_ERR_NoSuchOpt:
fprintf(stderr, "Undefined option Found");
break;
case CMD_ERR_WildEmpty:
fprintf(stderr, "Empty input for '!*?' seq.");
break;
case CMD_ERR_NumRead:
fprintf(stderr, "Failed on reading number");
break;
case CMD_ERR_AllSatis:
fprintf(stderr, "Fail to satisfy");
break;
}
fprintf(stderr, " - '%s'.\n", GAErrorToken);
}
/***************************************************************************
Routine to print correct format of command line allowed:
***************************************************************************/
void
GAPrintHowTo(char *CtrlStr) {
int i = 0;
bool SpaceFlag;
fprintf(stderr, "Usage: ");
/* Print program name - first word in ctrl. str. (optional): */
while (!(ISSPACE(CtrlStr[i])) && (!ISCTRLCHAR(CtrlStr[i + 1])))
fprintf(stderr, "%c", CtrlStr[i++]);
while (i < (int)strlen(CtrlStr)) {
// cppcheck-suppress arrayIndexThenCheck
while ((ISSPACE(CtrlStr[i])) && (i < (int)strlen(CtrlStr)))
i++;
switch (CtrlStr[i + 1]) {
case '%':
fprintf(stderr, " [-%c", CtrlStr[i++]);
i += 2; /* Skip the '%-' or '!- after the char! */
SpaceFlag = true;
while (!ISCTRLCHAR(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) &&
(!ISSPACE(CtrlStr[i])))
if (SpaceFlag) {
if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, " %c", CtrlStr[i - 1]);
SpaceFlag = false;
} else if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, "%c", CtrlStr[i - 1]);
while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr))) {
if (CtrlStr[i] == '*')
fprintf(stderr, "...");
i++; /* Skip the rest of it. */
}
fprintf(stderr, "]");
break;
case '!':
fprintf(stderr, " -%c", CtrlStr[i++]);
i += 2; /* Skip the '%-' or '!- after the char! */
SpaceFlag = true;
while (!ISCTRLCHAR(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) &&
(!ISSPACE(CtrlStr[i])))
if (SpaceFlag) {
if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, " %c", CtrlStr[i - 1]);
SpaceFlag = false;
} else if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, "%c", CtrlStr[i - 1]);
while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr))) {
if (CtrlStr[i] == '*')
fprintf(stderr, "...");
i++; /* Skip the rest of it. */
}
break;
default: /* Not checked, but must be last one! */
fprintf(stderr, " ");
while (!ISSPACE(CtrlStr[i]) && (i < (int)strlen(CtrlStr)) &&
!ISCTRLCHAR(CtrlStr[i]))
fprintf(stderr, "%c", CtrlStr[i++]);
fprintf(stderr, "\n");
return;
}
}
fprintf(stderr, "\n");
}
/* end */

52
third_party/giflib/giflib/getarg.h vendored Normal file
View File

@ -0,0 +1,52 @@
/***************************************************************************
getarg.h - Support routines for the giflib utilities
SPDX-License-Identifier: MIT
**************************************************************************/
#ifndef _GETARG_H
#define _GETARG_H
#include "gif_lib.h"
#include <stdbool.h>
#define VERSION_COOKIE " Version %d.%d, "
/***************************************************************************
Error numbers as returned by GAGetArg routine:
***************************************************************************/
#define CMD_ERR_NotAnOpt 1 /* None Option found. */
#define CMD_ERR_NoSuchOpt 2 /* Undefined Option Found. */
#define CMD_ERR_WildEmpty 3 /* Empty input for !*? seq. */
#define CMD_ERR_NumRead 4 /* Failed on reading number. */
#define CMD_ERR_AllSatis 5 /* Fail to satisfy (must-'!') option. */
bool GAGetArgs(int argc, char **argv, char *CtrlStr, ...);
void GAPrintErrMsg(int Error);
void GAPrintHowTo(char *CtrlStr);
/******************************************************************************
From qprintf.c
******************************************************************************/
extern bool GifNoisyPrint;
extern void GifQprintf(char *Format, ...);
extern void PrintGifError(int ErrorCode);
/******************************************************************************
Color table quantization
******************************************************************************/
int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
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); }
#endif /* _GETARG_H */
/* end */

538
third_party/giflib/giflib/gif2rgb.c vendored Normal file
View File

@ -0,0 +1,538 @@
/*****************************************************************************
gif2rgb - convert GIF to 24-bit RGB pixel triples or vice-versa
SPDX-License-Identifier: MIT
*****************************************************************************/
/***************************************************************************
Toshio Kuratomi had written this in a comment about the rgb2gif code:
Besides fixing bugs, what's really needed is for someone to work out how to
calculate a colormap for writing GIFs from rgb sources. Right now, an rgb
source that has only two colors (b/w) is being converted into an 8 bit GIF....
Which is horrendously wasteful without compression.
I (ESR) took this off the main to-do list in 2012 because I don't think
the GIFLIB project actually needs to be in the converters-and-tools business.
Plenty of hackers do that; our job is to supply stable library capability
with our utilities mainly interesting as test tools.
***************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif /* _WIN32 */
#include "gif_lib.h"
#include "getarg.h"
#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);
/******************************************************************************
Load RGB file into internal frame buffer.
******************************************************************************/
static void LoadRGB(char *FileName,
int OneFileFlag,
GifByteType **RedBuffer,
GifByteType **GreenBuffer,
GifByteType **BlueBuffer,
int Width, int Height)
{
int i;
unsigned long Size;
GifByteType *RedP, *GreenP, *BlueP;
FILE *rgbfp[3];
Size = ((long) Width) * Height * sizeof(GifByteType);
if ((*RedBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL ||
(*GreenBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL ||
(*BlueBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
RedP = *RedBuffer;
GreenP = *GreenBuffer;
BlueP = *BlueBuffer;
if (FileName != NULL) {
if (OneFileFlag) {
if ((rgbfp[0] = fopen(FileName, "rb")) == NULL)
GIF_EXIT("Can't open input file name.");
}
else {
static char *Postfixes[] = { ".R", ".G", ".B" };
char OneFileName[80];
for (i = 0; i < 3; i++) {
strncpy(OneFileName, FileName, sizeof(OneFileName)-1);
strncat(OneFileName, Postfixes[i],
sizeof(OneFileName) - 1 - strlen(OneFileName));
if ((rgbfp[i] = fopen(OneFileName, "rb")) == NULL)
GIF_EXIT("Can't open input file name.");
}
}
}
else {
OneFileFlag = true;
#ifdef _WIN32
_setmode(0, O_BINARY);
#endif /* _WIN32 */
rgbfp[0] = stdin;
}
GifQprintf("\n%s: RGB image: ", PROGRAM_NAME);
if (OneFileFlag) {
GifByteType *Buffer, *BufferP;
if ((Buffer = (GifByteType *) malloc(Width * 3)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
for (i = 0; i < Height; i++) {
int j;
GifQprintf("\b\b\b\b%-4d", i);
if (fread(Buffer, Width * 3, 1, rgbfp[0]) != 1)
GIF_EXIT("Input file(s) terminated prematurly.");
for (j = 0, BufferP = Buffer; j < Width; j++) {
*RedP++ = *BufferP++;
*GreenP++ = *BufferP++;
*BlueP++ = *BufferP++;
}
}
free((char *) Buffer);
fclose(rgbfp[0]);
}
else {
for (i = 0; i < Height; i++) {
GifQprintf("\b\b\b\b%-4d", i);
if (fread(RedP, Width, 1, rgbfp[0]) != 1 ||
fread(GreenP, Width, 1, rgbfp[1]) != 1 ||
fread(BlueP, Width, 1, rgbfp[2]) != 1)
GIF_EXIT("Input file(s) terminated prematurly.");
RedP += Width;
GreenP += Width;
BlueP += Width;
}
fclose(rgbfp[0]);
fclose(rgbfp[1]);
fclose(rgbfp[2]);
}
}
/******************************************************************************
Save the GIF resulting image.
******************************************************************************/
static void SaveGif(GifByteType *OutputBuffer,
int Width, int Height,
int ExpColorMapSize, ColorMapObject *OutputColorMap)
{
int i, Error;
GifFileType *GifFile;
GifByteType *Ptr = OutputBuffer;
/* Open stdout for the output file: */
if ((GifFile = EGifOpenFileHandle(1, &Error)) == NULL) {
PrintGifError(Error);
exit(EXIT_FAILURE);
}
if (EGifPutScreenDesc(GifFile,
Width, Height, ExpColorMapSize, 0,
OutputColorMap) == GIF_ERROR ||
EGifPutImageDesc(GifFile,
0, 0, Width, Height, false, NULL) == GIF_ERROR) {
PrintGifError(Error);
exit(EXIT_FAILURE);
}
GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ",
PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
GifFile->Image.Width, GifFile->Image.Height);
for (i = 0; i < Height; i++) {
if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR)
exit(EXIT_FAILURE);
GifQprintf("\b\b\b\b%-4d", Height - i - 1);
Ptr += Width;
}
if (EGifCloseFile(GifFile, &Error) == GIF_ERROR) {
PrintGifError(Error);
exit(EXIT_FAILURE);
}
}
/******************************************************************************
Close output file (if open), and exit.
******************************************************************************/
static void RGB2GIF(bool OneFileFlag, int NumFiles, char *FileName,
int ExpNumOfColors, int Width, int Height)
{
int ColorMapSize;
GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL,
*OutputBuffer = NULL;
ColorMapObject *OutputColorMap = NULL;
ColorMapSize = 1 << ExpNumOfColors;
if (NumFiles == 1) {
LoadRGB(FileName, OneFileFlag,
&RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height);
}
else {
LoadRGB(NULL, OneFileFlag,
&RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height);
}
if ((OutputColorMap = GifMakeMapObject(ColorMapSize, NULL)) == NULL ||
(OutputBuffer = (GifByteType *) malloc(Width * Height *
sizeof(GifByteType))) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
if (GifQuantizeBuffer(Width, Height, &ColorMapSize,
RedBuffer, GreenBuffer, BlueBuffer,
OutputBuffer, OutputColorMap->Colors) == GIF_ERROR)
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;
#ifdef _WIN32
_setmode(1, O_BINARY);
#endif /* _WIN32 */
rgbfp[0] = stdout;
}
if (ColorMap == NULL) {
fprintf(stderr, "Color map pointer is NULL.\n");
exit(EXIT_FAILURE);
}
if (OneFileFlag) {
unsigned char *Buffer, *BufferP;
if ((Buffer = (unsigned char *) malloc(ScreenWidth * 3)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
for (i = 0; i < ScreenHeight; i++) {
GifRow = ScreenBuffer[i];
GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
for (j = 0, BufferP = Buffer; j < ScreenWidth; j++) {
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);
}
}
}
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);
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);
return 0;
}
/* end */

99
third_party/giflib/giflib/gif_err.c vendored Normal file
View File

@ -0,0 +1,99 @@
/*****************************************************************************
gif_err.c - handle error reporting for the GIF library.
SPDX-License-Identifier: MIT
****************************************************************************/
#include <stdio.h>
#include "gif_lib.h"
#include "gif_lib_private.h"
/*****************************************************************************
Return a string description of the last GIF error
*****************************************************************************/
const char *
GifErrorString(int ErrorCode)
{
const char *Err;
switch (ErrorCode) {
case E_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case E_GIF_ERR_WRITE_FAILED:
Err = "Failed to write to given file";
break;
case E_GIF_ERR_HAS_SCRN_DSCR:
Err = "Screen descriptor has already been set";
break;
case E_GIF_ERR_HAS_IMAG_DSCR:
Err = "Image descriptor is still active";
break;
case E_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
case E_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
case E_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
case E_GIF_ERR_DISK_IS_FULL:
Err = "Write failed (disk full?)";
break;
case E_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case E_GIF_ERR_NOT_WRITEABLE:
Err = "Given file was not opened for write";
break;
case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case D_GIF_ERR_READ_FAILED:
Err = "Failed to read from given file";
break;
case D_GIF_ERR_NOT_GIF_FILE:
Err = "Data is not in GIF format";
break;
case D_GIF_ERR_NO_SCRN_DSCR:
Err = "No screen descriptor detected";
break;
case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
case D_GIF_ERR_NO_COLOR_MAP:
Err = "Neither global nor local color map";
break;
case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
case D_GIF_ERR_DATA_TOO_BIG:
Err = "Number of pixels bigger than width * height";
break;
case D_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Failed to allocate required memory";
break;
case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case D_GIF_ERR_NOT_READABLE:
Err = "Given file was not opened for read";
break;
case D_GIF_ERR_IMAGE_DEFECT:
Err = "Image is defective, decoding aborted";
break;
case D_GIF_ERR_EOF_TOO_SOON:
Err = "Image EOF detected before image complete";
break;
default:
Err = NULL;
break;
}
return Err;
}
/* end */

261
third_party/giflib/giflib/gif_font.c vendored Normal file
View File

@ -0,0 +1,261 @@
/*****************************************************************************
gif_font.c - utility font handling and simple drawing for the GIF library
SPDX-License-Identifier: MIT
****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "gif_lib.h"
/*****************************************************************************
Ascii 8 by 8 regular font - only first 128 characters are supported.
*****************************************************************************/
/*
* Each array entry holds the bits for 8 horizontal scan lines, topmost
* first. The most significant bit of each constant is the leftmost bit of
* the scan line.
*/
/*@+charint@*/
const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Ascii 0 */
{0x3c, 0x42, 0xa5, 0x81, 0xbd, 0x42, 0x3c, 0x00}, /* Ascii 1 */
{0x3c, 0x7e, 0xdb, 0xff, 0xc3, 0x7e, 0x3c, 0x00}, /* Ascii 2 */
{0x00, 0xee, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 3 */
{0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 4 */
{0x00, 0x3c, 0x18, 0xff, 0xff, 0x08, 0x18, 0x00}, /* Ascii 5 */
{0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x10, 0x38, 0x00}, /* Ascii 6 */
{0x00, 0x00, 0x18, 0x3c, 0x18, 0x00, 0x00, 0x00}, /* Ascii 7 */
{0xff, 0xff, 0xe7, 0xc3, 0xe7, 0xff, 0xff, 0xff}, /* Ascii 8 */
{0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00}, /* Ascii 9 */
{0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0xbd, 0xc3, 0xff}, /* Ascii 10 */
{0x1f, 0x07, 0x0d, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* Ascii 11 */
{0x00, 0x7e, 0xc3, 0xc3, 0x7e, 0x18, 0x7e, 0x18}, /* Ascii 12 */
{0x04, 0x06, 0x07, 0x04, 0x04, 0xfc, 0xf8, 0x00}, /* Ascii 13 */
{0x0c, 0x0a, 0x0d, 0x0b, 0xf9, 0xf9, 0x1f, 0x1f}, /* Ascii 14 */
{0x00, 0x92, 0x7c, 0x44, 0xc6, 0x7c, 0x92, 0x00}, /* Ascii 15 */
{0x00, 0x00, 0x60, 0x78, 0x7e, 0x78, 0x60, 0x00}, /* Ascii 16 */
{0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00}, /* Ascii 17 */
{0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18}, /* Ascii 18 */
{0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00}, /* Ascii 19 */
{0xff, 0xb6, 0x76, 0x36, 0x36, 0x36, 0x36, 0x00}, /* Ascii 20 */
{0x7e, 0xc1, 0xdc, 0x22, 0x22, 0x1f, 0x83, 0x7e}, /* Ascii 21 */
{0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00}, /* Ascii 22 */
{0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x00, 0xff}, /* Ascii 23 */
{0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, /* Ascii 24 */
{0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x00}, /* Ascii 25 */
{0x00, 0x04, 0x06, 0xff, 0x06, 0x04, 0x00, 0x00}, /* Ascii 26 */
{0x00, 0x20, 0x60, 0xff, 0x60, 0x20, 0x00, 0x00}, /* Ascii 27 */
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0x00}, /* Ascii 28 */
{0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00}, /* Ascii 29 */
{0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00}, /* Ascii 30 */
{0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00}, /* Ascii 31 */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* */
{0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x00}, /* ! */
{0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* " */
{0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00}, /* # */
{0x10, 0x7c, 0xd2, 0x7c, 0x86, 0x7c, 0x10, 0x00}, /* $ */
{0xf0, 0x96, 0xfc, 0x18, 0x3e, 0x72, 0xde, 0x00}, /* % */
{0x30, 0x48, 0x30, 0x78, 0xce, 0xcc, 0x78, 0x00}, /* & */
{0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ' */
{0x10, 0x60, 0xc0, 0xc0, 0xc0, 0x60, 0x10, 0x00}, /* ( */
{0x10, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x10, 0x00}, /* ) */
{0x00, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x00, 0x00}, /* * */
{0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00}, /* + */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70}, /* , */
{0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}, /* - */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00}, /* . */
{0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00}, /* / */
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* 0 */
{0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* 1 */
{0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x60, 0xfe, 0x00}, /* 2 */
{0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00}, /* 3 */
{0x0e, 0x1e, 0x36, 0x66, 0xfe, 0x06, 0x06, 0x00}, /* 4 */
{0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xfc, 0x00}, /* 5 */
{0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00}, /* 6 */
{0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x00}, /* 7 */
{0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00}, /* 8 */
{0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00}, /* 9 */
{0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00}, /* : */
{0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x20, 0x00}, /* }, */
{0x00, 0x1c, 0x30, 0x60, 0x30, 0x1c, 0x00, 0x00}, /* < */
{0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00}, /* = */
{0x00, 0x70, 0x18, 0x0c, 0x18, 0x70, 0x00, 0x00}, /* > */
{0x7c, 0xc6, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00}, /* ? */
{0x7c, 0x82, 0x9a, 0xaa, 0xaa, 0x9e, 0x7c, 0x00}, /* @ */
{0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00}, /* A */
{0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x00}, /* B */
{0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00}, /* C */
{0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00}, /* D */
{0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xfe, 0x00}, /* E */
{0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* F */
{0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7e, 0x00}, /* G */
{0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00}, /* H */
{0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, /* I */
{0x1e, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00}, /* J */
{0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00}, /* K */
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00}, /* L */
{0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00}, /* M */
{0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00}, /* N */
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* O */
{0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00}, /* P */
{0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x06}, /* Q */
{0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0x00}, /* R */
{0x78, 0xcc, 0x60, 0x30, 0x18, 0xcc, 0x78, 0x00}, /* S */
{0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00}, /* T */
{0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* U */
{0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* V */
{0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00}, /* W */
{0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00}, /* X */
{0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00}, /* Y */
{0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00}, /* Z */
{0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00}, /* [ */
{0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x00}, /* \ */
{0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00}, /* ] */
{0x00, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00}, /* ^ */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, /* _ */
{0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ` */
{0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00}, /* a */
{0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0x00}, /* b */
{0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7e, 0x00}, /* c */
{0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x00}, /* d */
{0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7e, 0x00}, /* e */
{0x1e, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x00}, /* f */
{0x00, 0x00, 0x7e, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* g */
{0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* */
{0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* i */
{0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0xf0}, /* j */
{0xc0, 0xc0, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0x00}, /* k */
{0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00}, /* l */
{0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xc6, 0xc6, 0x00}, /* m */
{0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* n */
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00}, /* o */
{0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0}, /* p */
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x06}, /* q */
{0x00, 0x00, 0x6e, 0x70, 0x60, 0x60, 0x60, 0x00}, /* r */
{0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0xfc, 0x00}, /* s */
{0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00}, /* t */
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00}, /* u */
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, /* v */
{0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00}, /* w */
{0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00}, /* x */
{0x00, 0x00, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x7c}, /* y */
{0x00, 0x00, 0xfc, 0x18, 0x30, 0x60, 0xfc, 0x00}, /* z */
{0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00}, /* { */
{0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, /* | */
{0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00}, /* } */
{0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00}, /* ~ */
{0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00} /* Ascii 127 */
};
/*@=charint@*/
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
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);
}
}
/* end */

133
third_party/giflib/giflib/gif_hash.c vendored Normal file
View File

@ -0,0 +1,133 @@
/*****************************************************************************
gif_hash.c -- module to support the following operations:
1. InitHashTable - initialize hash table.
2. ClearHashTable - clear the hash table to an empty state.
2. InsertHashTable - insert one item into data structure.
3. ExistsHashTable - test if item exists in data structure.
This module is used to hash the GIF codes during encoding.
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_hash.h"
#include "gif_lib_private.h"
/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */
#ifdef DEBUG_HIT_RATE
static long NumberOfTests = 0,
NumberOfMisses = 0;
#endif /* DEBUG_HIT_RATE */
static int KeyItem(uint32_t Item);
/******************************************************************************
Initialize HashTable - allocate the memory needed and clear it. *
******************************************************************************/
GifHashTableType *_InitHashTable(void)
{
GifHashTableType *HashTable;
if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
== NULL)
return NULL;
_ClearHashTable(HashTable);
return HashTable;
}
/******************************************************************************
Routine to clear the HashTable to an empty state. *
This part is a little machine depended. Use the commented part otherwise. *
******************************************************************************/
void _ClearHashTable(GifHashTableType *HashTable)
{
memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(uint32_t));
}
/******************************************************************************
Routine to insert a new Item into the HashTable. The data is assumed to be *
new one. *
******************************************************************************/
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code)
{
int HKey = KeyItem(Key);
uint32_t *HTable = HashTable -> HTable;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
HKey = (HKey + 1) & HT_KEY_MASK;
}
HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
}
/******************************************************************************
Routine to test if given Key exists in HashTable and if so returns its code *
Returns the Code if key was found, -1 if not. *
******************************************************************************/
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key)
{
int HKey = KeyItem(Key);
uint32_t *HTable = HashTable -> HTable, HTKey;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
HKey = (HKey + 1) & HT_KEY_MASK;
}
return -1;
}
/******************************************************************************
Routine to generate an HKey for the hashtable out of the given unique key. *
The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
new postfix character, while the upper 12 bits are the prefix code. *
Because the average hit ratio is only 2 (2 hash references per entry), *
evaluating more complex keys (such as twin prime keys) does not worth it! *
******************************************************************************/
static int KeyItem(uint32_t Item)
{
return ((Item >> 12) ^ Item) & HT_KEY_MASK;
}
#ifdef DEBUG_HIT_RATE
/******************************************************************************
Debugging routine to print the hit ratio - number of times the hash table *
was tested per operation. This routine was used to test the KeyItem routine *
******************************************************************************/
void HashTablePrintHitRatio(void)
{
printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
NumberOfMisses, NumberOfTests,
NumberOfMisses * 100 / NumberOfTests);
}
#endif /* DEBUG_HIT_RATE */
/* end */

41
third_party/giflib/giflib/gif_hash.h vendored Normal file
View File

@ -0,0 +1,41 @@
/******************************************************************************
gif_hash.h - magfic constants and declarations for GIF LZW
SPDX-License-Identifier: MIT
******************************************************************************/
#ifndef _GIF_HASH_H_
#define _GIF_HASH_H_
#include <unistd.h>
#include <stdint.h>
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
/* The 32 bits of the long are divided into two parts for the key & code: */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
/* The key is the upper 20 bits. The code is the lower 12. */
#define HT_GET_KEY(l) (l >> 12)
#define HT_GET_CODE(l) (l & 0x0FFF)
#define HT_PUT_KEY(l) (l << 12)
#define HT_PUT_CODE(l) (l & 0x0FFF)
typedef struct GifHashTableType {
uint32_t HTable[HT_SIZE];
} GifHashTableType;
GifHashTableType *_InitHashTable(void);
void _ClearHashTable(GifHashTableType *HashTable);
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code);
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key);
#endif /* _GIF_HASH_H_ */
/* end */

303
third_party/giflib/giflib/gif_lib.h vendored Normal file
View File

@ -0,0 +1,303 @@
/******************************************************************************
gif_lib.h - service library for decoding and encoding GIF images
SPDX-License-Identifier: MIT
*****************************************************************************/
#ifndef _GIF_LIB_H_
#define _GIF_LIB_H_ 1
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 2
#define GIFLIB_RELEASE 1
#define GIF_ERROR 0
#define GIF_OK 1
#include <stddef.h>
#include <stdbool.h>
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
typedef unsigned int GifPrefixType;
typedef int GifWord;
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
bool SortFlag;
GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height; /* Current image dimensions. */
bool Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct ExtensionBlock {
int ByteCount;
GifByteType *Bytes; /* on malloc(3) heap */
int Function; /* The block function code */
#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
} ExtensionBlock;
typedef struct SavedImage {
GifImageDesc ImageDesc;
GifByteType *RasterBits; /* on malloc(3) heap */
int ExtensionBlockCount; /* Count of extensions before image */
ExtensionBlock *ExtensionBlocks; /* Extensions before image */
} SavedImage;
typedef struct GifFileType {
GifWord SWidth, SHeight; /* Size of virtual canvas */
GifWord SColorResolution; /* How many colors can we generate? */
GifWord SBackGroundColor; /* Background color for virtual canvas */
GifByteType AspectByte; /* Used to compute pixel aspect ratio */
ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
int ImageCount; /* Number of current image (both APIs) */
GifImageDesc Image; /* Current image (low-level API) */
SavedImage *SavedImages; /* Image sequence (high-level API) */
int ExtensionBlockCount; /* Count extensions past last image */
ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
int Error; /* Last error condition reported */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
/* func type to write gif data to arbitrary targets.
* Returns count of bytes written. (MRB)
*/
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
/******************************************************************************
GIF89 structures
******************************************************************************/
typedef struct GraphicsControlBlock {
int DisposalMode;
#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
#define DISPOSE_DO_NOT 1 /* Leave image in place */
#define DISPOSE_BACKGROUND 2 /* Set area too background color */
#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
bool UserInputFlag; /* User confirmation required before disposal */
int DelayTime; /* pre-display delay in 0.01sec units */
int TransparentColor; /* Palette index for transparency, -1 if none */
#define NO_TRANSPARENT_COLOR -1
} GraphicsControlBlock;
/******************************************************************************
GIF encoding routines
******************************************************************************/
/* Main entry points */
GifFileType *EGifOpenFileName(const char *GifFileName,
const bool GifTestExistence, int *Error);
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
int EGifSpew(GifFileType * GifFile);
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_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
/* These are legacy. You probably do not want to call them directly */
int EGifPutScreenDesc(GifFileType *GifFile,
const int GifWidth, const int GifHeight,
const int GifColorRes,
const int GifBackGround,
const ColorMapObject *GifColorMap);
int EGifPutImageDesc(GifFileType *GifFile,
const int GifLeft, const int GifTop,
const int GifWidth, const int GifHeight,
const bool GifInterlace,
const ColorMapObject *GifColorMap);
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, const char *GifComment);
int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
int EGifPutExtensionBlock(GifFileType *GifFile,
const int GifExtLen, const void *GifExtension);
int EGifPutExtensionTrailer(GifFileType *GifFile);
int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
const int GifExtLen,
const void *GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
const GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile,
const GifByteType *GifCodeBlock);
/******************************************************************************
GIF decoding routines
******************************************************************************/
/* Main entry points */
GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
#define D_GIF_SUCCEEDED 0
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/* These are legacy. You probably do not want to call them directly */
int DGifGetScreenDesc(GifFileType *GifFile);
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
int DGifGetImageHeader(GifFileType *GifFile);
int DGifGetImageDesc(GifFileType *GifFile);
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
GifByteType **GifExtension);
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
GifByteType **GifCodeBlock);
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
const char *DGifGetGifVersion(GifFileType *GifFile);
/******************************************************************************
Error handling and reporting.
******************************************************************************/
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
/*****************************************************************************
Everything below this point is new after version 1.2, supporting `slurp
mode' for doing I/O in two big belts with all the image-bashing in core.
******************************************************************************/
/******************************************************************************
Color map handling from gif_alloc.c
******************************************************************************/
extern ColorMapObject *GifMakeMapObject(int ColorCount,
const GifColorType *ColorMap);
extern void GifFreeMapObject(ColorMapObject *Object);
extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);
/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks,
int Function,
unsigned int Len, unsigned char ExtData[]);
extern void GifFreeExtensions(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks);
extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
const SavedImage *CopyFrom);
extern void GifFreeSavedImages(GifFileType *GifFile);
/******************************************************************************
5.x functions for GIF89 graphics control blocks
******************************************************************************/
int DGifExtensionToGCB(const size_t GifExtensionLength,
const GifByteType *GifExtension,
GraphicsControlBlock *GCB);
size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
GifByteType *GifExtension);
int DGifSavedExtensionToGCB(GifFileType *GifFile,
int ImageIndex,
GraphicsControlBlock *GCB);
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
GifFileType *GifFile,
int ImageIndex);
/******************************************************************************
The library's internal utility font
******************************************************************************/
#define GIF_FONT_WIDTH 8
#define GIF_FONT_HEIGHT 8
extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
extern void GifDrawText8x8(SavedImage *Image,
const int x, const int y,
const char *legend, const int color);
extern void GifDrawBox(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawRectangle(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawBoxedText8x8(SavedImage *Image,
const int x, const int y,
const char *legend,
const int border, const int bg, const int fg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _GIF_LIB_H */
/* end */

View File

@ -0,0 +1,70 @@
/****************************************************************************
gif_lib_private.h - internal giflib routines and structures
SPDX-License-Identifier: MIT
****************************************************************************/
#ifndef _GIF_LIB_PRIVATE_H
#define _GIF_LIB_PRIVATE_H
#include "gif_lib.h"
#include "gif_hash.h"
#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#endif
#define EXTENSION_INTRODUCER 0x21
#define DESCRIPTOR_INTRODUCER 0x2c
#define TERMINATOR_INTRODUCER 0x3b
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
#define FILE_STATE_WRITE 0x01
#define FILE_STATE_SCREEN 0x02
#define FILE_STATE_IMAGE 0x04
#define FILE_STATE_READ 0x08
#define IS_READABLE(Private) (Private->FileState & FILE_STATE_READ)
#define IS_WRITEABLE(Private) (Private->FileState & FILE_STATE_WRITE)
typedef struct GifFilePrivateType {
GifWord FileState, FileHandle, /* Where all this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits, /* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
unsigned long PixelCount; /* Number of pixels in image. */
FILE *File; /* File as stream. */
InputFunc Read; /* function to read gif input (TVT) */
OutputFunc Write; /* function to write gif output (MRB) */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
GifHashTableType *HashTable;
bool gif89;
} GifFilePrivateType;
#ifndef HAVE_REALLOCARRAY
extern void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size);
#define reallocarray openbsd_reallocarray
#endif
#endif /* _GIF_LIB_PRIVATE_H */
/* end */

420
third_party/giflib/giflib/gifalloc.c vendored Normal file
View File

@ -0,0 +1,420 @@
/*****************************************************************************
GIF construction tools
SPDX-License-Identifier: MIT
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_lib_private.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
/******************************************************************************
Miscellaneous utility functions
******************************************************************************/
/* return smallest bitfield size n will fit in */
int
GifBitSize(int n)
{
register int i;
for (i = 1; i <= 8; i++)
if ((1 << i) >= n)
break;
return (i);
}
/******************************************************************************
Color map object functions
******************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
ColorMapObject *
GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
{
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
* make the user know that or should we automatically round up instead? */
if (ColorCount != (1 << GifBitSize(ColorCount))) {
return ((ColorMapObject *) NULL);
}
Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
if (Object == (ColorMapObject *) NULL) {
return ((ColorMapObject *) NULL);
}
Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *) NULL) {
free(Object);
return ((ColorMapObject *) NULL);
}
Object->ColorCount = ColorCount;
Object->BitsPerPixel = GifBitSize(ColorCount);
Object->SortFlag = false;
if (ColorMap != NULL) {
memcpy((char *)Object->Colors,
(char *)ColorMap, ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*******************************************************************************
Free a color map object
*******************************************************************************/
void
GifFreeMapObject(ColorMapObject *Object)
{
if (Object != NULL) {
(void)free(Object->Colors);
(void)free(Object);
}
}
#ifdef DEBUG
void
DumpColorMap(ColorMapObject *Object,
FILE * fp)
{
if (Object != NULL) {
int i, j, Len = Object->ColorCount;
for (i = 0; i < Len; i += 4) {
for (j = 0; j < 4 && j < Len; j++) {
(void)fprintf(fp, "%3d: %02x %02x %02x ", i + j,
Object->Colors[i + j].Red,
Object->Colors[i + j].Green,
Object->Colors[i + j].Blue);
}
(void)fprintf(fp, "\n");
}
}
}
#endif /* DEBUG */
/*******************************************************************************
Compute the union of two given color maps and return it. If result can't
fit into 256 colors, NULL is returned, the allocated union otherwise.
ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
copied iff they didn't exist before. ColorTransIn2 maps the old
ColorIn2 into the ColorUnion color map table./
*******************************************************************************/
ColorMapObject *
GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[])
{
int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
ColorMapObject *ColorUnion;
/*
* We don't worry about duplicates within either color map; if
* the caller wants to resolve those, he can perform unions
* with an empty color map.
*/
/* Allocate table which will hold the result for sure. */
ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
ColorIn2->ColorCount) * 2, NULL);
if (ColorUnion == NULL)
return (NULL);
/*
* Copy ColorIn1 to ColorUnion.
*/
for (i = 0; i < ColorIn1->ColorCount; i++)
ColorUnion->Colors[i] = ColorIn1->Colors[i];
CrntSlot = ColorIn1->ColorCount;
/*
* Potentially obnoxious hack:
*
* Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
* of table 1. This is very useful if your display is limited to
* 16 colors.
*/
while (ColorIn1->Colors[CrntSlot - 1].Red == 0
&& ColorIn1->Colors[CrntSlot - 1].Green == 0
&& ColorIn1->Colors[CrntSlot - 1].Blue == 0)
CrntSlot--;
/* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
/* Let's see if this color already exists: */
for (j = 0; j < ColorIn1->ColorCount; j++)
if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
sizeof(GifColorType)) == 0)
break;
if (j < ColorIn1->ColorCount)
ColorTransIn2[i] = j; /* color exists in Color1 */
else {
/* Color is new - copy it to a new slot: */
ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
ColorTransIn2[i] = CrntSlot++;
}
}
if (CrntSlot > 256) {
GifFreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
}
NewGifBitSize = GifBitSize(CrntSlot);
RoundUpTo = (1 << NewGifBitSize);
if (RoundUpTo != ColorUnion->ColorCount) {
register GifColorType *Map = ColorUnion->Colors;
/*
* Zero out slots up to next power of 2.
* We know these slots exist because of the way ColorUnion's
* start dimension was computed.
*/
for (j = CrntSlot; j < RoundUpTo; j++)
Map[j].Red = Map[j].Green = Map[j].Blue = 0;
/* perhaps we can shrink the map? */
if (RoundUpTo < ColorUnion->ColorCount) {
GifColorType *new_map = (GifColorType *)reallocarray(Map,
RoundUpTo, sizeof(GifColorType));
if( new_map == NULL ) {
GifFreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
}
ColorUnion->Colors = new_map;
}
}
ColorUnion->ColorCount = RoundUpTo;
ColorUnion->BitsPerPixel = NewGifBitSize;
return (ColorUnion);
}
/*******************************************************************************
Apply a given color translation to the raster bits of an image
*******************************************************************************/
void
GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
{
register int i;
register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
for (i = 0; i < RasterSize; i++)
Image->RasterBits[i] = Translation[Image->RasterBits[i]];
}
/******************************************************************************
Extension record functions
******************************************************************************/
int
GifAddExtensionBlock(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks,
int Function,
unsigned int Len,
unsigned char ExtData[])
{
ExtensionBlock *ep;
if (*ExtensionBlocks == NULL)
*ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
else {
ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
(*ExtensionBlocks, (*ExtensionBlockCount + 1),
sizeof(ExtensionBlock));
if( ep_new == NULL )
return (GIF_ERROR);
*ExtensionBlocks = ep_new;
}
if (*ExtensionBlocks == NULL)
return (GIF_ERROR);
ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
ep->Function = Function;
ep->ByteCount=Len;
ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
if (ExtData != NULL) {
memcpy(ep->Bytes, ExtData, Len);
}
return (GIF_OK);
}
void
GifFreeExtensions(int *ExtensionBlockCount,
ExtensionBlock **ExtensionBlocks)
{
ExtensionBlock *ep;
if (*ExtensionBlocks == NULL)
return;
for (ep = *ExtensionBlocks;
ep < (*ExtensionBlocks + *ExtensionBlockCount);
ep++)
(void)free((char *)ep->Bytes);
(void)free((char *)*ExtensionBlocks);
*ExtensionBlocks = NULL;
*ExtensionBlockCount = 0;
}
/******************************************************************************
Image block allocation functions
******************************************************************************/
/* Private Function:
* Frees the last image in the GifFile->SavedImages array
*/
void
FreeLastSavedImage(GifFileType *GifFile)
{
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
return;
/* Remove one SavedImage from the GifFile */
GifFile->ImageCount--;
sp = &GifFile->SavedImages[GifFile->ImageCount];
/* Deallocate its Colormap */
if (sp->ImageDesc.ColorMap != NULL) {
GifFreeMapObject(sp->ImageDesc.ColorMap);
sp->ImageDesc.ColorMap = NULL;
}
/* Deallocate the image data */
if (sp->RasterBits != NULL)
free((char *)sp->RasterBits);
/* Deallocate any extensions */
GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
/*** FIXME: We could realloc the GifFile->SavedImages structure but is
* there a point to it? Saves some memory but we'd have to do it every
* time. If this is used in GifFreeSavedImages then it would be inefficient
* (The whole array is going to be deallocated.) If we just use it when
* we want to free the last Image it's convenient to do it here.
*/
}
/*
* Append an image block to the SavedImages array
*/
SavedImage *
GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
{
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 */

349
third_party/giflib/giflib/gifbg.c vendored Normal file
View File

@ -0,0 +1,349 @@
/*****************************************************************************
gifbg - generate a test-pattern GIF
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifbg"
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 350
#define DEFAULT_COLOR_RED 0
#define DEFAULT_COLOR_GREEN 0
#define DEFAULT_COLOR_BLUE 255
#define DEFAULT_MIN_INTENSITY 10 /* In percent. */
#define DEFAULT_MAX_INTENSITY 100
#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen in image. */
#define DIR_NONE 0 /* Direction the levels can be changed: */
#define DIR_TOP 1
#define DIR_TOP_RIGHT 2
#define DIR_RIGHT 3
#define DIR_BOT_RIGHT 4
#define DIR_BOT 5
#define DIR_BOT_LEFT 6
#define DIR_LEFT 7
#define DIR_TOP_LEFT 8
#define DEFAULT_DIR "T" /* TOP (North) direction. */
static char
*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);
}
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]);
switch(DirectionStr[0]) {
case 'T': /* Top or North */
case 'N':
if (strlen(DirectionStr) < 2)
Direction = DIR_TOP;
else
switch(DirectionStr[1]) {
case 'R':
case 'E':
Direction = DIR_TOP_RIGHT;
break;
case 'L':
case 'W':
Direction = DIR_TOP_LEFT;
FlipDir = true;
break;
}
break;
case 'R': /* Right or East */
case 'E':
Direction = DIR_RIGHT;
break;
case 'B': /* Bottom or South */
case 'S':
if (strlen(DirectionStr) < 2) {
Direction = DIR_BOT;
FlipDir = true;
}
else
switch(DirectionStr[1]) {
case 'R':
case 'E':
Direction = DIR_BOT_RIGHT;
break;
case 'L':
case 'W':
Direction = DIR_BOT_LEFT;
FlipDir = true;
break;
}
break;
case 'L': /* Left or West */
case 'W':
Direction = DIR_LEFT;
FlipDir = true;
break;
}
if (Direction == DIR_NONE)
GIF_EXIT("Direction requested (-d option) is weird!");
/* We are going to handle only TOP, TOP_RIGHT, RIGHT, BOT_RIGHT so flip */
/* the complement cases (TOP <-> BOT for example) by flipping the */
/* Color i with color (NumLevels - i - 1). */
if (FlipDir) {
switch (Direction) {
case DIR_BOT:
Direction = DIR_TOP;
break;
case DIR_BOT_LEFT:
Direction = DIR_TOP_RIGHT;
break;
case DIR_LEFT:
Direction = DIR_RIGHT;
break;
case DIR_TOP_LEFT:
Direction = DIR_BOT_RIGHT;
break;
}
}
/* If binary mask is requested (special case): */
if (MinimumIntensity == 100 && MaximumIntensity == 100 && NumLevels == 2) {
MinimumIntensity = 0;
DoAllMaximum = true;
Direction = DIR_RIGHT;
}
/* Make sure colors are in the right range: */
if (RedColor > 255 || GreenColor > 255 || BlueColor > 255)
GIF_EXIT("Colors are not in the ragne [0..255].");
/* Make sure number of levels is power of 2 (up to 8 bits per pixel). */
for (i = 1; i < 8; i++) if (NumLevels == (1 << i)) break;
if (i == 8) GIF_EXIT("#Lvls (-l option) is not power of 2.");
LogNumLevels = i;
/* Open stdout for the output file: */
if ((GifFile = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* Dump out screen description with given size and generated color map: */
if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
for (i = 1; i <= NumLevels; i++) {
/* Ratio will be in the range of 0..100 for required intensity: */
unsigned int Ratio = (MaximumIntensity * (i * (256 / NumLevels)) +
MinimumIntensity * ((NumLevels - i) * (256 / NumLevels))) /
256;
ColorMap->Colors[i-1].Red = (RedColor * Ratio) / 100;
ColorMap->Colors[i-1].Green = (GreenColor * Ratio) / 100;
ColorMap->Colors[i-1].Blue = (BlueColor * Ratio) / 100;
}
if (EGifPutScreenDesc(GifFile,
ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap)
== GIF_ERROR)
QuitGifError(GifFile);
/* Dump out the image descriptor: */
if (EGifPutImageDesc(GifFile,
0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ",
PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
GifFile->Image.Width, GifFile->Image.Height);
/* Allocate one scan line twice as big as image is, as we are going to */
/* shift along it, while we dump the scan lines: */
if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth * 2)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
if (Direction == DIR_TOP) {
int LevelHeight;
/* We must evaluate the line each time level is changing: */
LevelHeight = ImageHeight / NumLevels;
for (Color = NumLevels, i = l = 0; i < ImageHeight; i++) {
if (i == l) {
int j;
/* Time to update the line to next color level: */
if (Color != 0) Color--;
for (j = 0; j < ImageWidth; j++)
Line[j] = (FlipDir ? NumLevels - Color - 1 : Color);
l += LevelHeight;
}
if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\b\b\b\b%-4d", Count++);
}
}
else if (Direction == DIR_RIGHT) {
/* We pre-prepare the scan lines as going from color zero to maximum */
/* color and dump the same scan line Height times: */
/* Note this case should handle the Boolean Mask special case. */
LevelWidth = ImageWidth / NumLevels;
if (DoAllMaximum) {
/* Special case - do all in maximum color: */
for (i = 0; i < ImageWidth; i++) Line[i] = 1;
}
else {
for (Color = i = 0, l = LevelWidth; i < ImageWidth; i++, l--) {
if (l == 0) {
l = LevelWidth;
if (Color < NumLevels - 1) Color++;
}
Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
}
}
for (i = 0; i < ImageHeight; i++) {
/* coverity[uninit_use_in_call] */
if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\b\b\b\b%-4d", Count++);
}
}
else {
int Accumulator, StartX, StepX;
/* We are in one of the TOP_RIGHT, BOT_RIGHT cases: we will */
/* initialize the Line with its double ImageWidth length from the */
/* minimum intensity to the maximum intensity and shift along it */
/* while we go along the image height. */
LevelWidth = ImageWidth * 2 / NumLevels;
for (Color = i = 0, l = LevelWidth; i < ImageWidth * 2; i++, l--) {
if (l == 0) {
l = LevelWidth;
if (Color < NumLevels - 1) Color++;
}
Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
}
/* We need to implement a DDA to know how much to shift Line while */
/* we go down along image height. we set the parameters for it now: */
Accumulator = 0;
switch(Direction) {
case DIR_TOP_RIGHT:
StartX = ImageWidth;
StepX = -1;
break;
case DIR_BOT_RIGHT:
default:
StartX = 0;
StepX = 1;
break;
}
/* Time to dump information out: */
for (i = 0; i < ImageHeight; i++) {
if (EGifPutLine(GifFile, &Line[StartX], ImageWidth) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\b\b\b\b%-4d", Count++);
if ((Accumulator += ImageWidth) > ImageHeight) {
while (Accumulator > ImageHeight) {
Accumulator -= ImageHeight;
StartX += StepX;
}
if (Direction < 0) Direction = 0;
if (Direction > ImageWidth) Direction = ImageWidth;
}
}
}
if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/******************************************************************************
Close output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFile)
{
if (GifFile != NULL) {
PrintGifError(GifFile->Error);
EGifCloseFile(GifFile, NULL);
}
exit(EXIT_FAILURE);
}
/* end */

940
third_party/giflib/giflib/gifbuild.c vendored Normal file
View File

@ -0,0 +1,940 @@
/*****************************************************************************
gifbuild - dump GIF data in a textual format, or undump it to a GIF
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#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[] = "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 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]);
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);
}
(void) fclose(fp);
}
}
return 0;
}
/******************************************************************************
Parse image directives
******************************************************************************/
#define PARSE_ERROR(str) (void) fprintf(stderr,"%s:%d: %s\n",FileName,LineNum,str);
static void Icon2Gif(char *FileName, FILE *txtin, int fdout)
{
unsigned int ColorMapSize = 0;
GifColorType GlobalColorMap[256], LocalColorMap[256],
*ColorMap = GlobalColorMap;
char GlobalColorKeys[PRINTABLES], LocalColorKeys[PRINTABLES],
*KeyTable = GlobalColorKeys;
bool SortFlag = false;
unsigned int ExtCode, intval;
int red, green, blue, n;
char buf[BUFSIZ * 2], InclusionFile[64];
GifFileType *GifFileOut;
SavedImage *NewImage = NULL;
int LeadingExtensionBlockCount = 0;
ExtensionBlock *LeadingExtensionBlocks = NULL;
int ErrorCode, LineNum = 0;
if ((GifFileOut = EGifOpenFileHandle(fdout, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* OK, interpret directives */
/* coverity[tainted_data_transitive] */
while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
{
char *cp;
++LineNum;
/*
* Skip lines consisting only of whitespace and comments
*/
for (cp = buf; isspace((int)(*cp)); cp++)
continue;
if (*cp == '#' || *cp == '\0')
continue;
/*
* If there's a trailing comment, nuke it and all preceding whitespace.
* But preserve the EOL.
*/
if ((cp = strchr(buf, '#')) && (cp == strrchr(cp, '#')))
{
while (isspace((int)(*--cp)))
continue;
*++cp = '\n';
*++cp = '\0';
}
/*
* Explicit header declarations
*/
if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == 1)
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);
}
GifFileOut->SColorResolution = ResBits;
continue;
}
else if (sscanf(buf,
"screen background %d\n",
&GifFileOut->SBackGroundColor) == 1)
continue;
else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) {
GifFileOut->AspectByte = (GifByteType)(intval & 0xff);
continue;
}
/*
* Color table parsing
*/
else if (strcmp(buf, "screen map\n") == 0)
{
if (GifFileOut->SColorMap != NULL)
{
PARSE_ERROR("You've already declared a global color map.");
exit(EXIT_FAILURE);
}
ColorMapSize = 0;
ColorMap = GlobalColorMap;
SortFlag = false;
KeyTable = GlobalColorKeys;
memset(GlobalColorKeys, '\0', sizeof(GlobalColorKeys));
}
else if (strcmp(buf, "image map\n") == 0)
{
if (NewImage == NULL)
{
PARSE_ERROR("No previous image declaration.");
exit(EXIT_FAILURE);
}
ColorMapSize = 0;
ColorMap = LocalColorMap;
KeyTable = LocalColorKeys;
memset(LocalColorKeys, '\0', sizeof(LocalColorKeys));
}
else if (sscanf(buf, " rgb %d %d %d is %c",
&red, &green, &blue, &KeyTable[ColorMapSize]) == 4)
{
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 (strcmp(buf, " sort flag on\n") == 0)
SortFlag = true;
else if (strcmp(buf, " sort flag off\n") == 0)
SortFlag = false;
else if (strcmp(buf, "end\n") == 0)
{
ColorMapObject *NewMap;
NewMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ColorMap);
if (NewMap == (ColorMapObject *)NULL)
{
PARSE_ERROR("Out of memory while allocating new color map.");
exit(EXIT_FAILURE);
}
NewMap->SortFlag = SortFlag;
if (NewImage)
NewImage->ImageDesc.ColorMap = NewMap;
else
GifFileOut->SColorMap = NewMap;
}
/* GIF inclusion */
/* ugly magic number is because scanf has no */
else if (sscanf(buf, "include %63s", InclusionFile) == 1)
{
int ErrorCode;
bool DoTranslation;
GifPixelType Translation[256];
GifFileType *Inclusion;
SavedImage *CopyFrom;
if ((Inclusion = DGifOpenFileName(InclusionFile, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (DGifSlurp(Inclusion) == GIF_ERROR)
{
PARSE_ERROR("Inclusion read failed.");
if (Inclusion != NULL) {
PrintGifError(Inclusion->Error);
DGifCloseFile(Inclusion, NULL);
}
if (GifFileOut != NULL) {
EGifCloseFile(GifFileOut, NULL);
};
exit(EXIT_FAILURE);
}
//cppcheck-suppress nullPointerRedundantCheck
if ((DoTranslation = (GifFileOut->SColorMap!=(ColorMapObject*)NULL)))
{
ColorMapObject *UnionMap;
//cppcheck-suppress nullPointerRedundantCheck
UnionMap = GifUnionColorMap(GifFileOut->SColorMap, Inclusion->SColorMap, Translation);
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);
}
(void) DGifCloseFile(Inclusion, NULL);
}
/*
* Extension blocks.
*/
else if (strcmp(buf, "comment\n") == 0)
{
int bc = 0;
while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
if (strcmp(buf, "end\n") == 0)
break;
else
{
int Len;
buf[strlen(buf) - 1] = '\0';
Len = EscapeString(buf, buf);
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
bc++ == CONTINUE_EXT_FUNC_CODE ? COMMENT_EXT_FUNC_CODE : 0,
Len,
(unsigned char *)buf) == GIF_ERROR) {
PARSE_ERROR("out of memory while adding comment block.");
exit(EXIT_FAILURE);
}
}
}
else if (strcmp(buf, "plaintext\n") == 0)
{
int bc = 0;
while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
if (strcmp(buf, "end\n") == 0)
break;
else
{
int Len;
buf[strlen(buf) - 1] = '\0';
Len = EscapeString(buf, buf);
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
bc++ == CONTINUE_EXT_FUNC_CODE ? PLAINTEXT_EXT_FUNC_CODE : 0,
Len,
(unsigned char *)buf) == GIF_ERROR) {
PARSE_ERROR("out of memory while adding plaintext block.");
exit(EXIT_FAILURE);
}
}
}
else if (strcmp(buf, "graphics control\n") == 0)
{
GraphicsControlBlock gcb;
size_t Len;
memset(&gcb, '\0', sizeof(gcb));
gcb.TransparentColor = NO_TRANSPARENT_COLOR;
while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
if (strcmp(buf, "end\n") == 0)
break;
else
{
char *tp = buf;
while (isspace(*tp))
tp++;
if (sscanf(tp, "disposal mode %d\n", &gcb.DisposalMode))
continue;
if (strcmp(tp, "user input flag on\n") == 0) {
gcb.UserInputFlag = true;
continue;
}
if (strcmp(tp, "user input flag off\n") == 0) {
gcb.UserInputFlag = false;
continue;
}
if (sscanf(tp, "delay %d\n", &gcb.DelayTime))
continue;
if (sscanf(tp, "transparent index %d\n",
&gcb.TransparentColor))
continue;
(void) fputs(tp, stderr);
PARSE_ERROR("unrecognized directive in GCB block.");
exit(EXIT_FAILURE);
}
Len = EGifGCBToExtension(&gcb, (GifByteType *)buf);
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
GRAPHICS_EXT_FUNC_CODE,
Len,
(unsigned char *)buf) == GIF_ERROR) {
PARSE_ERROR("out of memory while adding GCB.");
exit(EXIT_FAILURE);
}
}
else if (sscanf(buf, "netscape loop %u", &intval))
{
unsigned char params[3] = {1, 0, 0};
/* Create a Netscape 2.0 loop block */
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
APPLICATION_EXT_FUNC_CODE,
11,
(unsigned char *)"NETSCAPE2.0")==GIF_ERROR) {
PARSE_ERROR("out of memory while adding loop block.");
exit(EXIT_FAILURE);
}
params[1] = (intval & 0xff);
params[2] = (intval >> 8) & 0xff;
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
0, sizeof(params), params) == GIF_ERROR) {
PARSE_ERROR("out of memory while adding loop continuation.");
exit(EXIT_FAILURE);
}
}
else if (sscanf(buf, "extension %x", &ExtCode))
{
int bc = 0;
while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
if (strcmp(buf, "end\n") == 0)
break;
else
{
int Len;
buf[strlen(buf) - 1] = '\0';
Len = EscapeString(buf, buf);
if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
&LeadingExtensionBlocks,
bc++ == CONTINUE_EXT_FUNC_CODE ? ExtCode : 0,
Len,
(unsigned char *)buf) == GIF_ERROR) {
PARSE_ERROR("out of memory while adding extension block.");
exit(EXIT_FAILURE);
}
}
}
/*
* Explicit image declarations
*/
else if (strcmp(buf, "image\n") == 0)
{
if ((NewImage = GifMakeSavedImage(GifFileOut, NULL)) == (SavedImage *)NULL)
{
PARSE_ERROR("Out of memory while allocating image block.");
exit(EXIT_FAILURE);
}
/* use global table unless user specifies a local one */
ColorMap = GlobalColorMap;
KeyTable = GlobalColorKeys;
/* connect leading extension blocks */
NewImage->ExtensionBlockCount = LeadingExtensionBlockCount;
NewImage->ExtensionBlocks = LeadingExtensionBlocks;
LeadingExtensionBlockCount = 0;
LeadingExtensionBlocks = NULL;
}
/*
* Nothing past this point is valid unless we've seen a previous
* image declaration.
*/
else if (NewImage == (SavedImage *)NULL)
{
(void) fputs(buf, stderr);
PARSE_ERROR("Syntax error in header block.");
exit(EXIT_FAILURE);
}
/*
* Accept image attributes
*/
else if (sscanf(buf, "image top %d\n", &NewImage->ImageDesc.Top) == 1)
continue;
else if (sscanf(buf, "image left %d\n", &NewImage->ImageDesc.Left)== 1)
continue;
else if (strcmp(buf, "image interlaced\n") == 0)
{
NewImage->ImageDesc.Interlace = true;
continue;
}
else if (sscanf(buf,
"image bits %d by %d",
&NewImage->ImageDesc.Width,
&NewImage->ImageDesc.Height) == 2)
{
int i, j;
static GifPixelType *Raster, *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.");
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);
cp = 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);
*cp++ = (hi << 4) | lo;
}
else if ((dp = strchr(KeyTable, c)))
*cp++ = (dp - KeyTable);
else {
PARSE_ERROR("Invalid ASCII pixel key.");
exit(EXIT_FAILURE);
}
if (GifNoisyPrint)
fprintf(stderr, "\b\b\b\b%-4d", i);
}
if (GifNoisyPrint)
putc('\n', stderr);
NewImage->RasterBits = (unsigned char *) Raster;
}
else
{
(void) fputs(buf, stderr);
PARSE_ERROR("Syntax error in image description.");
exit(EXIT_FAILURE);
}
}
/* connect trailing extension blocks */
GifFileOut->ExtensionBlockCount = LeadingExtensionBlockCount;
GifFileOut->ExtensionBlocks = LeadingExtensionBlocks;
//LeadingExtensionBlockCount = 0;
LeadingExtensionBlocks = NULL;
EGifSpew(GifFileOut);
}
static void VisibleDumpBuffer(GifByteType *buf, int len)
/* Visibilize a given string */
{
GifByteType *cp;
for (cp = buf; cp < buf + len; cp++)
{
if (isprint((int)(*cp)) || *cp == ' ')
putchar(*cp);
else if (*cp == '\n')
{
putchar('\\'); putchar('n');
}
else if (*cp == '\r')
{
putchar('\\'); putchar('r');
}
else if (*cp == '\b')
{
putchar('\\'); putchar('b');
}
else if (*cp < ' ')
{
putchar('\\'); putchar('^'); putchar('@' + *cp);
}
else
printf("\\0x%02x", *cp);
}
}
static void DumpExtensions(GifFileType *GifFileOut,
int ExtensionBlockCount,
ExtensionBlock *ExtensionBlocks)
{
ExtensionBlock *ep;
for (ep = ExtensionBlocks;
ep < ExtensionBlocks + ExtensionBlockCount;
ep++) {
bool last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
if (ep->Function == COMMENT_EXT_FUNC_CODE) {
printf("comment\n");
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
putchar('\n');
while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
++ep;
last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
putchar('\n');
}
printf("end\n\n");
}
else if (ep->Function == PLAINTEXT_EXT_FUNC_CODE) {
printf("plaintext\n");
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
putchar('\n');
while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
++ep;
last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
putchar('\n');
}
printf("end\n\n");
}
else if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
{
GraphicsControlBlock gcb;
printf("graphics control\n");
if (DGifExtensionToGCB(ep->ByteCount, ep->Bytes, &gcb) == GIF_ERROR) {
GIF_MESSAGE("invalid graphics control block");
exit(EXIT_FAILURE);
}
printf("\tdisposal mode %d\n", gcb.DisposalMode);
printf("\tuser input flag %s\n",
gcb.UserInputFlag ? "on" : "off");
printf("\tdelay %d\n", gcb.DelayTime);
printf("\ttransparent index %d\n", gcb.TransparentColor);
printf("end\n\n");
}
else if (!last
&& ep->Function == APPLICATION_EXT_FUNC_CODE
&& ep->ByteCount >= 11
&& (ep+1)->ByteCount >= 3
&& memcmp(ep->Bytes, "NETSCAPE2.0", 11) == 0) {
unsigned char *params = (++ep)->Bytes;
unsigned int loopcount = params[1] | (params[2] << 8);
printf("netscape loop %u\n\n", loopcount);
}
else {
printf("extension 0x%02x\n", ep->Function);
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
++ep;
last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
putchar('\n');
}
printf("end\n\n");
}
}
}
static void Gif2Icon(char *FileName,
int fdin, int fdout,
char NameTable[])
{
int ErrorCode, im, i, j, ColorCount = 0;
GifFileType *GifFile;
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);
}
}
static int EscapeString(char *cp, char *tp)
/* process standard C-style escape sequences in a string */
{
char *StartAddr = tp;
while (*cp)
{
int cval = 0;
if (*cp == '\\' && strchr("0123456789xX", cp[1]))
{
int dcount = 0;
if (*++cp == 'x' || *cp == 'X') {
char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
for (++cp; (dp = strchr(hex, *cp)) && (dcount++ < 2); cp++)
cval = (cval * 16) + (dp - hex) / 2;
} else if (*cp == '0')
while (strchr("01234567",*cp) != (char*)NULL && (dcount++ < 3))
cval = (cval * 8) + (*cp++ - '0');
else
while ((strchr("0123456789",*cp)!=(char*)NULL)&&(dcount++ < 3))
cval = (cval * 10) + (*cp++ - '0');
}
else if (*cp == '\\') /* C-style character escapes */
{
switch (*++cp)
{
case '\\': cval = '\\'; break;
case 'n': cval = '\n'; break;
case 't': cval = '\t'; break;
case 'b': cval = '\b'; break;
case 'r': cval = '\r'; break;
default: cval = *cp;
}
cp++;
}
else if (*cp == '^') /* expand control-character syntax */
{
cval = (*++cp & 0x1f);
cp++;
}
else
cval = *cp++;
*tp++ = cval;
}
return(tp - StartAddr);
}
/* end */

361
third_party/giflib/giflib/gifclrmp.c vendored Normal file
View File

@ -0,0 +1,361 @@
/*****************************************************************************
gifclrmap - extract colormaps from GIF images
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <math.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include "gif_lib.h"
#include "getarg.h"
#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 ColorMapObject *ModifyColorMap(ColorMapObject *ColorMap);
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut);
/******************************************************************************
Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
int NumFiles, ExtCode, CodeSize, ImageNum = 0,
ImageN, HasGIFOutput, ErrorCode;
bool Error, ImageNFlag = false, HelpFlag = false;
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 (NumFiles == 1) {
if ((GifFileIn = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
}
else {
/* Use stdin instead: */
if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
}
if (SaveFlag) {
/* We are dumping out the color map as text file to stdout: */
ColorFile = stdout;
}
else {
if (TranslateFlag) {
/* We are loading new color map from specified file: */
if ((TranslateFile = fopen(TranslateFileName, "rt")) == NULL)
GIF_EXIT("Failed to open specified color translation file.");
}
if (LoadFlag) {
/* We are loading new color map from specified file: */
if ((ColorFile = fopen(ColorFileName, "rt")) == NULL)
GIF_EXIT("Failed to open specified color map file.");
}
}
if ((HasGIFOutput = (LoadFlag || TranslateFlag || GammaFlag)) != 0) {
/* Open stdout for GIF output file: */
if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
}
if (!ImageNFlag) {
/* We are supposed to modify the screen color map, so do it: */
if (!GifFileIn->SColorMap)
GIF_EXIT("No colormap to modify");
GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap);
if (!HasGIFOutput) {
/* We can quit here, as we have the color map: */
DGifCloseFile(GifFileIn, NULL);
fclose(ColorFile);
exit(EXIT_SUCCESS);
}
}
/* And dump out its new possible repositioned screen information: */
if (HasGIFOutput)
if (EGifPutScreenDesc(GifFileOut,
GifFileIn->SWidth, GifFileIn->SHeight,
GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
GifFileIn->SColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Scan the content of the GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if ((++ImageNum == ImageN) && ImageNFlag) {
/* We are suppose to modify this image color map, do it: */
GifFileIn->SColorMap =ModifyColorMap(GifFileIn->SColorMap);
if (!HasGIFOutput) {
/* We can quit here, as we have the color map: */
DGifCloseFile(GifFileIn, NULL);
fclose(ColorFile);
exit(EXIT_SUCCESS);
}
}
if (HasGIFOutput)
if (EGifPutImageDesc(GifFileOut,
GifFileIn->Image.Left, GifFileIn->Image.Top,
GifFileIn->Image.Width, GifFileIn->Image.Height,
GifFileIn->Image.Interlace,
GifFileIn->Image.ColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (!TranslateFlag || (ImageNFlag && (ImageN != ImageNum)))
{
/* Now read image itself in decoded form as we don't */
/* really care what we have there, and this is much */
/* faster. */
if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (HasGIFOutput)
if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (HasGIFOutput)
if (EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
}
else /* we need to mung pixels intices */
{
int i;
register GifPixelType *cp;
GifPixelType *Line
= (GifPixelType *) malloc(GifFileIn->Image.Width *
sizeof(GifPixelType));
for (i = 0; i < GifFileIn->Image.Height; i++) {
if (DGifGetLine(GifFileIn, Line,GifFileIn->Image.Width)
== GIF_ERROR) {
QuitGifError(GifFileIn, GifFileOut);
}
/* translation step goes here */
for (cp = Line; cp < Line+GifFileIn->Image.Width; cp++)
*cp = Translation[*cp];
if (EGifPutLine(GifFileOut,
Line, GifFileIn->Image.Width)
== GIF_ERROR) {
QuitGifError(GifFileIn, GifFileOut);
}
}
free((char *) Line);
}
break;
case EXTENSION_RECORD_TYPE:
assert(GifFileOut != NULL); /* might pacify Coverity */
/* pass through extension records */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (Extension == NULL)
break;
if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (Extension != NULL)
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType. */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (HasGIFOutput)
if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/******************************************************************************
Modify the given colormap according to global variables setting.
******************************************************************************/
static ColorMapObject *ModifyColorMap(ColorMapObject *ColorMap)
{
int i, Dummy, Red, Green, Blue;
if (SaveFlag) {
/* Save this color map to ColorFile: */
for (i = 0; i < ColorMap->ColorCount; i++)
fprintf(ColorFile, "%3d %3d %3d %3d\n", i,
ColorMap->Colors[i].Red,
ColorMap->Colors[i].Green,
ColorMap->Colors[i].Blue);
return(ColorMap);
}
else if (LoadFlag) {
/* Read the color map in ColorFile into this color map: */
for (i = 0; i < ColorMap->ColorCount; i++) {
if (feof(ColorFile))
GIF_EXIT("Color file to load color map from, too small.");
if (fscanf(ColorFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue) == 4) {
ColorMap->Colors[i].Red = Red;
ColorMap->Colors[i].Green = Green;
ColorMap->Colors[i].Blue = Blue;
}
}
return(ColorMap);
}
else if (GammaFlag) {
/* Apply gamma correction to this color map: */
double Gamma1 = 1.0 / Gamma;
for (i = 0; i < ColorMap->ColorCount; i++) {
ColorMap->Colors[i].Red =
((int) (255 * pow(ColorMap->Colors[i].Red / 255.0, Gamma1)));
ColorMap->Colors[i].Green =
((int) (255 * pow(ColorMap->Colors[i].Green / 255.0, Gamma1)));
ColorMap->Colors[i].Blue =
((int) (255 * pow(ColorMap->Colors[i].Blue / 255.0, Gamma1)));
}
return(ColorMap);
}
else if (TranslateFlag) {
ColorMapObject *NewMap;
int Max = 0;
/* Read the translation table in TranslateFile: */
for (i = 0; i < ColorMap->ColorCount; i++) {
int tmp;
if (feof(TranslateFile))
GIF_EXIT("Color file to load color map from, too small.");
if (fscanf(TranslateFile, "%3d %3d\n", &Dummy, &tmp) == 2) {
Translation[i] = tmp & 0xff;
if (Translation[i] > Max)
Max = Translation[i];
}
}
if ((NewMap = GifMakeMapObject(1 << GifBitSize(Max+1), NULL)) == NULL)
GIF_EXIT("Out of memory while allocating color map!");
/* Apply the translation; we'll do it to the pixels, too */
for (i = 0; i < ColorMap->ColorCount; i++) {
NewMap->Colors[i] = ColorMap->Colors[Translation[i]];
}
return(NewMap);
}
else
{
GIF_EXIT("Nothing to do!");
return(ColorMap);
}
}
/******************************************************************************
Close both input and output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
if (GifFileIn != NULL) {
PrintGifError(GifFileIn->Error);
EGifCloseFile(GifFileIn, NULL);
}
if (GifFileOut != NULL) {
PrintGifError(GifFileOut->Error);
EGifCloseFile(GifFileOut, NULL);
}
exit(EXIT_FAILURE);
}
/* end */

170
third_party/giflib/giflib/gifcolor.c vendored Normal file
View File

@ -0,0 +1,170 @@
/*****************************************************************************
gifcolor - generate color test-pattern GIFs
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifcolor"
#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 int BackGround = 0;
static void QuitGifError(GifFileType *GifFile);
static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
int BufferWidth, int ForeGroundIndex);
/******************************************************************************
Interpret the command line and generate the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
int i, j, l, GifNoisyPrint, ColorMapSize, ErrorCode;
bool Error, BackGroundFlag = false, HelpFlag = false;
char Line[LINE_LEN];
GifRowType RasterBuffer[GIF_FONT_HEIGHT];
ColorMapObject *ColorMap;
GifFileType *GifFile;
GifColorType ScratchMap[256];
int red, green, blue;
if ((Error = GAGetArgs(argc, argv, CtrlStr,
&GifNoisyPrint,
&BackGroundFlag, &BackGround,
&HelpFlag)) != false) {
GAPrintErrMsg(Error);
GAPrintHowTo(CtrlStr);
exit(EXIT_FAILURE);
}
if (HelpFlag) {
(void)fprintf(stderr, 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);
}
/* Read the color map in ColorFile into this color map: */
ColorMapSize = 0;
while (fscanf(stdin,
"%*3d %3d %3d %3d\n",
&red, &green, &blue) == 3) {
if (ColorMapSize < 256) {
ScratchMap[ColorMapSize].Red = red;
ScratchMap[ColorMapSize].Green = green;
ScratchMap[ColorMapSize].Blue = blue;
ColorMapSize++;
} else {
GIF_EXIT("Too many color map triples, aborting.");
}
}
if ((ColorMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ScratchMap)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
if (EGifPutScreenDesc(GifFile,
IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT,
GifBitSize(ColorMapSize),
BackGround, ColorMap) == GIF_ERROR)
QuitGifError(GifFile);
/* Dump out the image descriptor: */
if (EGifPutImageDesc(GifFile,
0, 0, IMAGEWIDTH, ColorMapSize * GIF_FONT_HEIGHT, false, NULL) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ",
PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
GifFile->Image.Width, GifFile->Image.Height);
for (i = l = 0; i < ColorMap->ColorCount; i++) {
(void)snprintf(Line, sizeof(Line),
"Color %-3d: [%-3d, %-3d, %-3d] ", i,
ColorMap->Colors[i].Red,
ColorMap->Colors[i].Green,
ColorMap->Colors[i].Blue);
GenRasterTextLine(RasterBuffer, Line, IMAGEWIDTH, i);
for (j = 0; j < GIF_FONT_HEIGHT; j++) {
if (EGifPutLine(GifFile, RasterBuffer[j], IMAGEWIDTH) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\b\b\b\b%-4d", l++);
}
}
if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/******************************************************************************
Close output file (if open), and exit.
******************************************************************************/
static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
int BufferWidth, int ForeGroundIndex)
{
unsigned char Byte, Mask;
int i, j, k, CharPosX, Len = strlen(TextLine);
for (i = 0; i < BufferWidth; i++)
for (j = 0; j < GIF_FONT_HEIGHT; j++) RasterBuffer[j][i] = BackGround;
for (i = CharPosX = 0; i < Len; i++, CharPosX += GIF_FONT_WIDTH) {
unsigned char c = TextLine[i];
for (j = 0; j < GIF_FONT_HEIGHT; j++) {
Byte = GifAsciiTable8x8[(unsigned short)c][j];
for (k = 0, Mask = 128; k < GIF_FONT_WIDTH; k++, Mask >>= 1)
if (Byte & Mask)
RasterBuffer[j][CharPosX + k] = ForeGroundIndex;
}
}
}
/******************************************************************************
Close output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFile)
{
if (GifFile != NULL) {
PrintGifError(GifFile->Error);
EGifCloseFile(GifFile, NULL);
}
exit(EXIT_FAILURE);
}

209
third_party/giflib/giflib/gifecho.c vendored Normal file
View File

@ -0,0 +1,209 @@
/*****************************************************************************
gifecho - generate a GIF from ASCII text
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifecho"
#define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */
#define LINE_LEN 256 /* Maximum length of one text line. */
#define DEFAULT_FG_INDEX 1 /* Text foreground index. */
#define DEFAULT_COLOR_RED 255 /* Text foreground color. */
#define DEFAULT_COLOR_GREEN 255
#define DEFAULT_COLOR_BLUE 255
static char
*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);
/******************************************************************************
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);
}
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);
}
/* Dump out screen description with given size and generated color map: */
for (LogNumLevels = 1, NumLevels = 2;
NumLevels < ForeGroundIndex;
LogNumLevels++, NumLevels <<= 1);
if (NumLevels < (1 << ColorMapSize)) {
NumLevels = (1 << ColorMapSize);
LogNumLevels = ColorMapSize;
}
if ((ColorMap = GifMakeMapObject(NumLevels, NULL)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
for (i = 0; i < NumLevels; i++)
ColorMap->Colors[i].Red = ColorMap->Colors[i].Green = ColorMap->Colors[i].Blue = 0;
ColorMap->Colors[ForeGroundIndex].Red = RedColor;
ColorMap->Colors[ForeGroundIndex].Green = GreenColor;
ColorMap->Colors[ForeGroundIndex].Blue = BlueColor;
if (EGifPutScreenDesc(GifFile,
ImageWidth, ImageHeight, LogNumLevels, 0, ColorMap)
== GIF_ERROR)
QuitGifError(GifFile);
/* Dump out the image descriptor: */
if (EGifPutImageDesc(GifFile,
0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ",
PROGRAM_NAME, GifFile->Image.Left, GifFile->Image.Top,
GifFile->Image.Width, GifFile->Image.Height);
for (i = l = 0; i < NumOfLines; i++) {
GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth,
ForeGroundIndex);
for (j = 0; j < GIF_FONT_HEIGHT; j++) {
if (EGifPutLine(GifFile, RasterBuffer[j], ImageWidth) == GIF_ERROR)
QuitGifError(GifFile);
GifQprintf("\b\b\b\b%-4d", l++);
}
}
if (EGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/******************************************************************************
Generate raster bits corresponding to given text
******************************************************************************/
static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine,
int BufferWidth, int ForeGroundIndex)
{
unsigned char Byte, Mask;
int i, j, k, CharPosX, Len = strlen(TextLine);
for (i = 0; i < BufferWidth; i++)
for (j = 0; j < GIF_FONT_HEIGHT; j++) RasterBuffer[j][i] = 0;
for (i = CharPosX = 0; i < Len; i++, CharPosX += GIF_FONT_WIDTH) {
unsigned char c = TextLine[i];
for (j = 0; j < GIF_FONT_HEIGHT; j++) {
Byte = GifAsciiTable8x8[(unsigned short)c][j];
for (k = 0, Mask = 128; k < GIF_FONT_WIDTH; k++, Mask >>= 1)
if (Byte & Mask)
RasterBuffer[j][CharPosX + k] = ForeGroundIndex;
}
}
}
/******************************************************************************
* Close output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFile)
{
if (GifFile != NULL) {
PrintGifError(GifFile->Error);
EGifCloseFile(GifFile, NULL);
}
exit(EXIT_FAILURE);
}
/* end */

154
third_party/giflib/giflib/giffilter.c vendored Normal file
View File

@ -0,0 +1,154 @@
/******************************************************************************
giffilter.c - skeleton file for generic GIF `filter' program
Sequentially read GIF records from stdin, process them, send them out.
Most of the junk above `int main' isn't needed for the skeleton, but
is likely to be for what you'll do with it.
If you compile this, it will turn into an expensive GIF copying routine;
stdin to stdout with no changes and minimal validation. Well, it's a
decent test of the low-level routines, anyway.
Note: due to the vicissitudes of Lempel-Ziv compression, the output of this
copier may not be bitwise identical to its input. This can happen if you
copy an image from a much more (or much *less*) memory-limited system; your
compression may use more (or fewer) bits. The uncompressed rasters should,
however, be identical (you can check this with gifbuild -d).
SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "giffilter"
/******************************************************************************
Close both input and output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
if (GifFileIn != NULL) {
PrintGifError(GifFileIn->Error);
EGifCloseFile(GifFileIn, NULL);
}
if (GifFileOut != NULL) {
PrintGifError(GifFileOut->Error);
EGifCloseFile(GifFileOut, NULL);
}
exit(EXIT_FAILURE);
}
/******************************************************************************
Main sequence
******************************************************************************/
int main(int argc, char **argv)
{
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
GifRecordType RecordType;
int CodeSize, ExtCode, ErrorCode;
GifByteType *CodeBlock, *Extension;
/*
* Command-line processing goes here.
*/
/* Use stdin as input (note this also read screen descriptor in: */
if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* Use the stdout as output: */
if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* And dump out its screen information: */
if (EGifPutScreenDesc(GifFileOut,
GifFileIn->SWidth, GifFileIn->SHeight,
GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
GifFileIn->SColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Scan the content of the input GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Put image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn->Image.Left, GifFileIn->Image.Top,
GifFileIn->Image.Width, GifFileIn->Image.Height,
GifFileIn->Image.Interlace,
GifFileIn->Image.ColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Now read image itself in decoded form as we dont really */
/* care what we have there, and this is much faster. */
if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR ||
EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* pass through extension records */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR || Extension == NULL)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (Extension != NULL)
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/* end */

218
third_party/giflib/giflib/giffix.c vendored Normal file
View File

@ -0,0 +1,218 @@
/*****************************************************************************
giffix - attempt to fix a truncated GIF
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#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 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);
}
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);
}
/* Dump out exactly same screen information: */
/* coverity[var_deref_op] */
if (EGifPutScreenDesc(GifFileOut,
GifFileIn->SWidth, GifFileIn->SHeight,
GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
GifFileIn->SColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL)
GIF_EXIT("Failed to allocate memory required, aborted.");
/* Scan the content of the GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (GifFileIn->Image.Interlace)
GIF_EXIT("Cannot fix interlaced images.");
Row = GifFileIn->Image.Top; /* Image Position relative to Screen. */
Col = GifFileIn->Image.Left;
Width = GifFileIn->Image.Width;
Height = GifFileIn->Image.Height;
GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ",
PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
if (Width > GifFileIn->SWidth)
GIF_EXIT("Image is wider than total");
/* Put the image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut, Col, Row, Width, Height,
false, GifFileIn->Image.ColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Find the darkest color in color map to use as a filler. */
ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap :
GifFileIn->SColorMap);
for (i = 0; i < ColorMap->ColorCount; i++) {
j = ((int) ColorMap->Colors[i].Red) * 30 +
((int) ColorMap->Colors[i].Green) * 59 +
((int) ColorMap->Colors[i].Blue) * 11;
if (j < ColorIntens) {
ColorIntens = j;
DarkestColor = i;
}
}
/* Load the image, and dump it. */
for (i = 0; i < Height; i++) {
GifQprintf("\b\b\b\b%-4d", i);
if (DGifGetLine(GifFileIn, LineBuffer, Width)
== GIF_ERROR) break;
if (EGifPutLine(GifFileOut, LineBuffer, Width)
== GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
}
if (i < Height) {
fprintf(stderr,"\nFollowing error occurred (and ignored):");
PrintGifError(GifFileIn->Error);
/* Fill in with the darkest color in color map. */
for (j = 0; j < Width; j++)
LineBuffer[j] = DarkestColor;
for (; i < Height; i++)
if (EGifPutLine(GifFileOut, LineBuffer, Width)
== GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* pass through extension records */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (Extension != NULL)
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (Extension != NULL)
if (EGifPutExtensionBlock(GifFileOut,
Extension[0],
Extension + 1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType. */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
return 0;
}
/******************************************************************************
Close both input and output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
fprintf(stderr, "\nFollowing unrecoverable error occurred:");
if (GifFileIn != NULL) {
PrintGifError(GifFileIn->Error);
EGifCloseFile(GifFileIn, NULL);
}
if (GifFileOut != NULL) {
PrintGifError(GifFileOut->Error);
EGifCloseFile(GifFileOut, NULL);
}
exit(EXIT_FAILURE);
}
/* end */

259
third_party/giflib/giflib/gifhisto.c vendored Normal file
View File

@ -0,0 +1,259 @@
/*****************************************************************************
gifhisto - make a color histogram from image color frequencies
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifhisto"
#define DEFAULT_HISTO_WIDTH 100 /* Histogram image diemnsions. */
#define DEFAULT_HISTO_HEIGHT 256
#define HISTO_BITS_PER_PIXEL 2 /* Size of bitmap for histogram GIF. */
static char
*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);
}
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)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL)
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType. */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
/* We requested suppression of the background count: */
if (BackGroundFlag) Histogram[GifFileIn->SBackGroundColor] = 0;
if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* We may required to dump out the histogram as text file: */
if (TextFlag) {
for (i = 0; i < NumColors; i++)
printf("%12ld %3d\n", Histogram[i], i);
}
else {
int Color, Count;
long Scaler;
/* Open stdout for the histogram output file: */
if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* Dump out screen descriptor to fit histogram dimensions: */
if (EGifPutScreenDesc(GifFileOut,
ImageWidth, ImageHeight, HISTO_BITS_PER_PIXEL, 0,
GifMakeMapObject(4, HistoColorMap)) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Dump out image descriptor to fit histogram dimensions: */
if (EGifPutImageDesc(GifFileOut,
0, 0, ImageWidth, ImageHeight, false, NULL) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Prepare scan line for histogram file, and find scaler to scale */
/* histogram to be between 0 and ImageWidth: */
Line = (GifRowType) malloc(ImageWidth * sizeof(GifPixelType));
for (Scaler = 0, i = 0; i < NumColors; i++) if (Histogram[i] > Scaler)
Scaler = Histogram[i];
Scaler /= ImageWidth;
if (Scaler == 0) Scaler = 1; /* In case maximum is less than width. */
/* Dump out the image itself: */
for (Count = ImageHeight, i = 0, Color = 1; i < NumColors; i++) {
int Size;
if ((Size = Histogram[i] / Scaler) > ImageWidth) Size = ImageWidth;
for (j = 0; j < Size; j++)
Line[j] = Color;
for (j = Size; j < ImageWidth; j++)
Line[j] = GifFileOut->SBackGroundColor;
/* Move to next color: */
if (++Color >= (1 << HISTO_BITS_PER_PIXEL)) Color = 1;
/* Dump this histogram entry as many times as required: */
for (j = 0; j < ImageHeight / NumColors; j++) {
if (EGifPutLine(GifFileOut, Line, ImageWidth) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
GifQprintf("\b\b\b\b%-4d", Count--);
}
}
if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
{
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
}
return 0;
}
/******************************************************************************
Close both input and output file (if open), and exit.
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
if (GifFileIn != NULL) {
PrintGifError(GifFileIn->Error);
EGifCloseFile(GifFileIn, NULL);
}
if (GifFileOut != NULL) {
PrintGifError(GifFileOut->Error);
EGifCloseFile(GifFileOut, NULL);
}
exit(EXIT_FAILURE);
}
/* end */

191
third_party/giflib/giflib/gifinto.c vendored Normal file
View File

@ -0,0 +1,191 @@
/*****************************************************************************
gifinto - save GIF on stdin to file if size over set threshold
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif /* _WIN32 */
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifinto"
#define STRLEN 512
#define DEFAULT_MIN_FILE_SIZE 14 /* More than GIF stamp + screen desc. */
#define DEFAULT_OUT_NAME "GifInto.Gif"
#define DEFAULT_TMP_NAME "TempInto.XXXXXX"
static char
*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;
#ifdef _WIN32
#include <errno.h>
#include <sys/stat.h>
int
mkstemp(char *tpl)
{
int fd = -1;
char *p;
int e = errno;
errno = 0;
p = _mktemp(tpl);
if (*p && errno == 0)
{
errno = e;
fd = _open(p, _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY,
_S_IREAD | _S_IWRITE);
}
return fd;
}
#endif
/******************************************************************************
This is simply: read until EOF, then close the output, test its length, and
if non zero then rename it.
******************************************************************************/
int main(int argc, char **argv)
{
int FD;
int NumFiles;
bool Error, MinSizeFlag = false, HelpFlag = false;
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: */
#ifdef _WIN32
_setmode(0, O_BINARY); /* Make sure it is in binary mode. */
#endif
Fin = fdopen(0, "rb"); /* Make it into a stream: */
if (Fin == NULL)
{
GIF_EXIT("Failed to open input.");
}
/* Isolate the directory where our destination is, and set tmp file name */
/* in the very same directory. This code is isecure because it creates */
/* predictable names, but it's not worth the effort and risk to fix. */
if ( *FileName == NULL ) GIF_EXIT("No valid Filename given.");
if ( strlen(*FileName) > STRLEN-1 ) GIF_EXIT("Filename too long.");
memset(FullPath, '\0', sizeof(FullPath));
strncpy(FullPath, *FileName, STRLEN);
if ((p = strrchr(FullPath, '/')) != NULL ||
(p = strrchr(FullPath, '\\')) != NULL)
p[1] = 0;
else if ((p = strrchr(FullPath, ':')) != NULL)
p[1] = 0;
else
FullPath[0] = 0; /* No directory or disk specified. */
if ( strlen(FullPath) > STRLEN-1 ) GIF_EXIT("Filename too long.");
strncpy(FoutTmpName, FullPath, STRLEN); /* First setup the Path */
/* then add a name for the tempfile */
if ( (strlen(FoutTmpName) + strlen(DEFAULT_TMP_NAME)) > STRLEN-1 ) GIF_EXIT("Filename too long.");
strcat(FoutTmpName, DEFAULT_TMP_NAME);
#ifdef _WIN32
char *tmpFN = _mktemp(FoutTmpName);
if (tmpFN)
FD = open(tmpFN, O_CREAT | O_EXCL | O_WRONLY);
else
FD = -1;
#else
FD = mkstemp(FoutTmpName); /* returns filedescriptor */
#endif
if (FD == -1 )
{
GIF_EXIT("Failed to open output.");
}
Fout = fdopen(FD, "wb"); /* returns a stream with FD */
if (Fout == NULL )
{
GIF_EXIT("Failed to open output.");
}
while (1) {
int c = getc(Fin);
if (feof(Fin))
break;
if (putc(c, Fout) == EOF)
GIF_EXIT("Failed to write output.");
}
fclose(Fin);
if (ftell(Fout) >= (long) MinFileSize) {
fclose(Fout);
unlink(*FileName);
if (rename(FoutTmpName, *FileName) != 0) {
char DefaultName[STRLEN+1];
memset(DefaultName, '\0', sizeof(DefaultName));
if ( (strlen(FullPath) + strlen(DEFAULT_OUT_NAME)) > STRLEN-1 ) GIF_EXIT("Filename too long.");
strncpy(DefaultName, FullPath, STRLEN);
strcat(DefaultName, DEFAULT_OUT_NAME);
if (rename(FoutTmpName, DefaultName) == 0) {
char s[STRLEN];
snprintf(s, STRLEN, "Failed to rename out file - left as %s.",
DefaultName);
GIF_MESSAGE(s);
}
else {
unlink(FoutTmpName);
GIF_MESSAGE("Failed to rename out file - deleted.");
}
}
}
else {
fclose(Fout);
unlink(FoutTmpName);
GIF_MESSAGE("File too small - not renamed.");
}
return 0;
}
/* end */

79
third_party/giflib/giflib/giflib.cbp vendored Normal file
View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="giflib" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/giflib" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Debug/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-Wall" />
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/giflib" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="obj/Release/" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-Wall" />
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-fPIC" />
</Compiler>
<Unit filename="dgif_lib.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="egif_lib.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="getarg.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="getarg.h" />
<Unit filename="gif_err.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="gif_font.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="gif_hash.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="gif_hash.h" />
<Unit filename="gif_lib.h" />
<Unit filename="gif_lib_private.h" />
<Unit filename="gifalloc.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="openbsd-reallocarray.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="qprintf.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="quantize.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<code_completion />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

87
third_party/giflib/giflib/gifsponge.c vendored Normal file
View File

@ -0,0 +1,87 @@
/****************************************************************************
gifsponge.c - skeleton file for generic GIF `sponge' program
Slurp a GIF into core, operate on it, spew it out again. Most of the
junk above `int main' isn't needed for the skeleton, but is likely to
be for what you'll do with it.
If you compile this, it will turn into an expensive GIF copying routine;
stdin to stdout with no changes and minimal validation. Well, it's a
decent test of DGifSlurp() and EGifSpew(), anyway.
Note: due to the vicissitudes of Lempel-Ziv compression, the output of this
copier may not be bitwise identical to its input. This can happen if you
copy an image from a much more (or much *less*) memory-limited system; your
compression may use more (or fewer) bits. The uncompressed rasters should,
however, be identical (you can check this with gifbuild -d).
SPDX-License-Identifier: MIT
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "gif_lib.h"
#include "getarg.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);
if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
PrintGifError(ErrorCode);
return 0;
}
/* end */

466
third_party/giflib/giflib/giftext.c vendored Normal file
View File

@ -0,0 +1,466 @@
/*****************************************************************************
giftext - dump GIF pixels and metadata as text
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdbool.h>
#ifdef _WIN32
#include <io.h>
#endif /* _WIN32 */
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "giftext"
#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 void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, bool Reset);
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, bool Reset);
static void PrintExtBlock(GifByteType *Extension, bool Reset);
static void PrintLZCodes(GifFileType *GifFile);
/******************************************************************************
Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
int i, j, ExtCode, ErrorCode, CodeSize, NumFiles, Len, ImageNum = 1;
bool Error,
ColorMapFlag = false, EncodedFlag = false, LZCodesFlag = false,
PixelFlag = false, HelpFlag = false, RawFlag = false;
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");
}
}
}
if (EncodedFlag) {
if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
printf("\nImage LZ compressed Codes (Code Size = %d):\n",
CodeSize);
PrintCodeBlock(GifFile, CodeBlock, true);
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
PrintCodeBlock(GifFile, CodeBlock, false);
}
}
else if (LZCodesFlag) {
PrintLZCodes(GifFile);
}
else if (PixelFlag) {
Line = (GifPixelType *) malloc(GifFile->Image.Width *
sizeof(GifPixelType));
for (i = 0; i < GifFile->Image.Height; i++) {
if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
== GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
PrintPixelBlock(Line, GifFile->Image.Width, i == 0);
}
PrintPixelBlock(NULL, GifFile->Image.Width, false);
free((char *) Line);
}
else if (RawFlag) {
Line = (GifPixelType *) malloc(GifFile->Image.Width *
sizeof(GifPixelType));
for (i = 0; i < GifFile->Image.Height; i++) {
if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
== GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
fwrite(Line, 1, GifFile->Image.Width, stdout);
}
free((char *) Line);
}
else {
/* Skip the image: */
if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
}
}
break;
case EXTENSION_RECORD_TYPE:
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
if (!RawFlag) {
putchar('\n');
switch (ExtCode)
{
case COMMENT_EXT_FUNC_CODE:
printf("GIF89 comment");
break;
case GRAPHICS_EXT_FUNC_CODE:
printf("GIF89 graphics control");
break;
case PLAINTEXT_EXT_FUNC_CODE:
printf("GIF89 plaintext");
break;
case APPLICATION_EXT_FUNC_CODE:
printf("GIF89 application block");
break;
default:
printf("Extension record of unknown type");
break;
}
printf(" (Ext Code = %d [%c]):\n",
ExtCode, MAKE_PRINTABLE(ExtCode));
PrintExtBlock(Extension, true);
if (ExtCode == GRAPHICS_EXT_FUNC_CODE) {
GraphicsControlBlock gcb;
if (Extension == NULL) {
printf("Invalid extension block\n");
GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
if (DGifExtensionToGCB(Extension[0], Extension+1, &gcb) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
printf("\tDisposal Mode: %d\n", gcb.DisposalMode);
printf("\tUser Input Flag: %d\n", gcb.UserInputFlag);
printf("\tTransparency on: %s\n",
gcb.TransparentColor != -1 ? "yes" : "no");
printf("\tDelayTime: %d\n", gcb.DelayTime);
printf("\tTransparent Index: %d\n", gcb.TransparentColor);
}
}
for (;;) {
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
PrintGifError(GifFile->Error);
exit(EXIT_FAILURE);
}
if (Extension == NULL)
break;
PrintExtBlock(Extension, false);
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (!RawFlag) printf("\nGIF file terminated normally.\n");
return 0;
}
/******************************************************************************
Print the given CodeBlock - a string in pascal notation (size in first
place). Save local information so printing can be performed continuously,
or reset to start state if Reset. If CodeBlock is NULL, output is flushed
******************************************************************************/
static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, bool Reset)
{
static int CrntPlace = 0;
static long CodeCount = 0;
int i, Len;
if (Reset || CodeBlock == NULL) {
if (CodeBlock == NULL) {
long NumBytes = 0;
if (CrntPlace > 0) {
printf("\n");
CodeCount += CrntPlace - 16;
}
if (GifFile->Image.ColorMap)
NumBytes = ((((long) GifFile->Image.Width) * GifFile->Image.Height)
* GifFile->Image.ColorMap->BitsPerPixel) / 8;
else if (GifFile->SColorMap != NULL)
NumBytes = ((((long) GifFile->Image.Width) * GifFile->Image.Height)
* GifFile->SColorMap->BitsPerPixel) / 8;
/* FIXME: What should the compression ratio be if no color table? */
if (NumBytes > 0) {
int Percent = 100 * CodeCount / NumBytes;
printf("\nCompression ratio: %ld/%ld (%d%%).\n",
CodeCount, NumBytes, Percent);
}
return;
}
CrntPlace = 0;
CodeCount = 0;
}
Len = CodeBlock[0];
for (i = 1; i <= Len; i++) {
if (CrntPlace == 0) {
printf("\n%05lxh: ", CodeCount);
CodeCount += 16;
}
(void)printf(" %02xh", CodeBlock[i]);
if (++CrntPlace >= 16) CrntPlace = 0;
}
}
/******************************************************************************
Print the given Extension - a string in pascal notation (size in first
place). Save local information so printing can be performed continuously,
or reset to start state if Reset. If Extension is NULL, output is flushed
******************************************************************************/
static void PrintExtBlock(GifByteType *Extension, bool Reset)
{
static int CrntPlace = 0;
static long ExtCount = 0;
static char HexForm[49], AsciiForm[17];
if (Reset || Extension == NULL) {
if (Extension == NULL) {
if (CrntPlace > 0) {
HexForm[CrntPlace * 3] = 0;
AsciiForm[CrntPlace] = 0;
printf("\n%05lx: %-49s %-17s\n", ExtCount, HexForm, AsciiForm);
return;
}
else
printf("\n");
}
CrntPlace = 0;
ExtCount = 0;
}
if (Extension != NULL) {
int i, Len;
Len = Extension[0];
for (i = 1; i <= Len; i++) {
(void)snprintf(&HexForm[CrntPlace * 3], 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;
}
}
}
}
/******************************************************************************
Print the given PixelBlock of length Len.
Save local information so printing can be performed continuously,
or reset to start state if Reset. If PixelBlock is NULL, output is flushed
******************************************************************************/
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, bool Reset)
{
static int CrntPlace = 0;
static long ExtCount = 0;
static char HexForm[49], AsciiForm[17];
int i;
if (Reset || PixelBlock == NULL) {
if (PixelBlock == NULL) {
if (CrntPlace > 0) {
HexForm[CrntPlace * 3] = 0;
AsciiForm[CrntPlace] = 0;
printf("\n%05lx: %-49s %-17s\n", ExtCount, HexForm, AsciiForm);
}
else
printf("\n");
}
CrntPlace = 0;
ExtCount = 0;
if (PixelBlock == NULL) return;
}
for (i = 0; i < Len; i++) {
(void)snprintf(&HexForm[CrntPlace * 3], 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);
}
/* end */

579
third_party/giflib/giflib/giftool.c vendored Normal file
View File

@ -0,0 +1,579 @@
/****************************************************************************
giftool.c - GIF transformation tool.
SPDX-License-Identifier: MIT
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdbool.h>
#include "getopt.h"
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "giftool"
#define MAX_OPERATIONS 256
#define MAX_IMAGES 2048
enum boolmode {numeric, onoff, tf, yesno};
char *putbool(bool flag, enum boolmode mode)
{
if (flag)
switch (mode) {
case numeric: return "1"; break;
case onoff: return "on"; break;
case tf: return "true"; break;
case yesno: return "yes"; break;
}
else
switch (mode) {
case numeric: return "0"; break;
case onoff: return "off"; break;
case tf: return "false"; break;
case yesno: return "no"; break;
}
return "FAIL"; /* should never happen */
}
bool getbool(char *from)
{
struct valmap {char *name; bool val;}
boolnames[] = {
{"yes", true},
{"on", true},
{"1", true},
{"t", true},
{"no", false},
{"off", false},
{"0", false},
{"f", false},
{NULL, false},
}, *sp;
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);
}
struct operation {
enum {
aspect,
delaytime,
background,
info,
interlace,
position,
screensize,
transparent,
userinput,
disposal,
} mode;
union {
GifByteType numerator;
int delay;
int color;
int dispose;
char *format;
bool flag;
struct {
int x, y;
} p;
};
};
int main(int argc, char **argv)
{
extern char *optarg; /* set by getopt */
extern int optind; /* set by getopt */
struct operation operations[MAX_OPERATIONS];
struct operation *top = operations;
int selected[MAX_IMAGES], nselected = 0;
bool have_selection = false;
char *cp;
int i, status, ErrorCode;
GifFileType *GifFileIn, *GifFileOut = (GifFileType *)NULL;
struct operation *op;
/*
* Gather operations from the command line. We use regular
* getopt(3) here rather than Gershom's argument getter because
* preserving the order of operations is important.
*/
while ((status = getopt(argc, argv, "a:b:d:f:i:n:p:s:u:x:")) != EOF)
{
if (top >= operations + MAX_OPERATIONS) {
(void)fprintf(stderr, "giftool: too many operations.");
exit(EXIT_FAILURE);
}
switch (status)
{
case 'a':
top->mode = aspect;
top->numerator = (GifByteType)atoi(optarg);
break;
case 'b':
top->mode = background;
top->color = atoi(optarg);
break;
case 'd':
top->mode = delaytime;
top->delay = atoi(optarg);
break;
case 'f':
top->mode = info;
top->format = optarg;
break;
case 'i':
top->mode = interlace;
top->flag = getbool(optarg);
break;
case 'n':
have_selection = true;
nselected = 0;
cp = optarg;
for (;;)
{
size_t span = strspn(cp, "0123456789");
if (span > 0)
{
selected[nselected++] = atoi(cp)-1;
cp += span;
if (*cp == '\0')
break;
else if (*cp == ',')
continue;
}
(void) fprintf(stderr, "giftool: bad selection.\n");
exit(EXIT_FAILURE);
}
break;
case 'p':
case 's':
if (status == 'p')
top->mode = position;
else
top->mode = screensize;
cp = strchr(optarg, ',');
if (cp == NULL)
{
(void) fprintf(stderr, "giftool: missing comma in coordinate pair.\n");
exit(EXIT_FAILURE);
}
top->p.x = atoi(optarg);
top->p.y = atoi(cp+1);
if (top->p.x < 0 || top->p.y < 0)
{
(void) fprintf(stderr, "giftool: negative coordinate.\n");
exit(EXIT_FAILURE);
}
break;
case 'u':
top->mode = userinput;
top->flag = getbool(optarg);
break;
case 'x':
top->mode = disposal;
top->dispose = atoi(optarg);
break;
default:
fprintf(stderr, "usage: giftool [-b color] [-d delay] [-iI] [-t color] -[uU] [-x disposal]\n");
break;
}
++top;
}
/* read in a GIF */
if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
if (DGifSlurp(GifFileIn) == GIF_ERROR) {
PrintGifError(GifFileIn->Error);
exit(EXIT_FAILURE);
}
if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
PrintGifError(ErrorCode);
exit(EXIT_FAILURE);
}
/* if the selection is defaulted, compute it; otherwise bounds-check it */
if (!have_selection)
for (i = nselected = 0; i < GifFileIn->ImageCount; i++)
selected[nselected++] = i;
else
for (i = 0; i < nselected; i++)
if (selected[i] >= GifFileIn->ImageCount || selected[i] < 0)
{
(void) fprintf(stderr,
"giftool: selection index out of bounds.\n");
exit(EXIT_FAILURE);
}
/* perform the operations we've gathered */
for (op = operations; op < top; op++)
switch (op->mode)
{
case background:
GifFileIn->SBackGroundColor = op->color;
break;
case delaytime:
for (i = 0; i < nselected; i++)
{
GraphicsControlBlock gcb;
DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb);
gcb.DelayTime = op->delay;
EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]);
}
break;
case info:
for (i = 0; i < nselected; i++) {
SavedImage *ip = &GifFileIn->SavedImages[selected[i]];
GraphicsControlBlock gcb;
for (cp = op->format; *cp; cp++) {
if (*cp == '\\')
{
char c;
switch (*++cp)
{
case 'b':
(void)putchar('\b');
break;
case 'e':
(void)putchar(0x1b);
break;
case 'f':
(void)putchar('\f');
break;
case 'n':
(void)putchar('\n');
break;
case 'r':
(void)putchar('\r');
break;
case 't':
(void)putchar('\t');
break;
case 'v':
(void)putchar('\v');
break;
case 'x':
switch (*++cp) {
case '0':
c = (char)0x00;
break;
case '1':
c = (char)0x10;
break;
case '2':
c = (char)0x20;
break;
case '3':
c = (char)0x30;
break;
case '4':
c = (char)0x40;
break;
case '5':
c = (char)0x50;
break;
case '6':
c = (char)0x60;
break;
case '7':
c = (char)0x70;
break;
case '8':
c = (char)0x80;
break;
case '9':
c = (char)0x90;
break;
case 'A':
case 'a':
c = (char)0xa0;
break;
case 'B':
case 'b':
c = (char)0xb0;
break;
case 'C':
case 'c':
c = (char)0xc0;
break;
case 'D':
case 'd':
c = (char)0xd0;
break;
case 'E':
case 'e':
c = (char)0xe0;
break;
case 'F':
case 'f':
c = (char)0xf0;
break;
default:
return -1;
}
switch (*++cp) {
case '0':
c += 0x00;
break;
case '1':
c += 0x01;
break;
case '2':
c += 0x02;
break;
case '3':
c += 0x03;
break;
case '4':
c += 0x04;
break;
case '5':
c += 0x05;
break;
case '6':
c += 0x06;
break;
case '7':
c += 0x07;
break;
case '8':
c += 0x08;
break;
case '9':
c += 0x09;
break;
case 'A':
case 'a':
c += 0x0a;
break;
case 'B':
case 'b':
c += 0x0b;
break;
case 'C':
case 'c':
c += 0x0c;
break;
case 'D':
case 'd':
c += 0x0d;
break;
case 'E':
case 'e':
c += 0x0e;
break;
case 'F':
case 'f':
c += 0x0f;
break;
default:
return -2;
}
putchar(c);
break;
default:
putchar(*cp);
break;
}
}
else if (*cp == '%')
{
enum boolmode boolfmt;
SavedImage *sp = &GifFileIn->SavedImages[i];
if (cp[1] == 't') {
boolfmt = tf;
++cp;
} else if (cp[1] == 'o') {
boolfmt = onoff;
++cp;
} else if (cp[1] == 'y') {
boolfmt = yesno;
++cp;
} else if (cp[1] == '1') {
boolfmt = numeric;
++cp;
} else
boolfmt = numeric;
switch (*++cp)
{
case '%':
putchar('%');
break;
case 'a':
(void)printf("%d", GifFileIn->AspectByte);
break;
case 'b':
(void)printf("%d", GifFileIn->SBackGroundColor);
break;
case 'd':
DGifSavedExtensionToGCB(GifFileIn,
selected[i],
&gcb);
(void)printf("%d", gcb.DelayTime);
break;
case 'h':
(void)printf("%d", ip->ImageDesc.Height);
break;
case 'n':
(void)printf("%d", selected[i]+1);
break;
case 'p':
(void)printf("%d,%d",
ip->ImageDesc.Left, ip->ImageDesc.Top);
break;
case 's':
(void)printf("%d,%d",
GifFileIn->SWidth,
GifFileIn->SHeight);
break;
case 'w':
(void)printf("%d", ip->ImageDesc.Width);
break;
case 't':
DGifSavedExtensionToGCB(GifFileIn,
selected[i],
&gcb);
(void)printf("%d", gcb.TransparentColor);
break;
case 'u':
DGifSavedExtensionToGCB(GifFileIn,
selected[i],
&gcb);
(void)printf("%s", putbool(gcb.UserInputFlag, boolfmt));
break;
case 'v':
fputs(EGifGetGifVersion(GifFileIn), stdout);
break;
case 'x':
DGifSavedExtensionToGCB(GifFileIn,
selected[i],
&gcb);
(void)printf("%d", gcb.DisposalMode);
break;
case 'z':
(void) printf("%s", putbool(sp->ImageDesc.ColorMap && sp->ImageDesc.ColorMap->SortFlag, boolfmt));
break;
default:
(void)fprintf(stderr,
"giftool: bad format %%%c\n", *cp);
}
}
else
(void)putchar(*cp);
}
}
exit(EXIT_SUCCESS);
break;
case interlace:
for (i = 0; i < nselected; i++)
GifFileIn->SavedImages[selected[i]].ImageDesc.Interlace = op->flag;
break;
case position:
for (i = 0; i < nselected; i++) {
GifFileIn->SavedImages[selected[i]].ImageDesc.Left = op->p.x;
GifFileIn->SavedImages[selected[i]].ImageDesc.Top = op->p.y;
}
break;
case screensize:
GifFileIn->SWidth = op->p.x;
GifFileIn->SHeight = op->p.y;
break;
case transparent:
for (i = 0; i < nselected; i++)
{
GraphicsControlBlock gcb;
DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb);
gcb.TransparentColor = op->color;
EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]);
}
break;
case userinput:
for (i = 0; i < nselected; i++)
{
GraphicsControlBlock gcb;
DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb);
gcb.UserInputFlag = op->flag;
EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]);
}
break;
case disposal:
for (i = 0; i < nselected; i++)
{
GraphicsControlBlock gcb;
DGifSavedExtensionToGCB(GifFileIn, selected[i], &gcb);
gcb.DisposalMode = op->dispose;
EGifGCBToSavedExtension(&gcb, GifFileIn, selected[i]);
}
break;
default:
(void)fprintf(stderr, "giftool: unknown operation mode\n");
exit(EXIT_FAILURE);
}
/* write out the results */
GifFileOut->SWidth = GifFileIn->SWidth;
GifFileOut->SHeight = GifFileIn->SHeight;
GifFileOut->SColorResolution = GifFileIn->SColorResolution;
GifFileOut->SBackGroundColor = GifFileIn->SBackGroundColor;
if (GifFileIn->SColorMap != NULL)
GifFileOut->SColorMap = GifMakeMapObject(
GifFileIn->SColorMap->ColorCount,
GifFileIn->SColorMap->Colors);
for (i = 0; i < GifFileIn->ImageCount; i++)
(void) GifMakeSavedImage(GifFileOut, &GifFileIn->SavedImages[i]);
if (EGifSpew(GifFileOut) == GIF_ERROR)
PrintGifError(GifFileOut->Error);
else if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
PrintGifError(ErrorCode);
return 0;
}
/* end */

143
third_party/giflib/giflib/gifwedge.c vendored Normal file
View File

@ -0,0 +1,143 @@
/*****************************************************************************
gifwedge - create a GIF test pattern
SPDX-License-Identifier: MIT
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include "gif_lib.h"
#include "getarg.h"
#define PROGRAM_NAME "gifwedge"
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 350
#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */
static char
*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;
/******************************************************************************
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) {
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;
}
/* end */

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
* SPDX-License-Identifier: MIT
*/
#include <sys/types.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#endif
/*
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
{
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
errno = ENOMEM;
return NULL;
}
/*
* Head off variations in realloc behavior on different
* platforms (reported by MarkR <mrogers6@users.sf.net>)
*
* The behaviour of reallocarray is implementation-defined if
* nmemb or size is zero. It can return NULL or non-NULL
* depending on the platform.
* https://www.securecoding.cert.org/confluence/display/c/MEM04-C.Beware+of+zero-lengthallocations
*
* Here are some extracts from realloc man pages on different platforms.
*
* void realloc( void memblock, size_t size );
*
* Windows:
*
* If there is not enough available memory to expand the block
* to the given size, the original block is left unchanged,
* and NULL is returned. If size is zero, then the block
* pointed to by memblock is freed; the return value is NULL,
* and memblock is left pointing at a freed block.
*
* OpenBSD:
*
* If size or nmemb is equal to 0, a unique pointer to an
* access protected, zero sized object is returned. Access via
* this pointer will generate a SIGSEGV exception.
*
* Linux:
*
* If size was equal to 0, either NULL or a pointer suitable
* to be passed to free() is returned.
*
* OS X:
*
* If size is zero and ptr is not NULL, a new, minimum sized
* object is allocated and the original object is freed.
*
* It looks like images with zero width or height can trigger
* this, and fuzzing behaviour will differ by platform, so
* fuzzing on one platform may not detect zero-size allocation
* problems on other platforms.
*/
if (size == 0 || nmemb == 0)
return NULL;
return realloc(optr, size * nmemb);
}

48
third_party/giflib/giflib/qprintf.c vendored Normal file
View File

@ -0,0 +1,48 @@
/*****************************************************************************
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 <stdio.h>
#include <stdbool.h>
#include <stdarg.h>
#include "gif_lib.h"
bool GifNoisyPrint = false;
/*****************************************************************************
Same as fprintf to stderr but with optional print.
******************************************************************************/
void
GifQprintf(char *Format, ...) {
va_list ArgPtr;
va_start(ArgPtr, Format);
if (GifNoisyPrint) {
char Line[128];
(void)vsnprintf(Line, sizeof(Line), Format, ArgPtr);
(void)fputs(Line, stderr);
}
va_end(ArgPtr);
}
void
PrintGifError(int ErrorCode) {
const char *Err = GifErrorString(ErrorCode);
if (Err != NULL)
fprintf(stderr, "GIF-LIB error: %s.\n", Err);
else
fprintf(stderr, "GIF-LIB undefined error %d.\n", ErrorCode);
}
/* end */

332
third_party/giflib/giflib/quantize.c vendored Normal file
View File

@ -0,0 +1,332 @@
/*****************************************************************************
quantize.c - quantize a high resolution image into lower one
Based on: "Color Image Quantization for frame buffer Display", by
Paul Heckbert SIGGRAPH 1982 page 297-307.
This doesn't really belong in the core library, was undocumented,
and was removed in 4.2. Then it turned out some client apps were
actually using it, so it was restored in 5.0.
SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "gif_lib.h"
#include "gif_lib_private.h"
#define ABS(x) ((x) > 0 ? (x) : (-(x)))
#define COLOR_ARRAY_SIZE 32768
#define BITS_PER_PRIM_COLOR 5
#define MAX_PRIM_COLOR 0x1f
static int SortRGBAxis;
typedef struct QuantizedColorType {
GifByteType RGB[3];
GifByteType NewColorIndex;
long Count;
struct QuantizedColorType *Pnext;
} QuantizedColorType;
typedef struct NewColorMapType {
GifByteType RGBMin[3], RGBWidth[3];
unsigned int NumEntries; /* # of QuantizedColorType in linked list below */
unsigned long Count; /* Total number of pixels in all the entries */
QuantizedColorType *QuantizedColors;
} NewColorMapType;
static int SubdivColorMap(NewColorMapType * NewColorSubdiv,
unsigned int ColorMapSize,
unsigned int *NewColorMapSize);
static int SortCmpRtn(const void *Entry1, const void *Entry2);
/******************************************************************************
Quantize high resolution image into lower one. Input image consists of a
2D array for each of the RGB colors with size Width by Height. There is no
Color map for the input. Output is a quantized image with 2D array of
indexes into the output color map.
Note input image can be 24 bits at the most (8 for red/green/blue) and
the output has 256 colors at the most (256 entries in the color map.).
ColorMapSize specifies size of color map up to 256 and will be updated to
real size before returning.
Also non of the parameter are allocated by this routine.
This function returns GIF_OK if successful, GIF_ERROR otherwise.
******************************************************************************/
int
GifQuantizeBuffer(unsigned int Width,
unsigned int Height,
int *ColorMapSize,
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]);
}
#ifdef DEBUG
fprintf(stderr,
"Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n",
MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]);
#endif /* DEBUG */
free((char *)ColorArrayEntries);
*ColorMapSize = NewColorMapSize;
return GIF_OK;
}
/******************************************************************************
Routine to subdivide the RGB space recursively using median cut in each
axes alternatingly until ColorMapSize different cubes exists.
The biggest cube in one dimension is subdivide unless it has only one entry.
Returns GIF_ERROR if failed, otherwise GIF_OK.
*******************************************************************************/
static int
SubdivColorMap(NewColorMapType * NewColorSubdiv,
unsigned int ColorMapSize,
unsigned int *NewColorMapSize) {
unsigned int i, j, Index = 0;
QuantizedColorType *QuantizedColor, **SortArray;
while (ColorMapSize > *NewColorMapSize) {
/* Find candidate for subdivision: */
long Sum, Count;
int MaxSize = -1;
unsigned int NumEntries, MinColor, MaxColor;
for (i = 0; i < *NewColorMapSize; i++) {
for (j = 0; j < 3; j++) {
if ((((int)NewColorSubdiv[i].RGBWidth[j]) > MaxSize) &&
(NewColorSubdiv[i].NumEntries > 1)) {
MaxSize = NewColorSubdiv[i].RGBWidth[j];
Index = i;
SortRGBAxis = j;
}
}
}
if (MaxSize == -1)
return GIF_OK;
/* Split the entry Index into two along the axis SortRGBAxis: */
/* Sort all elements in that entry along the given axis and split at
* the median. */
SortArray = (QuantizedColorType **)malloc(
sizeof(QuantizedColorType *) *
NewColorSubdiv[Index].NumEntries);
if (SortArray == NULL)
return GIF_ERROR;
for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors;
j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL;
j++, QuantizedColor = QuantizedColor->Pnext)
SortArray[j] = QuantizedColor;
/*
* Because qsort isn't stable, this can produce differing
* results for the order of tuples depending on platform
* details of how qsort() is implemented.
*
* We mitigate this problem by sorting on all three axes rather
* than only the one specied by SortRGBAxis; that way the instability
* can only become an issue if there are multiple color indices
* referring to identical RGB tuples. Older versions of this
* sorted on only the one axis.
*/
qsort(SortArray, NewColorSubdiv[Index].NumEntries,
sizeof(QuantizedColorType *), SortCmpRtn);
/* Relink the sorted list into one: */
for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++)
SortArray[j]->Pnext = SortArray[j + 1];
SortArray[NewColorSubdiv[Index].NumEntries - 1]->Pnext = NULL;
NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0];
free((char *)SortArray);
/* Now simply add the Counts until we have half of the Count: */
Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count;
NumEntries = 1;
Count = QuantizedColor->Count;
while (QuantizedColor->Pnext != NULL &&
(Sum -= QuantizedColor->Pnext->Count) >= 0 &&
QuantizedColor->Pnext->Pnext != NULL) {
QuantizedColor = QuantizedColor->Pnext;
NumEntries++;
Count += QuantizedColor->Count;
}
/* Save the values of the last color of the first half, and first
* of the second half so we can update the Bounding Boxes later.
* Also as the colors are quantized and the BBoxes are full 0..255,
* they need to be rescaled.
*/
MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */
/* coverity[var_deref_op] */
MinColor = QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */
MaxColor <<= (8 - BITS_PER_PRIM_COLOR);
MinColor <<= (8 - BITS_PER_PRIM_COLOR);
/* Partition right here: */
NewColorSubdiv[*NewColorMapSize].QuantizedColors =
QuantizedColor->Pnext;
QuantizedColor->Pnext = NULL;
NewColorSubdiv[*NewColorMapSize].Count = Count;
NewColorSubdiv[Index].Count -= Count;
NewColorSubdiv[*NewColorMapSize].NumEntries =
NewColorSubdiv[Index].NumEntries - NumEntries;
NewColorSubdiv[Index].NumEntries = NumEntries;
for (j = 0; j < 3; j++) {
NewColorSubdiv[*NewColorMapSize].RGBMin[j] =
NewColorSubdiv[Index].RGBMin[j];
NewColorSubdiv[*NewColorMapSize].RGBWidth[j] =
NewColorSubdiv[Index].RGBWidth[j];
}
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] =
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] +
NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - MinColor;
NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor;
NewColorSubdiv[Index].RGBWidth[SortRGBAxis] =
MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis];
(*NewColorMapSize)++;
}
return GIF_OK;
}
/****************************************************************************
Routine called by qsort to compare two entries.
*****************************************************************************/
static int
SortCmpRtn(const void *Entry1,
const void *Entry2) {
QuantizedColorType *entry1 = (*((QuantizedColorType **) Entry1));
QuantizedColorType *entry2 = (*((QuantizedColorType **) Entry2));
/* sort on all axes of the color space! */
int hash1 = entry1->RGB[SortRGBAxis] * 256 * 256
+ entry1->RGB[(SortRGBAxis+1) % 3] * 256
+ entry1->RGB[(SortRGBAxis+2) % 3];
int hash2 = entry2->RGB[SortRGBAxis] * 256 * 256
+ entry2->RGB[(SortRGBAxis+1) % 3] * 256
+ entry2->RGB[(SortRGBAxis+2) % 3];
return hash1 - hash2;
}
/* end */

View File

@ -0,0 +1,303 @@
/******************************************************************************
gif_lib.h - service library for decoding and encoding GIF images
SPDX-License-Identifier: MIT
*****************************************************************************/
#ifndef _GIF_LIB_H_
#define _GIF_LIB_H_ 1
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 2
#define GIFLIB_RELEASE 1
#define GIF_ERROR 0
#define GIF_OK 1
#include <stddef.h>
#include <stdbool.h>
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
typedef unsigned int GifPrefixType;
typedef int GifWord;
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
bool SortFlag;
GifColorType *Colors; /* on malloc(3) heap */
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height; /* Current image dimensions. */
bool Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct ExtensionBlock {
int ByteCount;
GifByteType *Bytes; /* on malloc(3) heap */
int Function; /* The block function code */
#define CONTINUE_EXT_FUNC_CODE 0x00 /* continuation subblock */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control (GIF89) */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block (GIF89) */
} ExtensionBlock;
typedef struct SavedImage {
GifImageDesc ImageDesc;
GifByteType *RasterBits; /* on malloc(3) heap */
int ExtensionBlockCount; /* Count of extensions before image */
ExtensionBlock *ExtensionBlocks; /* Extensions before image */
} SavedImage;
typedef struct GifFileType {
GifWord SWidth, SHeight; /* Size of virtual canvas */
GifWord SColorResolution; /* How many colors can we generate? */
GifWord SBackGroundColor; /* Background color for virtual canvas */
GifByteType AspectByte; /* Used to compute pixel aspect ratio */
ColorMapObject *SColorMap; /* Global colormap, NULL if nonexistent. */
int ImageCount; /* Number of current image (both APIs) */
GifImageDesc Image; /* Current image (low-level API) */
SavedImage *SavedImages; /* Image sequence (high-level API) */
int ExtensionBlockCount; /* Count extensions past last image */
ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
int Error; /* Last error condition reported */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
#define GIF_ASPECT_RATIO(n) ((n)+15.0/64.0)
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
/* func type to write gif data to arbitrary targets.
* Returns count of bytes written. (MRB)
*/
typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
/******************************************************************************
GIF89 structures
******************************************************************************/
typedef struct GraphicsControlBlock {
int DisposalMode;
#define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
#define DISPOSE_DO_NOT 1 /* Leave image in place */
#define DISPOSE_BACKGROUND 2 /* Set area too background color */
#define DISPOSE_PREVIOUS 3 /* Restore to previous content */
bool UserInputFlag; /* User confirmation required before disposal */
int DelayTime; /* pre-display delay in 0.01sec units */
int TransparentColor; /* Palette index for transparency, -1 if none */
#define NO_TRANSPARENT_COLOR -1
} GraphicsControlBlock;
/******************************************************************************
GIF encoding routines
******************************************************************************/
/* Main entry points */
GifFileType *EGifOpenFileName(const char *GifFileName,
const bool GifTestExistence, int *Error);
GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
int EGifSpew(GifFileType * GifFile);
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_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
/* These are legacy. You probably do not want to call them directly */
int EGifPutScreenDesc(GifFileType *GifFile,
const int GifWidth, const int GifHeight,
const int GifColorRes,
const int GifBackGround,
const ColorMapObject *GifColorMap);
int EGifPutImageDesc(GifFileType *GifFile,
const int GifLeft, const int GifTop,
const int GifWidth, const int GifHeight,
const bool GifInterlace,
const ColorMapObject *GifColorMap);
void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, const char *GifComment);
int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
int EGifPutExtensionBlock(GifFileType *GifFile,
const int GifExtLen, const void *GifExtension);
int EGifPutExtensionTrailer(GifFileType *GifFile);
int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
const int GifExtLen,
const void *GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
const GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile,
const GifByteType *GifCodeBlock);
/******************************************************************************
GIF decoding routines
******************************************************************************/
/* Main entry points */
GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error); /* new one (TVT) */
int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
#define D_GIF_SUCCEEDED 0
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/* These are legacy. You probably do not want to call them directly */
int DGifGetScreenDesc(GifFileType *GifFile);
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
int DGifGetImageHeader(GifFileType *GifFile);
int DGifGetImageDesc(GifFileType *GifFile);
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
GifByteType **GifExtension);
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
GifByteType **GifCodeBlock);
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
const char *DGifGetGifVersion(GifFileType *GifFile);
/******************************************************************************
Error handling and reporting.
******************************************************************************/
extern const char *GifErrorString(int ErrorCode); /* new in 2012 - ESR */
/*****************************************************************************
Everything below this point is new after version 1.2, supporting `slurp
mode' for doing I/O in two big belts with all the image-bashing in core.
******************************************************************************/
/******************************************************************************
Color map handling from gif_alloc.c
******************************************************************************/
extern ColorMapObject *GifMakeMapObject(int ColorCount,
const GifColorType *ColorMap);
extern void GifFreeMapObject(ColorMapObject *Object);
extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
const ColorMapObject *ColorIn2,
GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);
/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks,
int Function,
unsigned int Len, unsigned char ExtData[]);
extern void GifFreeExtensions(int *ExtensionBlock_Count,
ExtensionBlock **ExtensionBlocks);
extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
const SavedImage *CopyFrom);
extern void GifFreeSavedImages(GifFileType *GifFile);
/******************************************************************************
5.x functions for GIF89 graphics control blocks
******************************************************************************/
int DGifExtensionToGCB(const size_t GifExtensionLength,
const GifByteType *GifExtension,
GraphicsControlBlock *GCB);
size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
GifByteType *GifExtension);
int DGifSavedExtensionToGCB(GifFileType *GifFile,
int ImageIndex,
GraphicsControlBlock *GCB);
int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
GifFileType *GifFile,
int ImageIndex);
/******************************************************************************
The library's internal utility font
******************************************************************************/
#define GIF_FONT_WIDTH 8
#define GIF_FONT_HEIGHT 8
extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
extern void GifDrawText8x8(SavedImage *Image,
const int x, const int y,
const char *legend, const int color);
extern void GifDrawBox(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawRectangle(SavedImage *Image,
const int x, const int y,
const int w, const int d, const int color);
extern void GifDrawBoxedText8x8(SavedImage *Image,
const int x, const int y,
const char *legend,
const int border, const int bg, const int fg);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _GIF_LIB_H */
/* end */

Binary file not shown.