refactor: remove commits from C files (#372)

Drew Smirnoff and Lea created

Co-authored-by: Lea <lea@floatpane.com>

Change summary

clib/base64wrap.h      |   4 
clib/entity.c          |  28 --
clib/entity.h          |  31 --
clib/htmlconv.h        |  26 -
clib/imgconv.h         |  18 
clib/md4c-html.c       |  88 -----
clib/md4c-html.h       |  49 ---
clib/md4c.c            | 337 +++---------------------
clib/md4c.h            | 299 +++------------------
clib/stb_image.h       | 599 +++----------------------------------------
clib/stb_image_write.h | 470 ++++++---------------------------
11 files changed, 264 insertions(+), 1,685 deletions(-)

Detailed changes

clib/base64wrap.h 🔗

@@ -3,10 +3,6 @@
 
 #include <stddef.h>
 
-// wrap_base64 wraps base64-encoded data at 76 characters per line with \r\n
-// separators, as required by MIME (RFC 2045). The caller must free the returned
-// pointer with free().
-// Returns NULL if allocation fails.
 char* wrap_base64(const char* data, size_t len, size_t* out_len);
 
 #endif

clib/entity.c 🔗

@@ -1,33 +1,6 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #include "entity.h"
 #include <string.h>
 
-
-/* Generated by scripts/build_enity_map.py. */
 static const ENTITY ENTITY_MAP[] = {
     { "&AElig;", { 198, 0 } },
     { "&AMP;", { 38, 0 } },
@@ -2156,7 +2129,6 @@ static const ENTITY ENTITY_MAP[] = {
     { "&zwnj;", { 8204, 0 } }
 };
 
-
 typedef struct ENTITY_KEY_tag ENTITY_KEY;
 struct ENTITY_KEY_tag {
     const char* name;

clib/entity.h 🔗

@@ -1,36 +1,8 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #ifndef MD4C_ENTITY_H
 #define MD4C_ENTITY_H
 
 #include <stdlib.h>
 
-
-/* Most entities are formed by single Unicode codepoint, few by two codepoints.
- * Single-codepoint entities have codepoints[1] set to zero. */
 typedef struct ENTITY_tag ENTITY;
 struct ENTITY_tag {
     const char* name;
@@ -39,5 +11,4 @@ struct ENTITY_tag {
 
 const ENTITY* entity_lookup(const char* name, size_t name_size);
 
-
-#endif  /* MD4C_ENTITY_H */
+#endif

clib/htmlconv.h 🔗

@@ -3,25 +3,22 @@
 
 #include <stddef.h>
 
-// Element types found during HTML parsing.
 enum {
-    HELEM_TEXT       = 0,  // Plain text segment
-    HELEM_H1         = 1,  // <h1> text
-    HELEM_H2         = 2,  // <h2> text
-    HELEM_LINK       = 3,  // <a href="...">text</a>
-    HELEM_IMAGE      = 4,  // <img src="..." alt="...">
-    HELEM_BLOCKQUOTE = 5,  // <blockquote> content (with optional cite/prev)
+    HELEM_TEXT       = 0,
+    HELEM_H1         = 1,
+    HELEM_H2         = 2,
+    HELEM_LINK       = 3,
+    HELEM_IMAGE      = 4,
+    HELEM_BLOCKQUOTE = 5,
 };
 
-// HTMLElement represents a parsed element from the HTML document.
 typedef struct {
     int type;
-    char* text;     // Text content (h1/h2 text, link text, blockquote content)
-    char* attr1;    // href for links, src for images, cite for blockquotes
-    char* attr2;    // alt for images, prev_text for blockquotes (On...wrote:)
+    char* text;
+    char* attr1;
+    char* attr2;
 } HTMLElement;
 
-// HTMLConvertResult holds the output of html_to_elements.
 typedef struct {
     HTMLElement* elements;
     int count;
@@ -29,13 +26,8 @@ typedef struct {
     int ok;
 } HTMLConvertResult;
 
-// html_to_elements parses an HTML string and returns an array of structured
-// elements. The caller processes these elements to apply terminal styling.
-// style/script content is stripped. Block elements get proper spacing.
-// Returns a result with ok=1 on success. Caller must free with free_html_result.
 HTMLConvertResult html_to_elements(const char* html, size_t len);
 
-// free_html_result frees all memory in an HTMLConvertResult.
 void free_html_result(HTMLConvertResult* r);
 
 #endif

clib/imgconv.h 🔗

@@ -3,26 +3,18 @@
 
 #include <stddef.h>
 
-// ImageResult holds the output of decode_to_png.
 typedef struct {
-    unsigned char* png_data; // PNG-encoded bytes (caller must free)
-    size_t png_len;          // Length of png_data
-    int width;               // Image width in pixels
-    int height;              // Image height in pixels
-    int ok;                  // 1 on success, 0 on failure
+    unsigned char* png_data;
+    size_t png_len;
+    int width;
+    int height;
+    int ok;
 } ImageResult;
 
-// decode_to_png takes raw image bytes (JPEG, PNG, BMP, GIF, etc.),
-// decodes them, and re-encodes as PNG. Supports any format that
-// stb_image can decode.
 ImageResult decode_to_png(const unsigned char* data, size_t len);
 
-// free_image_result frees the PNG data inside an ImageResult.
 void free_image_result(ImageResult* r);
 
-// image_dimensions returns only the width and height of an image without
-// fully decoding pixel data. Faster than decode_to_png when you only need
-// dimensions. Returns 1 on success, 0 on failure.
 int image_dimensions(const unsigned char* data, size_t len, int* width, int* height);
 
 #endif

clib/md4c-html.c 🔗

@@ -1,37 +1,11 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #include <stdio.h>
 #include <string.h>
 
 #include "md4c-html.h"
 #include "entity.h"
 
-
 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L
-    /* C89/90 or old compilers in general may not understand "inline". */
+
     #if defined __GNUC__
         #define inline __inline__
     #elif defined _MSC_VER
@@ -45,8 +19,6 @@
     #define snprintf _snprintf
 #endif
 
-
-
 typedef struct MD_HTML_tag MD_HTML;
 struct MD_HTML_tag {
     void (*process_output)(const MD_CHAR*, MD_SIZE, void*);
@@ -59,40 +31,30 @@ struct MD_HTML_tag {
 #define NEED_HTML_ESC_FLAG   0x1
 #define NEED_URL_ESC_FLAG    0x2
 
-
-/*****************************************
- ***  HTML rendering helper functions  ***
- *****************************************/
-
 #define ISDIGIT(ch)     ('0' <= (ch) && (ch) <= '9')
 #define ISLOWER(ch)     ('a' <= (ch) && (ch) <= 'z')
 #define ISUPPER(ch)     ('A' <= (ch) && (ch) <= 'Z')
 #define ISALNUM(ch)     (ISLOWER(ch) || ISUPPER(ch) || ISDIGIT(ch))
 
-
 static inline void
 render_verbatim(MD_HTML* r, const MD_CHAR* text, MD_SIZE size)
 {
     r->process_output(text, size, r->userdata);
 }
 
-/* Keep this as a macro. Most compiler should then be smart enough to replace
- * the strlen() call with a compile-time constant if the string is a C literal. */
 #define RENDER_VERBATIM(r, verbatim)                                    \
         render_verbatim((r), (verbatim), (MD_SIZE) (strlen(verbatim)))
 
-
 static void
 render_html_escaped(MD_HTML* r, const MD_CHAR* data, MD_SIZE size)
 {
     MD_OFFSET beg = 0;
     MD_OFFSET off = 0;
 
-    /* Some characters need to be escaped in normal HTML text. */
     #define NEED_HTML_ESC(ch)   (r->escape_map[(unsigned char)(ch)] & NEED_HTML_ESC_FLAG)
 
     while(1) {
-        /* Optimization: Use some loop unrolling. */
+
         while(off + 3 < size  &&  !NEED_HTML_ESC(data[off+0])  &&  !NEED_HTML_ESC(data[off+1])
                               &&  !NEED_HTML_ESC(data[off+2])  &&  !NEED_HTML_ESC(data[off+3]))
             off += 4;
@@ -124,7 +86,6 @@ render_url_escaped(MD_HTML* r, const MD_CHAR* data, MD_SIZE size)
     MD_OFFSET beg = 0;
     MD_OFFSET off = 0;
 
-    /* Some characters need to be escaped in URL attributes. */
     #define NEED_URL_ESC(ch)    (r->escape_map[(unsigned char)(ch)] & NEED_URL_ESC_FLAG)
 
     while(1) {
@@ -200,8 +161,6 @@ render_utf8_codepoint(MD_HTML* r, unsigned codepoint,
         fn_append(r, utf8_replacement_char, 3);
 }
 
-/* Translate entity to its UTF-8 equivalent, or output the verbatim one
- * if such entity is unknown (or if the translation is disabled). */
 static void
 render_entity(MD_HTML* r, const MD_CHAR* text, MD_SIZE size,
               void (*fn_append)(MD_HTML*, const MD_CHAR*, MD_SIZE))
@@ -211,17 +170,16 @@ render_entity(MD_HTML* r, const MD_CHAR* text, MD_SIZE size,
         return;
     }
 
-    /* We assume UTF-8 output is what is desired. */
     if(size > 3 && text[1] == '#') {
         unsigned codepoint = 0;
 
         if(text[2] == 'x' || text[2] == 'X') {
-            /* Hexadecimal entity (e.g. "&#x1234abcd;")). */
+
             MD_SIZE i;
             for(i = 3; i < size-1; i++)
                 codepoint = 16 * codepoint + hex_val(text[i]);
         } else {
-            /* Decimal entity (e.g. "&1234;") */
+
             MD_SIZE i;
             for(i = 2; i < size-1; i++)
                 codepoint = 10 * codepoint + (text[i] - '0');
@@ -230,7 +188,7 @@ render_entity(MD_HTML* r, const MD_CHAR* text, MD_SIZE size,
         render_utf8_codepoint(r, codepoint, fn_append);
         return;
     } else {
-        /* Named entity (e.g. "&nbsp;"). */
+
         const ENTITY* ent;
 
         ent = entity_lookup(text, size);
@@ -265,7 +223,6 @@ render_attribute(MD_HTML* r, const MD_ATTRIBUTE* attr,
     }
 }
 
-
 static void
 render_open_ol_block(MD_HTML* r, const MD_BLOCK_OL_DETAIL* det)
 {
@@ -299,7 +256,6 @@ render_open_code_block(MD_HTML* r, const MD_BLOCK_CODE_DETAIL* det)
 {
     RENDER_VERBATIM(r, "<pre><code");
 
-    /* If known, output the HTML 5 attribute class="language-LANGNAME". */
     if(det->lang.text != NULL) {
         RENDER_VERBATIM(r, " class=\"language-");
         render_attribute(r, &det->lang, render_html_escaped);
@@ -366,11 +322,6 @@ render_open_wikilink_span(MD_HTML* r, const MD_SPAN_WIKILINK_DETAIL* det)
     RENDER_VERBATIM(r, "\">");
 }
 
-
-/**************************************
- ***  HTML renderer implementation  ***
- **************************************/
-
 static int
 enter_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata)
 {
@@ -378,7 +329,7 @@ enter_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata)
     MD_HTML* r = (MD_HTML*) userdata;
 
     switch(type) {
-        case MD_BLOCK_DOC:      /* noop */ break;
+        case MD_BLOCK_DOC:       break;
         case MD_BLOCK_QUOTE:    RENDER_VERBATIM(r, "<blockquote>\n"); break;
         case MD_BLOCK_UL:       RENDER_VERBATIM(r, "<ul>\n"); break;
         case MD_BLOCK_OL:       render_open_ol_block(r, (const MD_BLOCK_OL_DETAIL*)detail); break;
@@ -386,7 +337,7 @@ enter_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata)
         case MD_BLOCK_HR:       RENDER_VERBATIM(r, (r->flags & MD_HTML_FLAG_XHTML) ? "<hr />\n" : "<hr>\n"); break;
         case MD_BLOCK_H:        RENDER_VERBATIM(r, head[((MD_BLOCK_H_DETAIL*)detail)->level - 1]); break;
         case MD_BLOCK_CODE:     render_open_code_block(r, (const MD_BLOCK_CODE_DETAIL*) detail); break;
-        case MD_BLOCK_HTML:     /* noop */ break;
+        case MD_BLOCK_HTML:      break;
         case MD_BLOCK_P:        RENDER_VERBATIM(r, "<p>"); break;
         case MD_BLOCK_TABLE:    RENDER_VERBATIM(r, "<table>\n"); break;
         case MD_BLOCK_THEAD:    RENDER_VERBATIM(r, "<thead>\n"); break;
@@ -406,15 +357,15 @@ leave_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata)
     MD_HTML* r = (MD_HTML*) userdata;
 
     switch(type) {
-        case MD_BLOCK_DOC:      /*noop*/ break;
+        case MD_BLOCK_DOC:       break;
         case MD_BLOCK_QUOTE:    RENDER_VERBATIM(r, "</blockquote>\n"); break;
         case MD_BLOCK_UL:       RENDER_VERBATIM(r, "</ul>\n"); break;
         case MD_BLOCK_OL:       RENDER_VERBATIM(r, "</ol>\n"); break;
         case MD_BLOCK_LI:       RENDER_VERBATIM(r, "</li>\n"); break;
-        case MD_BLOCK_HR:       /*noop*/ break;
+        case MD_BLOCK_HR:        break;
         case MD_BLOCK_H:        RENDER_VERBATIM(r, head[((MD_BLOCK_H_DETAIL*)detail)->level - 1]); break;
         case MD_BLOCK_CODE:     RENDER_VERBATIM(r, "</code></pre>\n"); break;
-        case MD_BLOCK_HTML:     /* noop */ break;
+        case MD_BLOCK_HTML:      break;
         case MD_BLOCK_P:        RENDER_VERBATIM(r, "</p>\n"); break;
         case MD_BLOCK_TABLE:    RENDER_VERBATIM(r, "</table>\n"); break;
         case MD_BLOCK_THEAD:    RENDER_VERBATIM(r, "</thead>\n"); break;
@@ -433,20 +384,6 @@ enter_span_callback(MD_SPANTYPE type, void* detail, void* userdata)
     MD_HTML* r = (MD_HTML*) userdata;
     int inside_img = (r->image_nesting_level > 0);
 
-    /* We are inside a Markdown image label. Markdown allows to use any emphasis
-     * and other rich contents in that context similarly as in any link label.
-     *
-     * However, unlike in the case of links (where that contents becomescontents
-     * of the <a>...</a> tag), in the case of images the contents is supposed to
-     * fall into the attribute alt: <img alt="...">.
-     *
-     * In that context we naturally cannot output nested HTML tags. So lets
-     * suppress them and only output the plain text (i.e. what falls into text()
-     * callback).
-     *
-     * CommonMark specification declares this a recommended practice for HTML
-     * output.
-     */
     if(type == MD_SPAN_IMG)
         r->image_nesting_level++;
     if(inside_img)
@@ -486,7 +423,7 @@ leave_span_callback(MD_SPANTYPE type, void* detail, void* userdata)
         case MD_SPAN_IMG:               render_close_img_span(r, (MD_SPAN_IMG_DETAIL*) detail); break;
         case MD_SPAN_CODE:              RENDER_VERBATIM(r, "</code>"); break;
         case MD_SPAN_DEL:               RENDER_VERBATIM(r, "</del>"); break;
-        case MD_SPAN_LATEXMATH:         /*fall through*/
+        case MD_SPAN_LATEXMATH:
         case MD_SPAN_LATEXMATH_DISPLAY: RENDER_VERBATIM(r, "</x-equation>"); break;
         case MD_SPAN_WIKILINK:          RENDER_VERBATIM(r, "</x-wikilink>"); break;
     }
@@ -542,7 +479,6 @@ md_html(const MD_CHAR* input, MD_SIZE input_size,
         NULL
     };
 
-    /* Build map of characters which need escaping. */
     for(i = 0; i < 256; i++) {
         unsigned char ch = (unsigned char) i;
 
@@ -553,7 +489,6 @@ md_html(const MD_CHAR* input, MD_SIZE input_size,
             render.escape_map[i] |= NEED_URL_ESC_FLAG;
     }
 
-    /* Consider skipping UTF-8 byte order mark (BOM). */
     if(renderer_flags & MD_HTML_FLAG_SKIP_UTF8_BOM  &&  sizeof(MD_CHAR) == 1) {
         static const MD_CHAR bom[3] = { (char)0xef, (char)0xbb, (char)0xbf };
         if(input_size >= sizeof(bom)  &&  memcmp(input, bom, sizeof(bom)) == 0) {
@@ -564,4 +499,3 @@ md_html(const MD_CHAR* input, MD_SIZE input_size,
 
     return md_parse(input, input_size, &parser, (void*) &render);
 }
-

clib/md4c-html.h 🔗

@@ -1,28 +1,3 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #ifndef MD4C_HTML_H
 #define MD4C_HTML_H
 
@@ -32,37 +7,17 @@
     extern "C" {
 #endif
 
-
-/* If set, debug output from md_parse() is sent to stderr. */
 #define MD_HTML_FLAG_DEBUG                  0x0001
 #define MD_HTML_FLAG_VERBATIM_ENTITIES      0x0002
 #define MD_HTML_FLAG_SKIP_UTF8_BOM          0x0004
 #define MD_HTML_FLAG_XHTML                  0x0008
 
-
-/* Render Markdown into HTML.
- *
- * Note only contents of <body> tag is generated. Caller must generate
- * HTML header/footer manually before/after calling md_html().
- *
- * Params input and input_size specify the Markdown input.
- * Callback process_output() gets called with chunks of HTML output.
- * (Typical implementation may just output the bytes to a file or append to
- * some buffer).
- * Param userdata is just propagated back to process_output() callback.
- * Param parser_flags are flags from md4c.h propagated to md_parse().
- * Param render_flags is bitmask of MD_HTML_FLAG_xxxx.
- *
- * Returns -1 on error (if md_parse() fails.)
- * Returns 0 on success.
- */
 int md_html(const MD_CHAR* input, MD_SIZE input_size,
             void (*process_output)(const MD_CHAR*, MD_SIZE, void*),
             void* userdata, unsigned parser_flags, unsigned renderer_flags);
 
-
 #ifdef __cplusplus
-    }  /* extern "C" { */
+    }
 #endif
 
-#endif  /* MD4C_HTML_H */
+#endif

clib/md4c.c 🔗

@@ -1,28 +1,3 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #include "md4c.h"
 
 #include <limits.h>
@@ -31,13 +6,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-
-/*****************************
- ***  Miscellaneous Stuff  ***
- *****************************/
-
 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L
-    /* C89/90 or old compilers in general may not understand "inline". */
+
     #if defined __GNUC__
         #define inline __inline__
     #elif defined _MSC_VER
@@ -47,12 +17,10 @@
     #endif
 #endif
 
-/* Make the UTF-8 support the default. */
 #if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16
     #define MD4C_USE_UTF8
 #endif
 
-/* Magic for making wide literals with MD4C_USE_UTF16. */
 #ifdef _T
     #undef _T
 #endif
@@ -62,7 +30,6 @@
     #define _T(x)           x
 #endif
 
-/* Misc. macros. */
 #define SIZEOF_ARRAY(a)     (sizeof(a) / sizeof(a[0]))
 
 #define STRINGIZE_(x)       #x
@@ -106,7 +73,6 @@
     #endif
 #endif
 
-/* For falling through case labels in switch statements. */
 #if defined __clang__ && __clang_major__ >= 12
     #define MD_FALLTHROUGH()        __attribute__((fallthrough))
 #elif defined __GNUC__ && __GNUC__ >= 7
@@ -115,31 +81,12 @@
     #define MD_FALLTHROUGH()        ((void)0)
 #endif
 
-/* Suppress "unused parameter" warnings. */
 #define MD_UNUSED(x)                ((void)x)
 
-
-/******************************
- ***  Some internal limits  ***
- ******************************/
-
-/* We limit code span marks to lower than 32 backticks. This solves the
- * pathologic case of too many openers, each of different length: Their
- * resolving would be then O(n^2). */
 #define CODESPAN_MARK_MAXLEN    32
 
-/* We limit column count of tables to prevent quadratic explosion of output
- * from pathological input of a table thousands of columns and thousands
- * of rows where rows are requested with as little as single character
- * per-line, relying on us to "helpfully" fill all the missing "<td></td>". */
 #define TABLE_MAXCOLCOUNT       128
 
-
-/************************
- ***  Internal Types  ***
- ************************/
-
-/* These are omnipresent so lets save some typing. */
 #define CHAR    MD_CHAR
 #define SZ      MD_SIZE
 #define OFF     MD_OFFSET
@@ -152,33 +99,24 @@ typedef struct MD_BLOCK_tag MD_BLOCK;
 typedef struct MD_CONTAINER_tag MD_CONTAINER;
 typedef struct MD_REF_DEF_tag MD_REF_DEF;
 
-
-/* During analyzes of inline marks, we need to manage stacks of unresolved
- * openers of the given type.
- * The stack connects the marks via MD_MARK::next;
- */
 typedef struct MD_MARKSTACK_tag MD_MARKSTACK;
 struct MD_MARKSTACK_tag {
-    int top;        /* -1 if empty. */
+    int top;
 };
 
-/* Context propagated through all the parsing. */
 typedef struct MD_CTX_tag MD_CTX;
 struct MD_CTX_tag {
-    /* Immutable stuff (parameters of md_parse()). */
+
     const CHAR* text;
     SZ size;
     MD_PARSER parser;
     void* userdata;
 
-    /* When this is true, it allows some optimizations. */
     int doc_ends_with_newline;
 
-    /* Helper temporary growing buffer. */
     CHAR* buffer;
     unsigned alloc_buffer;
 
-    /* Reference definitions. */
     MD_REF_DEF* ref_defs;
     int n_ref_defs;
     int alloc_ref_defs;
@@ -186,10 +124,6 @@ struct MD_CTX_tag {
     int ref_def_hashtable_size;
     SZ max_ref_def_output;
 
-    /* Stack of inline/span markers.
-     * This is only used for parsing a single block contents but by storing it
-     * here we may reuse the stack for subsequent blocks; i.e. we have fewer
-     * (re)allocations. */
     MD_MARK* marks;
     int n_marks;
     int alloc_marks;
@@ -200,18 +134,17 @@ struct MD_CTX_tag {
     char mark_char_map[256];
 #endif
 
-    /* For resolving of inline spans. */
     MD_MARKSTACK opener_stacks[16];
-#define ASTERISK_OPENERS_oo_mod3_0      (ctx->opener_stacks[0])     /* Opener-only */
+#define ASTERISK_OPENERS_oo_mod3_0      (ctx->opener_stacks[0])
 #define ASTERISK_OPENERS_oo_mod3_1      (ctx->opener_stacks[1])
 #define ASTERISK_OPENERS_oo_mod3_2      (ctx->opener_stacks[2])
-#define ASTERISK_OPENERS_oc_mod3_0      (ctx->opener_stacks[3])     /* Both opener and closer candidate */
+#define ASTERISK_OPENERS_oc_mod3_0      (ctx->opener_stacks[3])
 #define ASTERISK_OPENERS_oc_mod3_1      (ctx->opener_stacks[4])
 #define ASTERISK_OPENERS_oc_mod3_2      (ctx->opener_stacks[5])
-#define UNDERSCORE_OPENERS_oo_mod3_0    (ctx->opener_stacks[6])     /* Opener-only */
+#define UNDERSCORE_OPENERS_oo_mod3_0    (ctx->opener_stacks[6])
 #define UNDERSCORE_OPENERS_oo_mod3_1    (ctx->opener_stacks[7])
 #define UNDERSCORE_OPENERS_oo_mod3_2    (ctx->opener_stacks[8])
-#define UNDERSCORE_OPENERS_oc_mod3_0    (ctx->opener_stacks[9])     /* Both opener and closer candidate */
+#define UNDERSCORE_OPENERS_oc_mod3_0    (ctx->opener_stacks[9])
 #define UNDERSCORE_OPENERS_oc_mod3_1    (ctx->opener_stacks[10])
 #define UNDERSCORE_OPENERS_oc_mod3_2    (ctx->opener_stacks[11])
 #define TILDE_OPENERS_1                 (ctx->opener_stacks[12])
@@ -219,49 +152,33 @@ struct MD_CTX_tag {
 #define BRACKET_OPENERS                 (ctx->opener_stacks[14])
 #define DOLLAR_OPENERS                  (ctx->opener_stacks[15])
 
-    /* Stack of dummies which need to call free() for pointers stored in them.
-     * These are constructed during inline parsing and freed after all the block
-     * is processed (i.e. all callbacks referring those strings are called). */
     MD_MARKSTACK ptr_stack;
 
-    /* For resolving table rows. */
     int n_table_cell_boundaries;
     int table_cell_boundaries_head;
     int table_cell_boundaries_tail;
 
-    /* For resolving links. */
     int unresolved_link_head;
     int unresolved_link_tail;
 
-    /* For resolving raw HTML. */
     OFF html_comment_horizon;
     OFF html_proc_instr_horizon;
     OFF html_decl_horizon;
     OFF html_cdata_horizon;
 
-    /* For block analysis.
-     * Notes:
-     *   -- It holds MD_BLOCK as well as MD_LINE structures. After each
-     *      MD_BLOCK, its (multiple) MD_LINE(s) follow.
-     *   -- For MD_BLOCK_HTML and MD_BLOCK_CODE, MD_VERBATIMLINE(s) are used
-     *      instead of MD_LINE(s).
-     */
     void* block_bytes;
     MD_BLOCK* current_block;
     int n_block_bytes;
     int alloc_block_bytes;
 
-    /* For container block analysis. */
     MD_CONTAINER* containers;
     int n_containers;
     int alloc_containers;
 
-    /* Minimal indentation to call the block "indented code block". */
     unsigned code_indent_offset;
 
-    /* Contextual info for line analysis. */
-    SZ code_fence_length;   /* For checking closing fence length. */
-    int html_block_type;    /* For checking closing raw HTML condition. */
+    SZ code_fence_length;
+    int html_block_type;
     int last_line_has_list_loosening_effect;
     int last_list_item_starts_with_two_blank_lines;
 };
@@ -288,7 +205,7 @@ struct MD_LINE_ANALYSIS_tag {
     int enforce_new_block;
     OFF beg;
     OFF end;
-    unsigned indent;        /* Indentation level. */
+    unsigned indent;
 };
 
 typedef struct MD_LINE_tag MD_LINE;
@@ -304,17 +221,9 @@ struct MD_VERBATIMLINE_tag {
     OFF indent;
 };
 
-
-/*****************
- ***  Helpers  ***
- *****************/
-
-/* Character accessors. */
 #define CH(off)                 (ctx->text[(off)])
 #define STR(off)                (ctx->text + (off))
 
-/* Character classification.
- * Note we assume ASCII compatibility of code points < 128 here. */
 #define ISIN_(ch, ch_min, ch_max)       ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max))
 #define ISANYOF_(ch, palette)           ((ch) != _T('\0')  &&  md_strchr((palette), (ch)) != NULL)
 #define ISANYOF2_(ch, ch1, ch2)         ((ch) == (ch1) || (ch) == (ch2))
@@ -348,15 +257,12 @@ struct MD_VERBATIMLINE_tag {
 #define ISXDIGIT(off)                   ISXDIGIT_(CH(off))
 #define ISALNUM(off)                    ISALNUM_(CH(off))
 
-
 #if defined MD4C_USE_UTF16
     #define md_strchr wcschr
 #else
     #define md_strchr strchr
 #endif
 
-
-/* Case insensitive check of string equality. */
 static inline int
 md_ascii_case_eq(const CHAR* s1, const CHAR* s2, SZ n)
 {
@@ -411,7 +317,6 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
     }
 }
 
-
 #define MD_CHECK(func)                                                      \
     do {                                                                    \
         ret = (func);                                                       \
@@ -419,7 +324,6 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
             goto abort;                                                     \
     } while(0)
 
-
 #define MD_TEMP_BUFFER(sz)                                                  \
     do {                                                                    \
         if(sz > ctx->alloc_buffer) {                                        \
@@ -438,7 +342,6 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
         }                                                                   \
     } while(0)
 
-
 #define MD_ENTER_BLOCK(type, arg)                                           \
     do {                                                                    \
         ret = ctx->parser.enter_block((type), (arg), ctx->userdata);        \
@@ -497,9 +400,6 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
         }                                                                   \
     } while(0)
 
-
-/* If the offset falls into a gap between line, we return the following
- * line. */
 static const MD_LINE*
 md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index)
 {
@@ -532,25 +432,14 @@ md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_i
     return NULL;
 }
 
-
-/*************************
- ***  Unicode Support  ***
- *************************/
-
 typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO;
 struct MD_UNICODE_FOLD_INFO_tag {
     unsigned codepoints[3];
     unsigned n_codepoints;
 };
 
-
 #if defined MD4C_USE_UTF16 || defined MD4C_USE_UTF8
-    /* Binary search over sorted "map" of codepoints. Consecutive sequences
-     * of codepoints may be encoded in the map by just using the
-     * (MIN_CODEPOINT | 0x40000000) and (MAX_CODEPOINT | 0x80000000).
-     *
-     * Returns index of the found record in the map (in the case of ranges,
-     * the minimal value is used); or -1 on failure. */
+
     static int
     md_unicode_bsearch__(unsigned codepoint, const unsigned* map, size_t map_size)
     {
@@ -560,7 +449,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
         beg = 0;
         end = (int) map_size-1;
         while(beg <= end) {
-            /* Pivot may be a range, not just a single value. */
+
             pivot_beg = pivot_end = (beg + end) / 2;
             if(map[pivot_end] & 0x40000000)
                 pivot_end++;
@@ -583,16 +472,13 @@ struct MD_UNICODE_FOLD_INFO_tag {
     {
 #define R(cp_min, cp_max)   ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
 #define S(cp)               (cp)
-        /* Unicode "Zs" category.
-         * (generated by scripts/build_whitespace_map.py) */
+
         static const unsigned WHITESPACE_MAP[] = {
             S(0x0020), S(0x00a0), S(0x1680), R(0x2000,0x200a), S(0x202f), S(0x205f), S(0x3000)
         };
 #undef R
 #undef S
 
-        /* The ASCII ones are the most frequently used ones, also CommonMark
-         * specification requests few more in this range. */
         if(codepoint <= 0x7f)
             return ISWHITESPACE_(codepoint);
 
@@ -604,8 +490,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
     {
 #define R(cp_min, cp_max)   ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
 #define S(cp)               (cp)
-        /* Unicode general "P" and "S" categories.
-         * (generated by scripts/build_punct_map.py) */
+
         static const unsigned PUNCT_MAP[] = {
             R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9),
             R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7),
@@ -669,8 +554,6 @@ struct MD_UNICODE_FOLD_INFO_tag {
 #undef R
 #undef S
 
-        /* The ASCII ones are the most frequently used ones, also CommonMark
-         * specification requests few more in this range. */
         if(codepoint <= 0x7f)
             return ISPUNCT_(codepoint);
 
@@ -682,8 +565,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
     {
 #define R(cp_min, cp_max)   ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
 #define S(cp)               (cp)
-        /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories.
-         * (generated by scripts/build_folding_map.py) */
+
         static const unsigned FOLD_MAP_1[] = {
             R(0x0041,0x005a), S(0x00b5), R(0x00c0,0x00d6), R(0x00d8,0x00de), R(0x0100,0x012e), R(0x0132,0x0136),
             R(0x0139,0x0147), R(0x014a,0x0176), S(0x0178), R(0x0179,0x017d), S(0x017f), S(0x0181), S(0x0182),
@@ -782,7 +664,6 @@ struct MD_UNICODE_FOLD_INFO_tag {
 
         int i;
 
-        /* Fast path for ASCII characters. */
         if(codepoint <= 0x7f) {
             info->codepoints[0] = codepoint;
             if(ISUPPER_(codepoint))
@@ -791,13 +672,12 @@ struct MD_UNICODE_FOLD_INFO_tag {
             return;
         }
 
-        /* Try to locate the codepoint in any of the maps. */
         for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) {
             int index;
 
             index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size);
             if(index >= 0) {
-                /* Found the mapping. */
+
                 unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints;
                 const unsigned* map = FOLD_MAP_LIST[i].map;
                 const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints);
@@ -806,13 +686,12 @@ struct MD_UNICODE_FOLD_INFO_tag {
                 info->n_codepoints = n_codepoints;
 
                 if(FOLD_MAP_LIST[i].map[index] != codepoint) {
-                    /* The found mapping maps whole range of codepoints,
-                     * i.e. we have to offset info->codepoints[0] accordingly. */
+
                     if((map[index] & 0x00ffffff)+1 == codepoints[0]) {
-                        /* Alternating type of the range. */
+
                         info->codepoints[0] = codepoint + ((codepoint & 0x1) == (map[index] & 0x1) ? 1 : 0);
                     } else {
-                        /* Range to range kind of mapping. */
+
                         info->codepoints[0] += (codepoint - (map[index] & 0x00ffffff));
                     }
                 }
@@ -821,13 +700,11 @@ struct MD_UNICODE_FOLD_INFO_tag {
             }
         }
 
-        /* No mapping found. Map the codepoint to itself. */
         info->codepoints[0] = codepoint;
         info->n_codepoints = 1;
     }
 #endif
 
-
 #if defined MD4C_USE_UTF16
     #define IS_UTF16_SURROGATE_HI(word)     (((WORD)(word) & 0xfc00) == 0xd800)
     #define IS_UTF16_SURROGATE_LO(word)     (((WORD)(word) & 0xfc00) == 0xdc00)
@@ -858,7 +735,6 @@ struct MD_UNICODE_FOLD_INFO_tag {
         return CH(off);
     }
 
-    /* No whitespace uses surrogates, so no decoding needed here. */
     #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint)
     #define ISUNICODEWHITESPACE(off)        md_is_unicode_whitespace__(CH(off))
     #define ISUNICODEWHITESPACEBEFORE(off)  md_is_unicode_whitespace__(CH((off)-1))
@@ -977,18 +853,6 @@ struct MD_UNICODE_FOLD_INFO_tag {
     }
 #endif
 
-
-/*************************************
- ***  Helper string manipulations  ***
- *************************************/
-
-/* Fill buffer with copy of the string between 'beg' and 'end' but replace any
- * line breaks with given replacement character.
- *
- * NOTE: Caller is responsible to make sure the buffer is large enough.
- * (Given the output is always shorter than input, (end - beg) is good idea
- * what the caller should allocate.)
- */
 static void
 md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines,
                CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size)
@@ -1024,8 +888,6 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_li
     }
 }
 
-/* Wrapper of md_merge_lines() which allocates new buffer for the output string.
- */
 static int
 md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines,
                     CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size)
@@ -1061,18 +923,6 @@ md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size)
     return off;
 }
 
-
-/******************************
- ***  Recognizing raw HTML  ***
- ******************************/
-
-/* md_is_html_tag() may be called when processing inlines (inline raw HTML)
- * or when breaking document to blocks (checking for start of HTML block type 7).
- *
- * When breaking document to blocks, we do not yet know line boundaries, but
- * in that case the whole tag has to live on a single line. We distinguish this
- * by n_lines == 0.
- */
 static int
 md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end)
 {
@@ -1087,39 +937,26 @@ md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF
         return FALSE;
     off++;
 
-    /* For parsing attributes, we need a little state automaton below.
-     * State -1: no attributes are allowed.
-     * State 0: attribute could follow after some whitespace.
-     * State 1: after a whitespace (attribute name may follow).
-     * State 2: after attribute name ('=' MAY follow).
-     * State 3: after '=' (value specification MUST follow).
-     * State 41: in middle of unquoted attribute value.
-     * State 42: in middle of single-quoted attribute value.
-     * State 43: in middle of double-quoted attribute value.
-     */
     attr_state = 0;
 
     if(CH(off) == _T('/')) {
-        /* Closer tag "</ ... >". No attributes may be present. */
+
         attr_state = -1;
         off++;
     }
 
-    /* Tag name */
     if(off >= line_end  ||  !ISALPHA(off))
         return FALSE;
     off++;
     while(off < line_end  &&  (ISALNUM(off)  ||  CH(off) == _T('-')))
         off++;
 
-    /* (Optional) attributes (if not closer), (optional) '/' (if not closer)
-     * and final '>'. */
     while(1) {
         while(off < line_end  &&  !ISNEWLINE(off)) {
             if(attr_state > 40) {
                 if(attr_state == 41 && (ISBLANK(off) || ISANYOF(off, _T("\"'=<>`")))) {
                     attr_state = 0;
-                    off--;  /* Put the char back for re-inspection in the new state. */
+                    off--;
                 } else if(attr_state == 42 && CH(off) == _T('\'')) {
                     attr_state = 0;
                 } else if(attr_state == 43 && CH(off) == _T('"')) {
@@ -1131,24 +968,24 @@ md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF
                     attr_state = 1;
                 off++;
             } else if(attr_state <= 2 && CH(off) == _T('>')) {
-                /* End. */
+
                 goto done;
             } else if(attr_state <= 2 && CH(off) == _T('/') && off+1 < line_end && CH(off+1) == _T('>')) {
-                /* End with digraph '/>' */
+
                 off++;
                 goto done;
             } else if((attr_state == 1 || attr_state == 2) && (ISALPHA(off) || CH(off) == _T('_') || CH(off) == _T(':'))) {
                 off++;
-                /* Attribute name */
+
                 while(off < line_end && (ISALNUM(off) || ISANYOF(off, _T("_.:-"))))
                     off++;
                 attr_state = 2;
             } else if(attr_state == 2 && CH(off) == _T('=')) {
-                /* Attribute assignment sign */
+
                 off++;
                 attr_state = 3;
             } else if(attr_state == 3) {
-                /* Expecting start of attribute value. */
+
                 if(CH(off) == _T('"'))
                     attr_state = 43;
                 else if(CH(off) == _T('\''))
@@ -1159,13 +996,11 @@ md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF
                     return FALSE;
                 off++;
             } else {
-                /* Anything unexpected. */
+
                 return FALSE;
             }
         }
 
-        /* We have to be on a single line. See definition of start condition
-         * of HTML block, type 7. */
         if(n_lines == 0)
             return FALSE;
 
@@ -1201,15 +1036,14 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len,
     MD_SIZE line_index = 0;
 
     if(off < *p_scan_horizon  &&  *p_scan_horizon >= max_end - len) {
-        /* We have already scanned the range up to the max_end so we know
-         * there is nothing to see. */
+
         return FALSE;
     }
 
     while(TRUE) {
         while(off + len <= lines[line_index].end  &&  off + len <= max_end) {
             if(md_ascii_eq(STR(off), str, len)) {
-                /* Success. */
+
                 *p_end = off + len;
                 return TRUE;
             }
@@ -1218,7 +1052,7 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len,
 
         line_index++;
         if(off >= max_end  ||  line_index >= n_lines) {
-            /* Failure. */
+
             *p_scan_horizon = off;
             return FALSE;
         }
@@ -1239,10 +1073,8 @@ md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
     if(CH(off+1) != _T('!')  ||  CH(off+2) != _T('-')  ||  CH(off+3) != _T('-'))
         return FALSE;
 
-    /* Skip only "<!" so that we accept also "<!-->" or "<!--->" */
     off += 2;
 
-    /* Scan for ordinary comment closer "-->". */
     return md_scan_for_html_closer(ctx, _T("-->"), 3,
                 lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon);
 }
@@ -1273,7 +1105,6 @@ md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF b
         return FALSE;
     off += 2;
 
-    /* Declaration name. */
     if(off >= lines[0].end  ||  !ISALPHA(off))
         return FALSE;
     off++;
@@ -1313,11 +1144,6 @@ md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF
             md_is_html_cdata(ctx, lines, n_lines, beg, max_end, p_end));
 }
 
-
-/****************************
- ***  Recognizing Entity  ***
- ****************************/
-
 static int
 md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
 {
@@ -1404,11 +1230,6 @@ md_is_entity(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end)
     return md_is_entity_str(ctx, ctx->text, beg, max_end, p_end);
 }
 
-
-/******************************
- ***  Attribute Management  ***
- ******************************/
-
 typedef struct MD_ATTRIBUTE_BUILD_tag MD_ATTRIBUTE_BUILD;
 struct MD_ATTRIBUTE_BUILD_tag {
     CHAR* text;
@@ -1420,7 +1241,6 @@ struct MD_ATTRIBUTE_BUILD_tag {
     OFF trivial_offsets[2];
 };
 
-
 #define MD_BUILD_ATTR_NO_ESCAPES    0x0001
 
 static int
@@ -1440,7 +1260,7 @@ md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build,
             MD_LOG("realloc() failed.");
             return -1;
         }
-        /* Note +1 to reserve space for final offset (== raw_size). */
+
         new_substr_offsets = (OFF*) realloc(build->substr_offsets,
                                     (build->substr_alloc+1) * sizeof(OFF));
         if(new_substr_offsets == NULL) {
@@ -1481,8 +1301,6 @@ md_build_attribute(MD_CTX* ctx, const CHAR* raw_text, SZ raw_size,
 
     memset(build, 0, sizeof(MD_ATTRIBUTE_BUILD));
 
-    /* If there is no backslash and no ampersand, build trivial attribute
-     * without any malloc(). */
     is_trivial = TRUE;
     for(raw_off = 0; raw_off < raw_size; raw_off++) {
         if(ISANYOF3_(raw_text[raw_off], _T('\\'), _T('&'), _T('\0'))) {
@@ -1556,11 +1374,6 @@ abort:
     return -1;
 }
 
-
-/*********************************************
- ***  Dictionary of Reference Definitions  ***
- *********************************************/
-
 #define MD_FNV1A_BASE       2166136261U
 #define MD_FNV1A_PRIME      16777619U
 
@@ -1579,7 +1392,6 @@ md_fnv1a(unsigned base, const void* data, size_t n)
     return hash;
 }
 
-
 struct MD_REF_DEF_tag {
     CHAR* label;
     CHAR* title;
@@ -1592,10 +1404,6 @@ struct MD_REF_DEF_tag {
     unsigned char title_needs_free : 1;
 };
 
-/* Label equivalence is quite complicated with regards to whitespace and case
- * folding. This complicates computing a hash of it as well as direct comparison
- * of two labels. */
-
 static unsigned
 md_link_label_hash(const CHAR* label, SZ size)
 {
@@ -1635,18 +1443,17 @@ md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size,
     SZ char_size;
 
     if(off >= size) {
-        /* Treat end of a link label as a whitespace. */
+
         goto whitespace;
     }
 
     codepoint = md_decode_unicode(label, off, size, &char_size);
     off += char_size;
     if(ISUNICODEWHITESPACE_(codepoint)) {
-        /* Treat all whitespace as equivalent */
+
         goto whitespace;
     }
 
-    /* Get real folding info. */
     md_get_unicode_fold_info(codepoint, fold_info);
     return off;
 
@@ -1672,7 +1479,7 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size
     while(a_off < a_size || a_fi_off < a_fi.n_codepoints ||
           b_off < b_size || b_fi_off < b_fi.n_codepoints)
     {
-        /* If needed, load fold info for next char. */
+
         if(a_fi_off >= a_fi.n_codepoints) {
             a_fi_off = 0;
             a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi);
@@ -1697,7 +1504,7 @@ typedef struct MD_REF_DEF_LIST_tag MD_REF_DEF_LIST;
 struct MD_REF_DEF_LIST_tag {
     int n_ref_defs;
     int alloc_ref_defs;
-    MD_REF_DEF* ref_defs[];  /* Valid items always  point into ctx->ref_defs[] */
+    MD_REF_DEF* ref_defs[];
 };
 
 static int
@@ -1721,7 +1528,6 @@ md_ref_def_cmp_for_sort(const void* a, const void* b)
 
     cmp = md_ref_def_cmp(a, b);
 
-    /* Ensure stability of the sorting. */
     if(cmp == 0) {
         const MD_REF_DEF* a_ref = *(const MD_REF_DEF**)a;
         const MD_REF_DEF* b_ref = *(const MD_REF_DEF**)b;
@@ -1753,12 +1559,6 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
     }
     memset(ctx->ref_def_hashtable, 0, ctx->ref_def_hashtable_size * sizeof(void*));
 
-    /* Each member of ctx->ref_def_hashtable[] can be:
-     *  -- NULL,
-     *  -- pointer to the MD_REF_DEF in ctx->ref_defs[], or
-     *  -- pointer to a MD_REF_DEF_LIST, which holds multiple pointers to
-     *     such MD_REF_DEFs.
-     */
     for(i = 0; i < ctx->n_ref_defs; i++) {
         MD_REF_DEF* def = &ctx->ref_defs[i];
         void* bucket;
@@ -1768,23 +1568,20 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
         bucket = ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size];
 
         if(bucket == NULL) {
-            /* The bucket is empty. Make it just point to the def. */
+
             ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = def;
             continue;
         }
 
         if(ctx->ref_defs <= (MD_REF_DEF*) bucket  &&  (MD_REF_DEF*) bucket < ctx->ref_defs + ctx->n_ref_defs) {
-            /* The bucket already contains one ref. def. Lets see whether it
-             * is the same label (ref. def. duplicate) or different one
-             * (hash conflict). */
+
             MD_REF_DEF* old_def = (MD_REF_DEF*) bucket;
 
             if(md_link_label_cmp(def->label, def->label_size, old_def->label, old_def->label_size) == 0) {
-                /* Duplicate label: Ignore this ref. def. */
+
                 continue;
             }
 
-            /* Make the bucket complex, i.e. able to hold more ref. defs. */
             list = (MD_REF_DEF_LIST*) malloc(sizeof(MD_REF_DEF_LIST) + 2 * sizeof(MD_REF_DEF*));
             if(list == NULL) {
                 MD_LOG("malloc() failed.");
@@ -1798,12 +1595,6 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
             continue;
         }
 
-        /* Append the def to the complex bucket list.
-         *
-         * Note in this case we ignore potential duplicates to avoid expensive
-         * iterating over the complex bucket. Below, we revisit all the complex
-         * buckets and handle it more cheaply after the complex bucket contents
-         * is sorted. */
         list = (MD_REF_DEF_LIST*) bucket;
         if(list->n_ref_defs >= list->alloc_ref_defs) {
             int alloc_ref_defs = list->alloc_ref_defs + list->alloc_ref_defs / 2;
@@ -1822,7 +1613,6 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
         list->n_ref_defs++;
     }
 
-    /* Sort the complex buckets so we can use bsearch() with them. */
     for(i = 0; i < ctx->ref_def_hashtable_size; i++) {
         void* bucket = ctx->ref_def_hashtable[i];
         MD_REF_DEF_LIST* list;
@@ -1835,10 +1625,6 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
         list = (MD_REF_DEF_LIST*) bucket;
         qsort(list->ref_defs, list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp_for_sort);
 
-        /* Disable all duplicates in the complex bucket by forcing all such
-         * records to point to the 1st such ref. def. I.e. no matter which
-         * record is found during the lookup, it will always point to the right
-         * ref. def. in ctx->ref_defs[]. */
         for(j = 1; j < list->n_ref_defs; j++) {
             if(md_ref_def_cmp(&list->ref_defs[j-1], &list->ref_defs[j]) == 0)
                 list->ref_defs[j] = list->ref_defs[j-1];
@@ -1910,15 +1696,6 @@ md_lookup_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size)
     }
 }
 
-
-/***************************
- ***  Recognizing Links  ***
- ***************************/
-
-/* Note this code is partially shared between processing inlines and blocks
- * as reference definitions and links share some helper parser functions.
- */
-
 typedef struct MD_LINK_ATTR_tag MD_LINK_ATTR;
 struct MD_LINK_ATTR_tag {
     OFF dest_beg;
@@ -1929,7 +1706,6 @@ struct MD_LINK_ATTR_tag {
     int title_needs_free;
 };
 
-
 static int
 md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
                  OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index,
@@ -1962,14 +1738,14 @@ md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
                 return FALSE;
             } else if(CH(off) == _T(']')) {
                 if(contents_beg < contents_end) {
-                    /* Success. */
+
                     *p_contents_beg = contents_beg;
                     *p_contents_end = contents_end;
                     *p_end = off+1;
                     *p_end_line_index = line_index;
                     return TRUE;
                 } else {
-                    /* Link label must have some non-whitespace contents. */
+
                     return FALSE;
                 }
             } else {
@@ -2024,7 +1800,7 @@ md_is_link_destination_A(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end,
             return FALSE;
 
         if(CH(off) == _T('>')) {
-            /* Success. */
+
             *p_contents_beg = beg+1;
             *p_contents_end = off;
             *p_end = off+1;
@@ -2053,9 +1829,6 @@ md_is_link_destination_B(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end,
         if(ISWHITESPACE(off) || ISCNTRL(off))
             break;
 
-        /* Link destination may include balanced pairs of unescaped '(' ')'.
-         * Note we limit the maximal nesting level by 32 to protect us from
-         * https://github.com/jgm/cmark/issues/214 */
         if(CH(off) == _T('(')) {
             parenthesis_level++;
             if(parenthesis_level > 32)
@@ -2072,7 +1845,6 @@ md_is_link_destination_B(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end,
     if(parenthesis_level != 0  ||  off == beg)
         return FALSE;
 
-    /* Success. */
     *p_contents_beg = beg;
     *p_contents_end = off;
     *p_end = off;
@@ -2098,7 +1870,6 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
     CHAR closer_char;
     MD_SIZE line_index = 0;
 
-    /* White space with up to one line break. */
     while(off < lines[line_index].end  &&  ISWHITESPACE(off))
         off++;
     if(off >= lines[line_index].end) {
@@ -2112,7 +1883,6 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
 
     *p_beg_line_index = line_index;
 
-    /* First char determines how to detect end of it. */
     switch(CH(off)) {
         case _T('"'):   closer_char = _T('"'); break;
         case _T('\''):  closer_char = _T('\''); break;
@@ -2130,13 +1900,13 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
             if(CH(off) == _T('\\')  &&  off+1 < ctx->size  &&  (ISPUNCT(off+1) || ISNEWLINE(off+1))) {
                 off++;
             } else if(CH(off) == closer_char) {
-                /* Success. */
+
                 *p_contents_end = off;
                 *p_end = off+1;
                 *p_end_line_index = line_index;
                 return TRUE;
             } else if(closer_char == _T(')')  &&  CH(off) == _T('(')) {
-                /* ()-style title cannot contain (unescaped '(')) */
+
                 return FALSE;
             }
 
@@ -2149,14 +1919,6 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg,
     return FALSE;
 }
 
-/* Returns 0 if it is not a reference definition.
- *
- * Returns N > 0 if it is a reference definition. N then corresponds to the
- * number of lines forming it). In this case the definition is stored for
- * resolving any links referring to it.
- *
- * Returns -1 in case of an error (out of memory).
- */
 static int
 md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
 {
@@ -2176,19 +1938,16 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lin
     MD_REF_DEF* def = NULL;
     int ret = 0;
 
-    /* Link label. */
     if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg,
                 &off, &label_contents_line_index, &line_index,
                 &label_contents_beg, &label_contents_end))
         return FALSE;
     label_is_multiline = (label_contents_line_index != line_index);
 
-    /* Colon. */
     if(off >= lines[line_index].end  ||  CH(off) != _T(':'))
         return FALSE;
     off++;
 
-    /* Optional white space with up to one line break. */
     while(off < lines[line_index].end  &&  ISWHITESPACE(off))
         off++;
     if(off >= lines[line_index].end) {
@@ -2198,13 +1957,10 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lin
         off = lines[line_index].beg;
     }
 
-    /* Link destination. */
     if(!md_is_link_destination(ctx, off, lines[line_index].end,
                 &off, &dest_contents_beg, &dest_contents_end))
         return FALSE;
 
-    /* (Optional) title. Note we interpret it as an title only if nothing
-     * more follows on its last line. */
     if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off,
                 &off, &title_contents_line_index, &tmp_line_index,
                 &title_contents_beg, &title_contents_end)
@@ -2214,18 +1970,16 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lin
         title_contents_line_index += line_index;
         line_index += tmp_line_index;
     } else {
-        /* Not a title. */
+
         title_is_multiline = FALSE;
         title_contents_beg = off;
         title_contents_end = off;
         title_contents_line_index = 0;
     }
 
-    /* Nothing more can follow on the last line. */
     if(off < lines[line_index].end)
         return FALSE;
 
-    /* So, it _is_ a reference definition. Remember it. */
     if(ctx->n_ref_defs >= ctx->alloc_ref_defs) {
         MD_REF_DEF* new_defs;
 
@@ -2266,12 +2020,11 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lin
     def->dest_beg = dest_contents_beg;
     def->dest_end = dest_contents_end;
 
-    /* Success. */
     ctx->n_ref_defs++;
     return line_index + 1;
 
 abort:
-    /* Failure. */
+
     if(def != NULL  &&  def->label_needs_free)
         free(def->label);
     if(def != NULL  &&  def->title_needs_free)

clib/md4c.h 🔗

@@ -1,28 +1,3 @@
-/*
- * MD4C: Markdown parser for C
- * (http://github.com/mity/md4c)
- *
- * Copyright (c) 2016-2024 Martin Mitáš
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
 #ifndef MD4C_H
 #define MD4C_H
 
@@ -31,9 +6,7 @@
 #endif
 
 #if defined MD4C_USE_UTF16
-    /* Magic to support UTF-16. Note that in order to use it, you have to define
-     * the macro MD4C_USE_UTF16 both when building MD4C as well as when
-     * including this header in your code. */
+
     #ifdef _WIN32
         #include <windows.h>
         typedef WCHAR       MD_CHAR;
@@ -47,53 +20,28 @@
 typedef unsigned MD_SIZE;
 typedef unsigned MD_OFFSET;
 
-
-/* Block represents a part of document hierarchy structure like a paragraph
- * or list item.
- */
 typedef enum MD_BLOCKTYPE {
-    /* <body>...</body> */
+
     MD_BLOCK_DOC = 0,
 
-    /* <blockquote>...</blockquote> */
     MD_BLOCK_QUOTE,
 
-    /* <ul>...</ul>
-     * Detail: Structure MD_BLOCK_UL_DETAIL. */
     MD_BLOCK_UL,
 
-    /* <ol>...</ol>
-     * Detail: Structure MD_BLOCK_OL_DETAIL. */
     MD_BLOCK_OL,
 
-    /* <li>...</li>
-     * Detail: Structure MD_BLOCK_LI_DETAIL. */
     MD_BLOCK_LI,
 
-    /* <hr> */
     MD_BLOCK_HR,
 
-    /* <h1>...</h1> (for levels up to 6)
-     * Detail: Structure MD_BLOCK_H_DETAIL. */
     MD_BLOCK_H,
 
-    /* <pre><code>...</code></pre>
-     * Note the text lines within code blocks are terminated with '\n'
-     * instead of explicit MD_TEXT_BR. */
     MD_BLOCK_CODE,
 
-    /* Raw HTML block. This itself does not correspond to any particular HTML
-     * tag. The contents of it _is_ raw HTML source intended to be put
-     * in verbatim form to the HTML output. */
     MD_BLOCK_HTML,
 
-    /* <p>...</p> */
     MD_BLOCK_P,
 
-    /* <table>...</table> and its contents.
-     * Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE),
-     *         structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD)
-     * Note all of these are used only if extension MD_FLAG_TABLES is enabled. */
     MD_BLOCK_TABLE,
     MD_BLOCK_THEAD,
     MD_BLOCK_TBODY,
@@ -102,132 +50,53 @@ typedef enum MD_BLOCKTYPE {
     MD_BLOCK_TD
 } MD_BLOCKTYPE;
 
-/* Span represents an in-line piece of a document which should be rendered with
- * the same font, color and other attributes. A sequence of spans forms a block
- * like paragraph or list item. */
 typedef enum MD_SPANTYPE {
-    /* <em>...</em> */
+
     MD_SPAN_EM,
 
-    /* <strong>...</strong> */
     MD_SPAN_STRONG,
 
-    /* <a href="xxx">...</a>
-     * Detail: Structure MD_SPAN_A_DETAIL. */
     MD_SPAN_A,
 
-    /* <img src="xxx">...</a>
-     * Detail: Structure MD_SPAN_IMG_DETAIL.
-     * Note: Image text can contain nested spans and even nested images.
-     * If rendered into ALT attribute of HTML <IMG> tag, it's responsibility
-     * of the parser to deal with it.
-     */
     MD_SPAN_IMG,
 
-    /* <code>...</code> */
     MD_SPAN_CODE,
 
-    /* <del>...</del>
-     * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled.
-     */
     MD_SPAN_DEL,
 
-    /* For recognizing inline ($) and display ($$) equations
-     * Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled.
-     */
     MD_SPAN_LATEXMATH,
     MD_SPAN_LATEXMATH_DISPLAY,
 
-    /* Wiki links
-     * Note: Recognized only when MD_FLAG_WIKILINKS is enabled.
-     */
     MD_SPAN_WIKILINK,
 
-    /* <u>...</u>
-     * Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */
     MD_SPAN_U
 } MD_SPANTYPE;
 
-/* Text is the actual textual contents of span. */
 typedef enum MD_TEXTTYPE {
-    /* Normal text. */
+
     MD_TEXT_NORMAL = 0,
 
-    /* NULL character. CommonMark requires replacing NULL character with
-     * the replacement char U+FFFD, so this allows caller to do that easily. */
     MD_TEXT_NULLCHAR,
 
-    /* Line breaks.
-     * Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE
-     * or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */
-    MD_TEXT_BR,         /* <br> (hard break) */
-    MD_TEXT_SOFTBR,     /* '\n' in source text where it is not semantically meaningful (soft break) */
-
-    /* Entity.
-     * (a) Named entity, e.g. &nbsp; 
-     *     (Note MD4C does not have a list of known entities.
-     *     Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is
-     *     treated as a named entity.)
-     * (b) Numerical entity, e.g. &#1234;
-     * (c) Hexadecimal entity, e.g. &#x12AB;
-     *
-     * As MD4C is mostly encoding agnostic, application gets the verbatim
-     * entity text into the MD_PARSER::text_callback(). */
+    MD_TEXT_BR,
+    MD_TEXT_SOFTBR,
+
     MD_TEXT_ENTITY,
 
-    /* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`).
-     * If it is inside MD_BLOCK_CODE, it includes spaces for indentation and
-     * '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this
-     * kind of text. */
     MD_TEXT_CODE,
 
-    /* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not
-     * an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used.
-     * The text contains verbatim '\n' for the new lines. */
     MD_TEXT_HTML,
 
-    /* Text is inside an equation. This is processed the same way as inlined code
-     * spans (`code`). */
     MD_TEXT_LATEXMATH
 } MD_TEXTTYPE;
 
-
-/* Alignment enumeration. */
 typedef enum MD_ALIGN {
-    MD_ALIGN_DEFAULT = 0,   /* When unspecified. */
+    MD_ALIGN_DEFAULT = 0,
     MD_ALIGN_LEFT,
     MD_ALIGN_CENTER,
     MD_ALIGN_RIGHT
 } MD_ALIGN;
 
-
-/* String attribute.
- *
- * This wraps strings which are outside of a normal text flow and which are
- * propagated within various detailed structures, but which still may contain
- * string portions of different types like e.g. entities.
- *
- * So, for example, lets consider this image:
- *
- *     ![image alt text](http://example.org/image.png 'foo &quot; bar')
- *
- * The image alt text is propagated as a normal text via the MD_PARSER::text()
- * callback. However, the image title ('foo &quot; bar') is propagated as
- * MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title.
- *
- * Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following:
- *  -- [0]: "foo "   (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0)
- *  -- [1]: "&quot;" (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4)
- *  -- [2]: " bar"   (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10)
- *  -- [3]: (n/a)    (n/a                              ; substr_offsets[3] == 14)
- *
- * Note that these invariants are always guaranteed:
- *  -- substr_offsets[0] == 0
- *  -- substr_offsets[LAST+1] == size
- *  -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR
- *     substrings can appear. This could change only of the specification
- *     changes.
- */
 typedef struct MD_ATTRIBUTE {
     const MD_CHAR* text;
     MD_SIZE size;
@@ -235,173 +104,105 @@ typedef struct MD_ATTRIBUTE {
     const MD_OFFSET* substr_offsets;
 } MD_ATTRIBUTE;
 
-
-/* Detailed info for MD_BLOCK_UL. */
 typedef struct MD_BLOCK_UL_DETAIL {
-    int is_tight;           /* Non-zero if tight list, zero if loose. */
-    MD_CHAR mark;           /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */
+    int is_tight;
+    MD_CHAR mark;
 } MD_BLOCK_UL_DETAIL;
 
-/* Detailed info for MD_BLOCK_OL. */
 typedef struct MD_BLOCK_OL_DETAIL {
-    unsigned start;         /* Start index of the ordered list. */
-    int is_tight;           /* Non-zero if tight list, zero if loose. */
-    MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */
+    unsigned start;
+    int is_tight;
+    MD_CHAR mark_delimiter;
 } MD_BLOCK_OL_DETAIL;
 
-/* Detailed info for MD_BLOCK_LI. */
 typedef struct MD_BLOCK_LI_DETAIL {
-    int is_task;            /* Can be non-zero only with MD_FLAG_TASKLISTS */
-    MD_CHAR task_mark;      /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */
-    MD_OFFSET task_mark_offset;  /* If is_task, then offset in the input of the char between '[' and ']'. */
+    int is_task;
+    MD_CHAR task_mark;
+    MD_OFFSET task_mark_offset;
 } MD_BLOCK_LI_DETAIL;
 
-/* Detailed info for MD_BLOCK_H. */
 typedef struct MD_BLOCK_H_DETAIL {
-    unsigned level;         /* Header level (1 - 6) */
+    unsigned level;
 } MD_BLOCK_H_DETAIL;
 
-/* Detailed info for MD_BLOCK_CODE. */
 typedef struct MD_BLOCK_CODE_DETAIL {
     MD_ATTRIBUTE info;
     MD_ATTRIBUTE lang;
-    MD_CHAR fence_char;     /* The character used for fenced code block; or zero for indented code block. */
+    MD_CHAR fence_char;
 } MD_BLOCK_CODE_DETAIL;
 
-/* Detailed info for MD_BLOCK_TABLE. */
 typedef struct MD_BLOCK_TABLE_DETAIL {
-    unsigned col_count;         /* Count of columns in the table. */
-    unsigned head_row_count;    /* Count of rows in the table header (currently always 1) */
-    unsigned body_row_count;    /* Count of rows in the table body */
+    unsigned col_count;
+    unsigned head_row_count;
+    unsigned body_row_count;
 } MD_BLOCK_TABLE_DETAIL;
 
-/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
 typedef struct MD_BLOCK_TD_DETAIL {
     MD_ALIGN align;
 } MD_BLOCK_TD_DETAIL;
 
-/* Detailed info for MD_SPAN_A. */
 typedef struct MD_SPAN_A_DETAIL {
     MD_ATTRIBUTE href;
     MD_ATTRIBUTE title;
-    int is_autolink;            /* nonzero if this is an autolink */
+    int is_autolink;
 } MD_SPAN_A_DETAIL;
 
-/* Detailed info for MD_SPAN_IMG. */
 typedef struct MD_SPAN_IMG_DETAIL {
     MD_ATTRIBUTE src;
     MD_ATTRIBUTE title;
 } MD_SPAN_IMG_DETAIL;
 
-/* Detailed info for MD_SPAN_WIKILINK. */
 typedef struct MD_SPAN_WIKILINK {
     MD_ATTRIBUTE target;
 } MD_SPAN_WIKILINK_DETAIL;
 
-/* Flags specifying extensions/deviations from CommonMark specification.
- *
- * By default (when MD_PARSER::flags == 0), we follow CommonMark specification.
- * The following flags may allow some extensions or deviations from it.
- */
-#define MD_FLAG_COLLAPSEWHITESPACE          0x0001  /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */
-#define MD_FLAG_PERMISSIVEATXHEADERS        0x0002  /* Do not require space in ATX headers ( ###header ) */
-#define MD_FLAG_PERMISSIVEURLAUTOLINKS      0x0004  /* Recognize URLs as autolinks even without '<', '>' */
-#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS    0x0008  /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */
-#define MD_FLAG_NOINDENTEDCODEBLOCKS        0x0010  /* Disable indented code blocks. (Only fenced code works.) */
-#define MD_FLAG_NOHTMLBLOCKS                0x0020  /* Disable raw HTML blocks. */
-#define MD_FLAG_NOHTMLSPANS                 0x0040  /* Disable raw HTML (inline). */
-#define MD_FLAG_TABLES                      0x0100  /* Enable tables extension. */
-#define MD_FLAG_STRIKETHROUGH               0x0200  /* Enable strikethrough extension. */
-#define MD_FLAG_PERMISSIVEWWWAUTOLINKS      0x0400  /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */
-#define MD_FLAG_TASKLISTS                   0x0800  /* Enable task list extension. */
-#define MD_FLAG_LATEXMATHSPANS              0x1000  /* Enable $ and $$ containing LaTeX equations. */
-#define MD_FLAG_WIKILINKS                   0x2000  /* Enable wiki links extension. */
-#define MD_FLAG_UNDERLINE                   0x4000  /* Enable underline extension (and disables '_' for normal emphasis). */
-#define MD_FLAG_HARD_SOFT_BREAKS            0x8000  /* Force all soft breaks to act as hard breaks. */
+#define MD_FLAG_COLLAPSEWHITESPACE          0x0001
+#define MD_FLAG_PERMISSIVEATXHEADERS        0x0002
+#define MD_FLAG_PERMISSIVEURLAUTOLINKS      0x0004
+#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS    0x0008
+#define MD_FLAG_NOINDENTEDCODEBLOCKS        0x0010
+#define MD_FLAG_NOHTMLBLOCKS                0x0020
+#define MD_FLAG_NOHTMLSPANS                 0x0040
+#define MD_FLAG_TABLES                      0x0100
+#define MD_FLAG_STRIKETHROUGH               0x0200
+#define MD_FLAG_PERMISSIVEWWWAUTOLINKS      0x0400
+#define MD_FLAG_TASKLISTS                   0x0800
+#define MD_FLAG_LATEXMATHSPANS              0x1000
+#define MD_FLAG_WIKILINKS                   0x2000
+#define MD_FLAG_UNDERLINE                   0x4000
+#define MD_FLAG_HARD_SOFT_BREAKS            0x8000
 
 #define MD_FLAG_PERMISSIVEAUTOLINKS         (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
 #define MD_FLAG_NOHTML                      (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)
 
-/* Convenient sets of flags corresponding to well-known Markdown dialects.
- *
- * Note we may only support subset of features of the referred dialect.
- * The constant just enables those extensions which bring us as close as
- * possible given what features we implement.
- *
- * ABI compatibility note: Meaning of these can change in time as new
- * extensions, bringing the dialect closer to the original, are implemented.
- */
 #define MD_DIALECT_COMMONMARK               0
 #define MD_DIALECT_GITHUB                   (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS)
 
-/* Parser structure.
- */
 typedef struct MD_PARSER {
-    /* Reserved. Set to zero.
-     */
+
     unsigned abi_version;
 
-    /* Dialect options. Bitmask of MD_FLAG_xxxx values.
-     */
     unsigned flags;
 
-    /* Caller-provided rendering callbacks.
-     *
-     * For some block/span types, more detailed information is provided in a
-     * type-specific structure pointed by the argument 'detail'.
-     *
-     * The last argument of all callbacks, 'userdata', is just propagated from
-     * md_parse() and is available for any use by the application.
-     *
-     * Note any strings provided to the callbacks as their arguments or as
-     * members of any detail structure are generally not zero-terminated.
-     * Application has to take the respective size information into account.
-     *
-     * Any rendering callback may abort further parsing of the document by
-     * returning non-zero.
-     */
-    int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
-    int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
-
-    int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
-    int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
-
-    int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/);
-
-    /* Debug callback. Optional (may be NULL).
-     *
-     * If provided and something goes wrong, this function gets called.
-     * This is intended for debugging and problem diagnosis for developers;
-     * it is not intended to provide any errors suitable for displaying to an
-     * end user.
-     */
-    void (*debug_log)(const char* /*msg*/, void* /*userdata*/);
-
-    /* Reserved. Set to NULL.
-     */
+    int (*enter_block)(MD_BLOCKTYPE , void* , void* );
+    int (*leave_block)(MD_BLOCKTYPE , void* , void* );
+
+    int (*enter_span)(MD_SPANTYPE , void* , void* );
+    int (*leave_span)(MD_SPANTYPE , void* , void* );
+
+    int (*text)(MD_TEXTTYPE , const MD_CHAR* , MD_SIZE , void* );
+
+    void (*debug_log)(const char* , void* );
+
     void (*syntax)(void);
 } MD_PARSER;
 
-
-/* For backward compatibility. Do not use in new code.
- */
 typedef MD_PARSER MD_RENDERER;
 
-
-/* Parse the Markdown document stored in the string 'text' of size 'size'.
- * The parser provides callbacks to be called during the parsing so the
- * caller can render the document on the screen or convert the Markdown
- * to another format.
- *
- * Zero is returned on success. If a runtime error occurs (e.g. a memory
- * fails), -1 is returned. If the processing is aborted due any callback
- * returning non-zero, the return value of the callback is returned.
- */
 int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata);
 
-
 #ifdef __cplusplus
-    }  /* extern "C" { */
+    }
 #endif
 
-#endif  /* MD4C_H */
+#endif

clib/stb_image.h 🔗

@@ -1,381 +1,15 @@
-/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
-                                  no warranty implied; use at your own risk
-
-   Do this:
-      #define STB_IMAGE_IMPLEMENTATION
-   before you include this file in *one* C or C++ file to create the implementation.
-
-   // i.e. it should look like this:
-   #include ...
-   #include ...
-   #include ...
-   #define STB_IMAGE_IMPLEMENTATION
-   #include "stb_image.h"
-
-   You can #define STBI_ASSERT(x) before the #include to avoid using assert.h.
-   And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free
-
-
-   QUICK NOTES:
-      Primarily of interest to game developers and other people who can
-          avoid problematic images and only need the trivial interface
-
-      JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
-      PNG 1/2/4/8/16-bit-per-channel
-
-      TGA (not sure what subset, if a subset)
-      BMP non-1bpp, non-RLE
-      PSD (composited view only, no extra channels, 8/16 bit-per-channel)
-
-      GIF (*comp always reports as 4-channel)
-      HDR (radiance rgbE format)
-      PIC (Softimage PIC)
-      PNM (PPM and PGM binary only)
-
-      Animated GIF still needs a proper API, but here's one way to do it:
-          http://gist.github.com/urraka/685d9a6340b26b830d49
-
-      - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
-      - decode from arbitrary I/O callbacks
-      - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
-
-   Full documentation under "DOCUMENTATION" below.
-
-
-LICENSE
-
-  See end of file for license information.
-
-RECENT REVISION HISTORY:
-
-      2.30  (2024-05-31) avoid erroneous gcc warning
-      2.29  (2023-05-xx) optimizations
-      2.28  (2023-01-29) many error fixes, security errors, just tons of stuff
-      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
-      2.22  (2019-03-04) gif fixes, fix warnings
-      2.21  (2019-02-25) fix typo in comment
-      2.20  (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
-      2.19  (2018-02-11) fix warning
-      2.18  (2018-01-30) fix warnings
-      2.17  (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
-      2.16  (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
-      2.15  (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
-      2.14  (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
-      2.13  (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
-      2.12  (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
-      2.11  (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
-                         RGB-format JPEG; remove white matting in PSD;
-                         allocate large structures on the stack;
-                         correct channel count for PNG & BMP
-      2.10  (2016-01-22) avoid warning introduced in 2.09
-      2.09  (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
-
-   See end of file for full revision history.
-
-
- ============================    Contributors    =========================
-
- Image formats                          Extensions, features
-    Sean Barrett (jpeg, png, bmp)          Jetro Lauha (stbi_info)
-    Nicolas Schulz (hdr, psd)              Martin "SpartanJ" Golini (stbi_info)
-    Jonathan Dummer (tga)                  James "moose2000" Brown (iPhone PNG)
-    Jean-Marc Lienher (gif)                Ben "Disch" Wenger (io callbacks)
-    Tom Seddon (pic)                       Omar Cornut (1/2/4-bit PNG)
-    Thatcher Ulrich (psd)                  Nicolas Guillemot (vertical flip)
-    Ken Miller (pgm, ppm)                  Richard Mitton (16-bit PSD)
-    github:urraka (animated gif)           Junggon Kim (PNM comments)
-    Christopher Forseth (animated gif)     Daniel Gibson (16-bit TGA)
-                                           socks-the-fox (16-bit PNG)
-                                           Jeremy Sawicki (handle all ImageNet JPGs)
- Optimizations & bugfixes                  Mikhail Morozov (1-bit BMP)
-    Fabian "ryg" Giesen                    Anael Seghezzi (is-16-bit query)
-    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       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              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
-    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
 #define STBI_INCLUDE_STB_IMAGE_H
 
-// DOCUMENTATION
-//
-// Limitations:
-//    - no 12-bit-per-channel JPEG
-//    - no JPEGs with arithmetic coding
-//    - GIF always returns *comp=4
-//
-// Basic usage (see HDR discussion below for HDR usage):
-//    int x,y,n;
-//    unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
-//    // ... process data if not NULL ...
-//    // ... x = width, y = height, n = # 8-bit components per pixel ...
-//    // ... replace '0' with '1'..'4' to force that many components per pixel
-//    // ... but 'n' will always be the number that it would have been if you said 0
-//    stbi_image_free(data);
-//
-// Standard parameters:
-//    int *x                 -- outputs image width in pixels
-//    int *y                 -- outputs image height in pixels
-//    int *channels_in_file  -- outputs # of image components in image file
-//    int desired_channels   -- if non-zero, # of image components requested in result
-//
-// The return value from an image loader is an 'unsigned char *' which points
-// to the pixel data, or NULL on an allocation failure or if the image is
-// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels,
-// with each pixel consisting of N interleaved 8-bit components; the first
-// pixel pointed to is top-left-most in the image. There is no padding between
-// image scanlines or between pixels, regardless of format. The number of
-// components N is 'desired_channels' if desired_channels is non-zero, or
-// *channels_in_file otherwise. If desired_channels is non-zero,
-// *channels_in_file has the number of components that _would_ have been
-// output otherwise. E.g. if you set desired_channels to 4, you will always
-// get RGBA output, but you can check *channels_in_file to see if it's trivially
-// opaque because e.g. there were only 3 channels in the source image.
-//
-// An output image with N components has the following components interleaved
-// in this order in each pixel:
-//
-//     N=#comp     components
-//       1           grey
-//       2           grey, alpha
-//       3           red, green, blue
-//       4           red, green, blue, alpha
-//
-// If image loading fails for any reason, the return value will be NULL,
-// and *x, *y, *channels_in_file will be unchanged. The function
-// stbi_failure_reason() can be queried for an extremely brief, end-user
-// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
-// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
-// more user-friendly ones.
-//
-// 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:
-//
-//   If compiling for Windows and you wish to use Unicode filenames, compile
-//   with
-//       #define STBI_WINDOWS_UTF8
-//   and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
-//   Windows wchar_t filenames to utf8.
-//
-// ===========================================================================
-//
-// Philosophy
-//
-// stb libraries are designed with the following priorities:
-//
-//    1. easy to use
-//    2. easy to maintain
-//    3. good performance
-//
-// Sometimes I let "good performance" creep up in priority over "easy to maintain",
-// and for best performance I may provide less-easy-to-use APIs that give higher
-// performance, in addition to the easy-to-use ones. Nevertheless, it's important
-// to keep in mind that from the standpoint of you, a client of this library,
-// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
-//
-// Some secondary priorities arise directly from the first two, some of which
-// provide more explicit reasons why performance can't be emphasized.
-//
-//    - Portable ("ease of use")
-//    - Small source code footprint ("easy to maintain")
-//    - No dependencies ("ease of use")
-//
-// ===========================================================================
-//
-// I/O callbacks
-//
-// I/O callbacks allow you to read from arbitrary sources, like packaged
-// files or some other source. Data read from callbacks are processed
-// through a small internal buffer (currently 128 bytes) to try to reduce
-// overhead.
-//
-// The three functions you must define are "read" (reads some bytes of data),
-// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
-//
-// ===========================================================================
-//
-// SIMD support
-//
-// The JPEG decoder will try to automatically use SIMD kernels on x86 when
-// supported by the compiler. For ARM Neon support, you must explicitly
-// request it.
-//
-// (The old do-it-yourself SIMD API is no longer supported in the current
-// code.)
-//
-// On x86, SSE2 will automatically be used when available based on a run-time
-// test; if not, the generic C versions are used as a fall-back. On ARM targets,
-// the typical path is to have separate builds for NEON and non-NEON devices
-// (at least this is true for iOS and Android). Therefore, the NEON support is
-// toggled by a build flag: define STBI_NEON to get NEON loops.
-//
-// If for some reason you do not want to use any of SIMD code, or if
-// you have issues compiling it, you can disable it entirely by
-// defining STBI_NO_SIMD.
-//
-// ===========================================================================
-//
-// HDR image support   (disable by defining STBI_NO_HDR)
-//
-// stb_image supports loading HDR images in general, and currently the Radiance
-// .HDR file format specifically. You can still load any file through the existing
-// interface; if you attempt to load an HDR file, it will be automatically remapped
-// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
-// both of these constants can be reconfigured through this interface:
-//
-//     stbi_hdr_to_ldr_gamma(2.2f);
-//     stbi_hdr_to_ldr_scale(1.0f);
-//
-// (note, do not use _inverse_ constants; stbi_image will invert them
-// appropriately).
-//
-// Additionally, there is a new, parallel interface for loading files as
-// (linear) floats to preserve the full dynamic range:
-//
-//    float *data = stbi_loadf(filename, &x, &y, &n, 0);
-//
-// If you load LDR images through this interface, those images will
-// be promoted to floating point values, run through the inverse of
-// constants corresponding to the above:
-//
-//     stbi_ldr_to_hdr_scale(1.0f);
-//     stbi_ldr_to_hdr_gamma(2.2f);
-//
-// Finally, given a filename (or an open file or memory block--see header
-// file for details) containing image data, you can query for the "most
-// appropriate" interface to use (that is, whether the image is HDR or
-// not), using:
-//
-//     stbi_is_hdr(char *filename);
-//
-// ===========================================================================
-//
-// iPhone PNG support:
-//
-// 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
-// says there's premultiplied data (currently only happens in iPhone images,
-// and only if iPhone convert-to-rgb processing is on).
-//
-// ===========================================================================
-//
-// ADDITIONAL CONFIGURATION
-//
-//  - You can suppress implementation of any of the decoders to reduce
-//    your code footprint by #defining one or more of the following
-//    symbols before creating the implementation.
-//
-//        STBI_NO_JPEG
-//        STBI_NO_PNG
-//        STBI_NO_BMP
-//        STBI_NO_PSD
-//        STBI_NO_TGA
-//        STBI_NO_GIF
-//        STBI_NO_HDR
-//        STBI_NO_PIC
-//        STBI_NO_PNM   (.ppm and .pgm)
-//
-//  - You can request *only* certain decoders and suppress all other ones
-//    (this will be more forward-compatible, as addition of new decoders
-//    doesn't require you to disable them explicitly):
-//
-//        STBI_ONLY_JPEG
-//        STBI_ONLY_PNG
-//        STBI_ONLY_BMP
-//        STBI_ONLY_PSD
-//        STBI_ONLY_TGA
-//        STBI_ONLY_GIF
-//        STBI_ONLY_HDR
-//        STBI_ONLY_PIC
-//        STBI_ONLY_PNM   (.ppm and .pgm)
-//
-//   - 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 <stdio.h>
-#endif // STBI_NO_STDIO
+#endif
 
 #define STBI_VERSION 1
 
 enum
 {
-   STBI_default = 0, // only used for desired_channels
+   STBI_default = 0,
 
    STBI_grey       = 1,
    STBI_grey_alpha = 2,
@@ -399,34 +33,20 @@ extern "C" {
 #endif
 #endif
 
-//////////////////////////////////////////////////////////////////////////////
-//
-// PRIMARY API - works on images of any type
-//
-
-//
-// load image by filename, open file, or memory buffer
-//
-
 typedef struct
 {
-   int      (*read)  (void *user,char *data,int size);   // fill 'data' with 'size' bytes.  return number of bytes actually read
-   void     (*skip)  (void *user,int n);                 // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
-   int      (*eof)   (void *user);                       // returns nonzero if we are at end of file/data
+   int      (*read)  (void *user,char *data,int size);
+   void     (*skip)  (void *user,int n);
+   int      (*eof)   (void *user);
 } stbi_io_callbacks;
 
-////////////////////////////////////
-//
-// 8-bits-per-channel interface
-//
-
 STBIDEF stbi_uc *stbi_load_from_memory   (stbi_uc           const *buffer, int len   , int *x, int *y, int *channels_in_file, int desired_channels);
 STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk  , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
 
 #ifndef STBI_NO_STDIO
 STBIDEF stbi_uc *stbi_load            (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
 STBIDEF stbi_uc *stbi_load_from_file  (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
-// for stbi_load_from_file, file pointer is left pointing immediately after image
+
 #endif
 
 #ifndef STBI_NO_GIF
@@ -437,11 +57,6 @@ STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int *
 STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
 #endif
 
-////////////////////////////////////
-//
-// 16-bits-per-channel interface
-//
-
 STBIDEF stbi_us *stbi_load_16_from_memory   (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
 STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
 
@@ -450,10 +65,6 @@ STBIDEF stbi_us *stbi_load_16          (char const *filename, int *x, int *y, in
 STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
 #endif
 
-////////////////////////////////////
-//
-// float-per-channel interface
-//
 #ifndef STBI_NO_LINEAR
    STBIDEF float *stbi_loadf_from_memory     (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
    STBIDEF float *stbi_loadf_from_callbacks  (stbi_io_callbacks const *clbk, void *user, int *x, int *y,  int *channels_in_file, int desired_channels);
@@ -467,30 +78,24 @@ STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_i
 #ifndef STBI_NO_HDR
    STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma);
    STBIDEF void   stbi_hdr_to_ldr_scale(float scale);
-#endif // STBI_NO_HDR
+#endif
 
 #ifndef STBI_NO_LINEAR
    STBIDEF void   stbi_ldr_to_hdr_gamma(float gamma);
    STBIDEF void   stbi_ldr_to_hdr_scale(float scale);
-#endif // STBI_NO_LINEAR
+#endif
 
-// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
 STBIDEF int    stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
 STBIDEF int    stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
 #ifndef STBI_NO_STDIO
 STBIDEF int      stbi_is_hdr          (char const *filename);
 STBIDEF int      stbi_is_hdr_from_file(FILE *f);
-#endif // STBI_NO_STDIO
-
+#endif
 
-// get a VERY brief reason for failure
-// on most compilers (and ALL modern mainstream compilers) this is threadsafe
 STBIDEF const char *stbi_failure_reason  (void);
 
-// free the loaded image -- this is just free()
 STBIDEF void     stbi_image_free      (void *retval_from_stbi_load);
 
-// get image dimensions & components without fully decoding
 STBIDEF int      stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
 STBIDEF int      stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
 STBIDEF int      stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
@@ -503,29 +108,16 @@ STBIDEF int      stbi_is_16_bit          (char const *filename);
 STBIDEF int      stbi_is_16_bit_from_file(FILE *f);
 #endif
 
-
-
-// for image formats that explicitly notate that they have premultiplied alpha,
-// we just return the colors as stored in the file. set this flag to force
-// unpremultiplication. results are undefined if the unpremultiply overflow.
 STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
 
-// indicate whether we should process iphone images back to canonical format,
-// or just pass them through "as-is"
 STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
 
-// flip the image vertically, so the first pixel in the output array is the bottom left
 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
-
 STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
 STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
 STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
@@ -534,15 +126,11 @@ STBIDEF int   stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuff
 STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
 STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
 
-
 #ifdef __cplusplus
 }
 #endif
 
-//
-//
-////   end header file   /////////////////////////////////////////////////////
-#endif // STBI_INCLUDE_STB_IMAGE_H
+#endif
 
 #ifdef STB_IMAGE_IMPLEMENTATION
 
@@ -583,15 +171,14 @@ STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
 #define STBI_NO_ZLIB
 #endif
 
-
 #include <stdarg.h>
-#include <stddef.h> // ptrdiff_t on osx
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 
 #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-#include <math.h>  // ldexp, pow
+#include <math.h>
 #endif
 
 #ifndef STBI_NO_STDIO
@@ -609,7 +196,6 @@ STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
 #define STBI_EXTERN extern
 #endif
 
-
 #ifndef _MSC_VER
    #ifdef __cplusplus
    #define stbi_inline inline
@@ -651,7 +237,6 @@ typedef uint32_t stbi__uint32;
 typedef int32_t  stbi__int32;
 #endif
 
-// should produce compiler error if size is wrong
 typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 
 #ifdef _MSC_VER
@@ -671,9 +256,9 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #endif
 
 #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
-// ok
+
 #elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
-// ok
+
 #else
 #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
 #endif
@@ -688,7 +273,6 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
 #endif
 
-// x86/x64 detection
 #if defined(__x86_64__) || defined(_M_X64)
 #define STBI__X64_TARGET
 #elif defined(__i386) || defined(_M_IX86)
@@ -696,28 +280,12 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 #endif
 
 #if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
-// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
-// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
-// but previous attempts to provide the SSE2 functions with runtime
-// detection caused numerous issues. The way architecture extensions are
-// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
-// New behavior: if compiled with -msse2, we use SSE2 without any
-// detection; if not, we don't use it at all.
+
 #define STBI_NO_SIMD
 #endif
 
 #if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
-// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
-//
-// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
-// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
-// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
-// simultaneously enabling "-mstackrealign".
-//
-// See https://github.com/nothings/stb/issues/81 for more information.
-//
-// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
-// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
+
 #define STBI_NO_SIMD
 #endif
 
@@ -727,8 +295,8 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
 
 #ifdef _MSC_VER
 
-#if _MSC_VER >= 1400  // not VC6
-#include <intrin.h> // __cpuid
+#if _MSC_VER >= 1400
+#include <intrin.h>
 static int stbi__cpuid3(void)
 {
    int info[4];
@@ -758,15 +326,13 @@ static int stbi__sse2_available(void)
 }
 #endif
 
-#else // assume GCC-style if not VC++
+#else
 #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
 
 #if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
 static int stbi__sse2_available(void)
 {
-   // If we're even attempting to compile this on GCC/Clang, that means
-   // -msse2 is on, which means the compiler is allowed to use SSE2
-   // instructions at will, and so are we.
+
    return 1;
 }
 #endif
@@ -774,7 +340,6 @@ static int stbi__sse2_available(void)
 #endif
 #endif
 
-// ARM NEON
 #if defined(STBI_NO_SIMD) && defined(STBI_NEON)
 #undef STBI_NEON
 #endif
@@ -796,12 +361,6 @@ static int stbi__sse2_available(void)
 #define STBI_MAX_DIMENSIONS (1 << 24)
 #endif
 
-///////////////////////////////////////////////
-//
-//  stbi__context struct and start_xxx functions
-
-// stbi__context structure is our basic context used by all images, so it
-// contains all the IO context, plus some basic image information
 typedef struct
 {
    stbi__uint32 img_x, img_y;
@@ -819,10 +378,8 @@ typedef struct
    stbi_uc *img_buffer_original, *img_buffer_original_end;
 } stbi__context;
 
-
 static void stbi__refill_buffer(stbi__context *s);
 
-// initialize a memory-decode context
 static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
 {
    s->io.read = NULL;
@@ -832,7 +389,6 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
    s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
 }
 
-// initialize a callback-based context
 static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user)
 {
    s->io = *c;
@@ -856,9 +412,9 @@ 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 */
+   ch = fgetc((FILE*) user);
    if (ch != EOF) {
-      ungetc(ch, (FILE *) user);  /* push byte back onto stream if valid. */
+      ungetc(ch, (FILE *) user);
    }
 }
 
@@ -879,15 +435,11 @@ static void stbi__start_file(stbi__context *s, FILE *f)
    stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
 }
 
-//static void stop_file(stbi__context *s) { }
-
-#endif // !STBI_NO_STDIO
+#endif
 
 static void stbi__rewind(stbi__context *s)
 {
-   // conceptually rewind SHOULD rewind to the beginning of the stream,
-   // but we just rewind to the beginning of the initial buffer, because
-   // we only use it after doing 'test', which only ever looks at at most 92 bytes
+
    s->img_buffer = s->img_buffer_original;
    s->img_buffer_end = s->img_buffer_original_end;
 }
@@ -987,54 +539,35 @@ static void *stbi__malloc(size_t size)
     return STBI_MALLOC(size);
 }
 
-// stb_image uses ints pervasively, including for offset calculations.
-// therefore the largest decoded image size we can support with the
-// current code, even on 64-bit targets, is INT_MAX. this is not a
-// significant limitation for the intended use case.
-//
-// we do, however, need to make sure our size calculations don't
-// overflow. hence a few helper functions for size calculations that
-// multiply integers together, making sure that they're non-negative
-// and no overflow occurs.
-
-// return 1 if the sum is valid, 0 on overflow.
-// negative terms are considered invalid.
 static int stbi__addsizes_valid(int a, int b)
 {
    if (b < 0) return 0;
-   // now 0 <= b <= INT_MAX, hence also
-   // 0 <= INT_MAX - b <= INTMAX.
-   // And "a + b <= INT_MAX" (which might overflow) is the
-   // same as a <= INT_MAX - b (no overflow)
+
    return a <= INT_MAX - b;
 }
 
-// returns 1 if the product is valid, 0 on overflow.
-// negative factors are considered invalid.
 static int stbi__mul2sizes_valid(int a, int b)
 {
    if (a < 0 || b < 0) return 0;
-   if (b == 0) return 1; // mul-by-0 is always safe
-   // portable way to check for no overflows in a*b
+   if (b == 0) return 1;
+
    return a <= INT_MAX/b;
 }
 
 #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
-// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
+
 static int stbi__mad2sizes_valid(int a, int b, int add)
 {
    return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
 }
 #endif
 
-// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
 static int stbi__mad3sizes_valid(int a, int b, int c, int add)
 {
    return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
       stbi__addsizes_valid(a*b*c, 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) || !defined(STBI_NO_PNM)
 static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
 {
@@ -1044,7 +577,7 @@ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
 #endif
 
 #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR)
-// mallocs with size overflow checking
+
 static void *stbi__malloc_mad2(int a, int b, int add)
 {
    if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
@@ -1066,27 +599,21 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
 }
 #endif
 
-// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
 static int stbi__addints_valid(int a, int b)
 {
-   if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
-   if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
+   if ((a >= 0) != (b >= 0)) return 1;
+   if (a < 0 && b < 0) return a >= INT_MIN - b;
    return a <= INT_MAX - b;
 }
 
-// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
 static int stbi__mul2shorts_valid(int a, int b)
 {
-   if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
-   if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
-   if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
+   if (b == 0 || b == -1) return 1;
+   if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b;
+   if (b < 0) return a <= SHRT_MIN / b;
    return a >= SHRT_MIN / b;
 }
 
-// stbi__err - error
-// stbi__errpf - error returning pointer to float
-// stbi__errpuc - error returning pointer to unsigned char
-
 #ifdef STBI_NO_FAILURE_STRINGS
    #define stbi__err(x,y)  0
 #elif defined(STBI_FAILURE_USERMSG)
@@ -1132,17 +659,15 @@ STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_fli
 #define stbi__vertically_flip_on_load  (stbi__vertically_flip_on_load_set       \
                                          ? stbi__vertically_flip_on_load_local  \
                                          : stbi__vertically_flip_on_load_global)
-#endif // STBI_THREAD_LOCAL
+#endif
 
 static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
 {
-   memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
-   ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
-   ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
+   memset(ri, 0, sizeof(*ri));
+   ri->bits_per_channel = 8;
+   ri->channel_order = STBI_ORDER_RGB;
    ri->num_channels = 0;
 
-   // 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
@@ -1161,9 +686,6 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
    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
@@ -1179,7 +701,7 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
    #endif
 
    #ifndef STBI_NO_TGA
-   // test tga last because it's a crappy test!
+
    if (stbi__tga_test(s))
       return stbi__tga_load(s,x,y,comp,req_comp, ri);
    #endif
@@ -1197,7 +719,7 @@ static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int chan
    if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
 
    for (i = 0; i < img_len; ++i)
-      reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
+      reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF);
 
    STBI_FREE(orig);
    return reduced;
@@ -1213,7 +735,7 @@ static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int chan
    if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
 
    for (i = 0; i < img_len; ++i)
-      enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
+      enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]);
 
    STBI_FREE(orig);
    return enlarged;
@@ -1229,7 +751,7 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
    for (row = 0; row < (h>>1); row++) {
       stbi_uc *row0 = bytes + row*bytes_per_row;
       stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
-      // swap row0 with row1
+
       size_t bytes_left = bytes_per_row;
       while (bytes_left) {
          size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
@@ -1265,7 +787,6 @@ 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) {
@@ -1273,8 +794,6 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
       ri.bits_per_channel = 8;
    }
 
-   // @TODO: move stbi__convert_format to here
-
    if (stbi__vertically_flip_on_load) {
       int channels = req_comp ? req_comp : *comp;
       stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
@@ -1291,7 +810,6 @@ 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) {
@@ -1299,9 +817,6 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
       ri.bits_per_channel = 16;
    }
 
-   // @TODO: move stbi__convert_format16 to here
-   // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
-
    if (stbi__vertically_flip_on_load) {
       int channels = req_comp ? req_comp : *comp;
       stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
@@ -1330,7 +845,7 @@ STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int
 #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);
+	return WideCharToMultiByte(65001 , 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
 }
 #endif
 
@@ -1340,10 +855,10 @@ static FILE *stbi__fopen(char const *filename, char const *mode)
 #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)/sizeof(*wFilename)))
+	if (0 == MultiByteToWideChar(65001 , 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
       return 0;
 
-	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
+	if (0 == MultiByteToWideChar(65001 , 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
       return 0;
 
 #if defined(_MSC_VER) && _MSC_VER >= 1400
@@ -1362,7 +877,6 @@ static FILE *stbi__fopen(char const *filename, char const *mode)
    return f;
 }
 
-
 STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
 {
    FILE *f = stbi__fopen(filename, "rb");
@@ -1380,7 +894,7 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
    stbi__start_file(&s,f);
    result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
    if (result) {
-      // need to 'unget' all the characters in the IO buffer
+
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
    }
    return result;
@@ -1393,7 +907,7 @@ STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp,
    stbi__start_file(&s,f);
    result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
    if (result) {
-      // need to 'unget' all the characters in the IO buffer
+
       fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
    }
    return result;
@@ -1409,8 +923,7 @@ STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, i
    return result;
 }
 
-
-#endif //!STBI_NO_STDIO
+#endif
 
 STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
 {
@@ -1506,13 +1019,9 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
    stbi__start_file(&s,f);
    return stbi__loadf_main(&s,x,y,comp,req_comp);
 }
-#endif // !STBI_NO_STDIO
-
-#endif // !STBI_NO_LINEAR
+#endif
 
-// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is
-// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always
-// reports false!
+#endif
 
 STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
 {
@@ -1554,7 +1063,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f)
    return 0;
    #endif
 }
-#endif // !STBI_NO_STDIO
+#endif
 
 STBIDEF int      stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
 {
@@ -1581,12 +1090,6 @@ static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
 STBIDEF void   stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
 STBIDEF void   stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
 
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Common code used by all image loaders
-//
-
 enum
 {
    STBI__SCAN_load=0,

clib/stb_image_write.h 🔗

@@ -1,159 +1,8 @@
-/* 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
-
-   Before #including,
-
-       #define STB_IMAGE_WRITE_IMPLEMENTATION
-
-   in the file that you want to have the implementation.
-
-   Will probably not work correctly with strict-aliasing optimizations.
-
-ABOUT:
-
-   This header file is a library for writing images to C stdio or a callback.
-
-   The PNG output is not optimal; it is 20-50% larger than the file
-   written by a decent optimizing implementation; though providing a custom
-   zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
-   This library is designed for source code compactness and simplicity,
-   not optimal image file size or run-time performance.
-
-BUILDING:
-
-   You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
-   You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
-   malloc,realloc,free.
-   You can #define STBIW_MEMMOVE() to replace memmove()
-   You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
-   for PNG compression (instead of the builtin one), it must have the following signature:
-   unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
-   The returned data will be freed with STBIW_FREE() (free() by default),
-   so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
-
-UNICODE:
-
-   If compiling for Windows and you wish to use Unicode filenames, compile
-   with
-       #define STBIW_WINDOWS_UTF8
-   and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
-   Windows wchar_t filenames to utf8.
-
-USAGE:
-
-   There are five functions, one for each image file format:
-
-     int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
-     int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
-     int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
-     int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
-     int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
-
-     void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
-
-   There are also five equivalent functions that use an arbitrary write function. You are
-   expected to open/close your file-equivalent before and after calling these:
-
-     int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data, int stride_in_bytes);
-     int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
-     int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
-     int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
-     int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
-
-   where the callback is:
-      void stbi_write_func(void *context, void *data, int size);
-
-   You can configure it with these global variables:
-      int stbi_write_tga_with_rle;             // defaults to true; set to 0 to disable RLE
-      int stbi_write_png_compression_level;    // defaults to 8; set to higher for more compression
-      int stbi_write_force_png_filter;         // defaults to -1; set to 0..5 to force a filter mode
-
-
-   You can define STBI_WRITE_NO_STDIO to disable the file variant of these
-   functions, so the library will not use stdio.h at all. However, this will
-   also disable HDR writing, because it requires stdio for formatted output.
-
-   Each function returns 0 on failure and non-0 on success.
-
-   The functions create an image file defined by the parameters. The image
-   is a rectangle of pixels stored from left-to-right, top-to-bottom.
-   Each pixel contains 'comp' channels of data stored interleaved with 8-bits
-   per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
-   monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
-   The *data pointer points to the first byte of the top-left-most pixel.
-   For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
-   a row of pixels to the first byte of the next row of pixels.
-
-   PNG creates output files with the same number of components as the input.
-   The BMP format expands Y to RGB in the file format and does not
-   output alpha.
-
-   PNG supports writing rectangles of data even when the bytes storing rows of
-   data are not consecutive in memory (e.g. sub-rectangles of a larger image),
-   by supplying the stride between the beginning of adjacent rows. The other
-   formats do not. (Thus you cannot write a native-format BMP through the BMP
-   writer, both because it is in BGR order and because it may have padding
-   at the end of the line.)
-
-   PNG allows you to set the deflate compression level by setting the global
-   variable 'stbi_write_png_compression_level' (it defaults to 8).
-
-   HDR expects linear float data. Since the format is always 32-bit rgb(e)
-   data, alpha (if provided) is discarded, and for monochrome data it is
-   replicated across all three channels.
-
-   TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
-   data, set the global variable 'stbi_write_tga_with_rle' to 0.
-
-   JPEG does ignore alpha channels in input data; quality is between 1 and 100.
-   Higher quality looks better but results in a bigger image.
-   JPEG baseline (no JPEG progressive).
-
-CREDITS:
-
-
-   Sean Barrett           -    PNG/BMP/TGA
-   Baldur Karlsson        -    HDR
-   Jean-Sebastien Guay    -    TGA monochrome
-   Tim Kelsey             -    misc enhancements
-   Alan Hickman           -    TGA RLE
-   Emmanuel Julien        -    initial file IO callback implementation
-   Jon Olick              -    original jo_jpeg.cpp code
-   Daniel Gibson          -    integrate JPEG, allow external zlib
-   Aarni Koskela          -    allow choosing PNG filter
-
-   bugfixes:
-      github:Chribba
-      Guillaume Chereau
-      github:jry2
-      github:romigrou
-      Sergio Gonzalez
-      Jonas Karlsson
-      Filip Wasil
-      Thatcher Ulrich
-      github:poppolopoppo
-      Patrick Boettcher
-      github:xeekworx
-      Cap Petschulat
-      Simon Rodriguez
-      Ivan Tikhonov
-      github:ignotion
-      Adam Schackart
-      Andrew Kensler
-
-LICENSE
-
-  See end of file for license information.
-
-*/
-
 #ifndef INCLUDE_STB_IMAGE_WRITE_H
 #define INCLUDE_STB_IMAGE_WRITE_H
 
 #include <stdlib.h>
 
-// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
 #ifndef STBIWDEF
 #ifdef STB_IMAGE_WRITE_STATIC
 #define STBIWDEF  static
@@ -166,7 +15,7 @@ LICENSE
 #endif
 #endif
 
-#ifndef STB_IMAGE_WRITE_STATIC  // C++ forbids static forward declarations
+#ifndef STB_IMAGE_WRITE_STATIC
 STBIWDEF int stbi_write_tga_with_rle;
 STBIWDEF int stbi_write_png_compression_level;
 STBIWDEF int stbi_write_force_png_filter;
@@ -194,7 +43,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
 
 STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 
-#endif//INCLUDE_STB_IMAGE_WRITE_H
+#endif
 
 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
 
@@ -209,7 +58,7 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 
 #ifndef STBI_WRITE_NO_STDIO
 #include <stdio.h>
-#endif // STBI_WRITE_NO_STDIO
+#endif
 
 #include <stdarg.h>
 #include <stdlib.h>
@@ -217,9 +66,9 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 #include <math.h>
 
 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
-// ok
+
 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
-// ok
+
 #else
 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
 #endif
@@ -234,12 +83,10 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
 #endif
 
-
 #ifndef STBIW_MEMMOVE
 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
 #endif
 
-
 #ifndef STBIW_ASSERT
 #include <assert.h>
 #define STBIW_ASSERT(x) assert(x)
@@ -272,7 +119,6 @@ typedef struct
    int buf_used;
 } stbi__write_context;
 
-// initialize a callback-based context
 static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
 {
    s->func    = c;
@@ -297,7 +143,7 @@ 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 , 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
 }
 #endif
 
@@ -307,10 +153,10 @@ static FILE *stbiw__fopen(char const *filename, char const *mode)
 #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)/sizeof(*wFilename)))
+   if (0 == MultiByteToWideChar(65001 , 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
       return 0;
 
-   if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
+   if (0 == MultiByteToWideChar(65001 , 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
       return 0;
 
 #if defined(_MSC_VER) && _MSC_VER >= 1400
@@ -341,7 +187,7 @@ static void stbi__end_write_file(stbi__write_context *s)
    fclose((FILE *)s->context);
 }
 
-#endif // !STBI_WRITE_NO_STDIO
+#endif
 
 typedef unsigned int stbiw_uint32;
 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
@@ -424,22 +270,22 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
       stbiw__write1(s, d[comp - 1]);
 
    switch (comp) {
-      case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
+      case 2:
       case 1:
          if (expand_mono)
-            stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
+            stbiw__write3(s, d[0], d[0], d[0]);
          else
-            stbiw__write1(s, d[0]);  // monochrome TGA
+            stbiw__write1(s, d[0]);
          break;
       case 4:
          if (!write_alpha) {
-            // composite against pink background
+
             for (k = 0; k < 3; ++k)
                px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
             stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
             break;
          }
-         /* FALLTHROUGH */
+
       case 3:
          stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
          break;
@@ -492,20 +338,18 @@ 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)
 {
    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
+              'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40,
+               40, x,y, 1,24, 0,0,0,0,0,0);
    } 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
+         'B', 'M', 14+108+x*y*4, 0, 0, 14+108,
+         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);
    }
 }
 
@@ -527,13 +371,13 @@ STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const
    } else
       return 0;
 }
-#endif //!STBI_WRITE_NO_STDIO
+#endif
 
 static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
 {
    int has_alpha = (comp == 2 || comp == 4);
    int colorbytes = has_alpha ? comp-1 : comp;
-   int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
+   int format = colorbytes < 2 ? 3 : 2;
 
    if (y < 0 || x < 0)
       return 0;
@@ -628,10 +472,6 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
 }
 #endif
 
-// *************************************************************************************************
-// Radiance RGBE HDR writer
-// by Baldur Karlsson
-
 #define stbiw__max(a, b)  ((a) > (b) ? (a) : (b))
 
 #ifndef STBI_WRITE_NO_STDIO
@@ -664,7 +504,7 @@ static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned c
 static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
 {
    unsigned char lengthbyte = STBIW_UCHAR(length);
-   STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
+   STBIW_ASSERT(length <= 128);
    s->func(s->context, &lengthbyte, 1);
    s->func(s->context, data, length);
 }
@@ -679,11 +519,10 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco
    scanlineheader[2] = (width&0xff00)>>8;
    scanlineheader[3] = (width&0x00ff);
 
-   /* skip RLE for images too small or large */
    if (width < 8 || width >= 32768) {
       for (x=0; x < width; x++) {
          switch (ncomp) {
-            case 4: /* fallthrough */
+            case 4:
             case 3: linear[2] = scanline[x*ncomp + 2];
                     linear[1] = scanline[x*ncomp + 1];
                     linear[0] = scanline[x*ncomp + 0];
@@ -697,10 +536,10 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco
       }
    } else {
       int c,r;
-      /* encode into scratch buffer */
+
       for (x=0; x < width; x++) {
          switch(ncomp) {
-            case 4: /* fallthrough */
+            case 4:
             case 3: linear[2] = scanline[x*ncomp + 2];
                     linear[1] = scanline[x*ncomp + 1];
                     linear[0] = scanline[x*ncomp + 0];
@@ -718,13 +557,12 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco
 
       s->func(s->context, scanlineheader, 4);
 
-      /* RLE each component separately */
       for (c=0; c < 4; c++) {
          unsigned char *comp = &scratch[width*c];
 
          x = 0;
          while (x < width) {
-            // find first run
+
             r = x;
             while (r+2 < width) {
                if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
@@ -733,19 +571,19 @@ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int nco
             }
             if (r+2 >= width)
                r = width;
-            // dump up to first run
+
             while (x < r) {
                int len = r-x;
                if (len > 128) len = 128;
                stbiw__write_dump_data(s, len, &comp[x]);
                x += len;
             }
-            // if there's a run, output it
-            if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
-               // find next byte after run
+
+            if (r+2 < width) {
+
                while (r < width && comp[r] == comp[x])
                   ++r;
-               // output run up to r
+
                while (x < r) {
                   int len = r-x;
                   if (len > 127) len = 127;
@@ -763,7 +601,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
    if (y <= 0 || x <= 0 || data == NULL)
       return 0;
    else {
-      // Each component is stored separately. Allocate scratch space for full output scanline.
+
       unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
       int i, len;
       char buffer[128];
@@ -801,16 +639,10 @@ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const
    } else
       return 0;
 }
-#endif // STBI_WRITE_NO_STDIO
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// PNG writer
-//
+#endif
 
 #ifndef STBIW_ZLIB_COMPRESS
-// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
+
 #define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
 #define stbiw__sbm(a)   stbiw__sbraw(a)[0]
 #define stbiw__sbn(a)   stbiw__sbraw(a)[1]
@@ -880,7 +712,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
 #define stbiw__zlib_add(code,codebits) \
       (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
 #define stbiw__zlib_huffa(b,c)  stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
-// default huffman tables
+
 #define stbiw__zlib_huff1(n)  stbiw__zlib_huffa(0x30 + (n), 8)
 #define stbiw__zlib_huff2(n)  stbiw__zlib_huffa(0x190 + (n)-144, 9)
 #define stbiw__zlib_huff3(n)  stbiw__zlib_huffa(0 + (n)-256,7)
@@ -890,14 +722,14 @@ static unsigned int stbiw__zhash(unsigned char *data)
 
 #define stbiw__ZHASH   16384
 
-#endif // STBIW_ZLIB_COMPRESS
+#endif
 
 STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
 {
 #ifdef STBIW_ZLIB_COMPRESS
-   // user provided a zlib compress implementation, use that
+
    return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
-#else // use builtin
+#else
    static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
    static unsigned char  lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5,  0 };
    static unsigned short distc[]   = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
@@ -910,28 +742,28 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
       return NULL;
    if (quality < 5) quality = 5;
 
-   stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
-   stbiw__sbpush(out, 0x5e);   // FLEVEL = 1
-   stbiw__zlib_add(1,1);  // BFINAL = 1
-   stbiw__zlib_add(1,2);  // BTYPE = 1 -- fixed huffman
+   stbiw__sbpush(out, 0x78);
+   stbiw__sbpush(out, 0x5e);
+   stbiw__zlib_add(1,1);
+   stbiw__zlib_add(1,2);
 
    for (i=0; i < stbiw__ZHASH; ++i)
       hash_table[i] = NULL;
 
    i=0;
    while (i < data_len-3) {
-      // hash next 3 bytes of data to be compressed
+
       int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
       unsigned char *bestloc = 0;
       unsigned char **hlist = hash_table[h];
       int n = stbiw__sbcount(hlist);
       for (j=0; j < n; ++j) {
-         if (hlist[j]-data > i-32768) { // if entry lies within window
+         if (hlist[j]-data > i-32768) {
             int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
             if (d >= best) { best=d; bestloc=hlist[j]; }
          }
       }
-      // when hash table entry is too long, delete half the entries
+
       if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
          STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
          stbiw__sbn(hash_table[h]) = quality;
@@ -939,14 +771,14 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
       stbiw__sbpush(hash_table[h],data+i);
 
       if (bestloc) {
-         // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
+
          h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
          hlist = hash_table[h];
          n = stbiw__sbcount(hlist);
          for (j=0; j < n; ++j) {
             if (hlist[j]-data > i-32767) {
                int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
-               if (e > best) { // if next match is better, bail on current match
+               if (e > best) {
                   bestloc = NULL;
                   break;
                }
@@ -955,7 +787,7 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
       }
 
       if (bestloc) {
-         int d = (int) (data+i - bestloc); // distance back
+         int d = (int) (data+i - bestloc);
          STBIW_ASSERT(d <= 32767 && best <= 258);
          for (j=0; best > lengthc[j+1]-1; ++j);
          stbiw__zlib_huff(j+257);
@@ -969,11 +801,11 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
          ++i;
       }
    }
-   // write out final bytes
+
    for (;i < data_len; ++i)
       stbiw__zlib_huffb(data[i]);
-   stbiw__zlib_huff(256); // end of block
-   // pad with 0 bits to byte boundary
+   stbiw__zlib_huff(256);
+
    while (bitcount)
       stbiw__zlib_add(0,1);
 
@@ -981,16 +813,15 @@ 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
+      stbiw__sbn(out) = 2;
       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, data_len - j == blocklen);
+         stbiw__sbpush(out, STBIW_UCHAR(blocklen));
          stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
-         stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
+         stbiw__sbpush(out, STBIW_UCHAR(~blocklen));
          stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
          memcpy(out+stbiw__sbn(out), data+j, blocklen);
          stbiw__sbn(out) += blocklen;
@@ -999,7 +830,7 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
    }
 
    {
-      // compute adler32 on input
+
       unsigned int s1=1, s2=0;
       int blocklen = (int) (data_len % 5552);
       j=0;
@@ -1015,10 +846,10 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
       stbiw__sbpush(out, STBIW_UCHAR(s1));
    }
    *out_len = stbiw__sbn(out);
-   // make returned pointer freeable
+
    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
    return (unsigned char *) stbiw__sbraw(out);
-#endif // STBIW_ZLIB_COMPRESS
+#endif
 }
 
 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
@@ -1088,7 +919,6 @@ static unsigned char stbiw__paeth(int a, int b, int c)
    return STBIW_UCHAR(c);
 }
 
-// @OPTIMIZE: provide an option that always forces left-predict or paeth predict
 static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer)
 {
    static int mapping[] = { 0,1,2,3,4 };
@@ -1104,7 +934,6 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
       return;
    }
 
-   // first loop isn't optimized since it's just one pixel
    for (i = 0; i < n; ++i) {
       switch (type) {
          case 1: line_buffer[i] = z[i]; break;
@@ -1148,12 +977,11 @@ STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int s
       if (force_filter > -1) {
          filter_type = force_filter;
          stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
-      } else { // Estimate the best filter by running through all of them:
+      } else {
          int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
          for (filter_type = 0; filter_type < 5; filter_type++) {
             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
 
-            // Estimate the entropy of the line using this filter; the less, the better.
             est = 0;
             for (i = 0; i < x*n; ++i) {
                est += abs((signed char) line_buffer[i]);
@@ -1163,12 +991,12 @@ STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int s
                best_filter = filter_type;
             }
          }
-         if (filter_type != best_filter) {  // If the last iteration already got us the best filter, don't redo it
+         if (filter_type != best_filter) {
             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
             filter_type = best_filter;
          }
       }
-      // when we get here, filter_type contains the filter type, and line_buffer contains the data
+
       filt[j*(x*n+1)] = (unsigned char) filter_type;
       STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
    }
@@ -1177,14 +1005,13 @@ STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int s
    STBIW_FREE(filt);
    if (!zlib) return 0;
 
-   // each tag requires 12 bytes of overhead
    out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
    if (!out) return 0;
    *out_len = 8 + 12+13 + 12+zlen + 12;
 
    o=out;
    STBIW_MEMMOVE(o,sig,8); o+= 8;
-   stbiw__wp32(o, 13); // header length
+   stbiw__wp32(o, 13);
    stbiw__wptag(o, "IHDR");
    stbiw__wp32(o, x);
    stbiw__wp32(o, y);
@@ -1238,15 +1065,6 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
    return 1;
 }
 
-
-/* ***************************************************************************
- *
- * JPEG writer
- *
- * This is based on Jon Olick's jo_jpeg.cpp:
- * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html
- */
-
 static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,
       24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 };
 
@@ -1280,34 +1098,31 @@ static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float
    float tmp3 = d3 + d4;
    float tmp4 = d3 - d4;
 
-   // Even part
-   float tmp10 = tmp0 + tmp3;   // phase 2
+   float tmp10 = tmp0 + tmp3;
    float tmp13 = tmp0 - tmp3;
    float tmp11 = tmp1 + tmp2;
    float tmp12 = tmp1 - tmp2;
 
-   d0 = tmp10 + tmp11;       // phase 3
+   d0 = tmp10 + tmp11;
    d4 = tmp10 - tmp11;
 
-   z1 = (tmp12 + tmp13) * 0.707106781f; // c4
-   d2 = tmp13 + z1;       // phase 5
+   z1 = (tmp12 + tmp13) * 0.707106781f;
+   d2 = tmp13 + z1;
    d6 = tmp13 - z1;
 
-   // Odd part
-   tmp10 = tmp4 + tmp5;       // phase 2
+   tmp10 = tmp4 + tmp5;
    tmp11 = tmp5 + tmp6;
    tmp12 = tmp6 + tmp7;
 
-   // The rotator is modified from fig 4-8 to avoid extra negations.
-   z5 = (tmp10 - tmp12) * 0.382683433f; // c6
-   z2 = tmp10 * 0.541196100f + z5; // c2-c6
-   z4 = tmp12 * 1.306562965f + z5; // c2+c6
-   z3 = tmp11 * 0.707106781f; // c4
+   z5 = (tmp10 - tmp12) * 0.382683433f;
+   z2 = tmp10 * 0.541196100f + z5;
+   z4 = tmp12 * 1.306562965f + z5;
+   z3 = tmp11 * 0.707106781f;
 
-   z11 = tmp7 + z3;      // phase 5
+   z11 = tmp7 + z3;
    z13 = tmp7 - z3;
 
-   *d5p = z13 + z2;         // phase 6
+   *d5p = z13 + z2;
    *d3p = z13 - z2;
    *d1p = z11 + z4;
    *d7p = z11 - z4;
@@ -1331,28 +1146,25 @@ static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt
    int dataOff, i, j, n, diff, end0pos, x, y;
    int DU[64];
 
-   // DCT rows
    for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
       stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
    }
-   // DCT columns
+
    for(dataOff=0; dataOff<8; ++dataOff) {
       stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
                      &CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
    }
-   // Quantize/descale/zigzag the coefficients
+
    for(y = 0, j=0; y < 8; ++y) {
       for(x = 0; x < 8; ++x,++j) {
          float v;
          i = y*du_stride+x;
          v = CDU[i]*fdtbl[j];
-         // DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
-         // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
+
          DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
       }
    }
 
-   // Encode DC
    diff = DU[0] - DC;
    if (diff == 0) {
       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
@@ -1362,11 +1174,11 @@ static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt
       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
       stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
    }
-   // Encode ACs
+
    end0pos = 63;
    for(; (end0pos>0)&&(DU[end0pos]==0); --end0pos) {
    }
-   // end0pos = first element in reverse order !=0
+
    if(end0pos == 0) {
       stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
       return DU[0];
@@ -1396,7 +1208,7 @@ static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt
 }
 
 static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) {
-   // Constants that don't pollute global namespace
+
    static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};
    static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
    static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d};
@@ -1421,7 +1233,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
       0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
       0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
    };
-   // Huffman tables
+
    static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}};
    static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}};
    static const unsigned short YAC_HT[256][2] = {
@@ -1494,7 +1306,6 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
       }
    }
 
-   // Write Headers
    {
       static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
       static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
@@ -1507,24 +1318,23 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
       s->func(s->context, (void*)head1, sizeof(head1));
       s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1);
       s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values));
-      stbiw__putc(s, 0x10); // HTYACinfo
+      stbiw__putc(s, 0x10);
       s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1);
       s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values));
-      stbiw__putc(s, 1); // HTUDCinfo
+      stbiw__putc(s, 1);
       s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1);
       s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
-      stbiw__putc(s, 0x11); // HTUACinfo
+      stbiw__putc(s, 0x11);
       s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1);
       s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
       s->func(s->context, (void*)head2, sizeof(head2));
    }
 
-   // Encode 8x8 macroblocks
    {
       static const unsigned short fillBits[] = {0x7F, 7};
       int DCY=0, DCU=0, DCV=0;
       int bitBuf=0, bitCnt=0;
-      // comp == 2 is grey+alpha (alpha is ignored)
+
       int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
       const unsigned char *dataR = (const unsigned char *)data;
       const unsigned char *dataG = dataR + ofsG;
@@ -1535,11 +1345,11 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
             for(x = 0; x < width; x += 16) {
                float Y[256], U[256], V[256];
                for(row = y, pos = 0; row < y+16; ++row) {
-                  // row >= height => use last input row
+
                   int clamped_row = (row < height) ? row : height - 1;
                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
                   for(col = x; col < x+16; ++col, ++pos) {
-                     // if col >= width => use pixel from last input column
+
                      int p = base_p + ((col < width) ? col : (width-1))*comp;
                      float r = dataR[p], g = dataG[p], b = dataB[p];
                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
@@ -1552,7 +1362,6 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
 
-               // subsample U,V
                {
                   float subU[64], subV[64];
                   int yy, xx;
@@ -1573,11 +1382,11 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
             for(x = 0; x < width; x += 8) {
                float Y[64], U[64], V[64];
                for(row = y, pos = 0; row < y+8; ++row) {
-                  // row >= height => use last input row
+
                   int clamped_row = (row < height) ? row : height - 1;
                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
                   for(col = x; col < x+8; ++col, ++pos) {
-                     // if col >= width => use pixel from last input column
+
                      int p = base_p + ((col < width) ? col : (width-1))*comp;
                      float r = dataR[p], g = dataG[p], b = dataB[p];
                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
@@ -1593,11 +1402,9 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
          }
       }
 
-      // Do the bit alignment of the EOI marker
       stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
    }
 
-   // EOI
    stbiw__putc(s, 0xFF);
    stbiw__putc(s, 0xD9);
 
@@ -1611,7 +1418,6 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
    return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
 }
 
-
 #ifndef STBI_WRITE_NO_STDIO
 STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
 {
@@ -1625,100 +1431,4 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
 }
 #endif
 
-#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
-      1.11  (2019-08-11)
-
-      1.10  (2019-02-07)
-             support utf8 filenames in Windows; fix warnings and platform ifdefs
-      1.09  (2018-02-11)
-             fix typo in zlib quality API, improve STB_I_W_STATIC in C++
-      1.08  (2018-01-29)
-             add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
-      1.07  (2017-07-24)
-             doc fix
-      1.06 (2017-07-23)
-             writing JPEG (using Jon Olick's code)
-      1.05   ???
-      1.04 (2017-03-03)
-             monochrome BMP expansion
-      1.03   ???
-      1.02 (2016-04-02)
-             avoid allocating large structures on the stack
-      1.01 (2016-01-16)
-             STBIW_REALLOC_SIZED: support allocators with no realloc support
-             avoid race-condition in crc initialization
-             minor compile issues
-      1.00 (2015-09-14)
-             installable file IO function
-      0.99 (2015-09-13)
-             warning fixes; TGA rle support
-      0.98 (2015-04-08)
-             added STBIW_MALLOC, STBIW_ASSERT etc
-      0.97 (2015-01-18)
-             fixed HDR asserts, rewrote HDR rle logic
-      0.96 (2015-01-17)
-             add HDR output
-             fix monochrome BMP
-      0.95 (2014-08-17)
-             add monochrome TGA output
-      0.94 (2014-05-31)
-             rename private functions to avoid conflicts with stb_image.h
-      0.93 (2014-05-27)
-             warning fixes
-      0.92 (2010-08-01)
-             casts to unsigned char to fix warnings
-      0.91 (2010-07-17)
-             first public release
-      0.90   first internal release
-*/
-
-/*
-------------------------------------------------------------------------------
-This software is available under 2 licenses -- choose whichever you prefer.
-------------------------------------------------------------------------------
-ALTERNATIVE A - MIT License
-Copyright (c) 2017 Sean Barrett
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-------------------------------------------------------------------------------
-ALTERNATIVE B - Public Domain (www.unlicense.org)
-This is free and unencumbered software released into the public domain.
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
-software, either in source code form or as a compiled binary, for any purpose,
-commercial or non-commercial, and by any means.
-In jurisdictions that recognize copyright laws, the author or authors of this
-software dedicate any and all copyright interest in the software to the public
-domain. We make this dedication for the benefit of the public at large and to
-the detriment of our heirs and successors. We intend this dedication to be an
-overt act of relinquishment in perpetuity of all present and future rights to
-this software under copyright law.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------------
-*/
+#endif