From e26d1ee8f3042feb52c470cfa2363e78eefbaea6456e14098ed7f9cad14fcc61 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 25 Jan 2023 23:23:02 +0000 Subject: [PATCH] Accepting request 1061067 from home:iznogood:branches:devel:libraries:c_c++ - 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. OBS-URL: https://build.opensuse.org/request/show/1061067 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/zxing-cpp?expand=0&rev=27 --- 0001-test-update-to-libfmt-v9.0.0.patch | 44 - 269.patch | 1647 ----------------------- baselibs.conf | 2 +- cmake-check-system-first.patch | 20 - zxing-cpp-1.2.0.tar.gz | 3 - zxing-cpp-2.0.0.tar.gz | 3 + zxing-cpp.changes | 65 + zxing-cpp.spec | 23 +- 8 files changed, 77 insertions(+), 1730 deletions(-) delete mode 100644 0001-test-update-to-libfmt-v9.0.0.patch delete mode 100644 269.patch delete mode 100644 cmake-check-system-first.patch delete mode 100644 zxing-cpp-1.2.0.tar.gz create mode 100644 zxing-cpp-2.0.0.tar.gz 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