diff --git a/0001-test-update-to-libfmt-v9.0.0.patch b/0001-test-update-to-libfmt-v9.0.0.patch deleted file mode 100644 index 065a435..0000000 --- a/0001-test-update-to-libfmt-v9.0.0.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 6dc756175003658cafb9039185a5094b9c157ba6 Mon Sep 17 00:00:00 2001 -From: axxel -Date: Tue, 26 Jul 2022 22:42:00 +0200 -Subject: [PATCH] test: update to libfmt v9.0.0 - ---- - test/blackbox/BlackboxTestRunner.cpp | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/test/blackbox/BlackboxTestRunner.cpp b/test/blackbox/BlackboxTestRunner.cpp -index 0df58ba..b8afe14 100644 ---- a/test/blackbox/BlackboxTestRunner.cpp -+++ b/test/blackbox/BlackboxTestRunner.cpp -@@ -158,8 +158,7 @@ static void doRunTests( - auto folderName = directory.stem(); - - if (Size(imgPaths) != totalTests) -- fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, -- imgPaths.size()); -+ fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName.string(), totalTests, imgPaths.size()); - - for (auto& test : tests) { - fmt::print("{:20} @ {:3}, {:3}", folderName.string(), test.rotation, Size(imgPaths)); -@@ -234,7 +233,7 @@ static void doRunStructuredAppendTest( - } - - if (Size(imageGroups) != totalTests) -- fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName, totalTests, -+ fmt::print("TEST {} => Expected number of tests: {}, got: {} => FAILED\n", folderName.string(), totalTests, - imageGroups.size()); - - for (auto& test : tests) { -@@ -445,7 +444,7 @@ int runBlackBoxTests(const fs::path& testPathPrefix, const std::set - { 17, 20, 0 }, - { 19, 20, 180 }, - }); -- -+ - runTests("upca-extension-1", "UPC-A", 6, { - { 3, 6, 0 }, - { 4, 6, 180 }, --- -2.37.3 - diff --git a/269.patch b/269.patch deleted file mode 100644 index 7acb1b6..0000000 --- a/269.patch +++ /dev/null @@ -1,1647 +0,0 @@ -From 1d031966e08aef92ef742ae3cf91e1addaf95a47 Mon Sep 17 00:00:00 2001 -From: "Benjamin A. Beasley" -Date: Wed, 8 Dec 2021 18:14:54 -0500 -Subject: [PATCH 1/4] Use a patch file to document changes from upstream - stb_image.h - ---- - thirdparty/stb/stb_image.patch | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - create mode 100644 thirdparty/stb/stb_image.patch - -diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch -new file mode 100644 -index 00000000..51537287 ---- /dev/null -+++ b/thirdparty/stb/stb_image.patch -@@ -0,0 +1,15 @@ -+diff -Naur upstream/stb_image.h zxing/stb_image.h -+--- upstream/stb_image.h 2021-12-08 18:11:28.170529096 -0500 -++++ zxing/stb_image.h 2021-12-08 18:06:42.706717697 -0500 -+@@ -1644,7 +1644,11 @@ -+ -+ static stbi_uc stbi__compute_y(int r, int g, int b) -+ { -++#if 0 // ori -+ return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); -++#else // zxing (see ReadBarcode.cpp:RGBToGray) -++ return (stbi_uc) ((306 * r + 601 * g + 117 * b + 0x200) >> 10); -++#endif -+ } -+ #endif -+ - -From 38f86eecd1e790329d56a4491ee0498d75d61c42 Mon Sep 17 00:00:00 2001 -From: "Benjamin A. Beasley" -Date: Wed, 8 Dec 2021 18:16:46 -0500 -Subject: [PATCH 2/4] Update stb_image_write from 1.14 to 1.16 - - 1.16 (2021-07-11) - make Deflate code emit uncompressed blocks when it would - otherwise expand support writing BMPs with alpha channel - 1.15 (2020-07-13) unknown ---- - thirdparty/stb/stb_image_write.h | 132 ++++++++++++++++++++++--------- - 1 file changed, 95 insertions(+), 37 deletions(-) - -diff --git a/thirdparty/stb/stb_image_write.h b/thirdparty/stb/stb_image_write.h -index cffd473c..e4b32ed1 100644 ---- a/thirdparty/stb/stb_image_write.h -+++ b/thirdparty/stb/stb_image_write.h -@@ -1,4 +1,4 @@ --/* stb_image_write - v1.14 - public domain - http://nothings.org/stb -+/* stb_image_write - v1.16 - public domain - http://nothings.org/stb - writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 - no warranty implied; use at your own risk - -@@ -140,6 +140,7 @@ - Ivan Tikhonov - github:ignotion - Adam Schackart -+ Andrew Kensler - - LICENSE - -@@ -166,9 +167,9 @@ LICENSE - #endif - - #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations --extern int stbi_write_tga_with_rle; --extern int stbi_write_png_compression_level; --extern int stbi_write_force_png_filter; -+STBIWDEF int stbi_write_tga_with_rle; -+STBIWDEF int stbi_write_png_compression_level; -+STBIWDEF int stbi_write_force_png_filter; - #endif - - #ifndef STBI_WRITE_NO_STDIO -@@ -178,7 +179,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const - STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); - STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); - --#ifdef STBI_WINDOWS_UTF8 -+#ifdef STBIW_WINDOWS_UTF8 - STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); - #endif - #endif -@@ -267,6 +268,8 @@ typedef struct - { - stbi_write_func *func; - void *context; -+ unsigned char buffer[64]; -+ int buf_used; - } stbi__write_context; - - // initialize a callback-based context -@@ -283,7 +286,7 @@ static void stbi__stdio_write(void *context, void *data, int size) - fwrite(data,1,size,(FILE*) context); - } - --#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) - #ifdef __cplusplus - #define STBIW_EXTERN extern "C" - #else -@@ -294,25 +297,25 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in - - STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) - { -- return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); -+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); - } - #endif - - static FILE *stbiw__fopen(char const *filename, char const *mode) - { - FILE *f; --#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) - wchar_t wMode[64]; - wchar_t wFilename[1024]; -- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) -+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) - return 0; - -- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) -+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) - return 0; - --#if _MSC_VER >= 1400 -- if (0 != _wfopen_s(&f, wFilename, wMode)) -- f = 0; -+#if defined(_MSC_VER) && _MSC_VER >= 1400 -+ if (0 != _wfopen_s(&f, wFilename, wMode)) -+ f = 0; - #else - f = _wfopen(wFilename, wMode); - #endif -@@ -380,16 +383,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) - va_end(v); - } - -+static void stbiw__write_flush(stbi__write_context *s) -+{ -+ if (s->buf_used) { -+ s->func(s->context, &s->buffer, s->buf_used); -+ s->buf_used = 0; -+ } -+} -+ - static void stbiw__putc(stbi__write_context *s, unsigned char c) - { - s->func(s->context, &c, 1); - } - -+static void stbiw__write1(stbi__write_context *s, unsigned char a) -+{ -+ if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) -+ stbiw__write_flush(s); -+ s->buffer[s->buf_used++] = a; -+} -+ - static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) - { -- unsigned char arr[3]; -- arr[0] = a; arr[1] = b; arr[2] = c; -- s->func(s->context, arr, 3); -+ int n; -+ if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) -+ stbiw__write_flush(s); -+ n = s->buf_used; -+ s->buf_used = n+3; -+ s->buffer[n+0] = a; -+ s->buffer[n+1] = b; -+ s->buffer[n+2] = c; - } - - static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) -@@ -398,7 +421,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in - int k; - - if (write_alpha < 0) -- s->func(s->context, &d[comp - 1], 1); -+ stbiw__write1(s, d[comp - 1]); - - switch (comp) { - case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case -@@ -406,7 +429,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in - if (expand_mono) - stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp - else -- s->func(s->context, d, 1); // monochrome TGA -+ stbiw__write1(s, d[0]); // monochrome TGA - break; - case 4: - if (!write_alpha) { -@@ -422,7 +445,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in - break; - } - if (write_alpha > 0) -- s->func(s->context, &d[comp - 1], 1); -+ stbiw__write1(s, d[comp - 1]); - } - - static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) -@@ -447,6 +470,7 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i - unsigned char *d = (unsigned char *) data + (j*x+i)*comp; - stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); - } -+ stbiw__write_flush(s); - s->func(s->context, &zero, scanline_pad); - } - } -@@ -467,16 +491,27 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, - - static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) - { -- int pad = (-x*3) & 3; -- return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, -- "11 4 22 4" "4 44 22 444444", -- 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header -- 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header -+ if (comp != 4) { -+ // write RGB bitmap -+ int pad = (-x*3) & 3; -+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, -+ "11 4 22 4" "4 44 22 444444", -+ 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header -+ 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header -+ } else { -+ // RGBA bitmaps need a v4 header -+ // use BI_BITFIELDS mode with 32bpp and alpha mask -+ // (straight BI_RGB with alpha mask doesn't work in most readers) -+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, -+ "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", -+ 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header -+ 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header -+ } - } - - STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - stbi__start_write_callbacks(&s, func, context); - return stbi_write_bmp_core(&s, x, y, comp, data); - } -@@ -484,7 +519,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, - #ifndef STBI_WRITE_NO_STDIO - STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - if (stbi__start_write_file(&s,filename)) { - int r = stbi_write_bmp_core(&s, x, y, comp, data); - stbi__end_write_file(&s); -@@ -557,24 +592,25 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v - - if (diff) { - unsigned char header = STBIW_UCHAR(len - 1); -- s->func(s->context, &header, 1); -+ stbiw__write1(s, header); - for (k = 0; k < len; ++k) { - stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); - } - } else { - unsigned char header = STBIW_UCHAR(len - 129); -- s->func(s->context, &header, 1); -+ stbiw__write1(s, header); - stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); - } - } - } -+ stbiw__write_flush(s); - } - return 1; - } - - STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - stbi__start_write_callbacks(&s, func, context); - return stbi_write_tga_core(&s, x, y, comp, (void *) data); - } -@@ -582,7 +618,7 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, - #ifndef STBI_WRITE_NO_STDIO - STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - if (stbi__start_write_file(&s,filename)) { - int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); - stbi__end_write_file(&s); -@@ -598,6 +634,8 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const - - #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) - -+#ifndef STBI_WRITE_NO_STDIO -+ - static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) - { - int exponent; -@@ -732,7 +770,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f - char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; - s->func(s->context, header, sizeof(header)-1); - --#ifdef __STDC_WANT_SECURE_LIB__ -+#ifdef __STDC_LIB_EXT1__ - len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); - #else - len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); -@@ -748,15 +786,14 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f - - STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - stbi__start_write_callbacks(&s, func, context); - return stbi_write_hdr_core(&s, x, y, comp, (float *) data); - } - --#ifndef STBI_WRITE_NO_STDIO - STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - if (stbi__start_write_file(&s,filename)) { - int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); - stbi__end_write_file(&s); -@@ -944,6 +981,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i - (void) stbiw__sbfree(hash_table[i]); - STBIW_FREE(hash_table); - -+ // store uncompressed instead if compression was worse -+ if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { -+ stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 -+ for (j = 0; j < data_len;) { -+ int blocklen = data_len - j; -+ if (blocklen > 32767) blocklen = 32767; -+ stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression -+ stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN -+ stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); -+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN -+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); -+ memcpy(out+stbiw__sbn(out), data+j, blocklen); -+ stbiw__sbn(out) += blocklen; -+ j += blocklen; -+ } -+ } -+ - { - // compute adler32 on input - unsigned int s1=1, s2=0; -@@ -1552,7 +1606,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in - - STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - stbi__start_write_callbacks(&s, func, context); - return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); - } -@@ -1561,7 +1615,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, - #ifndef STBI_WRITE_NO_STDIO - STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) - { -- stbi__write_context s; -+ stbi__write_context s = { 0 }; - if (stbi__start_write_file(&s,filename)) { - int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); - stbi__end_write_file(&s); -@@ -1574,6 +1628,10 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const - #endif // STB_IMAGE_WRITE_IMPLEMENTATION - - /* Revision history -+ 1.16 (2021-07-11) -+ make Deflate code emit uncompressed blocks when it would otherwise expand -+ support writing BMPs with alpha channel -+ 1.15 (2020-07-13) unknown - 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels - 1.13 - 1.12 -@@ -1611,7 +1669,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const - add HDR output - fix monochrome BMP - 0.95 (2014-08-17) -- add monochrome TGA output -+ add monochrome TGA output - 0.94 (2014-05-31) - rename private functions to avoid conflicts with stb_image.h - 0.93 (2014-05-27) - -From 40f3e3eb96adb4f1bfc612837653c8e81d8ad46d Mon Sep 17 00:00:00 2001 -From: "Benjamin A. Beasley" -Date: Wed, 8 Dec 2021 18:20:00 -0500 -Subject: [PATCH 3/4] Update stb_image from 2.25 to 2.27 - - 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes - 2.26 (2020-07-13) many minor fixes ---- - thirdparty/stb/stb_image.h | 475 +++++++++++++++++++++++++-------- - thirdparty/stb/stb_image.patch | 6 +- - 2 files changed, 361 insertions(+), 120 deletions(-) - -diff --git a/thirdparty/stb/stb_image.h b/thirdparty/stb/stb_image.h -index ee8f61c9..c58bc0c5 100644 ---- a/thirdparty/stb/stb_image.h -+++ b/thirdparty/stb/stb_image.h -@@ -1,4 +1,4 @@ --/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb -+/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb - no warranty implied; use at your own risk - - Do this: -@@ -48,6 +48,8 @@ LICENSE - - RECENT REVISION HISTORY: - -+ 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes -+ 2.26 (2020-07-13) many minor fixes - 2.25 (2020-02-02) fix warnings - 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically - 2.23 (2019-08-11) fix clang static analysis warning -@@ -88,27 +90,37 @@ RECENT REVISION HISTORY: - Jeremy Sawicki (handle all ImageNet JPGs) - Optimizations & bugfixes Mikhail Morozov (1-bit BMP) - Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) -- Arseny Kapoulkine -+ Arseny Kapoulkine Simon Breuss (16-bit PNM) - John-Mark Allen - Carmelo J Fdez-Aguera - - Bug & warning fixes -- Marc LeBlanc David Woo Guillaume George Martins Mozeiko -- Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan -- Dave Moore Roy Eltham Hayaki Saito Nathan Reed -- Won Chun Luke Graham Johan Duparc Nick Verigakis -- the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh -- Janez Zemva John Bartholomew Michal Cichon github:romigrou -- Jonathan Blow Ken Hamada Tero Hanninen github:svdijk -- Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar -- Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex -- Ryamond Barbiero Paul Du Bois Engin Manap github:grim210 -- Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw -- Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus -- Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo -- Christian Floisand Kevin Schmidt JR Smith github:darealshinji -- Brad Weinberger Matvey Cherevko github:Michaelangel007 -- Blazej Dariusz Roszkowski Alexander Veselov -+ Marc LeBlanc David Woo Guillaume George Martins Mozeiko -+ Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski -+ Phil Jordan Dave Moore Roy Eltham -+ Hayaki Saito Nathan Reed Won Chun -+ Luke Graham Johan Duparc Nick Verigakis the Horde3D community -+ Thomas Ruf Ronny Chevalier github:rlyeh -+ Janez Zemva John Bartholomew Michal Cichon github:romigrou -+ Jonathan Blow Ken Hamada Tero Hanninen github:svdijk -+ Eugene Golushkov Laurent Gomila Cort Stratton github:snagar -+ Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex -+ Cass Everitt Ryamond Barbiero github:grim210 -+ Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw -+ Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus -+ Josh Tobin Matthew Gregan github:poppolopoppo -+ Julian Raschke Gregory Mullen Christian Floisand github:darealshinji -+ Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 -+ Brad Weinberger Matvey Cherevko github:mosra -+ Luca Sas Alexander Veselov Zack Middleton [reserved] -+ Ryan C. Gordon [reserved] [reserved] -+ DO NOT ADD YOUR NAME HERE -+ -+ Jacko Dirks -+ -+ To add your name to the credits, pick a random blank space in the middle and fill it. -+ 80% of merge conflicts on stb PRs are due to people adding their name at the end -+ of the credits. - */ - - #ifndef STBI_INCLUDE_STB_IMAGE_H -@@ -167,6 +179,32 @@ RECENT REVISION HISTORY: - // - // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. - // -+// To query the width, height and component count of an image without having to -+// decode the full file, you can use the stbi_info family of functions: -+// -+// int x,y,n,ok; -+// ok = stbi_info(filename, &x, &y, &n); -+// // returns ok=1 and sets x, y, n if image is a supported format, -+// // 0 otherwise. -+// -+// Note that stb_image pervasively uses ints in its public API for sizes, -+// including sizes of memory buffers. This is now part of the API and thus -+// hard to change without causing breakage. As a result, the various image -+// loaders all have certain limits on image size; these differ somewhat -+// by format but generally boil down to either just under 2GB or just under -+// 1GB. When the decoded image would be larger than this, stb_image decoding -+// will fail. -+// -+// Additionally, stb_image will reject image files that have any of their -+// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, -+// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, -+// the only way to have an image with such dimensions load correctly -+// is for it to have a rather extreme aspect ratio. Either way, the -+// assumption here is that such larger images are likely to be malformed -+// or malicious. If you do need to load an image with individual dimensions -+// larger than that, and it still fits in the overall size limit, you can -+// #define STBI_MAX_DIMENSIONS on your own to be something larger. -+// - // =========================================================================== - // - // UNICODE: -@@ -272,11 +310,10 @@ RECENT REVISION HISTORY: - // - // iPhone PNG support: - // --// By default we convert iphone-formatted PNGs back to RGB, even though --// they are internally encoded differently. You can disable this conversion --// by calling stbi_convert_iphone_png_to_rgb(0), in which case --// you will always just get the native iphone "format" through (which --// is BGR stored in RGB). -+// We optionally support converting iPhone-formatted PNGs (which store -+// premultiplied BGRA) back to RGB, even though they're internally encoded -+// differently. To enable this conversion, call -+// stbi_convert_iphone_png_to_rgb(1). - // - // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per - // pixel to remove any premultiplied alpha *only* if the image file explicitly -@@ -318,7 +355,14 @@ RECENT REVISION HISTORY: - // - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still - // want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB - // -- -+// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater -+// than that size (in either width or height) without further processing. -+// This is to let programs in the wild set an upper bound to prevent -+// denial-of-service attacks on untrusted data, as one could generate a -+// valid image of gigantic dimensions and force stb_image to allocate a -+// huge block of memory and spend disproportionate time decoding it. By -+// default this is set to (1 << 24), which is 16777216, but that's still -+// very big. - - #ifndef STBI_NO_STDIO - #include -@@ -473,6 +517,8 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); - // as above, but only applies to images loaded on the thread that calls the function - // this function is only available if your compiler supports thread-local variables; - // calling it will fail to link if your compiler doesn't -+STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); -+STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); - STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); - - // ZLIB client - used by PNG, available for other purposes -@@ -574,13 +620,19 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch - #ifndef STBI_NO_THREAD_LOCALS - #if defined(__cplusplus) && __cplusplus >= 201103L - #define STBI_THREAD_LOCAL thread_local -- #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -- #define STBI_THREAD_LOCAL _Thread_local -- #elif defined(__GNUC__) -+ #elif defined(__GNUC__) && __GNUC__ < 5 - #define STBI_THREAD_LOCAL __thread - #elif defined(_MSC_VER) - #define STBI_THREAD_LOCAL __declspec(thread) --#endif -+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) -+ #define STBI_THREAD_LOCAL _Thread_local -+ #endif -+ -+ #ifndef STBI_THREAD_LOCAL -+ #if defined(__GNUC__) -+ #define STBI_THREAD_LOCAL __thread -+ #endif -+ #endif - #endif - - #ifdef _MSC_VER -@@ -612,7 +664,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; - #ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) - #else -- #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) -+ #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) - #endif - - #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) -@@ -726,14 +778,21 @@ static int stbi__sse2_available(void) - - #ifdef STBI_NEON - #include --// assume GCC or Clang on ARM targets -+#ifdef _MSC_VER -+#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name -+#else - #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) - #endif -+#endif - - #ifndef STBI_SIMD_ALIGN - #define STBI_SIMD_ALIGN(type, name) type name - #endif - -+#ifndef STBI_MAX_DIMENSIONS -+#define STBI_MAX_DIMENSIONS (1 << 24) -+#endif -+ - /////////////////////////////////////////////// - // - // stbi__context struct and start_xxx functions -@@ -751,6 +810,7 @@ typedef struct - int read_from_callbacks; - int buflen; - stbi_uc buffer_start[128]; -+ int callback_already_read; - - stbi_uc *img_buffer, *img_buffer_end; - stbi_uc *img_buffer_original, *img_buffer_original_end; -@@ -764,6 +824,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) - { - s->io.read = NULL; - s->read_from_callbacks = 0; -+ s->callback_already_read = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; - } -@@ -775,7 +836,8 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void * - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; -- s->img_buffer_original = s->buffer_start; -+ s->callback_already_read = 0; -+ s->img_buffer = s->img_buffer_original = s->buffer_start; - stbi__refill_buffer(s); - s->img_buffer_original_end = s->img_buffer_end; - } -@@ -789,12 +851,17 @@ static int stbi__stdio_read(void *user, char *data, int size) - - static void stbi__stdio_skip(void *user, int n) - { -+ int ch; - fseek((FILE*) user, n, SEEK_CUR); -+ ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ -+ if (ch != EOF) { -+ ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ -+ } - } - - static int stbi__stdio_eof(void *user) - { -- return feof((FILE*) user); -+ return feof((FILE*) user) || ferror((FILE *) user); - } - - static stbi_io_callbacks stbi__stdio_callbacks = -@@ -890,6 +957,7 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); - static int stbi__pnm_test(stbi__context *s); - static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); - static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); -+static int stbi__pnm_is16(stbi__context *s); - #endif - - static -@@ -964,7 +1032,7 @@ static int stbi__mad3sizes_valid(int a, int b, int c, int add) - } - - // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow --#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) - static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) - { - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && -@@ -987,7 +1055,7 @@ static void *stbi__malloc_mad3(int a, int b, int c, int add) - return stbi__malloc(a*b*c + add); - } - --#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) - static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) - { - if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; -@@ -1053,9 +1121,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re - ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order - ri->num_channels = 0; - -- #ifndef STBI_NO_JPEG -- if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); -- #endif -+ // test the formats with a very explicit header first (at least a FOURCC -+ // or distinctive magic number first) - #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); - #endif -@@ -1073,6 +1140,13 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re - #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); - #endif -+ -+ // then the formats that can end up attempting to load with just 1 or 2 -+ // bytes matching expectations; these are prone to false positives, so -+ // try them later -+ #ifndef STBI_NO_JPEG -+ if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); -+ #endif - #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); - #endif -@@ -1171,8 +1245,10 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, - if (result == NULL) - return NULL; - -+ // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. -+ STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); -+ - if (ri.bits_per_channel != 8) { -- STBI_ASSERT(ri.bits_per_channel == 16); - result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 8; - } -@@ -1195,8 +1271,10 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, - if (result == NULL) - return NULL; - -+ // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. -+ STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); -+ - if (ri.bits_per_channel != 16) { -- STBI_ASSERT(ri.bits_per_channel == 8); - result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 16; - } -@@ -1224,12 +1302,12 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in - - #ifndef STBI_NO_STDIO - --#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) - STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); - STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); - #endif - --#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) - STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) - { - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); -@@ -1239,16 +1317,16 @@ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wch - static FILE *stbi__fopen(char const *filename, char const *mode) - { - FILE *f; --#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) -+#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) - wchar_t wMode[64]; - wchar_t wFilename[1024]; -- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) -+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) - return 0; - -- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) -+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) - return 0; - --#if _MSC_VER >= 1400 -+#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (0 != _wfopen_s(&f, wFilename, wMode)) - f = 0; - #else -@@ -1499,6 +1577,7 @@ enum - static void stbi__refill_buffer(stbi__context *s) - { - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); -+ s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); - if (n == 0) { - // at end of file, treat same as if from memory, but need to handle case - // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file -@@ -1544,6 +1623,7 @@ stbi_inline static int stbi__at_eof(stbi__context *s) - #else - static void stbi__skip(stbi__context *s, int n) - { -+ if (n == 0) return; // already there! - if (n < 0) { - s->img_buffer = s->img_buffer_end; - return; -@@ -1622,7 +1702,8 @@ static int stbi__get16le(stbi__context *s) - static stbi__uint32 stbi__get32le(stbi__context *s) - { - stbi__uint32 z = stbi__get16le(s); -- return z + (stbi__get16le(s) << 16); -+ z += (stbi__uint32)stbi__get16le(s) << 16; -+ return z; - } - #endif - -@@ -1690,7 +1771,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r - STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; -- default: STBI_ASSERT(0); -+ default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); - } - #undef STBI__CASE - } -@@ -1747,7 +1828,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r - STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; -- default: STBI_ASSERT(0); -+ default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); - } - #undef STBI__CASE - } -@@ -2054,13 +2135,12 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n) - int sgn; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - -- sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB -+ sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) - k = stbi_lrot(j->code_buffer, n); -- STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; -- return k + (stbi__jbias[n] & ~sgn); -+ return k + (stbi__jbias[n] & (sgn - 1)); - } - - // get some unsigned bits -@@ -2110,7 +2190,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - t = stbi__jpeg_huff_decode(j, hdc); -- if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); -+ if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); -@@ -2167,11 +2247,12 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__ - // first scan for DC coefficient, must be first - memset(data,0,64*sizeof(data[0])); // 0 all the ac values now - t = stbi__jpeg_huff_decode(j, hdc); -+ if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - diff = t ? stbi__extend_receive(j, t) : 0; - - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; -- data[0] = (short) (dc << j->succ_low); -+ data[0] = (short) (dc * (1 << j->succ_low)); - } else { - // refinement scan for DC coefficient - if (stbi__jpeg_get_bit(j)) -@@ -2208,7 +2289,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__ - j->code_buffer <<= s; - j->code_bits -= s; - zig = stbi__jpeg_dezigzag[k++]; -- data[zig] = (short) ((r >> 8) << shift); -+ data[zig] = (short) ((r >> 8) * (1 << shift)); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); -@@ -2226,7 +2307,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__ - } else { - k += r; - zig = stbi__jpeg_dezigzag[k++]; -- data[zig] = (short) (stbi__extend_receive(j,s) << shift); -+ data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); - } - } - } while (k <= j->spec_end); -@@ -3157,6 +3238,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires -+ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); -+ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - c = stbi__get8(s); - if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); - s->img_n = c; -@@ -3188,6 +3271,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - -+ // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios -+ // and I've never seen a non-corrupted JPEG file actually use them -+ for (i=0; i < s->img_n; ++i) { -+ if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); -+ if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); -+ } -+ - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; -@@ -3743,6 +3833,10 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp - else - decode_n = z->s->img_n; - -+ // nothing to do if no components requested; check this now to avoid -+ // accessing uninitialized coutput[0] later -+ if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } -+ - // resample and color-convert - { - int k; -@@ -3885,6 +3979,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re - { - unsigned char* result; - stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); -+ if (!j) return stbi__errpuc("outofmem", "Out of memory"); - STBI_NOTUSED(ri); - j->s = s; - stbi__setup_jpeg(j); -@@ -3897,6 +3992,7 @@ static int stbi__jpeg_test(stbi__context *s) - { - int r; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); -+ if (!j) return stbi__err("outofmem", "Out of memory"); - j->s = s; - stbi__setup_jpeg(j); - r = stbi__decode_jpeg_header(j, STBI__SCAN_type); -@@ -3921,6 +4017,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) - { - int result; - stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); -+ if (!j) return stbi__err("outofmem", "Out of memory"); - j->s = s; - result = stbi__jpeg_info_raw(j, x, y, comp); - STBI_FREE(j); -@@ -3940,6 +4037,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) - // fast-way is faster to check than jpeg huffman, but slow way is slower - #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables - #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) -+#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet - - // zlib-style huffman encoding - // (jpegs packs from left, zlib from right, so can't share code) -@@ -3949,8 +4047,8 @@ typedef struct - stbi__uint16 firstcode[16]; - int maxcode[17]; - stbi__uint16 firstsymbol[16]; -- stbi_uc size[288]; -- stbi__uint16 value[288]; -+ stbi_uc size[STBI__ZNSYMS]; -+ stbi__uint16 value[STBI__ZNSYMS]; - } stbi__zhuffman; - - stbi_inline static int stbi__bitreverse16(int n) -@@ -4037,16 +4135,23 @@ typedef struct - stbi__zhuffman z_length, z_distance; - } stbi__zbuf; - -+stbi_inline static int stbi__zeof(stbi__zbuf *z) -+{ -+ return (z->zbuffer >= z->zbuffer_end); -+} -+ - stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) - { -- if (z->zbuffer >= z->zbuffer_end) return 0; -- return *z->zbuffer++; -+ return stbi__zeof(z) ? 0 : *z->zbuffer++; - } - - static void stbi__fill_bits(stbi__zbuf *z) - { - do { -- STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); -+ if (z->code_buffer >= (1U << z->num_bits)) { -+ z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ -+ return; -+ } - z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -@@ -4071,10 +4176,11 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) - for (s=STBI__ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; -- if (s == 16) return -1; // invalid code! -+ if (s >= 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; -- STBI_ASSERT(z->size[b] == s); -+ if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! -+ if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -@@ -4083,7 +4189,12 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) - stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) - { - int b,s; -- if (a->num_bits < 16) stbi__fill_bits(a); -+ if (a->num_bits < 16) { -+ if (stbi__zeof(a)) { -+ return -1; /* report error for unexpected end of data. */ -+ } -+ stbi__fill_bits(a); -+ } - b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { - s = b >> 9; -@@ -4097,13 +4208,16 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) - static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes - { - char *q; -- int cur, limit, old_limit; -+ unsigned int cur, limit, old_limit; - z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); -- cur = (int) (z->zout - z->zout_start); -- limit = old_limit = (int) (z->zout_end - z->zout_start); -- while (cur + n > limit) -+ cur = (unsigned int) (z->zout - z->zout_start); -+ limit = old_limit = (unsigned) (z->zout_end - z->zout_start); -+ if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); -+ while (cur + n > limit) { -+ if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); - limit *= 2; -+ } - q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); - STBI_NOTUSED(old_limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); -@@ -4201,11 +4315,12 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) - c = stbi__zreceive(a,2)+3; - if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); - fill = lencodes[n-1]; -- } else if (c == 17) -+ } else if (c == 17) { - c = stbi__zreceive(a,3)+3; -- else { -- STBI_ASSERT(c == 18); -+ } else if (c == 18) { - c = stbi__zreceive(a,7)+11; -+ } else { -+ return stbi__err("bad codelengths", "Corrupt PNG"); - } - if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); - memset(lencodes+n, fill, c); -@@ -4231,7 +4346,7 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a) - a->code_buffer >>= 8; - a->num_bits -= 8; - } -- STBI_ASSERT(a->num_bits == 0); -+ if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); - // now fill header the normal way - while (k < 4) - header[k++] = stbi__zget8(a); -@@ -4253,6 +4368,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a) - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); -+ if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png -@@ -4260,7 +4376,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a) - return 1; - } - --static const stbi_uc stbi__zdefault_length[288] = -+static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = - { - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -@@ -4306,7 +4422,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) - } else { - if (type == 1) { - // use fixed code lengths -- if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; -+ if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } else { - if (!stbi__compute_huffman_codes(a)) return 0; -@@ -4514,7 +4630,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r - return stbi__err("invalid filter","Corrupt PNG"); - - if (depth < 8) { -- STBI_ASSERT(img_width_bytes <= x); -+ if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG"); - cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; -@@ -4702,6 +4818,7 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3 - - // de-interlacing - final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); -+ if (!final) return stbi__err("outofmem", "Out of memory"); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; -@@ -4822,19 +4939,46 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int - return 1; - } - --static int stbi__unpremultiply_on_load = 0; --static int stbi__de_iphone_flag = 0; -+static int stbi__unpremultiply_on_load_global = 0; -+static int stbi__de_iphone_flag_global = 0; - - STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) - { -- stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; -+ stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; - } - - STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) - { -- stbi__de_iphone_flag = flag_true_if_should_convert; -+ stbi__de_iphone_flag_global = flag_true_if_should_convert; -+} -+ -+#ifndef STBI_THREAD_LOCAL -+#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global -+#define stbi__de_iphone_flag stbi__de_iphone_flag_global -+#else -+static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; -+static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; -+ -+STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) -+{ -+ stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; -+ stbi__unpremultiply_on_load_set = 1; - } - -+STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) -+{ -+ stbi__de_iphone_flag_local = flag_true_if_should_convert; -+ stbi__de_iphone_flag_set = 1; -+} -+ -+#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ -+ ? stbi__unpremultiply_on_load_local \ -+ : stbi__unpremultiply_on_load_global) -+#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ -+ ? stbi__de_iphone_flag_local \ -+ : stbi__de_iphone_flag_global) -+#endif // STBI_THREAD_LOCAL -+ - static void stbi__de_iphone(stbi__png *z) - { - stbi__context *s = z->s; -@@ -4909,8 +5053,10 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) - if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); -- s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); -- s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); -+ s->img_x = stbi__get32be(s); -+ s->img_y = stbi__get32be(s); -+ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); -+ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); - z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); -@@ -5059,10 +5205,12 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st - void *result=NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { -- if (p->depth < 8) -+ if (p->depth <= 8) - ri->bits_per_channel = 8; -+ else if (p->depth == 16) -+ ri->bits_per_channel = 16; - else -- ri->bits_per_channel = p->depth; -+ return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { -@@ -5211,6 +5359,32 @@ typedef struct - int extra_read; - } stbi__bmp_data; - -+static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) -+{ -+ // BI_BITFIELDS specifies masks explicitly, don't override -+ if (compress == 3) -+ return 1; -+ -+ if (compress == 0) { -+ if (info->bpp == 16) { -+ info->mr = 31u << 10; -+ info->mg = 31u << 5; -+ info->mb = 31u << 0; -+ } else if (info->bpp == 32) { -+ info->mr = 0xffu << 16; -+ info->mg = 0xffu << 8; -+ info->mb = 0xffu << 0; -+ info->ma = 0xffu << 24; -+ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 -+ } else { -+ // otherwise, use defaults, which is all-0 -+ info->mr = info->mg = info->mb = info->ma = 0; -+ } -+ return 1; -+ } -+ return 0; // error -+} -+ - static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - { - int hsz; -@@ -5223,6 +5397,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - info->mr = info->mg = info->mb = info->ma = 0; - info->extra_read = 14; - -+ if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); -+ - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = stbi__get16le(s); -@@ -5236,6 +5412,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - if (hsz != 12) { - int compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); -+ if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes -+ if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres -@@ -5250,17 +5428,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - } - if (info->bpp == 16 || info->bpp == 32) { - if (compress == 0) { -- if (info->bpp == 32) { -- info->mr = 0xffu << 16; -- info->mg = 0xffu << 8; -- info->mb = 0xffu << 0; -- info->ma = 0xffu << 24; -- info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 -- } else { -- info->mr = 31u << 10; -- info->mg = 31u << 5; -- info->mb = 31u << 0; -- } -+ stbi__bmp_set_mask_defaults(info, compress); - } else if (compress == 3) { - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); -@@ -5275,6 +5443,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else { -+ // V4/V5 header - int i; - if (hsz != 108 && hsz != 124) - return stbi__errpuc("bad BMP", "bad BMP"); -@@ -5282,6 +5451,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->ma = stbi__get32le(s); -+ if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs -+ stbi__bmp_set_mask_defaults(info, compress); - stbi__get32le(s); // discard color space - for (i=0; i < 12; ++i) - stbi__get32le(s); // discard color space parameters -@@ -5314,6 +5485,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - -+ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ - mr = info.mr; - mg = info.mg; - mb = info.mb; -@@ -5328,7 +5502,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req - psize = (info.offset - info.extra_read - info.hsz) >> 2; - } - if (psize == 0) { -- STBI_ASSERT(info.offset == (s->img_buffer - s->buffer_start)); -+ if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) { -+ return stbi__errpuc("bad offset", "Corrupt BMP"); -+ } - } - - if (info.bpp == 24 && ma == 0xff000000) -@@ -5423,6 +5599,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req - gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); -+ if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { -@@ -5647,6 +5824,9 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req - STBI_NOTUSED(tga_x_origin); // @TODO - STBI_NOTUSED(tga_y_origin); // @TODO - -+ if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ - // do a tiny bit of precessing - if ( tga_image_type >= 8 ) - { -@@ -5686,6 +5866,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req - // do I need to load a palette? - if ( tga_indexed) - { -+ if (tga_palette_len == 0) { /* you have to have at least one entry! */ -+ STBI_FREE(tga_data); -+ return stbi__errpuc("bad palette", "Corrupt TGA"); -+ } -+ - // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start ); - // load the palette -@@ -5894,6 +6079,9 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req - h = stbi__get32be(s); - w = stbi__get32be(s); - -+ if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ - // Make sure the depth is 8 bits. - bitdepth = stbi__get16be(s); - if (bitdepth != 8 && bitdepth != 16) -@@ -6248,6 +6436,10 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c - - x = stbi__get16be(s); - y = stbi__get16be(s); -+ -+ if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); - -@@ -6257,6 +6449,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c - - // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); -+ if (!result) return stbi__errpuc("outofmem", "Out of memory"); - memset(result, 0xff, x*y*4); - - if (!stbi__pic_load_core(s,x,y,comp, result)) { -@@ -6356,6 +6549,9 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in - g->ratio = stbi__get8(s); - g->transparent = -1; - -+ if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); -+ if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); -+ - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - - if (is_info) return 1; -@@ -6369,6 +6565,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in - static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) - { - stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); -+ if (!g) return stbi__err("outofmem", "Out of memory"); - if (!stbi__gif_header(s, g, comp, 1)) { - STBI_FREE(g); - stbi__rewind( s ); -@@ -6533,7 +6730,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i - memset(g->history, 0x00, pcount); // pixels that were affected previous frame - first_frame = 1; - } else { -- // second frame - how do we dispoase of the previous one? -+ // second frame - how do we dispose of the previous one? - dispose = (g->eflags & 0x1C) >> 2; - pcount = g->w * g->h; - -@@ -6678,6 +6875,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i - } - } - -+static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) -+{ -+ STBI_FREE(g->out); -+ STBI_FREE(g->history); -+ STBI_FREE(g->background); -+ -+ if (out) STBI_FREE(out); -+ if (delays && *delays) STBI_FREE(*delays); -+ return stbi__errpuc("outofmem", "Out of memory"); -+} -+ - static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) - { - if (stbi__gif_test(s)) { -@@ -6687,6 +6895,12 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, - stbi_uc *two_back = 0; - stbi__gif g; - int stride; -+ int out_size = 0; -+ int delays_size = 0; -+ -+ STBI_NOTUSED(out_size); -+ STBI_NOTUSED(delays_size); -+ - memset(&g, 0, sizeof(g)); - if (delays) { - *delays = 0; -@@ -6703,22 +6917,31 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, - stride = g.w * g.h * 4; - - if (out) { -- void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride ); -- if (NULL == tmp) { -- STBI_FREE(g.out); -- STBI_FREE(g.history); -- STBI_FREE(g.background); -- return stbi__errpuc("outofmem", "Out of memory"); -+ void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); -+ if (!tmp) -+ return stbi__load_gif_main_outofmem(&g, out, delays); -+ else { -+ out = (stbi_uc*) tmp; -+ out_size = layers * stride; - } -- else -- out = (stbi_uc*) tmp; -+ - if (delays) { -- *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); -+ int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); -+ if (!new_delays) -+ return stbi__load_gif_main_outofmem(&g, out, delays); -+ *delays = new_delays; -+ delays_size = layers * sizeof(int); - } - } else { - out = (stbi_uc*)stbi__malloc( layers * stride ); -+ if (!out) -+ return stbi__load_gif_main_outofmem(&g, out, delays); -+ out_size = layers * stride; - if (delays) { - *delays = (int*) stbi__malloc( layers * sizeof(int) ); -+ if (!*delays) -+ return stbi__load_gif_main_outofmem(&g, out, delays); -+ delays_size = layers * sizeof(int); - } - } - memcpy( out + ((layers - 1) * stride), u, stride ); -@@ -6897,6 +7120,9 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re - token += 3; - width = (int) strtol(token, NULL, 10); - -+ if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); -+ if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); -+ - *x = width; - *y = height; - -@@ -7039,9 +7265,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) - - info.all_a = 255; - p = stbi__bmp_parse_header(s, &info); -- stbi__rewind( s ); -- if (p == NULL) -+ if (p == NULL) { -+ stbi__rewind( s ); - return 0; -+ } - if (x) *x = s->img_x; - if (y) *y = s->img_y; - if (comp) { -@@ -7107,8 +7334,8 @@ static int stbi__psd_is16(stbi__context *s) - stbi__rewind( s ); - return 0; - } -- (void) stbi__get32be(s); -- (void) stbi__get32be(s); -+ STBI_NOTUSED(stbi__get32be(s)); -+ STBI_NOTUSED(stbi__get32be(s)); - depth = stbi__get16be(s); - if (depth != 16) { - stbi__rewind( s ); -@@ -7187,7 +7414,6 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) - // Known limitations: - // Does not support comments in the header section - // Does not support ASCII image data (formats P2 and P3) --// Does not support 16-bit-per-channel - - #ifndef STBI_NO_PNM - -@@ -7208,19 +7434,23 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req - stbi_uc *out; - STBI_NOTUSED(ri); - -- if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) -+ ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); -+ if (ri->bits_per_channel == 0) - return 0; - -+ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); -+ - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - -- if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) -+ if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) - return stbi__errpuc("too large", "PNM too large"); - -- out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); -+ out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); -- stbi__getn(s, out, s->img_n * s->img_x * s->img_y); -+ stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8)); - - if (req_comp && req_comp != s->img_n) { - out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); -@@ -7296,11 +7526,19 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) - stbi__pnm_skip_whitespace(s, &c); - - maxv = stbi__pnm_getinteger(s, &c); // read max value -- -- if (maxv > 255) -- return stbi__err("max value > 255", "PPM image not 8-bit"); -+ if (maxv > 65535) -+ return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); -+ else if (maxv > 255) -+ return 16; - else -- return 1; -+ return 8; -+} -+ -+static int stbi__pnm_is16(stbi__context *s) -+{ -+ if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) -+ return 1; -+ return 0; - } - #endif - -@@ -7356,6 +7594,9 @@ static int stbi__is_16_main(stbi__context *s) - if (stbi__psd_is16(s)) return 1; - #endif - -+ #ifndef STBI_NO_PNM -+ if (stbi__pnm_is16(s)) return 1; -+ #endif - return 0; - } - -diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch -index 51537287..f1fee52a 100644 ---- a/thirdparty/stb/stb_image.patch -+++ b/thirdparty/stb/stb_image.patch -@@ -1,7 +1,7 @@ - diff -Naur upstream/stb_image.h zxing/stb_image.h ----- upstream/stb_image.h 2021-12-08 18:11:28.170529096 -0500 --+++ zxing/stb_image.h 2021-12-08 18:06:42.706717697 -0500 --@@ -1644,7 +1644,11 @@ -+--- upstream/stb_image.h 2021-12-08 18:18:07.485461782 -0500 -++++ zxing/stb_image.h 2021-12-08 18:18:29.596689004 -0500 -+@@ -1725,7 +1725,11 @@ - - static stbi_uc stbi__compute_y(int r, int g, int b) - { - -From 5ca63122c53fa0703cad9a8257f123a1ca4c43b1 Mon Sep 17 00:00:00 2001 -From: "Benjamin A. Beasley" -Date: Wed, 8 Dec 2021 18:24:31 -0500 -Subject: [PATCH 4/4] Apply stb PR#1223 to stb_image - -Fixes a crash and an infinite loop in stb_image that could occur with -specially constructed PGM and HDR files - -https://github.com/nothings/stb/pull/1223 - -This is a candidate fix for: - - https://nvd.nist.gov/vuln/detail/CVE-2021-42715 - - In stb_image's HDR reader, loading a specially constructed invalid HDR - file can result in an infinite loop within the RLE decoder - https://github.com/nothings/stb/issues/1224 - -Additionally, this is a candidate fix for: - - https://nvd.nist.gov/vuln/detail/CVE-2021-42716 - - stbi__pnm_load heap-buffer-overflow bug - https://github.com/nothings/stb/issues/1166 - - In stb_image's PNM reader, loading a specially constructed valid - 16-bit PGM file with 4 channels can cause a crash due to an - out-of-bounds read - https://github.com/nothings/stb/issues/1225 ---- - thirdparty/stb/stb_image.h | 17 ++++++++++++----- - thirdparty/stb/stb_image.patch | 4 ++-- - 2 files changed, 14 insertions(+), 7 deletions(-) - -diff --git a/thirdparty/stb/stb_image.h b/thirdparty/stb/stb_image.h -index c58bc0c5..612bc4c1 100644 ---- a/thirdparty/stb/stb_image.h -+++ b/thirdparty/stb/stb_image.h -@@ -108,7 +108,7 @@ RECENT REVISION HISTORY: - Cass Everitt Ryamond Barbiero github:grim210 - Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw - Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus -- Josh Tobin Matthew Gregan github:poppolopoppo -+ Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo - Julian Raschke Gregory Mullen Christian Floisand github:darealshinji - Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 - Brad Weinberger Matvey Cherevko github:mosra -@@ -7191,12 +7191,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re - // Run - value = stbi__get8(s); - count -= 128; -- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } -+ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump -- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } -+ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = stbi__get8(s); - } -@@ -7450,10 +7450,17 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req - - out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); -- stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8)); -+ if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { -+ STBI_FREE(out); -+ return stbi__errpuc("bad PNM", "PNM file truncated"); -+ } - - if (req_comp && req_comp != s->img_n) { -- out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); -+ if (ri->bits_per_channel == 16) { -+ out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); -+ } else { -+ out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); -+ } - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - return out; -diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch -index f1fee52a..1768ba86 100644 ---- a/thirdparty/stb/stb_image.patch -+++ b/thirdparty/stb/stb_image.patch -@@ -1,6 +1,6 @@ - diff -Naur upstream/stb_image.h zxing/stb_image.h ----- upstream/stb_image.h 2021-12-08 18:18:07.485461782 -0500 --+++ zxing/stb_image.h 2021-12-08 18:18:29.596689004 -0500 -+--- upstream/stb_image.h 2021-12-08 18:22:56.724466161 -0500 -++++ zxing/stb_image.h 2021-12-08 18:23:15.084657043 -0500 - @@ -1725,7 +1725,11 @@ - - static stbi_uc stbi__compute_y(int r, int g, int b) diff --git a/baselibs.conf b/baselibs.conf index 5db5966..3d8b8cd 100644 --- a/baselibs.conf +++ b/baselibs.conf @@ -1 +1 @@ -libZXing1 +libZXing3 diff --git a/cmake-check-system-first.patch b/cmake-check-system-first.patch deleted file mode 100644 index 16cefc3..0000000 --- a/cmake-check-system-first.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -Nur zxing-cpp-1.2.0/test/blackbox/CMakeLists.txt new/test/blackbox/CMakeLists.txt ---- zxing-cpp-1.2.0/test/blackbox/CMakeLists.txt 2021-05-28 12:47:09.000000000 +0200 -+++ new/test/blackbox/CMakeLists.txt 2021-05-29 13:34:47.707152999 +0200 -@@ -1,10 +1,13 @@ - cmake_minimum_required(VERSION 3.14) - --include(FetchContent) --FetchContent_Declare (fmtlib -+find_package(fmt 7.1.2) -+if (NOT fmt_FOUND) -+ include(FetchContent) -+ FetchContent_Declare (fmtlib - GIT_REPOSITORY https://github.com/fmtlib/fmt.git - GIT_TAG 7.1.2) --FetchContent_MakeAvailable (fmtlib) # Adds fmt::fmt -+ FetchContent_MakeAvailable (fmtlib) # Adds fmt::fmt -+endif() - - if (BUILD_READERS) - add_executable (ReaderTest diff --git a/zxing-cpp-1.2.0.tar.gz b/zxing-cpp-1.2.0.tar.gz deleted file mode 100644 index 360b5f3..0000000 --- a/zxing-cpp-1.2.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:653d9e44195d86cf64a36af9ff3a1978ec5599df3882439fefa56e7064f55e8a -size 97942494 diff --git a/zxing-cpp-2.0.0.tar.gz b/zxing-cpp-2.0.0.tar.gz new file mode 100644 index 0000000..a0ddb7b --- /dev/null +++ b/zxing-cpp-2.0.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12b76b7005c30d34265fc20356d340da179b0b4d43d2c1b35bcca86776069f76 +size 856413 diff --git a/zxing-cpp.changes b/zxing-cpp.changes index 4a705c6..c69b21f 100644 --- a/zxing-cpp.changes +++ b/zxing-cpp.changes @@ -1,3 +1,68 @@ +------------------------------------------------------------------- +Wed Jan 25 14:01:00 UTC 2023 - Bjørn Lie + +- Update to version 2.0.0: + * Switch to UTF8 based API and remove deprecated UTF16 one + (Result::text()) + * Remove all API deprecated in 1.4 + * Adding a wrapper for iOS + * New Aztec detector implementation to support arbitrary rotation + and position of the symbol + * Support multi-symbol detection in Aztec detector + * Replace all Qt originated ECI/CharacterSet conversion code with + a new implementation + * Require c++17 to build library and client code + * New DecodeHints::textMode() and Result::text(TextMode) API to + specify how bytes are rendered into text + * HRI (human readable interpretation) is the new default for the + TextMode (has been for most cases before, but not all) + * New DecodeHits::tryInvert() feature to test for inverted + symbols (white on black background) +- Changes from version 1.4.0: + * Note: this is an intermediary release on the way to 2.0. This + code is (supposed to be) API compatible (via the ReadBarcode.h + interface) with v1.3.0 but contains quite a few additional + deprecations. It still has SO number 1, which is as wrong as it + was for release v1.3.0 and it is not ABI compatible with 1.3 + either. 2.0 will be basically 1.4 but with all deprecated API + removed and the final fix for #333. + * Reader support for Micro QRCode by @corbers + * Prepared switch from std::wstring based utf16 to std::string + based utf8 results, use new ZX_USE_UTF8 macro to transition to + the upcoming 2.0 API + * Much improved 'binary' data support via new Result::bytes() + API, see #334 for a detailed background discussion. + * New Result::contentType() API returning information about the + type of content (like text vs. binary, etc.) + * Better standards conformance with respect to ECI handling, see + Results::bytesECI() + * Support for proper ECI handling across structured append + symbols (see MergeStructuredAppendResults()) + * New Result::error() API with improved error handling, see also + DecodeHints::returnErrors() + * Removed all internal header files from the installed set, so + only the ReadBarcode.h based APIs are supported from here on + out + * Removed all sample images from the 'source' distribution + zip/tar balls (much reduced size) + * Python read_barcode returns None if no symbol was found (might + break existing code if not checked for None before) +- Changes from version 1.3.0: + * Multi-barcode reading with the new std::vector + ReadBardcodes(...) function. Does not work for Aztec, + DataMatrix and Maxicode, yet. + * Multi-resolution scanning that can automatically downscale the + input to substantially increase the detection rate on high + resolution scans, see DecodeHints::tryDownscale, currently only + enabled in the ReadBardcodes function + * New Result::symbologyIdentifier property + * Updated and improved android wrapper +- Drop patches fixed upstream: + * 269.patch + * 0001-test-update-to-libfmt-v9.0.0.patch + * cmake-check-system-first.patch +- Bump sover to 3 following upstream changes. + ------------------------------------------------------------------- Tue Sep 20 07:10:22 UTC 2022 - Christophe Giboudeaux diff --git a/zxing-cpp.spec b/zxing-cpp.spec index 918a5dd..925d817 100644 --- a/zxing-cpp.spec +++ b/zxing-cpp.spec @@ -1,7 +1,7 @@ # # spec file for package zxing-cpp # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,9 +16,9 @@ # -%define sover 1 +%define sover 3 Name: zxing-cpp -Version: 1.2.0 +Version: 2.0.0 Release: 0 Summary: Library for processing 1D and 2D barcodes License: Apache-2.0 AND Zlib AND LGPL-2.1-with-Qt-Company-Qt-exception-1.1 @@ -26,12 +26,7 @@ Group: Development/Languages/C and C++ URL: https://github.com/nu-book/zxing-cpp/ Source0: %{url}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source99: baselibs.conf -# PATCH-FIX-OPENSUSE cmake-check-system-first.patch -- Search system for needed libraries first -Patch0: cmake-check-system-first.patch -# PATCH-FIX-UPSTREAM 269.patch -- Update stb_image/stb_image_write -Patch1: 269.patch -# PATCH-FIX-UPSTREAM 0001-test-update-to-libfmt-v9.0.0.patch -- fmt 9 compatibility -Patch2: 0001-test-update-to-libfmt-v9.0.0.patch + BuildRequires: pkgconfig # Use cmake3 package on SLE12 because cmake is too old (version 3.5) %if !0%{?is_opensuse} && 0%{?sle_version} < 150000 @@ -99,17 +94,15 @@ export LD_LIBRARY_PATH=%{buildroot}%{_libdir} %endif %ctest -%post -n libZXing%{sover} -p /sbin/ldconfig -%postun -n libZXing%{sover} -p /sbin/ldconfig +%ldconfig_scriptlets -n libZXing%{sover} %files -n libZXing%{sover} %doc README.md -%license LICENSE.* -%{_libdir}/libZXing.so.%{sover} -%{_libdir}/libZXing.so.%{sover}.* +%license LICENSE +%{_libdir}/libZXing.so.* %files devel -%license LICENSE.* +%license LICENSE %{_includedir}/ZXing/ %{_libdir}/cmake/ZXing/ %{_libdir}/libZXing.so