Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1761481269, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"40c6c95a7165af87c18eea616abb9124", "commit": {"type":"commit", "time": 1647435588, "time_ofs": 0, "oid_tree": { "oid": "5843b9a44f1ab7fecdb5fbe85f527cf1ea745992", "alias": []}, "oid":{ "oid": "48907fca0a25c39ce35692c527cb8aa82ee60d85", "alias": []}, "msg": "upng: rewrite for stateful stream decode", "sig_commit": { "git_time": { "time": 1647435588, "offset": 0 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }, "sig_author": { "git_time": { "time": 1640616086, "offset": 0 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }}, "body": "upng: rewrite for stateful stream decode\n\nAdd a rewritten version of upng that decodes statefully line by line, and so\ndoes not require a bitmap buffer for the output. This compares to original\nupng approach that needs heap allocations for the input, the whole output\nand intermediate allocations.\n\nInstead of buffers for input, decompression and output, it only allocates\n2 x lines of RGBA pixels (ie, a few KB), and 32KB of decompressed data for\nbackward references in the decoder, and decodes as needed into the 2-line\nbuffer to produce line rasterized results. For a 600px width PNG, this is\njust 40KB heap for the duration.\n\n" , "diff": "diff --git a/CMakeLists.txt b/CMakeLists.txt\nindex 53eb5b4..1742cd1 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -159,6 +159,7 @@ option(LWS_WITH_SYS_STATE \u0022lws_system state support\u0022 ON)\n option(LWS_WITH_SYS_SMD \u0022Lws System Message Distribution\u0022 ON)\n option(LWS_WITH_SYS_FAULT_INJECTION \u0022Enable fault injection support\u0022 OFF)\n option(LWS_WITH_SYS_METRICS \u0022Lws Metrics API\u0022 OFF)\n+option(LWS_WITH_UPNG \u0022Enable stateful PNG stream decoder\u0022 ON)\n \n #\n # Secure Streams\ndiff --git a/LICENSE b/LICENSE\nindex 917f8dc..767d2d3 100644\n--- a/LICENSE\n+++ b/LICENSE\n@@ -7,7 +7,8 @@ them.\n Original liberal license retained:\n \n - lib/misc/sha-1.c - 3-clause BSD license retained, link to original [BSD3]\n- - win32port/zlib - ZLIB license (see zlib.h) [ZLIB]\n+ - win32port/zlib\n+ lib/drivers/display/upng.*\t\t - ZLIB license (see zlib.h) [ZLIB]\n - lib/tls/mbedtls/wrapper - Apache 2.0 (only built if linked against mbedtls) [APACHE2]\n lib/tls/mbedtls/mbedtls-extensions.c\n - lib/misc/base64-decode.c - already MIT\ndiff --git a/READMEs/README.png-decoder.md b/READMEs/README.png-decoder.md\nnew file mode 100644\nindex 0000000..d01b5bd\n--- /dev/null\n+++ b/READMEs/README.png-decoder.md\n@@ -0,0 +1,56 @@\n+# lws_upng stateful PNG decoder\n+\n+Lws includes a rewrite of UPNG that performs stateful, line-at-a-time decoding.\n+\n+The memory requirement is fixed at 40KB plus enough buffer for two output\n+lines of pixels. In particular the input PNG data is stream parsed, so there\n+is no requirement for it all to be in memory at the same time, and there is\n+no framebuffer required either, so there is no requirement for all the output\n+to be in memory at the same time, either.\n+\n+The results in an extremely tight decoder suitable for microcontroller type\n+platforms that lack enough memory to hold a framebuffer, but can stream the\n+rendered data out over SPI or i2c to a display device that does have its own\n+(usually write-only) framebuffer memory.\n+\n+## Creating and destroying the decoding context\n+\n+The apis to create and destroy a decoding context are very simple...\n+\n+```\n+LWS_VISIBLE LWS_EXTERN lws_upng_t *\n+lws_upng_new(void);\n+\n+LWS_VISIBLE LWS_EXTERN void\n+lws_upng_free(lws_upng_t **upng);\n+```\n+\n+## Performing the decoding\n+\n+The only decoding API provides input PNG data which may or may not be partly or\n+wholly consumed, to produce a line of output pixels that can be found at `*ppix`.\n+\n+```\n+LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t\n+lws_upng_emit_next_line(lws_upng_t *upng, const uint8_t **ppix,\n+\t\t\tconst uint8_t **buf, size_t *size);\n+```\n+\n+If input data is consumed, `*buf` and `*size` are adjusted accordingly.\n+This api returns a bitfield consisting of:\n+\n+|Return value bit|Meaning|\n+|---|---|\n+|`LWS_SRET_OK` (0, no bits set)|Completed|\n+|`LWS_SRET_WANT_INPUT`|Decoder needs to be called again with more PNG input before it can produce a line of pixels|\n+|`LWS_SRET_WANT_OUTPUT`|Decoder has paused to emit a line of pixels, and can resume|\n+|`LWS_SRET_FATAL`|Decoder has encountered a fatal error, any return greater than `LWS_SRET_FATAL` indicates the type of error|\n+|`LWS_SRET_NO_FURTHER_IN`|Indicate no further new input will be used|\n+|`LWS_SRET_NO_FURTHER_OUT`|Indicate no further output is forthcoming|\n+\n+To get early information about the dimensions and colourspace of the PNG, you\n+can call this api initially with the first 33 bytes (`*size` restricted to 33)\n+and adjust the true size -33 for further calls. This will make it return with\n+`WANT_INPUT` after having processed the PNG header information but not produced\n+any pixel line information.\n+\ndiff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in\nindex e87b187..50ee8d7 100644\n--- a/cmake/lws_config.h.in\n+++ b/cmake/lws_config.h.in\n@@ -241,6 +241,7 @@\n #cmakedefine LWS_WITH_UDP\n #cmakedefine LWS_WITH_ULOOP\n #cmakedefine LWS_WITH_UNIX_SOCK\n+#cmakedefine LWS_WITH_UPNG\n #cmakedefine LWS_WITH_ZIP_FOPS\n #cmakedefine USE_OLD_CYASSL\n #cmakedefine USE_WOLFSSL\ndiff --git a/include/libwebsockets.h b/include/libwebsockets.h\nindex 1f86720..e1bb158 100644\n--- a/include/libwebsockets.h\n+++ b/include/libwebsockets.h\n@@ -612,6 +612,19 @@ struct lws_tokens;\n struct lws_vhost;\n struct lws;\n \n+/* Generic stateful operation return codes */\n+\n+typedef enum {\n+\tLWS_SRET_OK\t\t\u003d 0,\n+\tLWS_SRET_WANT_INPUT \u003d (1 \u003c\u003c 16),\n+\tLWS_SRET_WANT_OUTPUT \u003d (1 \u003c\u003c 17),\n+\tLWS_SRET_FATAL \u003d (1 \u003c\u003c 18),\n+\tLWS_SRET_NO_FURTHER_IN \u003d (1 \u003c\u003c 19),\n+\tLWS_SRET_NO_FURTHER_OUT \u003d (1 \u003c\u003c 20),\n+\tLWS_SRET_AWAIT_RETRY \u003d (1 \u003c\u003c 21),\n+\tLWS_SRET_YIELD \u003d (1 \u003c\u003c 22), /* return to the event loop and continue */\n+} lws_stateful_ret_t;\n+\n typedef struct lws_fixed3232 {\n \tint32_t\t\twhole;\t/* signed 32-bit int */\n \tint32_t\t\tfrac;\t/* signed frac proportion from 0 to (100M - 1) */\n@@ -767,6 +780,7 @@ lws_fx_string(const lws_fx_t *a, char *buf, size_t size);\n #include \u003clibwebsockets/lws-button.h\u003e\n #include \u003clibwebsockets/lws-led.h\u003e\n #include \u003clibwebsockets/lws-pwm.h\u003e\n+#include \u003clibwebsockets/lws-upng.h\u003e\n #include \u003clibwebsockets/lws-display.h\u003e\n #include \u003clibwebsockets/lws-ssd1306-i2c.h\u003e\n #include \u003clibwebsockets/lws-ili9341-spi.h\u003e\n@@ -774,6 +788,7 @@ lws_fx_string(const lws_fx_t *a, char *buf, size_t size);\n #if defined(LWS_WITH_NETWORK)\n #include \u003clibwebsockets/lws-netdev.h\u003e\n #endif\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/include/libwebsockets/lws-upng.h b/include/libwebsockets/lws-upng.h\nnew file mode 100644\nindex 0000000..e7fef9d\n--- /dev/null\n+++ b/include/libwebsockets/lws-upng.h\n@@ -0,0 +1,118 @@\n+/*\n+ * uPNG -- derived from LodePNG version 20100808\n+ *\n+ * Copyright (c) 2005-2010 Lode Vandevenne\n+ * Copyright (c) 2010 Sean Middleditch\n+ * Copyright (c) 2021-2022 Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This software is provided 'as-is', without any express or implied\n+ * warranty. In no event will the authors be held liable for any damages\n+ * arising from the use of this software.\n+\n+ * Permission is granted to anyone to use this software for any purpose,\n+ * including commercial applications, and to alter it and redistribute it\n+ * freely, subject to the following restrictions:\n+ *\n+ * 1. The origin of this software must not be misrepresented; you must not\n+ * claim that you wrote the original software. If you use this software\n+ * in a product, an acknowledgment in the product documentation would be\n+ *\tappreciated but is not required.\n+ *\n+ * 2. Altered source versions must be plainly marked as such, and must not be\n+ *\tmisrepresented as being the original software.\n+ *\n+ * 3. This notice may not be removed or altered from any source\n+ *\tdistribution.\n+ *\n+ * The above notice is the ZLIB license, libpng also uses it.\n+ *\n+ * This version is based on upng project's fork of lodepng and rewritten for\n+ * lws, changing the whole approach to decode on demand to issue a line of\n+ * output at a time, statefully.\n+ */\n+\n+typedef enum lws_upng_format_t {\n+\tLWS_UPNG_BADFORMAT,\n+\tLWS_UPNG_RGB8,\n+\tLWS_UPNG_RGB16,\n+\tLWS_UPNG_RGBA8,\n+\tLWS_UPNG_RGBA16,\n+\tLWS_UPNG_LUMINANCE1,\n+\tLWS_UPNG_LUMINANCE2,\n+\tLWS_UPNG_LUMINANCE4,\n+\tLWS_UPNG_LUMINANCE8,\n+\tLWS_UPNG_LUMINANCE_ALPHA1,\n+\tLWS_UPNG_LUMINANCE_ALPHA2,\n+\tLWS_UPNG_LUMINANCE_ALPHA4,\n+\tLWS_UPNG_LUMINANCE_ALPHA8\n+} lws_upng_format_t;\n+\n+typedef struct lws_upng_t lws_upng_t;\n+\n+/**\n+ * lws_upng_new() - Create new UPNG decode object\n+ *\n+ * Returns a new PNG decoding object, which should be destroyed with\n+ * lws_upng_free() when done with, or NULL if OOM.\n+ */\n+LWS_VISIBLE LWS_EXTERN lws_upng_t *\n+lws_upng_new(void);\n+\n+/**\n+ * lws_upng_free() - Destroy a PNG decode object\n+ *\n+ * \u005cparam upng: Pointer to the decode object to destroy and set to NULL\n+ *\n+ * This also frees any sub-allocations in the object.\n+ */\n+LWS_VISIBLE LWS_EXTERN void\n+lws_upng_free(lws_upng_t **upng);\n+\n+/**\n+ * lws_upng_emit_next_line() - deocde the next line\n+ *\n+ * \u005cparam upng: the decode object\n+ * \u005cparam ppix: pointer to a pointer set to the line's decoded pixel data\n+ * \u005cparam buf: pointer to a const uint8_t array of PNG input\n+ * \u005cparam size: pointer to the count of bytes available at *buf\n+ * \u005cparam hold_at_metadata: true if we should not advance to decode\n+ *\n+ * Make PNG input available to the decoder so it can issue the next line's\n+ * worth of pixels. If the call consumed any input, *buf and *size are\n+ * adjusted accordingly.\n+ *\n+ * The decoder is stateful so it is not sensitive to the chunk size for the\n+ * input.\n+ *\n+ * If \u005cp hold_at_metadata is set, then the decoder will only go as far as\n+ * picking out the metadata like image dimensions, but not start the decode,\n+ * which requires the \u003e30KB heap allocation. This lets you put off for as long\n+ * as possible committing to the decode allocation... this only helps overall\n+ * if you have flow controlled the incoming PNG data.\n+ *\n+ * Return will be one of LWS_SRET_WANT_INPUT is the decoder is stalled waiting\n+ * for more input to be provided, LWS_SRET_WANT_OUTPUT is the decoder stopped\n+ * because it had produced a whole line of output pixels (which can be found\n+ * starting at *ppix), LWS_SRET_OK is it completed and LWS_SRET_FATAL or larger\n+ * if the decode failed.\n+ */\n+LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t\n+lws_upng_emit_next_line(lws_upng_t *upng, const uint8_t **ppix,\n+\t\t\tconst uint8_t **buf, size_t *size,\n+\t\t\tchar hold_at_metadata);\n+\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_width(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_height(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_bpp(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_bitdepth(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_components(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN unsigned int\n+lws_upng_get_pixelsize(const lws_upng_t *upng);\n+LWS_VISIBLE LWS_EXTERN lws_upng_format_t\n+lws_upng_get_format(const lws_upng_t *upng);\n+\ndiff --git a/lib/misc/CMakeLists.txt b/lib/misc/CMakeLists.txt\nindex 1b16acd..a956066 100644\n--- a/lib/misc/CMakeLists.txt\n+++ b/lib/misc/CMakeLists.txt\n@@ -60,6 +60,11 @@ if (LWS_WITH_FTS)\n \t\tmisc/fts/trie-fd.c)\n endif()\n \n+if (LWS_WITH_UPNG)\n+\tlist(APPEND SOURCES\n+\t\tmisc/upng.c)\n+endif()\n+\n # this is an older, standalone hashed disk cache\n # implementation unrelated to lws-cache-ttl\n if (LWS_WITH_DISKCACHE)\ndiff --git a/lib/misc/upng.c b/lib/misc/upng.c\nnew file mode 100644\nindex 0000000..cdf2bbc\n--- /dev/null\n+++ b/lib/misc/upng.c\n@@ -0,0 +1,1535 @@\n+/*\n+ * LWS PNG -- derived from uPNG -- derived from LodePNG version 20100808\n+ * Stateful, linewise PNG decode requiring ~36KB fixed heap\n+ *\n+ * Copyright (c) 2005-2010 Lode Vandevenne (LodePNG)\n+ * Copyright (c) 2010 Sean Middleditch (uPNG)\n+ * Copyright (c) 2021 Andy Green \u003candy@warmcat.com\u003e (Stateful, incremental)\n+ *\n+ * This software is provided 'as-is', without any express or implied\n+ * warranty. In no event will the authors be held liable for any damages\n+ * arising from the use of this software.\n+\n+ * Permission is granted to anyone to use this software for any purpose,\n+ * including commercial applications, and to alter it and redistribute it\n+ * freely, subject to the following restrictions:\n+ *\n+ * 1. The origin of this software must not be misrepresented; you must not\n+ * claim that you wrote the original software. If you use this software\n+ * in a product, an acknowledgment in the product documentation would be\n+ *\tappreciated but is not required.\n+ *\n+ * 2. Altered source versions must be plainly marked as such, and must not be\n+ *\tmisrepresented as being the original software.\n+ *\n+ * 3. This notice may not be removed or altered from any source\n+ *\tdistribution.\n+ *\n+ * AG: The above notice is the ZLIB license, libpng also uses it.\n+ *\n+ * This version was rewritten from the upng project's fork of lodepng and\n+ * adapted to be a stateful stream parser. This rewrite retains the ZLIB\n+ * license of the source material for simplicity.\n+ *\n+ * That allows it to use a fixed 32KB ringbuffer to hold decodes, and\n+ * incrementally decode chunks into it as we want output lines that are not yet\n+ * present there. The input png nor the output bitmap need to be all in one\n+ * place at one time.\n+ */\n+\n+#include \u003cprivate-lib-core.h\u003e\n+\n+#include \u003cstdio.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cstring.h\u003e\n+#include \u003climits.h\u003e\n+\n+#define FIRST_LENGTH_CODE_INDEX\t\t257\n+#define LAST_LENGTH_CODE_INDEX\t\t285\n+\n+/*256 literals, the end code, some length codes, and 2 unused codes */\n+#define NUM_DEFLATE_CODE_SYMBOLS\t288\n+/*the distance codes have their own symbols, 30 used, 2 unused */\n+#define NUM_DISTANCE_SYMBOLS\t\t32\n+/* The code length codes. 0-15: code lengths, 16: copy previous 3-6 times,\n+ * 17: 3-10 zeros, 18: 11-138 zeros */\n+#define NUM_CODE_LENGTH_CODES\t\t19\n+/* largest number of symbols used by any tree type */\n+#define MAX_SYMBOLS\t\t\t288\n+\n+#define DEFLATE_CODE_BITLEN\t\t15\n+#define DISTANCE_BITLEN\t\t\t15\n+#define CODE_LENGTH_BITLEN\t\t7\n+/* largest bitlen used by any tree type */\n+#define MAX_BIT_LENGTH\t\t\t15\n+\n+#define DEFLATE_CODE_BUFFER_SIZE\t(NUM_DEFLATE_CODE_SYMBOLS * 2)\n+#define DISTANCE_BUFFER_SIZE\t\t(NUM_DISTANCE_SYMBOLS * 2)\n+#define CODE_LENGTH_BUFFER_SIZE\t\t(NUM_DISTANCE_SYMBOLS * 2)\n+\n+typedef uint16_t huff_t;\n+\n+typedef enum upng_color {\n+\tLWS_UPNG_LUM\t\t\u003d 0,\n+\tLWS_UPNG_RGB\t\t\u003d 2,\n+\tLWS_UPNG_LUMA\t\t\u003d 4,\n+\tLWS_UPNG_RGBA\t\t\u003d 6\n+} upng_color;\n+\n+struct upng_unfline {\n+\tuint8_t\t\t\t*recon;\n+\tconst uint8_t\t\t*scanline;\n+\tconst uint8_t\t\t*precon;\n+\tuint8_t\t\t\tfilterType;\n+\tunsigned int\t\tbypp;\n+\tunsigned int\t\tbypl;\n+\n+\tconst uint8_t\t\t*in;\n+\tuint8_t\t\t\t*lines;\n+\tunsigned int\t\tbpp;\n+\n+\tunsigned int\t\ty;\n+\tunsigned long\t\tdiff;\n+\tunsigned long\t\tibp;\n+\tunsigned long\t\tsp;\n+\n+\tchar\t\t\tpadded;\n+\tchar\t\t\talt;\n+};\n+\n+typedef struct htree {\n+\thuff_t\t\t\t*tree2d;\n+\t/*maximum number of bits a single code can get */\n+\tuint16_t\t\tmaxbitlen;\n+\t/*number of symbols in the alphabet \u003d number of codes */\n+\tuint16_t\t\tnumcodes;\n+} htree_t;\n+\n+typedef enum {\n+\tUPNS_ID_BL_GB_DONE,\n+\tUPNS_ID_BL_GB_BTYPEb0,\n+\tUPNS_ID_BL_GB_BTYPEb1,\n+\n+\tUPNS_ID_BL_GB_BTYPE_0,\n+\tUPNS_ID_BL_GB_BTYPE_1,\n+\tUPNS_ID_BL_GB_BTYPE_2,\n+\n+\tUPNS_ID_BL_GB_BTYPE_0a,\n+\tUPNS_ID_BL_GB_BTYPE_0b,\n+\tUPNS_ID_BL_GB_BTYPE_0c,\n+\tUPNS_ID_BL_GB_BTYPE_0d,\n+\n+\tUPNS_ID_BL_GB_BTYPE_2a,\n+\tUPNS_ID_BL_GB_BTYPE_2b,\n+\tUPNS_ID_BL_GB_BTYPE_2c,\n+\tUPNS_ID_BL_GB_BTYPE_2d,\n+\tUPNS_ID_BL_GB_BTYPE_2e,\n+\n+\tUPNS_ID_BL_GB_BTYPE_2_16,\n+\tUPNS_ID_BL_GB_BTYPE_2_17,\n+\tUPNS_ID_BL_GB_BTYPE_2_18,\n+\n+\tUPNS_ID_BL_GB_SPIN,\n+\n+\tUPNS_ID_BL_GB_SPINa,\n+\tUPNS_ID_BL_GB_SPINb,\n+\tUPNS_ID_BL_GB_SPINc,\n+\tUPNS_ID_BL_GB_SPINd,\n+\tUPNS_ID_BL_GB_SPINe,\n+\n+} upng_inflate_states_t;\n+\n+typedef enum {\n+\tUOF_MAGIC,\n+\tUOF_SKIP,\n+\tUOF_TYPE4,\n+\tUOF_WIDTH4,\n+\tUOF_HEIGHT4,\n+\tUOF_CDEPTH,\n+\tUOF_CTYPE,\n+\tUOF_ONLY_ZERO3,\n+\tUOF_SKIP4,\n+\n+\tUOF_CHUNK_LEN,\n+\tUOF_CHUNK_TYPE,\n+\tUOF_INSIDE,\n+\n+\tUOF_SKIP_CHUNK_LEN,\n+} upng_outer_framing_t;\n+\n+typedef struct inflator_ctx {\n+\tunsigned int\t\tclenc[NUM_CODE_LENGTH_CODES];\n+\tunsigned int\t\tbitlen[NUM_DEFLATE_CODE_SYMBOLS];\n+\tunsigned int\t\tbitlenD[NUM_DISTANCE_SYMBOLS];\n+\thuff_t\t\t\tclct_buffer[CODE_LENGTH_BUFFER_SIZE];\n+\thuff_t\t\t\tct_buffer[DEFLATE_CODE_BUFFER_SIZE];\n+\thuff_t\t\t\tctD_buffer[DISTANCE_BUFFER_SIZE];\n+\n+\tlws_upng_t\t\t*upng;\n+\n+\tconst uint8_t\t\t*in;\n+\tuint8_t\t\t\t*out;\n+\n+\thtree_t\t\t\tclct;\n+\thtree_t\t\t\tct;\n+\thtree_t\t\t\tctD;\n+\n+\tsize_t\t\t\tbp;\n+\tsize_t\t\t\tinpos;\n+\tsize_t\t\t\tinlen;\n+\tsize_t\t\t\toutpos;\n+\tsize_t\t\t\toutpos_linear;\n+\tsize_t\t\t\tconsumed_linear;\n+\tsize_t\t\t\toutlen;\n+\tsize_t\t\t\tlength;\n+\tsize_t\t\t\tstart;\n+\tsize_t\t\t\tforward;\n+\tsize_t\t\t\tbackward;\n+\tsize_t\t\t\texbits;\n+\tsize_t\t\t\tbypl;\n+\n+\tupng_inflate_states_t\tstate;\n+\n+\tunsigned int\t\tlen;\n+\tunsigned int\t\tnlen;\n+\tunsigned int\t\tn;\n+\tunsigned int\t\thlit;\n+\tunsigned int\t\thdist;\n+\tunsigned int\t\thclen;\n+\tunsigned int\t\ti;\n+\tunsigned int\t\tt;\n+\tunsigned int\t\tcodeD;\n+\tunsigned int\t\tdistance;\n+\tunsigned int\t\texbitsD;\n+\tunsigned int\t\tcode;\n+\tunsigned int\t\ttreepos;\n+\n+\tunsigned int\t\tread_bits_shifter;\n+\tunsigned int\t\tread_bits_limit;\n+\tunsigned int \t\tread_bits_i;\n+\n+\tunsigned int\t\tinfo_size;\n+\n+\tuint8_t\t\t\tsubsequent;\n+\tuint8_t\t\t\tbtype;\n+\tuint8_t\t\t\tdone;\n+\n+\tchar\t\t\tread_bits_ongoing;\n+} inflator_ctx_t;\n+\n+struct lws_upng_t {\n+\tstruct upng_unfline\tu;\n+\tinflator_ctx_t\t\tinf;\n+\n+\tunsigned int\t\twidth;\n+\tunsigned int\t\theight;\n+\n+\tupng_color\t\tcolor_type;\n+\tunsigned int\t\tcolor_depth;\n+\tlws_upng_format_t\tformat;\n+\n+\tconst uint8_t\t\t*chunk;\n+\n+\tint\t\t\tsctr;\n+\tuint32_t\t\tacc;\n+\n+\tuint32_t\t\tchunklen;\n+\tuint32_t\t\tctype;\n+\n+\tupng_outer_framing_t\tof;\n+\n+\tuint8_t\t\t\tno_more_input;\n+\tchar\t\t\thold_at_metadata;\n+};\n+\n+static lws_stateful_ret_t\n+lws_upng_decode(lws_upng_t *upng, const uint8_t **buf, size_t *size);\n+\n+static const huff_t huff_length_base[] \u003d {\n+\t/*the base lengths represented by codes 257-285 */\n+\t3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,\n+\t67, 83, 99, 115, 131, 163, 195, 227, 258\n+};\n+\n+static const huff_t huff_length_extra[] \u003d {\n+\t/*the extra bits used by codes 257-285 (added to base length) */\n+\t0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,\n+\t5, 5, 5, 5, 0\n+};\n+\n+static const huff_t huff_distance_base[] \u003d {\n+\t/*\n+\t * The base backwards distances (the bits of distance codes appear\n+\t * after length codes and use their own huffman tree)\n+\t */\n+\t1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,\n+\t513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577\n+};\n+\n+static const huff_t huff_distance_extra[] \u003d {\n+\t/* the extra bits of backwards distances (added to base) */\n+\t0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,\n+\t10, 11, 11, 12, 12, 13, 13\n+};\n+\n+static const huff_t huff_cl_cl[] \u003d {\n+\t/*\n+\t * The order in which \u0022code length alphabet code lengths\u0022 are stored,\n+\t * out of this the huffman tree of the dynamic huffman tree lengths\n+\t * is generated\n+\t */\n+\t16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15\n+};\n+\n+static const huff_t FIXED_DEFLATE_CODE_TREE[NUM_DEFLATE_CODE_SYMBOLS * 2] \u003d {\n+\t289, 370, 290, 307, 546, 291, 561, 292, 293, 300, 294, 297, 295, 296,\n+\t0, 1, 2, 3, 298, 299, 4, 5, 6, 7, 301, 304, 302, 303, 8, 9, 10, 11, 305,\n+\t306, 12, 13, 14, 15, 308, 339, 309, 324, 310, 317, 311, 314, 312, 313,\n+\t16, 17, 18, 19, 315, 316, 20, 21, 22, 23, 318, 321, 319, 320, 24, 25,\n+\t26, 27, 322, 323, 28, 29, 30, 31, 325, 332, 326, 329, 327, 328, 32, 33,\n+\t34, 35, 330, 331, 36, 37, 38, 39, 333, 336, 334, 335, 40, 41, 42, 43,\n+\t337, 338, 44, 45, 46, 47, 340, 355, 341, 348, 342, 345, 343, 344, 48,\n+\t49, 50, 51, 346, 347, 52, 53, 54, 55, 349, 352, 350, 351, 56, 57, 58,\n+\t59, 353, 354, 60, 61, 62, 63, 356, 363, 357, 360, 358, 359, 64, 65, 66,\n+\t67, 361, 362, 68, 69, 70, 71, 364, 367, 365, 366, 72, 73, 74, 75, 368,\n+\t369, 76, 77, 78, 79, 371, 434, 372, 403, 373, 388, 374, 381, 375, 378,\n+\t376, 377, 80, 81, 82, 83, 379, 380, 84, 85, 86, 87, 382, 385, 383, 384,\n+\t88, 89, 90, 91, 386, 387, 92, 93, 94, 95, 389, 396, 390, 393, 391, 392,\n+\t96, 97, 98, 99, 394, 395, 100, 101, 102, 103, 397, 400, 398, 399, 104,\n+\t105, 106, 107, 401, 402, 108, 109, 110, 111, 404, 419, 405, 412, 406,\n+\t409, 407, 408, 112, 113, 114, 115, 410, 411, 116, 117, 118, 119, 413,\n+\t416, 414, 415, 120, 121, 122, 123, 417, 418, 124, 125, 126, 127, 420,\n+\t427, 421, 424, 422, 423, 128, 129, 130, 131, 425, 426, 132, 133, 134,\n+\t135, 428, 431, 429, 430, 136, 137, 138, 139, 432, 433, 140, 141, 142,\n+\t143, 435, 483, 436, 452, 568, 437, 438, 445, 439, 442, 440, 441, 144,\n+\t145, 146, 147, 443, 444, 148, 149, 150, 151, 446, 449, 447, 448, 152,\n+\t153, 154, 155, 450, 451, 156, 157, 158, 159, 453, 468, 454, 461, 455,\n+\t458, 456, 457, 160, 161, 162, 163, 459, 460, 164, 165, 166, 167, 462,\n+\t465, 463, 464, 168, 169, 170, 171, 466, 467, 172, 173, 174, 175, 469,\n+\t476, 470, 473, 471, 472, 176, 177, 178, 179, 474, 475, 180, 181, 182,\n+\t183, 477, 480, 478, 479, 184, 185, 186, 187, 481, 482, 188, 189, 190,\n+\t191, 484, 515, 485, 500, 486, 493, 487, 490, 488, 489, 192, 193, 194,\n+\t195, 491, 492, 196, 197, 198, 199, 494, 497, 495, 496, 200, 201, 202,\n+\t203, 498, 499, 204, 205, 206, 207, 501, 508, 502, 505, 503, 504, 208,\n+\t209, 210, 211, 506, 507, 212, 213, 214, 215, 509, 512, 510, 511, 216,\n+\t217, 218, 219, 513, 514, 220, 221, 222, 223, 516, 531, 517, 524, 518,\n+\t521, 519, 520, 224, 225, 226, 227, 522, 523, 228, 229, 230, 231, 525,\n+\t528, 526, 527, 232, 233, 234, 235, 529, 530, 236, 237, 238, 239, 532,\n+\t539, 533, 536, 534, 535, 240, 241, 242, 243, 537, 538, 244, 245, 246,\n+\t247, 540, 543, 541, 542, 248, 249, 250, 251, 544, 545, 252, 253, 254,\n+\t255, 547, 554, 548, 551, 549, 550, 256, 257, 258, 259, 552, 553, 260,\n+\t261, 262, 263, 555, 558, 556, 557, 264, 265, 266, 267, 559, 560, 268,\n+\t269, 270, 271, 562, 565, 563, 564, 272, 273, 274, 275, 566, 567, 276,\n+\t277, 278, 279, 569, 572, 570, 571, 280, 281, 282, 283, 573, 574, 284,\n+\t285, 286, 287, 0, 0\n+};\n+\n+static const huff_t FIXED_DISTANCE_TREE[] \u003d {\n+\t33, 48, 34, 41, 35, 38, 36, 37,\n+\t0, 1, 2, 3, 39, 40, 4, 5,\n+\t6, 7, 42, 45, 43, 44, 8, 9,\n+\t10, 11, 46, 47, 12, 13, 14, 15,\n+\t49, 56, 50, 53, 51, 52, 16, 17,\n+\t18, 19, 54, 55, 20, 21, 22, 23,\n+\t57, 60, 58, 59, 24, 25, 26, 27,\n+\t61, 62, 28, 29, 30, 31, 0, 0\n+};\n+\n+static lws_stateful_ret_t\n+read_bit(inflator_ctx_t *inf, uint8_t *bits)\n+{\n+\tsize_t bo \u003d inf-\u003ebp \u003e\u003e 3;\n+\n+\tif (bo + inf-\u003einpos \u003e\u003d inf-\u003einlen)\n+\t\treturn LWS_SRET_WANT_INPUT;\n+\n+\t*bits \u003d (uint8_t)((*(inf-\u003ein + inf-\u003einpos + bo) \u003e\u003e (inf-\u003ebp \u0026 7)) \u0026 1);\n+\n+\tinf-\u003ebp++;\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+/* Stateful, so it can pick up after running out of input partway thru */\n+\n+static lws_stateful_ret_t\n+read_bits(inflator_ctx_t *inf, unsigned int nbits, unsigned int *bits)\n+{\n+\tlws_stateful_ret_t r;\n+\tuint8_t b;\n+\n+\tif (!inf-\u003eread_bits_ongoing) {\n+\t\tinf-\u003eread_bits_ongoing\t\u003d 1;\n+\t\tinf-\u003eread_bits_shifter\t\u003d 0;\n+\t\tinf-\u003eread_bits_limit\t\u003d nbits;\n+\t\tinf-\u003eread_bits_i\t\u003d 0;\n+\t}\n+\n+\twhile (inf-\u003eread_bits_i \u003c inf-\u003eread_bits_limit) {\n+\t\t r \u003dread_bit(inf, \u0026b);\n+\t\t if (r)\n+\t\t\t return r;\n+\n+\t\t inf-\u003eread_bits_shifter \u003d inf-\u003eread_bits_shifter | (unsigned int)(b \u003c\u003c inf-\u003eread_bits_i);\n+\n+\t\t inf-\u003eread_bits_i++;\n+\t}\n+\n+\tinf-\u003eread_bits_ongoing \u003d 0;\n+\t*bits \u003d inf-\u003eread_bits_shifter;\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+static lws_stateful_ret_t\n+read_byte(inflator_ctx_t *inf, uint8_t *byte)\n+{\n+\tsize_t bo;\n+\n+\twhile (inf-\u003ebp \u0026 7)\n+\t\tinf-\u003ebp++;\n+\n+\tbo \u003d inf-\u003ebp \u003e\u003e 3;\n+\n+\tif (bo + inf-\u003einpos \u003e\u003d inf-\u003einlen)\n+\t\treturn LWS_SRET_WANT_INPUT;\n+\n+\t*byte \u003d *(inf-\u003ein + inf-\u003einpos + bo);\n+\n+\tinf-\u003ebp +\u003d 8;\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+/* buffer must be numcodes*2 in size! */\n+static void\n+huffman_tree_init(htree_t *tree, huff_t *buffer, uint16_t numcodes,\n+\t\t uint16_t maxbitlen)\n+{\n+\ttree-\u003etree2d \u003d buffer;\n+\n+\ttree-\u003enumcodes \u003d numcodes;\n+\ttree-\u003emaxbitlen \u003d maxbitlen;\n+}\n+\n+#define EMPTY 32767\n+\n+/*\n+ * Given the code lengths (as stored in the PNG file), generate the tree as\n+ * defined by Deflate. maxbitlen is the maximum bits that a code in the tree\n+ * can have.\n+ */\n+static lws_stateful_ret_t\n+huffman_tree_create_lengths(lws_upng_t *upng, htree_t *tree,\n+\t\t\t const unsigned *bitlen)\n+{\n+\tunsigned int tree1d[MAX_SYMBOLS], blcount[MAX_BIT_LENGTH],\n+\t\t nextcode[MAX_BIT_LENGTH + 1];\n+\tunsigned int bits, n, i, nodefilled \u003d 0, treepos \u003d 0;\n+\n+\tmemset(blcount, 0, sizeof(blcount));\n+\tmemset(nextcode, 0, sizeof(nextcode));\n+\n+\tfor (bits \u003d 0; bits \u003c tree-\u003enumcodes; bits++)\n+\t\tblcount[bitlen[bits]]++;\n+\n+\tfor (bits \u003d 1; bits \u003c\u003d (unsigned int)tree-\u003emaxbitlen; bits++)\n+\t\tnextcode[bits] \u003d (nextcode[bits - 1] + blcount[bits - 1]) \u003c\u003c 1;\n+\n+\tfor (n \u003d 0; n \u003c tree-\u003enumcodes; n++)\n+\t\tif (bitlen[n])\n+\t\t\ttree1d[n] \u003d nextcode[bitlen[n]]++;\n+\n+\tfor (n \u003d 0; n \u003c (unsigned int)tree-\u003enumcodes * 2u; n++)\n+\t\ttree-\u003etree2d[n] \u003d EMPTY;\n+\n+\tfor (n \u003d 0; n \u003c tree-\u003enumcodes; n++) {\t/* the codes */\n+\t\tfor (i \u003d 0; i \u003c bitlen[n]; i++) { /* the bits for this code */\n+\t\t\tuint8_t bit \u003d (uint8_t)((tree1d[n] \u003e\u003e\n+\t\t\t\t\t\t(bitlen[n] - i - 1)) \u0026 1);\n+\n+\t\t\t/* check if oversubscribed */\n+\t\t\tif (treepos \u003e tree-\u003enumcodes - 2u)\n+\t\t\t\treturn LWS_SRET_FATAL + 1;\n+\n+\t\t\tif (tree-\u003etree2d[2 * treepos + bit] \u003d\u003d EMPTY) {\n+\t\t\t\tif (i + 1 \u003d\u003d bitlen[n]) { /* ... last bit */\n+\t\t\t\t\ttree-\u003etree2d[2 * treepos + bit] \u003d (huff_t)n;\n+\t\t\t\t\ttreepos \u003d 0;\n+\t\t\t\t} else {\n+\t\t\t\t\tnodefilled++;\n+\t\t\t\t\ttree-\u003etree2d[2 * treepos + bit] \u003d\n+\t\t\t\t\t (huff_t)(nodefilled + tree-\u003enumcodes);\n+\t\t\t\t\ttreepos \u003d nodefilled;\n+\t\t\t\t}\n+\t\t\t} else\n+\t\t\t\ttreepos \u003d (unsigned int)(tree-\u003etree2d[2 * treepos + bit] -\n+\t\t\t\t\t\ttree-\u003enumcodes);\n+\t\t}\n+\t}\n+\n+\tfor (n \u003d 0; n \u003c tree-\u003enumcodes * 2u; n++)\n+\t\tif (tree-\u003etree2d[n] \u003d\u003d EMPTY)\n+\t\t\ttree-\u003etree2d[n] \u003d 0;\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+static lws_stateful_ret_t\n+huffman_decode_symbol(inflator_ctx_t *inf, const htree_t *ct, unsigned int *uct)\n+{\n+\tlws_stateful_ret_t r;\n+\tuint8_t bit;\n+\n+\tdo {\n+\t\tr \u003d read_bit(inf, \u0026bit);\n+\t\tif (r)\n+\t\t\treturn r;\n+\n+\t\t*uct \u003d ct-\u003etree2d[(inf-\u003etreepos \u003c\u003c 1) | bit];\n+\t\tif (*uct \u003c ct-\u003enumcodes)\n+\t\t\treturn LWS_SRET_OK;\n+\n+\t\tinf-\u003etreepos \u003d *uct - ct-\u003enumcodes;\n+\t\tif (inf-\u003etreepos \u003e\u003d ct-\u003enumcodes)\n+\t\t\treturn LWS_SRET_FATAL + 2;\n+\t} while (1);\n+}\n+\n+static lws_stateful_ret_t\n+uz_inflate_data(inflator_ctx_t *inf)\n+{\n+\tunsigned int count, val, tu;\n+\tuint8_t t, done \u003d 0;\n+\tlws_stateful_ret_t r;\n+\tsize_t virt;\n+\n+\twhile (!done) {\n+\t\tswitch (inf-\u003estate) {\n+\t\tcase UPNS_ID_BL_GB_DONE:\n+\t\t\tr \u003d read_bit(inf, \u0026inf-\u003edone);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPEb0:\n+\t\t\tr \u003d read_bit(inf, \u0026inf-\u003ebtype);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPEb1:\n+\t\t\tr \u003d read_bit(inf, \u0026t);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003ebtype |\u003d (uint8_t)(t \u003c\u003c 1);\n+\n+\t\t\tif (inf-\u003ebtype \u003d\u003d 3)\n+\t\t\t\treturn LWS_SRET_FATAL + 3;\n+\n+\t\t\tinf-\u003ei \u003d 0;\n+\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_0 + inf-\u003ebtype;\n+\t\t\tcontinue;\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_0: /* no compression */\n+\t\t\tr \u003d read_byte(inf, \u0026t);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003elen \u003d t;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_0a;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_0a:\n+\t\t\tr \u003d read_byte(inf, \u0026t);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003elen \u003d inf-\u003elen | (unsigned int)(t \u003c\u003c 8);\n+\t\t\tinf-\u003estate++;\n+\t\t\t/* fallthru */\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_0b:\n+\t\t\tr \u003d read_byte(inf, \u0026t);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003enlen \u003d t;\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_0c:\n+\t\t\tr \u003d read_byte(inf, \u0026t);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003enlen \u003d inf-\u003enlen | (unsigned int)(t \u003c\u003c 8);\n+\n+\t\t\tif (inf-\u003elen + inf-\u003enlen !\u003d 65535)\n+\t\t\t\treturn LWS_SRET_FATAL + 4;\n+\n+\t\t\tinf-\u003estate++;\n+\t\t\tinf-\u003en \u003d 0;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_0d:\n+\n+\t\t\tif (inf-\u003en \u003c inf-\u003elen) {\n+\n+\t\t\t\tr \u003d read_byte(inf, \u0026t);\n+\t\t\t\tif (r)\n+\t\t\t\t\treturn r;\n+\n+\t\t\t\tinf-\u003eout[inf-\u003eoutpos++] \u003d t;\n+\t\t\t\tif (inf-\u003eoutpos \u003e\u003d inf-\u003eoutlen)\n+\t\t\t\t\tinf-\u003eoutpos \u003d 0;\n+\t\t\t\tinf-\u003eoutpos_linear++;\n+\n+\t\t\t\tif (inf-\u003eoutpos_linear - inf-\u003econsumed_linear \u003e\u003d\n+\t\t\t\t\t\tinf-\u003ebypl + 1)\n+\t\t\t\t\treturn LWS_SRET_WANT_OUTPUT;\n+\n+\t\t\t\tinf-\u003en++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPIN;\n+\t\t\tcontinue;\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_1: /* fixed trees */\n+\t\t\thuffman_tree_init(\u0026inf-\u003ect,\n+\t\t\t\t\t (huff_t *)FIXED_DEFLATE_CODE_TREE,\n+\t\t\t\t\t NUM_DEFLATE_CODE_SYMBOLS,\n+\t\t\t\t\t DEFLATE_CODE_BITLEN);\n+\t\t\thuffman_tree_init(\u0026inf-\u003ectD,\n+\t\t\t\t\t (huff_t *)FIXED_DISTANCE_TREE,\n+\t\t\t\t\t NUM_DISTANCE_SYMBOLS,\n+\t\t\t\t\t DISTANCE_BITLEN);\n+\n+\t\t\tlwsl_notice(\u0022%s: fixed tree init\u005cn\u0022, __func__);\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPIN;\n+\t\t\tcontinue;\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2: /* dynamic trees */\n+\t\t\thuffman_tree_init(\u0026inf-\u003ect, inf-\u003ect_buffer,\n+\t\t\t\t\t NUM_DEFLATE_CODE_SYMBOLS,\n+\t\t\t\t\t DEFLATE_CODE_BITLEN);\n+\t\t\thuffman_tree_init(\u0026inf-\u003ectD, inf-\u003ectD_buffer,\n+\t\t\t\t\t NUM_DISTANCE_SYMBOLS,\n+\t\t\t\t\t DISTANCE_BITLEN);\n+\t\t\thuffman_tree_init(\u0026inf-\u003eclct, inf-\u003eclct_buffer,\n+\t\t\t\t\t NUM_CODE_LENGTH_CODES,\n+\t\t\t\t\t CODE_LENGTH_BITLEN);\n+\n+\t\t\t/* clear bitlen arrays */\n+\t\t\tmemset(inf-\u003ebitlen, 0, sizeof(inf-\u003ebitlen));\n+\t\t\tmemset(inf-\u003ebitlenD, 0, sizeof(inf-\u003ebitlenD));\n+\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2a;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2a:\n+\t\t\tr \u003d read_bits(inf, 5, \u0026inf-\u003ehlit);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tinf-\u003ehlit +\u003d 257;\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2b:\n+\t\t\tr \u003d read_bits(inf, 5, \u0026inf-\u003ehdist);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tinf-\u003ehdist++;\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2c:\n+\t\t\tr \u003d read_bits(inf, 4, \u0026inf-\u003ehclen);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tinf-\u003ehclen +\u003d 4;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2d;\n+\t\t\tinf-\u003ei \u003d 0;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2d:\n+\t\t\tif (inf-\u003ei \u003c NUM_CODE_LENGTH_CODES) {\n+\t\t\t\tif (inf-\u003ei \u003c inf-\u003ehclen) {\n+\t\t\t\t\tr \u003d read_bits(inf, 3,\n+\t\t\t\t\t\t\u0026inf-\u003eclenc[huff_cl_cl[inf-\u003ei]]);\n+\t\t\t\t\tif (r)\n+\t\t\t\t\t\treturn r;\n+\t\t\t\t} else\n+\t\t\t\t\t/*if not, it must stay 0 */\n+\t\t\t\t\tinf-\u003eclenc[huff_cl_cl[inf-\u003ei]] \u003d 0;\n+\n+\t\t\t\tinf-\u003ei++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tr \u003d huffman_tree_create_lengths(inf-\u003eupng, \u0026inf-\u003eclct,\n+\t\t\t\t\t\t\tinf-\u003eclenc);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003ei \u003d 0;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2e;\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2e:\n+\n+\t\t\tif (inf-\u003ei \u003e\u003d inf-\u003ehlit + inf-\u003ehdist) {\n+\t\t\t\tif (inf-\u003ebitlen[256] \u003d\u003d 0)\n+\t\t\t\t\treturn LWS_SRET_FATAL + 6;\n+\n+\t\t\t\tif (huffman_tree_create_lengths(inf-\u003eupng,\n+\t\t\t\t\t\t\t\t\u0026inf-\u003ect,\n+\t\t\t\t\t\t\t\tinf-\u003ebitlen))\n+\t\t\t\t\treturn LWS_SRET_FATAL + 7;\n+\n+\t\t\t\tif (huffman_tree_create_lengths(inf-\u003eupng,\n+\t\t\t\t\t\t\t\t\u0026inf-\u003ectD,\n+\t\t\t\t\t\t\t\tinf-\u003ebitlenD))\n+\t\t\t\t\treturn LWS_SRET_FATAL + 8;\n+\n+\t\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPIN;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tr \u003d huffman_decode_symbol(inf, \u0026inf-\u003eclct, \u0026inf-\u003ecode);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tswitch (inf-\u003ecode) {\n+\t\t\tcase 16:\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2_16;\n+\t\t\t\tcontinue;\n+\t\t\tcase 17:\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2_17;\n+\t\t\t\tcontinue;\n+\t\t\tcase 18:\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2_18;\n+\t\t\t\tcontinue;\n+\t\t\tdefault:\n+\t\t\t\tif (inf-\u003ecode \u003e 15)\n+\t\t\t\t\treturn LWS_SRET_FATAL + 9;\n+\n+\t\t\t\tif (inf-\u003ei \u003c inf-\u003ehlit)\n+\t\t\t\t\tinf-\u003ebitlen[inf-\u003ei] \u003d inf-\u003ecode;\n+\t\t\t\telse\n+\t\t\t\t\tinf-\u003ebitlenD[inf-\u003ei - inf-\u003ehlit] \u003d\n+\t\t\t\t\t\t\t\tinf-\u003ecode;\n+\n+\t\t\t\tinf-\u003ei++;\n+\t\t\t\tinf-\u003etreepos \u003d 0;\n+\n+\t\t\t\t/* stay in 2e */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2_16: /* repeat previous */\n+\t\t\tr \u003d read_bits(inf, 2, \u0026tu);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tcount \u003d tu + 3;\n+\n+\t\t\tif ((inf-\u003ei - 1) \u003c inf-\u003ehlit)\n+\t\t\t\tval \u003d inf-\u003ebitlen[inf-\u003ei - 1];\n+\t\t\telse\n+\t\t\t\tval \u003d inf-\u003ebitlenD[inf-\u003ei - inf-\u003ehlit - 1];\n+\n+\t\t\tgoto fill;\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2_17: /*repeat \u00220\u0022 3-10 times */\n+\t\t\tr \u003d read_bits(inf, 3, \u0026tu);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tcount \u003d tu + 3;\n+\n+\t\t\tval \u003d 0;\n+\t\t\tgoto fill;\n+\n+\t\tcase UPNS_ID_BL_GB_BTYPE_2_18: /*repeat \u00220\u0022 11-138 times */\n+\t\t\tr \u003d read_bits(inf, 7, \u0026tu);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\t\t\tcount \u003d tu + 11;\n+\t\t\tval \u003d 0;\n+fill:\n+\t\t\tif (inf-\u003ei + count \u003e inf-\u003ehlit + inf-\u003ehdist)\n+\t\t\t\treturn LWS_SRET_FATAL + 10;\n+\n+\t\t\t{\n+\t\t\t\tunsigned int n;\n+\n+\t\t\t\tfor (n \u003d 0; n \u003c count; n++) {\n+\n+\t\t\t\t\tif (inf-\u003ei \u003c inf-\u003ehlit)\n+\t\t\t\t\t\tinf-\u003ebitlen[inf-\u003ei] \u003d val;\n+\t\t\t\t\telse\n+\t\t\t\t\t\tinf-\u003ebitlenD[inf-\u003ei - inf-\u003ehlit] \u003d val;\n+\n+\t\t\t\t\tinf-\u003ei++;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_BTYPE_2e;\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\tcontinue;\n+\n+\n+\t\tcase UPNS_ID_BL_GB_SPIN:\n+\n+\t\t\tr \u003d huffman_decode_symbol(inf, \u0026inf-\u003ect, \u0026inf-\u003ecode);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tif (inf-\u003ecode \u003e\u003d FIRST_LENGTH_CODE_INDEX \u0026\u0026\n+\t\t\t inf-\u003ecode - FIRST_LENGTH_CODE_INDEX \u003c\n+\t\t\t\t\t LWS_ARRAY_SIZE(huff_length_base))\n+\t\t\t\tinf-\u003elength \u003d huff_length_base[inf-\u003ecode -\n+\t\t\t FIRST_LENGTH_CODE_INDEX];\n+\t\t\telse\n+\t\t\t\tinf-\u003elength \u003d 0;\n+\n+\t\t\tif (inf-\u003ecode \u003d\u003d 256) {\n+\t\t\t\t/*\n+\t\t\t\t * We're finished with this huffman block, we\n+\t\t\t\t * need to go back up a level\n+\t\t\t\t */\n+\t\t\t\tdone \u003d inf-\u003edone;\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_DONE;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif (inf-\u003ecode \u003c\u003d 255) {\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPINa;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif (inf-\u003ecode \u003c FIRST_LENGTH_CODE_INDEX ||\n+\t\t\t inf-\u003ecode \u003e LAST_LENGTH_CODE_INDEX) {\n+\t\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tinf-\u003eexbits \u003d huff_length_extra[inf-\u003ecode -\n+\t\t\t FIRST_LENGTH_CODE_INDEX];\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPINb;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_SPINb:\n+\t\t\tr \u003d read_bits(inf, (unsigned int)inf-\u003eexbits, \u0026tu);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003elength +\u003d tu;\n+\t\t\tinf-\u003estate++;\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_SPINc:\n+\n+\t\t\t/* part 3: get distance code */\n+\n+\t\t\tr \u003d huffman_decode_symbol(inf, \u0026inf-\u003ectD, \u0026inf-\u003ecodeD);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\t/* invalid distance code (30-31 are never used) */\n+\t\t\tif (inf-\u003ecodeD \u003e 29)\n+\t\t\t\treturn LWS_SRET_FATAL + 11;\n+\n+\t\t\tinf-\u003edistance \u003d huff_distance_base[inf-\u003ecodeD];\n+\n+\t\t\t/* part 4: get extra bits from distance */\n+\n+\t\t\tinf-\u003eexbitsD \u003d huff_distance_extra[inf-\u003ecodeD];\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_SPINd:\n+\n+\t\t\tr \u003d read_bits(inf, inf-\u003eexbitsD, \u0026tu);\n+\t\t\tif (r)\n+\t\t\t\treturn r;\n+\n+\t\t\tinf-\u003edistance +\u003d tu;\n+\n+\t\t\tif (inf-\u003edistance \u003e inf-\u003einfo_size) {\n+\t\t\t\tlwsl_err(\u0022%s: distance %lu\u005cn\u0022, __func__,\n+\t\t\t\t\t\t(unsigned long)inf-\u003edistance);\n+\t\t\t\tassert(0);\n+\t\t\t}\n+\n+\t\t\t/*\n+\t\t\t * Part 5: fill in all the out[n] values based\n+\t\t\t * on the length and dist\n+\t\t\t */\n+\t\t\tinf-\u003estart \u003d inf-\u003eoutpos;\n+\t\t\tinf-\u003eforward \u003d 0;\n+\t\t\tinf-\u003ebackward \u003d inf-\u003edistance; /* from inf-\u003estart */\n+\n+\t\t\tinf-\u003estate++;\n+\n+\t\t\t/* fallthru */\n+\t\tcase UPNS_ID_BL_GB_SPINe:\n+\n+\t\t\tif (inf-\u003eforward \u003e\u003d inf-\u003elength) {\n+\t\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPIN;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif (inf-\u003ebackward \u003c\u003d inf-\u003estart)\n+\t\t\t\tvirt \u003d inf-\u003estart - inf-\u003ebackward;\n+\t\t\telse /* wrapped... backward \u003e\u003d start */\n+\t\t\t\tvirt \u003d inf-\u003einfo_size -\n+\t\t\t\t\t(inf-\u003ebackward - inf-\u003estart);\n+\n+\t\t\tif (virt \u003e\u003d inf-\u003einfo_size)\n+\t\t\t\tlwsl_err(\u0022virt %d\u005cn\u0022, (int)virt);\n+\n+\t\t\tinf-\u003eout[inf-\u003eoutpos++] \u003d inf-\u003eout[virt];\n+\t\t\tif (inf-\u003eoutpos \u003e\u003d inf-\u003eoutlen)\n+\t\t\t\tinf-\u003eoutpos \u003d 0;\n+\n+\t\t\tinf-\u003eoutpos_linear++;\n+\t\t\tinf-\u003ebackward--;\n+\n+\t\t\tif (!inf-\u003ebackward)\n+\t\t\t\tinf-\u003ebackward \u003d inf-\u003edistance;\n+\n+\t\t\tinf-\u003eforward++;\n+\n+\t\t\tif (inf-\u003eoutpos_linear - inf-\u003econsumed_linear \u003e\u003d\n+\t\t\t\t\t\t\t\tinf-\u003ebypl + 1)\n+\t\t\t\treturn LWS_SRET_WANT_OUTPUT;\n+\n+\t\t\tcontinue;\n+\n+\t\tcase UPNS_ID_BL_GB_SPINa:\n+\n+\t\t\tinf-\u003eout[inf-\u003eoutpos++] \u003d (uint8_t)inf-\u003ecode;\n+\t\t\tif (inf-\u003eoutpos \u003e\u003d inf-\u003eoutlen)\n+\t\t\t\tinf-\u003eoutpos \u003d 0;\n+\n+\t\t\tinf-\u003eoutpos_linear++;\n+\t\t\tinf-\u003etreepos \u003d 0;\n+\t\t\tinf-\u003estate \u003d UPNS_ID_BL_GB_SPIN;\n+\n+\t\t\tif (inf-\u003eoutpos_linear - inf-\u003econsumed_linear \u003e\u003d\n+\t\t\t\t\t\t\t\tinf-\u003ebypl + 1)\n+\t\t\t\treturn LWS_SRET_WANT_OUTPUT;\n+\n+\t\t\tcontinue;\n+\t\t}\n+\t}\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+static int\n+paeth(int a, int b, int c)\n+{\n+\tint p \u003d a + b - c;\n+\tint pa \u003d p \u003e a ? p - a : a - p;\n+\tint pb \u003d p \u003e b ? p - b : b - p;\n+\tint pc \u003d p \u003e c ? p - c : c - p;\n+\n+\tif (pa \u003c\u003d pb \u0026\u0026 pa \u003c\u003d pc)\n+\t\treturn a;\n+\n+\tif (pb \u003c\u003d pc)\n+\t\treturn b;\n+\n+\treturn c;\n+}\n+\n+static lws_stateful_ret_t\n+unfilter_scanline(lws_upng_t *u)\n+{\n+\tstruct upng_unfline *uf \u003d \u0026u-\u003eu;\n+\tunsigned long i;\n+\n+\tswitch (uf-\u003efilterType) {\n+\tcase 0: /* None */\n+\t\tfor (i \u003d 0; i \u003c uf-\u003ebypl; i++)\n+\t\t\tuf-\u003erecon[i] \u003d u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t u-\u003einf.info_size];\n+\t\tbreak;\n+\tcase 1: /* Sub */\n+\t\tfor (i \u003d 0; i \u003c uf-\u003ebypp; i++)\n+\t\t\tuf-\u003erecon[i] \u003d u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t u-\u003einf.info_size];\n+\n+\t\tfor (i \u003d uf-\u003ebypp; i \u003c uf-\u003ebypl; i++)\n+\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t u-\u003einf.info_size] +\n+\t\t\t\tuf-\u003erecon[i - uf-\u003ebypp]);\n+\t\tbreak;\n+\tcase 2: /* Up */\n+\t\tif (uf-\u003ey)\n+\t\t\tfor (i \u003d 0; i \u003c uf-\u003ebypl; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size] + uf-\u003eprecon[i]);\n+\t\telse\n+\t\t\tfor (i \u003d 0; i \u003c uf-\u003ebypl; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size]);\n+\t\tbreak;\n+\tcase 3: /* Average */\n+\t\tif (uf-\u003ey) {\n+\t\t\tfor (i \u003d 0; i \u003c uf-\u003ebypp; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size] + uf-\u003eprecon[i] / 2);\n+\t\t\tfor (i \u003d uf-\u003ebypp; i \u003c uf-\u003ebypl; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)\n+\t\t\t\t\t(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t\t u-\u003einf.info_size] +\n+\t\t\t\t\t((uf-\u003erecon[i - uf-\u003ebypp] +\n+\t\t\t\t\t\t\tuf-\u003eprecon[i]) / 2));\n+\t\t} else {\n+\t\t\tfor (i \u003d 0; i \u003c uf-\u003ebypp; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size]);\n+\t\t\tfor (i \u003d uf-\u003ebypp; i \u003c uf-\u003ebypl; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size] +\n+\t\t\t\t\tuf-\u003erecon[i - uf-\u003ebypp] / 2);\n+\t\t}\n+\t\tbreak;\n+\tcase 4: /* Paeth */\n+\t\tif (uf-\u003ey) {\n+\t\t\tfor (i \u003d 0; i \u003c uf-\u003ebypp; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size] +\n+\t\t\t\t\tpaeth(0, uf-\u003eprecon[i], 0));\n+\t\t\tfor (i \u003d uf-\u003ebypp; i \u003c uf-\u003ebypl; i++)\n+\t\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t\t u-\u003einf.info_size] +\n+\t\t\t\t\tpaeth(uf-\u003erecon[i - uf-\u003ebypp],\n+\t\t\t\t\t\t\tuf-\u003eprecon[i],\n+\t\t\t\t\t\t\tuf-\u003eprecon[i - uf-\u003ebypp]));\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tfor (i \u003d 0; i \u003c uf-\u003ebypp; i++)\n+\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t u-\u003einf.info_size]);\n+\t\tfor (i \u003d uf-\u003ebypp; i \u003c uf-\u003ebypl; i++)\n+\t\t\tuf-\u003erecon[i] \u003d (uint8_t)(u-\u003einf.out[(uf-\u003esp + i) %\n+\t\t\t u-\u003einf.info_size] +\n+\t\t\t\tpaeth(uf-\u003erecon[i - uf-\u003ebypp], 0, 0));\n+\t\tbreak;\n+\tdefault:\n+\t\tlwsl_err(\u0022%s: line start is broken %d\u005cn\u0022, __func__,\n+\t\t\t\tuf-\u003efilterType);\n+\t\treturn LWS_SRET_FATAL + 12;\n+\t}\n+\n+\tu-\u003einf.consumed_linear +\u003d uf-\u003ebypl;\n+\n+\treturn LWS_SRET_OK;\n+}\n+\n+lws_stateful_ret_t\n+lws_upng_emit_next_line(lws_upng_t *u, const uint8_t **ppix,\n+\t\t const uint8_t **pos, size_t *size, char hold_at_metadata)\n+{\n+\tstruct upng_unfline\t*uf \u003d \u0026u-\u003eu;\n+\tunsigned long\t\tobp;\n+\tlws_stateful_ret_t\tret \u003d LWS_SRET_OK;\n+\n+\t*ppix \u003d NULL;\n+\n+\tu-\u003ehold_at_metadata \u003d hold_at_metadata;\n+\n+\tif (u-\u003eheight \u0026\u0026 uf-\u003ey \u003e\u003d u-\u003eheight)\n+\t\tgoto out;\n+\n+\t/*\n+\t * The decoder emits into the 32KB window ringbuffer, if we don't\n+\t * already have at least one line's worth of output in there, we'll\n+\t * have to do more inflation\n+\t */\n+\n+\tif (u-\u003einf.outpos_linear - u-\u003einf.consumed_linear \u003c uf-\u003ebypl + 1) {\n+\t\tret \u003d lws_upng_decode(u, pos, size);\n+\t\tif ((!*size \u0026\u0026 ret \u003d\u003d LWS_SRET_WANT_INPUT) ||\n+\t\t (ret \u0026 (LWS_SRET_FATAL | LWS_SRET_YIELD)) ||\n+\t\t !u-\u003einf.outpos_linear)\n+\t\t\treturn ret;\n+\n+\t\tassert(u-\u003einf.info_size);\n+\t\tassert(uf-\u003ebypl + 1);\n+\t}\n+\n+\tif (u-\u003einf.outpos_linear - u-\u003einf.consumed_linear \u003c uf-\u003ebypl + 1)\n+\t\treturn ret;\n+\n+\tobp\t\t\u003d uf-\u003ealt ? uf-\u003ebypl : 0;\n+\tuf-\u003eprecon\t\u003d uf-\u003ealt ? uf-\u003elines : uf-\u003elines + uf-\u003ebypl;\n+\tuf-\u003erecon\t\u003d \u0026uf-\u003elines[obp];\n+\t*ppix\t\t\u003d uf-\u003erecon;\n+\tuf-\u003efilterType\t\u003d uf-\u003ein[(u-\u003einf.consumed_linear++) % u-\u003einf.info_size];\n+\tuf-\u003esp\t\t\u003d u-\u003einf.consumed_linear % u-\u003einf.info_size;\n+\n+\tif (unfilter_scanline(u) !\u003d LWS_SRET_OK) {\n+\t\tret \u003d LWS_SRET_FATAL + 13;\n+\n+\t\tgoto out;\n+\t}\n+\n+\tif (uf-\u003epadded) {\n+\t\tunsigned long x;\n+\n+\t\tfor (x \u003d 0; x \u003c (unsigned long)u-\u003ewidth * (unsigned long)uf-\u003ebpp; x++) {\n+\t\t\tuint8_t bit \u003d (uint8_t)((uf-\u003ein[(uf-\u003eibp) \u003e\u003e 3] \u003e\u003e\n+\t\t\t\t\t\t(7 - ((uf-\u003eibp) \u0026 7))) \u0026 1);\n+\t\t\tuf-\u003eibp++;\n+\n+\t\t\tif (!bit)\n+\t\t\t\tuf-\u003elines[obp \u003e\u003e 3] \u0026\u003d\n+\t\t\t\t\t(uint8_t)(~(1 \u003c\u003c (7 - (obp \u0026 7))));\n+\t\t\telse\n+\t\t\t\tuf-\u003elines[obp \u003e\u003e 3] \u003d (uint8_t)(uf-\u003elines[obp \u003e\u003e 3] |\n+\t\t\t\t\t\t(uint8_t)(1 \u003c\u003c (7 - (obp \u0026 7))));\n+\n+\t\t\tobp++;\n+\t\t}\n+\n+\t\tuf-\u003eibp +\u003d uf-\u003ediff;\n+\t}\n+\n+out:\n+\tuf-\u003ealt ^\u003d 1;\n+\tuf-\u003ey++;\n+\n+\treturn ret;\n+}\n+\n+static lws_upng_format_t\n+determine_format(lws_upng_t* upng) {\n+\tswitch (upng-\u003ecolor_type) {\n+\tcase LWS_UPNG_LUM:\n+\t\tswitch (upng-\u003ecolor_depth) {\n+\t\tcase 1:\n+\t\t\treturn LWS_UPNG_LUMINANCE1;\n+\t\tcase 2:\n+\t\t\treturn LWS_UPNG_LUMINANCE2;\n+\t\tcase 4:\n+\t\t\treturn LWS_UPNG_LUMINANCE4;\n+\t\tcase 8:\n+\t\t\treturn LWS_UPNG_LUMINANCE8;\n+\t\tdefault:\n+\t\t\treturn LWS_UPNG_BADFORMAT;\n+\t\t}\n+\tcase LWS_UPNG_RGB:\n+\t\tswitch (upng-\u003ecolor_depth) {\n+\t\tcase 8:\n+\t\t\treturn LWS_UPNG_RGB8;\n+\t\tcase 16:\n+\t\t\treturn LWS_UPNG_RGB16;\n+\t\tdefault:\n+\t\t\treturn LWS_UPNG_BADFORMAT;\n+\t\t}\n+\tcase LWS_UPNG_LUMA:\n+\t\tswitch (upng-\u003ecolor_depth) {\n+\t\tcase 1:\n+\t\t\treturn LWS_UPNG_LUMINANCE_ALPHA1;\n+\t\tcase 2:\n+\t\t\treturn LWS_UPNG_LUMINANCE_ALPHA2;\n+\t\tcase 4:\n+\t\t\treturn LWS_UPNG_LUMINANCE_ALPHA4;\n+\t\tcase 8:\n+\t\t\treturn LWS_UPNG_LUMINANCE_ALPHA8;\n+\t\tdefault:\n+\t\t\treturn LWS_UPNG_BADFORMAT;\n+\t\t}\n+\tcase LWS_UPNG_RGBA:\n+\t\tswitch (upng-\u003ecolor_depth) {\n+\t\tcase 8:\n+\t\t\treturn LWS_UPNG_RGBA8;\n+\t\tcase 16:\n+\t\t\treturn LWS_UPNG_RGBA16;\n+\t\tdefault:\n+\t\t\treturn LWS_UPNG_BADFORMAT;\n+\t\t}\n+\tdefault:\n+\t\treturn LWS_UPNG_BADFORMAT;\n+\t}\n+}\n+\n+static const uint8_t magic[] \u003d { 137, 80, 78, 71, 13, 10, 26, 10 };\n+\n+static lws_stateful_ret_t\n+lws_upng_decode(lws_upng_t* u, const uint8_t **_pos, size_t *_size)\n+{\n+\tconst uint8_t *pos \u003d _pos ? *_pos : NULL, *end \u003d pos + *_size;\n+\tlws_stateful_ret_t r \u003d LWS_SRET_FATAL + 60;\n+\tsize_t m;\n+\n+\tif (u-\u003eof \u003d\u003d UOF_INSIDE \u0026\u0026 !u-\u003einf.in) {\n+\t\tu-\u003einf.inpos \u003d 0;\n+\t\tu-\u003einf.in \u003d pos;\n+\t\tu-\u003einf.bp \u003d 0;\n+\t\tm \u003d lws_ptr_diff_size_t(end, pos);\n+\t\tif (m \u003e u-\u003echunklen)\n+\t\t\tm \u003d u-\u003echunklen;\n+\t\tu-\u003einf.inlen \u003d m;\n+\t}\n+\n+\twhile (!u-\u003eno_more_input \u0026\u0026\n+\t ((u-\u003eof \u003d\u003d UOF_INSIDE \u0026\u0026 _pos \u003d\u003d NULL) || pos \u003c end)) {\n+\t\tswitch (u-\u003eof) {\n+\t\tcase UOF_MAGIC:\n+\t\t\tif (*pos++ !\u003d magic[u-\u003esctr++])\n+\t\t\t\treturn LWS_SRET_FATAL + 17;\n+\t\t\tif (u-\u003esctr \u003d\u003d sizeof(magic)) {\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_SKIP:\n+\t\t\tpos++;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 4) {\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_TYPE4:\n+\t\t\tu-\u003eacc \u003d (u-\u003eacc \u003c\u003c 8) | *pos++;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 4) {\n+\t\t\t\tif (u-\u003eacc !\u003d LWS_FOURCC('I','H','D','R'))\n+\t\t\t\t\treturn LWS_SRET_FATAL + 18;\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_WIDTH4:\n+\t\t\tu-\u003eacc \u003d (u-\u003eacc \u003c\u003c 8) | *pos++;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 4) {\n+\t\t\t\tu-\u003ewidth \u003d u-\u003eacc;\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_HEIGHT4:\n+\t\t\tu-\u003eacc \u003d (u-\u003eacc \u003c\u003c 8) | *pos++;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 4) {\n+\t\t\t\tu-\u003eheight \u003d u-\u003eacc;\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_CDEPTH:\n+\t\t\tu-\u003ecolor_depth \u003d*pos++;\n+\t\t\tu-\u003eof++;\n+\t\t\tbreak;\n+\n+\t\tcase UOF_CTYPE:\n+\t\t\tu-\u003ecolor_type \u003d *pos++;\n+\t\t\t//lwsl_notice(\u0022w %d, h %d, depth %d, type %d\u005cn\u0022,\n+\t\t\t//\t\tu-\u003ewidth, u-\u003eheight,\n+\t\t\t//\t\tu-\u003ecolor_depth, u-\u003ecolor_type);\n+\t\t\tu-\u003eformat \u003d determine_format(u);\n+\t\t\tif (u-\u003eformat \u003d\u003d LWS_UPNG_BADFORMAT)\n+\t\t\t\treturn LWS_SRET_FATAL + 19;\n+\t\t\tu-\u003eof++;\n+\t\t\tbreak;\n+\n+\t\tcase UOF_ONLY_ZERO3:\n+\t\t\tif (*pos++)\n+\t\t\t\treturn LWS_SRET_FATAL + 20;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 3) {\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_SKIP4:\n+\t\t\tpos++;\n+\t\t\tif (++u-\u003esctr !\u003d 4)\n+\t\t\t\tbreak;\n+\n+\t\t\t/* takes us to +33 */\n+\n+\t\t\tmemset(\u0026u-\u003einf, 0, sizeof(u-\u003einf));\n+\n+\t\t\t/* 32KB gz sliding window */\n+\t\t\tu-\u003einf.info_size \u003d 32768 + 512;\n+\t\t\tu-\u003eu.bpp\t \u003d lws_upng_get_bpp(u);\n+\t\t\tif (!u-\u003eu.bpp)\n+\t\t\t\treturn LWS_SRET_FATAL + 14;\n+\n+\t\t\tu-\u003eu.y\t\t\u003d 0;\n+\t\t\tu-\u003eu.ibp\t\u003d 0;\n+\t\t\tu-\u003eu.bypp\t\u003d (u-\u003eu.bpp + 7) / 8;\n+\t\t\tu-\u003einf.bypl \u003d u-\u003eu.bypl\t\u003d u-\u003ewidth * u-\u003eu.bypp;\n+\n+\t\t\tu-\u003einf.outlen\t\u003d u-\u003einf.info_size;\n+\t\t\tu-\u003einf.outpos\t\u003d 0;\n+\t\t\tu-\u003einf.state\t\u003d UPNS_ID_BL_GB_DONE;\n+\t\t\tu-\u003einf.upng\t\u003d u;\n+\n+\t\t\tu-\u003eu.alt\t\u003d 0; /* which of the two lines to write to */\n+\t\t\tu-\u003eu.padded\t\u003d u-\u003eu.bpp \u003c 8 \u0026\u0026\n+\t\t\t\t\t u-\u003ewidth * u-\u003eu.bpp !\u003d\n+\t\t\t\t\t ((u-\u003ewidth * u-\u003eu.bpp + 7) / 8) * 8;\n+\t\t\tu-\u003eu.diff\t\u003d (((u-\u003ewidth * u-\u003eu.bpp + 7) / 8) * 8) -\n+\t\t\t\t\t\t(u-\u003ewidth * u-\u003eu.bpp);\n+\n+\t\t\tu-\u003eof++;\n+\t\t\tu-\u003esctr \u003d 0;\n+\t\t\tbreak;\n+\n+\t\tcase UOF_CHUNK_LEN:\n+\t\t\tif (!u-\u003einf.out) {\n+\t\t\t\tsize_t ims \u003d (u-\u003eu.bypl * 2) + u-\u003einf.info_size;\n+\n+\t\t\t\tif (u-\u003ehold_at_metadata)\n+\t\t\t\t\treturn LWS_SRET_AWAIT_RETRY;\n+\n+\t\t\t\tu-\u003einf.out \u003d (uint8_t *)lws_malloc(ims, __func__);\n+\t\t\t\tif (!u-\u003einf.out) {\n+\t\t\t\t\tlwsl_notice(\u0022%s: inf malloc %u OOM\u005cn\u0022,\n+\t\t\t\t\t\t__func__, (unsigned int)ims);\n+\n+\t\t\t\t\treturn LWS_SRET_YIELD;\n+\t\t\t\t}\n+\t\t\t\tu-\u003eu.lines \u003d u-\u003einf.out + u-\u003einf.info_size;\n+\t\t\t\tu-\u003eu.in\t\t\u003d u-\u003einf.out;\n+\t\t\t}\n+\t\t\tu-\u003echunklen \u003d (u-\u003echunklen \u003c\u003c 8) | *pos++;\n+\t\t\tif (++u-\u003esctr \u003d\u003d 4) {\n+\t\t\t\tu-\u003eof++;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_CHUNK_TYPE:\n+\t\t\tu-\u003ectype \u003d (u-\u003ectype \u003c\u003c 8) | *pos++;\n+\t\t\tif (++u-\u003esctr !\u003d 4)\n+\t\t\t\tbreak;\n+\t\t\tu-\u003esctr \u003d 0;\n+\t\t\tif (u-\u003ectype \u003d\u003d LWS_FOURCC('I','E','N','D')) {\n+\t\t\t\tu-\u003eno_more_input \u003d 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (u-\u003ectype !\u003d LWS_FOURCC('I','D','A','T')) {\n+\t\t\t\tif (!(u-\u003ectype \u0026 (32 \u003c\u003c 24)))\n+\t\t\t\t\t/* says it is critical... */\n+\t\t\t\t\t return LWS_SRET_FATAL + 27;\n+\n+\t\t\t\tu-\u003echunklen +\u003d 4; /* chunk-end CRC */\n+\n+\t\t\t\t/* noncritical, skip */\n+\t\t\t\tu-\u003eof \u003d UOF_SKIP_CHUNK_LEN;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (u-\u003echunklen \u003c 2)\n+\t\t\t\treturn LWS_SRET_FATAL + 31;\n+\n+\t\t\t/* it's a usable IDAT */\n+\n+\t\t\tif (!u-\u003einf.subsequent)\n+\t\t\t\tu-\u003einf.inpos \u003d 2;\n+\t\t\telse\n+\t\t\t\tu-\u003einf.inpos \u003d 0;\n+\n+\t\t\tm \u003d lws_ptr_diff_size_t(end, pos);\n+\t\t\tif (m \u003e u-\u003echunklen)\n+\t\t\t\tm \u003d u-\u003echunklen;\n+\n+\t\t\tu-\u003einf.in \u003d pos;\n+\t\t\tu-\u003einf.inlen \u003d m;\n+\t\t\tu-\u003einf.bp \u003d 0;\n+\t\t\tu-\u003eof++;\n+\t\t\tbreak;\n+\n+\t\tcase UOF_INSIDE:\n+\t\t\tif (!u-\u003einf.subsequent) {\n+\n+\t\t\t\tswitch (u-\u003esctr) {\n+\t\t\t\tcase 0:\n+\t\t\t\t\tu-\u003eacc \u003d (uint32_t)((*pos++) \u003c\u003c 8);\n+\t\t\t\t\tu-\u003esctr++;\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\tcase 1:\n+\t\t\t\t\tu-\u003eacc |\u003d *pos++;\n+\n+\t\t\t\t\tif (u-\u003eacc % 31)\n+\t\t\t\t\t\treturn LWS_SRET_FATAL + 31;\n+\n+\t\t\t\t\tif (((u-\u003eacc \u003e\u003e 8) \u0026 15) !\u003d 8 ||\n+\t\t\t\t\t ((u-\u003eacc \u003e\u003e 12) \u0026 15) \u003e 7)\n+\t\t\t\t\t\treturn LWS_SRET_FATAL + 31;\n+\n+\t\t\t\t\tif ((u-\u003eacc \u003e\u003e 5) \u0026 1)\n+\t\t\t\t\t\treturn LWS_SRET_FATAL + 31;\n+\n+\t\t\t\t\tu-\u003einf.subsequent \u003d 1;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tr \u003d uz_inflate_data(\u0026u-\u003einf);\n+\t\t\tswitch (r) {\n+\n+\t\t\tcase LWS_SRET_WANT_INPUT:\n+\n+\t\t\t\t/* indicate no existing to drain */\n+\t\t\t\tu-\u003einf.in \u003d NULL;\n+\n+\t\t\t\tpos +\u003d u-\u003einf.inlen - u-\u003einf.inpos;\n+\t\t\t\tu-\u003echunklen \u003d u-\u003echunklen -\n+\t\t\t\t\t\t(unsigned int)(u-\u003einf.inlen);\n+\n+\t\t\t\tif (!u-\u003echunklen) {\n+\t\t\t\t\tu-\u003echunklen \u003d 4; /* skip the 32-bit CRC */\n+\n+\t\t\t\t\tu-\u003eof \u003d UOF_SKIP_CHUNK_LEN;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tif (pos !\u003d end) {\n+\t\t\t\t\tu-\u003einf.inpos \u003d 0;\n+\t\t\t\t\tu-\u003einf.in \u003d pos;\n+\t\t\t\t\tm \u003d lws_ptr_diff_size_t(end, pos);\n+\t\t\t\t\tif (m \u003e u-\u003echunklen)\n+\t\t\t\t\t\tm \u003d u-\u003echunklen;\n+\t\t\t\t\tu-\u003einf.inlen \u003d m;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t\tgoto bail;\n+\t\t\tdefault:\n+\t\t\t\tgoto bail;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase UOF_SKIP_CHUNK_LEN:\n+\t\t\tpos++;\n+\t\t\tif (!--u-\u003echunklen) {\n+\t\t\t\tu-\u003eof \u003d UOF_CHUNK_LEN;\n+\t\t\t\tu-\u003esctr \u003d 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tr \u003d LWS_SRET_OK;\n+\tif (!u-\u003eno_more_input)\n+\t\tr \u003d LWS_SRET_WANT_INPUT;\n+\n+bail:\n+\t*_pos \u003d pos;\n+\t*_size \u003d lws_ptr_diff_size_t(end, pos);\n+\n+\treturn r;\n+}\n+\n+lws_upng_t *\n+lws_upng_new(void)\n+{\n+\tlws_upng_t* upng;\n+\n+\tupng \u003d (lws_upng_t*)lws_zalloc(sizeof(lws_upng_t), __func__);\n+\tif (upng \u003d\u003d NULL)\n+\t\treturn NULL;\n+\n+\tupng-\u003ecolor_type \u003d LWS_UPNG_RGBA;\n+\tupng-\u003ecolor_depth \u003d 8;\n+\tupng-\u003eformat \u003d LWS_UPNG_RGBA8;\n+\n+\tupng-\u003eof \u003d UOF_MAGIC;\n+\tupng-\u003esctr \u003d 0;\n+\n+\tupng-\u003einf.upng \u003d upng;\n+\n+\treturn upng;\n+}\n+\n+void\n+lws_upng_free(lws_upng_t** upng)\n+{\n+\tif ((*upng)-\u003einf.out)\n+\t\tlws_free_set_NULL((*upng)-\u003einf.out);\n+\n+\tlws_free_set_NULL(*upng);\n+}\n+\n+\n+unsigned int\n+lws_upng_get_width(const lws_upng_t* upng)\n+{\n+\treturn upng-\u003ewidth;\n+}\n+\n+unsigned int\n+lws_upng_get_height(const lws_upng_t* upng)\n+{\n+\treturn upng-\u003eheight;\n+}\n+\n+unsigned int\n+lws_upng_get_bpp(const lws_upng_t* upng)\n+{\n+\treturn lws_upng_get_bitdepth(upng) *\n+\t\t\tlws_upng_get_components(upng);\n+}\n+\n+unsigned int\n+lws_upng_get_components(const lws_upng_t* upng)\n+{\n+\tswitch (upng-\u003ecolor_type) {\n+\tcase LWS_UPNG_LUM:\n+\t\treturn 1;\n+\tcase LWS_UPNG_RGB:\n+\t\treturn 3;\n+\tcase LWS_UPNG_LUMA:\n+\t\treturn 2;\n+\tcase LWS_UPNG_RGBA:\n+\t\treturn 4;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+unsigned int\n+lws_upng_get_bitdepth(const lws_upng_t* upng)\n+{\n+\treturn upng-\u003ecolor_depth;\n+}\n+\n+unsigned int\n+lws_upng_get_pixelsize(const lws_upng_t* upng)\n+{\n+\tunsigned bits \u003d lws_upng_get_bitdepth(upng) *\n+\t\t\t\tlws_upng_get_components(upng);\n+\n+\tbits +\u003d bits % 8;\n+\n+\treturn bits;\n+}\n+\n+lws_upng_format_t\n+lws_upng_get_format(const lws_upng_t *upng)\n+{\n+\treturn upng-\u003eformat;\n+}\ndiff --git a/minimal-examples-lowlevel/api-tests/api-test-upng/CMakeLists.txt b/minimal-examples-lowlevel/api-tests/api-test-upng/CMakeLists.txt\nnew file mode 100644\nindex 0000000..547d3a2\n--- /dev/null\n+++ b/minimal-examples-lowlevel/api-tests/api-test-upng/CMakeLists.txt\n@@ -0,0 +1,25 @@\n+project(lws-api-test-upng C)\n+cmake_minimum_required(VERSION 2.8.12)\n+find_package(libwebsockets CONFIG REQUIRED)\n+list(APPEND CMAKE_MODULE_PATH ${LWS_CMAKE_DIR})\n+include(CheckCSourceCompiles)\n+include(LwsCheckRequirements)\n+\n+set(SAMP lws-api-test-upng)\n+set(SRCS main.c )\n+\n+set(requirements 1)\n+require_lws_config(LWS_WITH_UPNG 1 requirements)\n+require_lws_config(LWS_WITH_CLIENT 1 requirements)\n+\n+if (requirements)\n+\n+\tadd_executable(${SAMP} ${SRCS})\n+\n+\tif (websockets_shared)\n+\t\ttarget_link_libraries(${SAMP} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS})\n+\t\tadd_dependencies(${SAMP} websockets_shared)\n+\telse()\n+\t\ttarget_link_libraries(${SAMP} websockets ${LIBWEBSOCKETS_DEP_LIBS})\n+\tendif()\n+endif()\ndiff --git a/minimal-examples-lowlevel/api-tests/api-test-upng/main.c b/minimal-examples-lowlevel/api-tests/api-test-upng/main.c\nnew file mode 100644\nindex 0000000..31791e2\n--- /dev/null\n+++ b/minimal-examples-lowlevel/api-tests/api-test-upng/main.c\n@@ -0,0 +1,138 @@\n+/*\n+ * lws-api-test-upng\n+ *\n+ * Written in 2010-2022 by Andy Green \u003candy@warmcat.com\u003e\n+ *\n+ * This file is made available under the Creative Commons CC0 1.0\n+ * Universal Public Domain Dedication.\n+ */\n+\n+#include \u003clibwebsockets.h\u003e\n+#include \u003cstdlib.h\u003e\n+#include \u003cstdio.h\u003e\n+#include \u003cfcntl.h\u003e\n+#include \u003cerrno.h\u003e\n+\n+int fdin \u003d 0, fdout \u003d 1;\n+\n+int\n+main(int argc, const char **argv)\n+{\n+\tint result \u003d 0, logs \u003d LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;\n+\tlws_stateful_ret_t r \u003d LWS_SRET_WANT_INPUT;\n+\tconst char *p;\n+\tlws_upng_t *u;\n+\n+\tif ((p \u003d lws_cmdline_option(argc, argv, \u0022-d\u0022)))\n+\t\tlogs \u003d atoi(p);\n+\n+\tlws_set_log_level(logs, NULL);\n+\tlwsl_user(\u0022LWS UPNG test tool\u005cn\u0022);\n+\n+\tif ((p \u003d lws_cmdline_option(argc, argv, \u0022--stdin\u0022))) {\n+\t\tfdin \u003d open(p, LWS_O_RDONLY, 0);\n+\t\tif (fdin \u003c 0) {\n+\t\t\tresult \u003d 1;\n+\t\t\tlwsl_err(\u0022%s: unable to open stdin file\u005cn\u0022, __func__);\n+\t\t\tgoto bail;\n+\t\t}\n+\t}\n+\n+\tif ((p \u003d lws_cmdline_option(argc, argv, \u0022--stdout\u0022))) {\n+\t\tfdout \u003d open(p, LWS_O_WRONLY | LWS_O_CREAT | LWS_O_TRUNC, 0600);\n+\t\tif (fdout \u003c 0) {\n+\t\t\tresult \u003d 1;\n+\t\t\tlwsl_err(\u0022%s: unable to open stdout file\u005cn\u0022, __func__);\n+\t\t\tgoto bail;\n+\t\t}\n+\t}\n+\n+\tif (!fdin) {\n+\t\tstruct timeval\ttimeout;\n+\t\tfd_set\tfds;\n+\n+\t\tFD_ZERO(\u0026fds);\n+\t\tFD_SET(0, \u0026fds);\n+\n+\t\ttimeout.tv_sec \u003d 0;\n+\t\ttimeout.tv_usec \u003d 1000;\n+\n+\t\tif (select(fdin + 1, \u0026fds, NULL, NULL, \u0026timeout) \u003c 0 ||\n+\t\t !FD_ISSET(0, \u0026fds)) {\n+\t\t\tresult \u003d 1;\n+\t\t\tlwsl_err(\u0022%s: pass PNG \u0022\n+\t\t\t\t \u0022on stdin or use --stdin\u005cn\u0022, __func__);\n+\t\t\tgoto bail;\n+\t\t}\n+\t}\n+\n+\n+\tu \u003d lws_upng_new();\n+\tif (!u) {\n+\t\tlwsl_err(\u0022%s: failed to allocate\u005cn\u0022, __func__);\n+\t\tgoto bail;\n+\t}\n+\n+\tdo {\n+\t\tconst uint8_t *pix;\n+\t\tuint8_t ib[256];\n+\t\tconst uint8_t *pib \u003d (const uint8_t *)ib;\n+\t\tssize_t s, os;\n+\t\tsize_t ps;\n+\n+\t\tif (r \u003d\u003d LWS_SRET_WANT_INPUT) {\n+\t\t\ts \u003d read(fdin, ib, sizeof(ib));\n+\n+\t\t\tif (s \u003c\u003d 0) {\n+\t\t\t\tlwsl_err(\u0022%s: failed to read: %d\u005cn\u0022, __func__, errno);\n+\t\t\t\tgoto bail1;\n+\t\t\t}\n+\n+\t\t\tps \u003d (size_t)s;\n+\n+\t\t\t// lwsl_notice(\u0022%s: fetched %d\u005cn\u0022, __func__, (int)s);\n+\t\t}\n+\n+\t\tdo {\n+\t\t\tr \u003d lws_upng_emit_next_line(u, \u0026pix, \u0026pib, \u0026ps, 0);\n+\t\t\tif (r \u003d\u003d LWS_SRET_WANT_INPUT)\n+\t\t\t\tbreak;\n+\n+\t\t\tif (r \u003e LWS_SRET_FATAL) {\n+\t\t\t\tlwsl_err(\u0022%s: emit returned FATAL %d\u005cn\u0022, __func__, r \u00260xff);\n+\t\t\t\tresult \u003d 1;\n+\t\t\t\tgoto bail1;\n+\t\t\t}\n+\n+\t\t\tif (!pix)\n+\t\t\t\tgoto bail1;\n+\n+\t\t\tos \u003d (ssize_t)(lws_upng_get_width(u) * (lws_upng_get_pixelsize(u) / 8));\n+\n+\t\t\tif (write(fdout, pix, \n+#if defined(WIN32)\n+\t\t\t\t\t\t(unsigned int)\n+#endif\n+\t\t\t\t\t\t(size_t)os) \u003c os) {\n+\t\t\t\tlwsl_err(\u0022%s: write %d failed %d\u005cn\u0022, __func__, (int)os, errno);\n+\t\t\t\tgoto bail1;\n+\t\t\t}\n+\n+\t\t\tlwsl_notice(\u0022%s: wrote %d\u005cn\u0022, __func__, (int)os);\n+\t\t} while (ps);\n+\n+\t} while (1);\n+\n+bail1:\n+\tif (fdin)\n+\t\tclose(fdin);\n+\tif (fdout !\u003d 1)\n+\t\tclose(fdout);\n+\n+\tlws_upng_free(\u0026u);\n+\n+bail:\n+\tlwsl_user(\u0022Completed: %s\u005cn\u0022, result ? \u0022FAIL\u0022 : \u0022PASS\u0022);\n+\n+\treturn result;\n+}\n","s":{"c":1761481269,"u": 7245}} ],"g": 12993,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}