Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:51

0001 /* stb_image_write - v1.16 - public domain - http://nothings.org/stb
0002    writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
0003                                      no warranty implied; use at your own risk
0004 
0005    Before #including,
0006 
0007        #define STB_IMAGE_WRITE_IMPLEMENTATION
0008 
0009    in the file that you want to have the implementation.
0010 
0011    Will probably not work correctly with strict-aliasing optimizations.
0012 
0013 ABOUT:
0014 
0015    This header file is a library for writing images to C stdio or a callback.
0016 
0017    The PNG output is not optimal; it is 20-50% larger than the file
0018    written by a decent optimizing implementation; though providing a custom
0019    zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
0020    This library is designed for source code compactness and simplicity,
0021    not optimal image file size or run-time performance.
0022 
0023 BUILDING:
0024 
0025    You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
0026    You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
0027    malloc,realloc,free.
0028    You can #define STBIW_MEMMOVE() to replace memmove()
0029    You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
0030    for PNG compression (instead of the builtin one), it must have the following signature:
0031    unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
0032    The returned data will be freed with STBIW_FREE() (free() by default),
0033    so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
0034 
0035 UNICODE:
0036 
0037    If compiling for Windows and you wish to use Unicode filenames, compile
0038    with
0039        #define STBIW_WINDOWS_UTF8
0040    and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
0041    Windows wchar_t filenames to utf8.
0042 
0043 USAGE:
0044 
0045    There are five functions, one for each image file format:
0046 
0047      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
0048      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
0049      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
0050      int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
0051      int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
0052 
0053      void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
0054 
0055    There are also five equivalent functions that use an arbitrary write function. You are
0056    expected to open/close your file-equivalent before and after calling these:
0057 
0058      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);
0059      int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
0060      int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
0061      int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
0062      int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
0063 
0064    where the callback is:
0065       void stbi_write_func(void *context, void *data, int size);
0066 
0067    You can configure it with these global variables:
0068       int stbi_write_tga_with_rle;             // defaults to true; set to 0 to disable RLE
0069       int stbi_write_png_compression_level;    // defaults to 8; set to higher for more compression
0070       int stbi_write_force_png_filter;         // defaults to -1; set to 0..5 to force a filter mode
0071 
0072 
0073    You can define STBI_WRITE_NO_STDIO to disable the file variant of these
0074    functions, so the library will not use stdio.h at all. However, this will
0075    also disable HDR writing, because it requires stdio for formatted output.
0076 
0077    Each function returns 0 on failure and non-0 on success.
0078 
0079    The functions create an image file defined by the parameters. The image
0080    is a rectangle of pixels stored from left-to-right, top-to-bottom.
0081    Each pixel contains 'comp' channels of data stored interleaved with 8-bits
0082    per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
0083    monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
0084    The *data pointer points to the first byte of the top-left-most pixel.
0085    For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
0086    a row of pixels to the first byte of the next row of pixels.
0087 
0088    PNG creates output files with the same number of components as the input.
0089    The BMP format expands Y to RGB in the file format and does not
0090    output alpha.
0091 
0092    PNG supports writing rectangles of data even when the bytes storing rows of
0093    data are not consecutive in memory (e.g. sub-rectangles of a larger image),
0094    by supplying the stride between the beginning of adjacent rows. The other
0095    formats do not. (Thus you cannot write a native-format BMP through the BMP
0096    writer, both because it is in BGR order and because it may have padding
0097    at the end of the line.)
0098 
0099    PNG allows you to set the deflate compression level by setting the global
0100    variable 'stbi_write_png_compression_level' (it defaults to 8).
0101 
0102    HDR expects linear float data. Since the format is always 32-bit rgb(e)
0103    data, alpha (if provided) is discarded, and for monochrome data it is
0104    replicated across all three channels.
0105 
0106    TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
0107    data, set the global variable 'stbi_write_tga_with_rle' to 0.
0108 
0109    JPEG does ignore alpha channels in input data; quality is between 1 and 100.
0110    Higher quality looks better but results in a bigger image.
0111    JPEG baseline (no JPEG progressive).
0112 
0113 CREDITS:
0114 
0115 
0116    Sean Barrett           -    PNG/BMP/TGA
0117    Baldur Karlsson        -    HDR
0118    Jean-Sebastien Guay    -    TGA monochrome
0119    Tim Kelsey             -    misc enhancements
0120    Alan Hickman           -    TGA RLE
0121    Emmanuel Julien        -    initial file IO callback implementation
0122    Jon Olick              -    original jo_jpeg.cpp code
0123    Daniel Gibson          -    integrate JPEG, allow external zlib
0124    Aarni Koskela          -    allow choosing PNG filter
0125 
0126    bugfixes:
0127       github:Chribba
0128       Guillaume Chereau
0129       github:jry2
0130       github:romigrou
0131       Sergio Gonzalez
0132       Jonas Karlsson
0133       Filip Wasil
0134       Thatcher Ulrich
0135       github:poppolopoppo
0136       Patrick Boettcher
0137       github:xeekworx
0138       Cap Petschulat
0139       Simon Rodriguez
0140       Ivan Tikhonov
0141       github:ignotion
0142       Adam Schackart
0143       Andrew Kensler
0144 
0145 LICENSE
0146 
0147   See end of file for license information.
0148 
0149 */
0150 
0151 #ifndef INCLUDE_STB_IMAGE_WRITE_H
0152 #define INCLUDE_STB_IMAGE_WRITE_H
0153 
0154 #include <stdlib.h>
0155 
0156 // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
0157 #ifndef STBIWDEF
0158 #ifdef STB_IMAGE_WRITE_STATIC
0159 #define STBIWDEF  static
0160 #else
0161 #ifdef __cplusplus
0162 #define STBIWDEF  extern "C"
0163 #else
0164 #define STBIWDEF  extern
0165 #endif
0166 #endif
0167 #endif
0168 
0169 #ifndef STB_IMAGE_WRITE_STATIC  // C++ forbids static forward declarations
0170 STBIWDEF int stbi_write_tga_with_rle;
0171 STBIWDEF int stbi_write_png_compression_level;
0172 STBIWDEF int stbi_write_force_png_filter;
0173 #endif
0174 
0175 #ifndef STBI_WRITE_NO_STDIO
0176 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void  *data, int stride_in_bytes);
0177 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void  *data);
0178 STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void  *data);
0179 STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
0180 STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void  *data, int quality);
0181 
0182 #ifdef STBIW_WINDOWS_UTF8
0183 STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
0184 #endif
0185 #endif
0186 
0187 typedef void stbi_write_func(void *context, void *data, int size);
0188 
0189 STBIWDEF 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);
0190 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
0191 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
0192 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
0193 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void  *data, int quality);
0194 
0195 STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
0196 
0197 #endif//INCLUDE_STB_IMAGE_WRITE_H
0198 
0199 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
0200 
0201 #ifdef _WIN32
0202    #ifndef _CRT_SECURE_NO_WARNINGS
0203    #define _CRT_SECURE_NO_WARNINGS
0204    #endif
0205    #ifndef _CRT_NONSTDC_NO_DEPRECATE
0206    #define _CRT_NONSTDC_NO_DEPRECATE
0207    #endif
0208 #endif
0209 
0210 #ifndef STBI_WRITE_NO_STDIO
0211 #include <stdio.h>
0212 #endif // STBI_WRITE_NO_STDIO
0213 
0214 #include <stdarg.h>
0215 #include <stdlib.h>
0216 #include <string.h>
0217 #include <math.h>
0218 
0219 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
0220 // ok
0221 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
0222 // ok
0223 #else
0224 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
0225 #endif
0226 
0227 #ifndef STBIW_MALLOC
0228 #define STBIW_MALLOC(sz)        malloc(sz)
0229 #define STBIW_REALLOC(p,newsz)  realloc(p,newsz)
0230 #define STBIW_FREE(p)           free(p)
0231 #endif
0232 
0233 #ifndef STBIW_REALLOC_SIZED
0234 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
0235 #endif
0236 
0237 
0238 #ifndef STBIW_MEMMOVE
0239 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
0240 #endif
0241 
0242 
0243 #ifndef STBIW_ASSERT
0244 #include <assert.h>
0245 #define STBIW_ASSERT(x) assert(x)
0246 #endif
0247 
0248 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
0249 
0250 #ifdef STB_IMAGE_WRITE_STATIC
0251 static int stbi_write_png_compression_level = 8;
0252 static int stbi_write_tga_with_rle = 1;
0253 static int stbi_write_force_png_filter = -1;
0254 #else
0255 int stbi_write_png_compression_level = 8;
0256 int stbi_write_tga_with_rle = 1;
0257 int stbi_write_force_png_filter = -1;
0258 #endif
0259 
0260 static int stbi__flip_vertically_on_write = 0;
0261 
0262 STBIWDEF void stbi_flip_vertically_on_write(int flag)
0263 {
0264    stbi__flip_vertically_on_write = flag;
0265 }
0266 
0267 typedef struct
0268 {
0269    stbi_write_func *func;
0270    void *context;
0271    unsigned char buffer[64];
0272    int buf_used;
0273 } stbi__write_context;
0274 
0275 // initialize a callback-based context
0276 static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
0277 {
0278    s->func    = c;
0279    s->context = context;
0280 }
0281 
0282 #ifndef STBI_WRITE_NO_STDIO
0283 
0284 static void stbi__stdio_write(void *context, void *data, int size)
0285 {
0286    fwrite(data,1,size,(FILE*) context);
0287 }
0288 
0289 #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
0290 #ifdef __cplusplus
0291 #define STBIW_EXTERN extern "C"
0292 #else
0293 #define STBIW_EXTERN extern
0294 #endif
0295 STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
0296 STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
0297 
0298 STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
0299 {
0300    return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
0301 }
0302 #endif
0303 
0304 static FILE *stbiw__fopen(char const *filename, char const *mode)
0305 {
0306    FILE *f;
0307 #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
0308    wchar_t wMode[64];
0309    wchar_t wFilename[1024];
0310    if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
0311       return 0;
0312 
0313    if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
0314       return 0;
0315 
0316 #if defined(_MSC_VER) && _MSC_VER >= 1400
0317    if (0 != _wfopen_s(&f, wFilename, wMode))
0318       f = 0;
0319 #else
0320    f = _wfopen(wFilename, wMode);
0321 #endif
0322 
0323 #elif defined(_MSC_VER) && _MSC_VER >= 1400
0324    if (0 != fopen_s(&f, filename, mode))
0325       f=0;
0326 #else
0327    f = fopen(filename, mode);
0328 #endif
0329    return f;
0330 }
0331 
0332 static int stbi__start_write_file(stbi__write_context *s, const char *filename)
0333 {
0334    FILE *f = stbiw__fopen(filename, "wb");
0335    stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
0336    return f != NULL;
0337 }
0338 
0339 static void stbi__end_write_file(stbi__write_context *s)
0340 {
0341    fclose((FILE *)s->context);
0342 }
0343 
0344 #endif // !STBI_WRITE_NO_STDIO
0345 
0346 typedef unsigned int stbiw_uint32;
0347 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
0348 
0349 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
0350 {
0351    while (*fmt) {
0352       switch (*fmt++) {
0353          case ' ': break;
0354          case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int));
0355                      s->func(s->context,&x,1);
0356                      break; }
0357          case '2': { int x = va_arg(v,int);
0358                      unsigned char b[2];
0359                      b[0] = STBIW_UCHAR(x);
0360                      b[1] = STBIW_UCHAR(x>>8);
0361                      s->func(s->context,b,2);
0362                      break; }
0363          case '4': { stbiw_uint32 x = va_arg(v,int);
0364                      unsigned char b[4];
0365                      b[0]=STBIW_UCHAR(x);
0366                      b[1]=STBIW_UCHAR(x>>8);
0367                      b[2]=STBIW_UCHAR(x>>16);
0368                      b[3]=STBIW_UCHAR(x>>24);
0369                      s->func(s->context,b,4);
0370                      break; }
0371          default:
0372             STBIW_ASSERT(0);
0373             return;
0374       }
0375    }
0376 }
0377 
0378 static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
0379 {
0380    va_list v;
0381    va_start(v, fmt);
0382    stbiw__writefv(s, fmt, v);
0383    va_end(v);
0384 }
0385 
0386 static void stbiw__write_flush(stbi__write_context *s)
0387 {
0388    if (s->buf_used) {
0389       s->func(s->context, &s->buffer, s->buf_used);
0390       s->buf_used = 0;
0391    }
0392 }
0393 
0394 static void stbiw__putc(stbi__write_context *s, unsigned char c)
0395 {
0396    s->func(s->context, &c, 1);
0397 }
0398 
0399 static void stbiw__write1(stbi__write_context *s, unsigned char a)
0400 {
0401    if ((size_t)s->buf_used + 1 > sizeof(s->buffer))
0402       stbiw__write_flush(s);
0403    s->buffer[s->buf_used++] = a;
0404 }
0405 
0406 static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
0407 {
0408    int n;
0409    if ((size_t)s->buf_used + 3 > sizeof(s->buffer))
0410       stbiw__write_flush(s);
0411    n = s->buf_used;
0412    s->buf_used = n+3;
0413    s->buffer[n+0] = a;
0414    s->buffer[n+1] = b;
0415    s->buffer[n+2] = c;
0416 }
0417 
0418 static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
0419 {
0420    unsigned char bg[3] = { 255, 0, 255}, px[3];
0421    int k;
0422 
0423    if (write_alpha < 0)
0424       stbiw__write1(s, d[comp - 1]);
0425 
0426    switch (comp) {
0427       case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
0428       case 1:
0429          if (expand_mono)
0430             stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
0431          else
0432             stbiw__write1(s, d[0]);  // monochrome TGA
0433          break;
0434       case 4:
0435          if (!write_alpha) {
0436             // composite against pink background
0437             for (k = 0; k < 3; ++k)
0438                px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
0439             stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
0440             break;
0441          }
0442          /* FALLTHROUGH */
0443       case 3:
0444          stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
0445          break;
0446    }
0447    if (write_alpha > 0)
0448       stbiw__write1(s, d[comp - 1]);
0449 }
0450 
0451 static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
0452 {
0453    stbiw_uint32 zero = 0;
0454    int i,j, j_end;
0455 
0456    if (y <= 0)
0457       return;
0458 
0459    if (stbi__flip_vertically_on_write)
0460       vdir *= -1;
0461 
0462    if (vdir < 0) {
0463       j_end = -1; j = y-1;
0464    } else {
0465       j_end =  y; j = 0;
0466    }
0467 
0468    for (; j != j_end; j += vdir) {
0469       for (i=0; i < x; ++i) {
0470          unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
0471          stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
0472       }
0473       stbiw__write_flush(s);
0474       s->func(s->context, &zero, scanline_pad);
0475    }
0476 }
0477 
0478 static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
0479 {
0480    if (y < 0 || x < 0) {
0481       return 0;
0482    } else {
0483       va_list v;
0484       va_start(v, fmt);
0485       stbiw__writefv(s, fmt, v);
0486       va_end(v);
0487       stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
0488       return 1;
0489    }
0490 }
0491 
0492 static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
0493 {
0494    if (comp != 4) {
0495       // write RGB bitmap
0496       int pad = (-x*3) & 3;
0497       return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
0498               "11 4 22 4" "4 44 22 444444",
0499               'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40,  // file header
0500                40, x,y, 1,24, 0,0,0,0,0,0);             // bitmap header
0501    } else {
0502       // RGBA bitmaps need a v4 header
0503       // use BI_BITFIELDS mode with 32bpp and alpha mask
0504       // (straight BI_RGB with alpha mask doesn't work in most readers)
0505       return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0,
0506          "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444",
0507          'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header
0508          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
0509    }
0510 }
0511 
0512 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
0513 {
0514    stbi__write_context s = { 0 };
0515    stbi__start_write_callbacks(&s, func, context);
0516    return stbi_write_bmp_core(&s, x, y, comp, data);
0517 }
0518 
0519 #ifndef STBI_WRITE_NO_STDIO
0520 STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
0521 {
0522    stbi__write_context s = { 0 };
0523    if (stbi__start_write_file(&s,filename)) {
0524       int r = stbi_write_bmp_core(&s, x, y, comp, data);
0525       stbi__end_write_file(&s);
0526       return r;
0527    } else
0528       return 0;
0529 }
0530 #endif //!STBI_WRITE_NO_STDIO
0531 
0532 static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
0533 {
0534    int has_alpha = (comp == 2 || comp == 4);
0535    int colorbytes = has_alpha ? comp-1 : comp;
0536    int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
0537 
0538    if (y < 0 || x < 0)
0539       return 0;
0540 
0541    if (!stbi_write_tga_with_rle) {
0542       return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
0543          "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
0544    } else {
0545       int i,j,k;
0546       int jend, jdir;
0547 
0548       stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8);
0549 
0550       if (stbi__flip_vertically_on_write) {
0551          j = 0;
0552          jend = y;
0553          jdir = 1;
0554       } else {
0555          j = y-1;
0556          jend = -1;
0557          jdir = -1;
0558       }
0559       for (; j != jend; j += jdir) {
0560          unsigned char *row = (unsigned char *) data + j * x * comp;
0561          int len;
0562 
0563          for (i = 0; i < x; i += len) {
0564             unsigned char *begin = row + i * comp;
0565             int diff = 1;
0566             len = 1;
0567 
0568             if (i < x - 1) {
0569                ++len;
0570                diff = memcmp(begin, row + (i + 1) * comp, comp);
0571                if (diff) {
0572                   const unsigned char *prev = begin;
0573                   for (k = i + 2; k < x && len < 128; ++k) {
0574                      if (memcmp(prev, row + k * comp, comp)) {
0575                         prev += comp;
0576                         ++len;
0577                      } else {
0578                         --len;
0579                         break;
0580                      }
0581                   }
0582                } else {
0583                   for (k = i + 2; k < x && len < 128; ++k) {
0584                      if (!memcmp(begin, row + k * comp, comp)) {
0585                         ++len;
0586                      } else {
0587                         break;
0588                      }
0589                   }
0590                }
0591             }
0592 
0593             if (diff) {
0594                unsigned char header = STBIW_UCHAR(len - 1);
0595                stbiw__write1(s, header);
0596                for (k = 0; k < len; ++k) {
0597                   stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
0598                }
0599             } else {
0600                unsigned char header = STBIW_UCHAR(len - 129);
0601                stbiw__write1(s, header);
0602                stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
0603             }
0604          }
0605       }
0606       stbiw__write_flush(s);
0607    }
0608    return 1;
0609 }
0610 
0611 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
0612 {
0613    stbi__write_context s = { 0 };
0614    stbi__start_write_callbacks(&s, func, context);
0615    return stbi_write_tga_core(&s, x, y, comp, (void *) data);
0616 }
0617 
0618 #ifndef STBI_WRITE_NO_STDIO
0619 STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
0620 {
0621    stbi__write_context s = { 0 };
0622    if (stbi__start_write_file(&s,filename)) {
0623       int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
0624       stbi__end_write_file(&s);
0625       return r;
0626    } else
0627       return 0;
0628 }
0629 #endif
0630 
0631 // *************************************************************************************************
0632 // Radiance RGBE HDR writer
0633 // by Baldur Karlsson
0634 
0635 #define stbiw__max(a, b)  ((a) > (b) ? (a) : (b))
0636 
0637 #ifndef STBI_WRITE_NO_STDIO
0638 
0639 static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
0640 {
0641    int exponent;
0642    float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
0643 
0644    if (maxcomp < 1e-32f) {
0645       rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
0646    } else {
0647       float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
0648 
0649       rgbe[0] = (unsigned char)(linear[0] * normalize);
0650       rgbe[1] = (unsigned char)(linear[1] * normalize);
0651       rgbe[2] = (unsigned char)(linear[2] * normalize);
0652       rgbe[3] = (unsigned char)(exponent + 128);
0653    }
0654 }
0655 
0656 static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
0657 {
0658    unsigned char lengthbyte = STBIW_UCHAR(length+128);
0659    STBIW_ASSERT(length+128 <= 255);
0660    s->func(s->context, &lengthbyte, 1);
0661    s->func(s->context, &databyte, 1);
0662 }
0663 
0664 static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
0665 {
0666    unsigned char lengthbyte = STBIW_UCHAR(length);
0667    STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
0668    s->func(s->context, &lengthbyte, 1);
0669    s->func(s->context, data, length);
0670 }
0671 
0672 static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
0673 {
0674    unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
0675    unsigned char rgbe[4];
0676    float linear[3];
0677    int x;
0678 
0679    scanlineheader[2] = (width&0xff00)>>8;
0680    scanlineheader[3] = (width&0x00ff);
0681 
0682    /* skip RLE for images too small or large */
0683    if (width < 8 || width >= 32768) {
0684       for (x=0; x < width; x++) {
0685          switch (ncomp) {
0686             case 4: /* fallthrough */
0687             case 3: linear[2] = scanline[x*ncomp + 2];
0688                     linear[1] = scanline[x*ncomp + 1];
0689                     linear[0] = scanline[x*ncomp + 0];
0690                     break;
0691             default:
0692                     linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
0693                     break;
0694          }
0695          stbiw__linear_to_rgbe(rgbe, linear);
0696          s->func(s->context, rgbe, 4);
0697       }
0698    } else {
0699       int c,r;
0700       /* encode into scratch buffer */
0701       for (x=0; x < width; x++) {
0702          switch(ncomp) {
0703             case 4: /* fallthrough */
0704             case 3: linear[2] = scanline[x*ncomp + 2];
0705                     linear[1] = scanline[x*ncomp + 1];
0706                     linear[0] = scanline[x*ncomp + 0];
0707                     break;
0708             default:
0709                     linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
0710                     break;
0711          }
0712          stbiw__linear_to_rgbe(rgbe, linear);
0713          scratch[x + width*0] = rgbe[0];
0714          scratch[x + width*1] = rgbe[1];
0715          scratch[x + width*2] = rgbe[2];
0716          scratch[x + width*3] = rgbe[3];
0717       }
0718 
0719       s->func(s->context, scanlineheader, 4);
0720 
0721       /* RLE each component separately */
0722       for (c=0; c < 4; c++) {
0723          unsigned char *comp = &scratch[width*c];
0724 
0725          x = 0;
0726          while (x < width) {
0727             // find first run
0728             r = x;
0729             while (r+2 < width) {
0730                if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
0731                   break;
0732                ++r;
0733             }
0734             if (r+2 >= width)
0735                r = width;
0736             // dump up to first run
0737             while (x < r) {
0738                int len = r-x;
0739                if (len > 128) len = 128;
0740                stbiw__write_dump_data(s, len, &comp[x]);
0741                x += len;
0742             }
0743             // if there's a run, output it
0744             if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
0745                // find next byte after run
0746                while (r < width && comp[r] == comp[x])
0747                   ++r;
0748                // output run up to r
0749                while (x < r) {
0750                   int len = r-x;
0751                   if (len > 127) len = 127;
0752                   stbiw__write_run_data(s, len, comp[x]);
0753                   x += len;
0754                }
0755             }
0756          }
0757       }
0758    }
0759 }
0760 
0761 static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
0762 {
0763    if (y <= 0 || x <= 0 || data == NULL)
0764       return 0;
0765    else {
0766       // Each component is stored separately. Allocate scratch space for full output scanline.
0767       unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
0768       int i, len;
0769       char buffer[128];
0770       char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
0771       s->func(s->context, header, sizeof(header)-1);
0772 
0773 #ifdef __STDC_LIB_EXT1__
0774       len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
0775 #else
0776       len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
0777 #endif
0778       s->func(s->context, buffer, len);
0779 
0780       for(i=0; i < y; i++)
0781          stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
0782       STBIW_FREE(scratch);
0783       return 1;
0784    }
0785 }
0786 
0787 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
0788 {
0789    stbi__write_context s = { 0 };
0790    stbi__start_write_callbacks(&s, func, context);
0791    return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
0792 }
0793 
0794 STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
0795 {
0796    stbi__write_context s = { 0 };
0797    if (stbi__start_write_file(&s,filename)) {
0798       int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
0799       stbi__end_write_file(&s);
0800       return r;
0801    } else
0802       return 0;
0803 }
0804 #endif // STBI_WRITE_NO_STDIO
0805 
0806 
0807 //////////////////////////////////////////////////////////////////////////////
0808 //
0809 // PNG writer
0810 //
0811 
0812 #ifndef STBIW_ZLIB_COMPRESS
0813 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
0814 #define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
0815 #define stbiw__sbm(a)   stbiw__sbraw(a)[0]
0816 #define stbiw__sbn(a)   stbiw__sbraw(a)[1]
0817 
0818 #define stbiw__sbneedgrow(a,n)  ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
0819 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
0820 #define stbiw__sbgrow(a,n)  stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
0821 
0822 #define stbiw__sbpush(a, v)      (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
0823 #define stbiw__sbcount(a)        ((a) ? stbiw__sbn(a) : 0)
0824 #define stbiw__sbfree(a)         ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
0825 
0826 static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
0827 {
0828    int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
0829    void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
0830    STBIW_ASSERT(p);
0831    if (p) {
0832       if (!*arr) ((int *) p)[1] = 0;
0833       *arr = (void *) ((int *) p + 2);
0834       stbiw__sbm(*arr) = m;
0835    }
0836    return *arr;
0837 }
0838 
0839 static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
0840 {
0841    while (*bitcount >= 8) {
0842       stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
0843       *bitbuffer >>= 8;
0844       *bitcount -= 8;
0845    }
0846    return data;
0847 }
0848 
0849 static int stbiw__zlib_bitrev(int code, int codebits)
0850 {
0851    int res=0;
0852    while (codebits--) {
0853       res = (res << 1) | (code & 1);
0854       code >>= 1;
0855    }
0856    return res;
0857 }
0858 
0859 static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
0860 {
0861    int i;
0862    for (i=0; i < limit && i < 258; ++i)
0863       if (a[i] != b[i]) break;
0864    return i;
0865 }
0866 
0867 static unsigned int stbiw__zhash(unsigned char *data)
0868 {
0869    stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
0870    hash ^= hash << 3;
0871    hash += hash >> 5;
0872    hash ^= hash << 4;
0873    hash += hash >> 17;
0874    hash ^= hash << 25;
0875    hash += hash >> 6;
0876    return hash;
0877 }
0878 
0879 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
0880 #define stbiw__zlib_add(code,codebits) \
0881       (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
0882 #define stbiw__zlib_huffa(b,c)  stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
0883 // default huffman tables
0884 #define stbiw__zlib_huff1(n)  stbiw__zlib_huffa(0x30 + (n), 8)
0885 #define stbiw__zlib_huff2(n)  stbiw__zlib_huffa(0x190 + (n)-144, 9)
0886 #define stbiw__zlib_huff3(n)  stbiw__zlib_huffa(0 + (n)-256,7)
0887 #define stbiw__zlib_huff4(n)  stbiw__zlib_huffa(0xc0 + (n)-280,8)
0888 #define stbiw__zlib_huff(n)  ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
0889 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
0890 
0891 #define stbiw__ZHASH   16384
0892 
0893 #endif // STBIW_ZLIB_COMPRESS
0894 
0895 STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
0896 {
0897 #ifdef STBIW_ZLIB_COMPRESS
0898    // user provided a zlib compress implementation, use that
0899    return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
0900 #else // use builtin
0901    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 };
0902    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 };
0903    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 };
0904    static unsigned char  disteb[]  = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
0905    unsigned int bitbuf=0;
0906    int i,j, bitcount=0;
0907    unsigned char *out = NULL;
0908    unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
0909    if (hash_table == NULL)
0910       return NULL;
0911    if (quality < 5) quality = 5;
0912 
0913    stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
0914    stbiw__sbpush(out, 0x5e);   // FLEVEL = 1
0915    stbiw__zlib_add(1,1);  // BFINAL = 1
0916    stbiw__zlib_add(1,2);  // BTYPE = 1 -- fixed huffman
0917 
0918    for (i=0; i < stbiw__ZHASH; ++i)
0919       hash_table[i] = NULL;
0920 
0921    i=0;
0922    while (i < data_len-3) {
0923       // hash next 3 bytes of data to be compressed
0924       int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
0925       unsigned char *bestloc = 0;
0926       unsigned char **hlist = hash_table[h];
0927       int n = stbiw__sbcount(hlist);
0928       for (j=0; j < n; ++j) {
0929          if (hlist[j]-data > i-32768) { // if entry lies within window
0930             int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
0931             if (d >= best) { best=d; bestloc=hlist[j]; }
0932          }
0933       }
0934       // when hash table entry is too long, delete half the entries
0935       if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
0936          STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
0937          stbiw__sbn(hash_table[h]) = quality;
0938       }
0939       stbiw__sbpush(hash_table[h],data+i);
0940 
0941       if (bestloc) {
0942          // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
0943          h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
0944          hlist = hash_table[h];
0945          n = stbiw__sbcount(hlist);
0946          for (j=0; j < n; ++j) {
0947             if (hlist[j]-data > i-32767) {
0948                int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
0949                if (e > best) { // if next match is better, bail on current match
0950                   bestloc = NULL;
0951                   break;
0952                }
0953             }
0954          }
0955       }
0956 
0957       if (bestloc) {
0958          int d = (int) (data+i - bestloc); // distance back
0959          STBIW_ASSERT(d <= 32767 && best <= 258);
0960          for (j=0; best > lengthc[j+1]-1; ++j);
0961          stbiw__zlib_huff(j+257);
0962          if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
0963          for (j=0; d > distc[j+1]-1; ++j);
0964          stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
0965          if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
0966          i += best;
0967       } else {
0968          stbiw__zlib_huffb(data[i]);
0969          ++i;
0970       }
0971    }
0972    // write out final bytes
0973    for (;i < data_len; ++i)
0974       stbiw__zlib_huffb(data[i]);
0975    stbiw__zlib_huff(256); // end of block
0976    // pad with 0 bits to byte boundary
0977    while (bitcount)
0978       stbiw__zlib_add(0,1);
0979 
0980    for (i=0; i < stbiw__ZHASH; ++i)
0981       (void) stbiw__sbfree(hash_table[i]);
0982    STBIW_FREE(hash_table);
0983 
0984    // store uncompressed instead if compression was worse
0985    if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
0986       stbiw__sbn(out) = 2;  // truncate to DEFLATE 32K window and FLEVEL = 1
0987       for (j = 0; j < data_len;) {
0988          int blocklen = data_len - j;
0989          if (blocklen > 32767) blocklen = 32767;
0990          stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
0991          stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
0992          stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
0993          stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
0994          stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
0995          memcpy(out+stbiw__sbn(out), data+j, blocklen);
0996          stbiw__sbn(out) += blocklen;
0997          j += blocklen;
0998       }
0999    }
1000 
1001    {
1002       // compute adler32 on input
1003       unsigned int s1=1, s2=0;
1004       int blocklen = (int) (data_len % 5552);
1005       j=0;
1006       while (j < data_len) {
1007          for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
1008          s1 %= 65521; s2 %= 65521;
1009          j += blocklen;
1010          blocklen = 5552;
1011       }
1012       stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
1013       stbiw__sbpush(out, STBIW_UCHAR(s2));
1014       stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
1015       stbiw__sbpush(out, STBIW_UCHAR(s1));
1016    }
1017    *out_len = stbiw__sbn(out);
1018    // make returned pointer freeable
1019    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
1020    return (unsigned char *) stbiw__sbraw(out);
1021 #endif // STBIW_ZLIB_COMPRESS
1022 }
1023 
1024 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
1025 {
1026 #ifdef STBIW_CRC32
1027     return STBIW_CRC32(buffer, len);
1028 #else
1029    static unsigned int crc_table[256] =
1030    {
1031       0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
1032       0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
1033       0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
1034       0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
1035       0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
1036       0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
1037       0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
1038       0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
1039       0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
1040       0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
1041       0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
1042       0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1043       0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
1044       0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
1045       0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1046       0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
1047       0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
1048       0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1049       0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
1050       0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
1051       0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1052       0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
1053       0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
1054       0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1055       0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
1056       0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
1057       0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1058       0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
1059       0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
1060       0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1061       0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
1062       0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
1063    };
1064 
1065    unsigned int crc = ~0u;
1066    int i;
1067    for (i=0; i < len; ++i)
1068       crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
1069    return ~crc;
1070 #endif
1071 }
1072 
1073 #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
1074 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
1075 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
1076 
1077 static void stbiw__wpcrc(unsigned char **data, int len)
1078 {
1079    unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
1080    stbiw__wp32(*data, crc);
1081 }
1082 
1083 static unsigned char stbiw__paeth(int a, int b, int c)
1084 {
1085    int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
1086    if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
1087    if (pb <= pc) return STBIW_UCHAR(b);
1088    return STBIW_UCHAR(c);
1089 }
1090 
1091 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
1092 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)
1093 {
1094    static int mapping[] = { 0,1,2,3,4 };
1095    static int firstmap[] = { 0,1,0,5,6 };
1096    int *mymap = (y != 0) ? mapping : firstmap;
1097    int i;
1098    int type = mymap[filter_type];
1099    unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
1100    int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
1101 
1102    if (type==0) {
1103       memcpy(line_buffer, z, width*n);
1104       return;
1105    }
1106 
1107    // first loop isn't optimized since it's just one pixel
1108    for (i = 0; i < n; ++i) {
1109       switch (type) {
1110          case 1: line_buffer[i] = z[i]; break;
1111          case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1112          case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
1113          case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
1114          case 5: line_buffer[i] = z[i]; break;
1115          case 6: line_buffer[i] = z[i]; break;
1116       }
1117    }
1118    switch (type) {
1119       case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
1120       case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
1121       case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1122       case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
1123       case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
1124       case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1125    }
1126 }
1127 
1128 STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1129 {
1130    int force_filter = stbi_write_force_png_filter;
1131    int ctype[5] = { -1, 0, 4, 2, 6 };
1132    unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
1133    unsigned char *out,*o, *filt, *zlib;
1134    signed char *line_buffer;
1135    int j,zlen;
1136 
1137    if (stride_bytes == 0)
1138       stride_bytes = x * n;
1139 
1140    if (force_filter >= 5) {
1141       force_filter = -1;
1142    }
1143 
1144    filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
1145    line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
1146    for (j=0; j < y; ++j) {
1147       int filter_type;
1148       if (force_filter > -1) {
1149          filter_type = force_filter;
1150          stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
1151       } else { // Estimate the best filter by running through all of them:
1152          int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1153          for (filter_type = 0; filter_type < 5; filter_type++) {
1154             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
1155 
1156             // Estimate the entropy of the line using this filter; the less, the better.
1157             est = 0;
1158             for (i = 0; i < x*n; ++i) {
1159                est += abs((signed char) line_buffer[i]);
1160             }
1161             if (est < best_filter_val) {
1162                best_filter_val = est;
1163                best_filter = filter_type;
1164             }
1165          }
1166          if (filter_type != best_filter) {  // If the last iteration already got us the best filter, don't redo it
1167             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
1168             filter_type = best_filter;
1169          }
1170       }
1171       // when we get here, filter_type contains the filter type, and line_buffer contains the data
1172       filt[j*(x*n+1)] = (unsigned char) filter_type;
1173       STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
1174    }
1175    STBIW_FREE(line_buffer);
1176    zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level);
1177    STBIW_FREE(filt);
1178    if (!zlib) return 0;
1179 
1180    // each tag requires 12 bytes of overhead
1181    out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
1182    if (!out) return 0;
1183    *out_len = 8 + 12+13 + 12+zlen + 12;
1184 
1185    o=out;
1186    STBIW_MEMMOVE(o,sig,8); o+= 8;
1187    stbiw__wp32(o, 13); // header length
1188    stbiw__wptag(o, "IHDR");
1189    stbiw__wp32(o, x);
1190    stbiw__wp32(o, y);
1191    *o++ = 8;
1192    *o++ = STBIW_UCHAR(ctype[n]);
1193    *o++ = 0;
1194    *o++ = 0;
1195    *o++ = 0;
1196    stbiw__wpcrc(&o,13);
1197 
1198    stbiw__wp32(o, zlen);
1199    stbiw__wptag(o, "IDAT");
1200    STBIW_MEMMOVE(o, zlib, zlen);
1201    o += zlen;
1202    STBIW_FREE(zlib);
1203    stbiw__wpcrc(&o, zlen);
1204 
1205    stbiw__wp32(o,0);
1206    stbiw__wptag(o, "IEND");
1207    stbiw__wpcrc(&o,0);
1208 
1209    STBIW_ASSERT(o == out + *out_len);
1210 
1211    return out;
1212 }
1213 
1214 #ifndef STBI_WRITE_NO_STDIO
1215 STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
1216 {
1217    FILE *f;
1218    int len;
1219    unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1220    if (png == NULL) return 0;
1221 
1222    f = stbiw__fopen(filename, "wb");
1223    if (!f) { STBIW_FREE(png); return 0; }
1224    fwrite(png, 1, len, f);
1225    fclose(f);
1226    STBIW_FREE(png);
1227    return 1;
1228 }
1229 #endif
1230 
1231 STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
1232 {
1233    int len;
1234    unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1235    if (png == NULL) return 0;
1236    func(context, png, len);
1237    STBIW_FREE(png);
1238    return 1;
1239 }
1240 
1241 
1242 /* ***************************************************************************
1243  *
1244  * JPEG writer
1245  *
1246  * This is based on Jon Olick's jo_jpeg.cpp:
1247  * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html
1248  */
1249 
1250 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,
1251       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 };
1252 
1253 static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) {
1254    int bitBuf = *bitBufP, bitCnt = *bitCntP;
1255    bitCnt += bs[1];
1256    bitBuf |= bs[0] << (24 - bitCnt);
1257    while(bitCnt >= 8) {
1258       unsigned char c = (bitBuf >> 16) & 255;
1259       stbiw__putc(s, c);
1260       if(c == 255) {
1261          stbiw__putc(s, 0);
1262       }
1263       bitBuf <<= 8;
1264       bitCnt -= 8;
1265    }
1266    *bitBufP = bitBuf;
1267    *bitCntP = bitCnt;
1268 }
1269 
1270 static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) {
1271    float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
1272    float z1, z2, z3, z4, z5, z11, z13;
1273 
1274    float tmp0 = d0 + d7;
1275    float tmp7 = d0 - d7;
1276    float tmp1 = d1 + d6;
1277    float tmp6 = d1 - d6;
1278    float tmp2 = d2 + d5;
1279    float tmp5 = d2 - d5;
1280    float tmp3 = d3 + d4;
1281    float tmp4 = d3 - d4;
1282 
1283    // Even part
1284    float tmp10 = tmp0 + tmp3;   // phase 2
1285    float tmp13 = tmp0 - tmp3;
1286    float tmp11 = tmp1 + tmp2;
1287    float tmp12 = tmp1 - tmp2;
1288 
1289    d0 = tmp10 + tmp11;       // phase 3
1290    d4 = tmp10 - tmp11;
1291 
1292    z1 = (tmp12 + tmp13) * 0.707106781f; // c4
1293    d2 = tmp13 + z1;       // phase 5
1294    d6 = tmp13 - z1;
1295 
1296    // Odd part
1297    tmp10 = tmp4 + tmp5;       // phase 2
1298    tmp11 = tmp5 + tmp6;
1299    tmp12 = tmp6 + tmp7;
1300 
1301    // The rotator is modified from fig 4-8 to avoid extra negations.
1302    z5 = (tmp10 - tmp12) * 0.382683433f; // c6
1303    z2 = tmp10 * 0.541196100f + z5; // c2-c6
1304    z4 = tmp12 * 1.306562965f + z5; // c2+c6
1305    z3 = tmp11 * 0.707106781f; // c4
1306 
1307    z11 = tmp7 + z3;      // phase 5
1308    z13 = tmp7 - z3;
1309 
1310    *d5p = z13 + z2;         // phase 6
1311    *d3p = z13 - z2;
1312    *d1p = z11 + z4;
1313    *d7p = z11 - z4;
1314 
1315    *d0p = d0;  *d2p = d2;  *d4p = d4;  *d6p = d6;
1316 }
1317 
1318 static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
1319    int tmp1 = val < 0 ? -val : val;
1320    val = val < 0 ? val-1 : val;
1321    bits[1] = 1;
1322    while(tmp1 >>= 1) {
1323       ++bits[1];
1324    }
1325    bits[0] = val & ((1<<bits[1])-1);
1326 }
1327 
1328 static int stbiw__jpg_processDU(stbi__write_context *s, int *bitBuf, int *bitCnt, float *CDU, int du_stride, float *fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) {
1329    const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
1330    const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
1331    int dataOff, i, j, n, diff, end0pos, x, y;
1332    int DU[64];
1333 
1334    // DCT rows
1335    for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
1336       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]);
1337    }
1338    // DCT columns
1339    for(dataOff=0; dataOff<8; ++dataOff) {
1340       stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
1341                      &CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
1342    }
1343    // Quantize/descale/zigzag the coefficients
1344    for(y = 0, j=0; y < 8; ++y) {
1345       for(x = 0; x < 8; ++x,++j) {
1346          float v;
1347          i = y*du_stride+x;
1348          v = CDU[i]*fdtbl[j];
1349          // DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
1350          // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
1351          DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
1352       }
1353    }
1354 
1355    // Encode DC
1356    diff = DU[0] - DC;
1357    if (diff == 0) {
1358       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
1359    } else {
1360       unsigned short bits[2];
1361       stbiw__jpg_calcBits(diff, bits);
1362       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
1363       stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1364    }
1365    // Encode ACs
1366    end0pos = 63;
1367    for(; (end0pos>0)&&(DU[end0pos]==0); --end0pos) {
1368    }
1369    // end0pos = first element in reverse order !=0
1370    if(end0pos == 0) {
1371       stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1372       return DU[0];
1373    }
1374    for(i = 1; i <= end0pos; ++i) {
1375       int startpos = i;
1376       int nrzeroes;
1377       unsigned short bits[2];
1378       for (; DU[i]==0 && i<=end0pos; ++i) {
1379       }
1380       nrzeroes = i-startpos;
1381       if ( nrzeroes >= 16 ) {
1382          int lng = nrzeroes>>4;
1383          int nrmarker;
1384          for (nrmarker=1; nrmarker <= lng; ++nrmarker)
1385             stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
1386          nrzeroes &= 15;
1387       }
1388       stbiw__jpg_calcBits(DU[i], bits);
1389       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]);
1390       stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1391    }
1392    if(end0pos != 63) {
1393       stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1394    }
1395    return DU[0];
1396 }
1397 
1398 static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) {
1399    // Constants that don't pollute global namespace
1400    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};
1401    static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1402    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};
1403    static const unsigned char std_ac_luminance_values[] = {
1404       0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
1405       0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
1406       0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
1407       0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1408       0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
1409       0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
1410       0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1411    };
1412    static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};
1413    static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1414    static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};
1415    static const unsigned char std_ac_chrominance_values[] = {
1416       0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
1417       0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
1418       0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
1419       0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
1420       0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
1421       0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
1422       0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1423    };
1424    // Huffman tables
1425    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}};
1426    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}};
1427    static const unsigned short YAC_HT[256][2] = {
1428       {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1429       {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1430       {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1431       {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1432       {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1433       {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1434       {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1435       {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1436       {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1437       {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1438       {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1439       {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1440       {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1441       {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1442       {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1443       {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1444    };
1445    static const unsigned short UVAC_HT[256][2] = {
1446       {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1447       {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1448       {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1449       {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1450       {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1451       {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1452       {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1453       {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1454       {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1455       {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1456       {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1457       {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1458       {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1459       {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1460       {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1461       {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1462    };
1463    static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,
1464                              37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
1465    static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
1466                               99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
1467    static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1468                                  1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
1469 
1470    int row, col, i, k, subsample;
1471    float fdtbl_Y[64], fdtbl_UV[64];
1472    unsigned char YTable[64], UVTable[64];
1473 
1474    if(!data || !width || !height || comp > 4 || comp < 1) {
1475       return 0;
1476    }
1477 
1478    quality = quality ? quality : 90;
1479    subsample = quality <= 90 ? 1 : 0;
1480    quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
1481    quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
1482 
1483    for(i = 0; i < 64; ++i) {
1484       int uvti, yti = (YQT[i]*quality+50)/100;
1485       YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti);
1486       uvti = (UVQT[i]*quality+50)/100;
1487       UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
1488    }
1489 
1490    for(row = 0, k = 0; row < 8; ++row) {
1491       for(col = 0; col < 8; ++col, ++k) {
1492          fdtbl_Y[k]  = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1493          fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1494       }
1495    }
1496 
1497    // Write Headers
1498    {
1499       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 };
1500       static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
1501       const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
1502                                       3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1503       s->func(s->context, (void*)head0, sizeof(head0));
1504       s->func(s->context, (void*)YTable, sizeof(YTable));
1505       stbiw__putc(s, 1);
1506       s->func(s->context, UVTable, sizeof(UVTable));
1507       s->func(s->context, (void*)head1, sizeof(head1));
1508       s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1);
1509       s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values));
1510       stbiw__putc(s, 0x10); // HTYACinfo
1511       s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1);
1512       s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values));
1513       stbiw__putc(s, 1); // HTUDCinfo
1514       s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1);
1515       s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
1516       stbiw__putc(s, 0x11); // HTUACinfo
1517       s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1);
1518       s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
1519       s->func(s->context, (void*)head2, sizeof(head2));
1520    }
1521 
1522    // Encode 8x8 macroblocks
1523    {
1524       static const unsigned short fillBits[] = {0x7F, 7};
1525       int DCY=0, DCU=0, DCV=0;
1526       int bitBuf=0, bitCnt=0;
1527       // comp == 2 is grey+alpha (alpha is ignored)
1528       int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
1529       const unsigned char *dataR = (const unsigned char *)data;
1530       const unsigned char *dataG = dataR + ofsG;
1531       const unsigned char *dataB = dataR + ofsB;
1532       int x, y, pos;
1533       if(subsample) {
1534          for(y = 0; y < height; y += 16) {
1535             for(x = 0; x < width; x += 16) {
1536                float Y[256], U[256], V[256];
1537                for(row = y, pos = 0; row < y+16; ++row) {
1538                   // row >= height => use last input row
1539                   int clamped_row = (row < height) ? row : height - 1;
1540                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1541                   for(col = x; col < x+16; ++col, ++pos) {
1542                      // if col >= width => use pixel from last input column
1543                      int p = base_p + ((col < width) ? col : (width-1))*comp;
1544                      float r = dataR[p], g = dataG[p], b = dataB[p];
1545                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1546                      U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1547                      V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1548                   }
1549                }
1550                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0,   16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1551                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8,   16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1552                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1553                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1554 
1555                // subsample U,V
1556                {
1557                   float subU[64], subV[64];
1558                   int yy, xx;
1559                   for(yy = 0, pos = 0; yy < 8; ++yy) {
1560                      for(xx = 0; xx < 8; ++xx, ++pos) {
1561                         int j = yy*32+xx*2;
1562                         subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
1563                         subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
1564                      }
1565                   }
1566                   DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1567                   DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1568                }
1569             }
1570          }
1571       } else {
1572          for(y = 0; y < height; y += 8) {
1573             for(x = 0; x < width; x += 8) {
1574                float Y[64], U[64], V[64];
1575                for(row = y, pos = 0; row < y+8; ++row) {
1576                   // row >= height => use last input row
1577                   int clamped_row = (row < height) ? row : height - 1;
1578                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1579                   for(col = x; col < x+8; ++col, ++pos) {
1580                      // if col >= width => use pixel from last input column
1581                      int p = base_p + ((col < width) ? col : (width-1))*comp;
1582                      float r = dataR[p], g = dataG[p], b = dataB[p];
1583                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1584                      U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1585                      V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1586                   }
1587                }
1588 
1589                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y,  DCY, YDC_HT, YAC_HT);
1590                DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1591                DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1592             }
1593          }
1594       }
1595 
1596       // Do the bit alignment of the EOI marker
1597       stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
1598    }
1599 
1600    // EOI
1601    stbiw__putc(s, 0xFF);
1602    stbiw__putc(s, 0xD9);
1603 
1604    return 1;
1605 }
1606 
1607 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
1608 {
1609    stbi__write_context s = { 0 };
1610    stbi__start_write_callbacks(&s, func, context);
1611    return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
1612 }
1613 
1614 
1615 #ifndef STBI_WRITE_NO_STDIO
1616 STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
1617 {
1618    stbi__write_context s = { 0 };
1619    if (stbi__start_write_file(&s,filename)) {
1620       int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
1621       stbi__end_write_file(&s);
1622       return r;
1623    } else
1624       return 0;
1625 }
1626 #endif
1627 
1628 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1629 
1630 /* Revision history
1631       1.16  (2021-07-11)
1632              make Deflate code emit uncompressed blocks when it would otherwise expand
1633              support writing BMPs with alpha channel
1634       1.15  (2020-07-13) unknown
1635       1.14  (2020-02-02) updated JPEG writer to downsample chroma channels
1636       1.13
1637       1.12
1638       1.11  (2019-08-11)
1639 
1640       1.10  (2019-02-07)
1641              support utf8 filenames in Windows; fix warnings and platform ifdefs
1642       1.09  (2018-02-11)
1643              fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1644       1.08  (2018-01-29)
1645              add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
1646       1.07  (2017-07-24)
1647              doc fix
1648       1.06 (2017-07-23)
1649              writing JPEG (using Jon Olick's code)
1650       1.05   ???
1651       1.04 (2017-03-03)
1652              monochrome BMP expansion
1653       1.03   ???
1654       1.02 (2016-04-02)
1655              avoid allocating large structures on the stack
1656       1.01 (2016-01-16)
1657              STBIW_REALLOC_SIZED: support allocators with no realloc support
1658              avoid race-condition in crc initialization
1659              minor compile issues
1660       1.00 (2015-09-14)
1661              installable file IO function
1662       0.99 (2015-09-13)
1663              warning fixes; TGA rle support
1664       0.98 (2015-04-08)
1665              added STBIW_MALLOC, STBIW_ASSERT etc
1666       0.97 (2015-01-18)
1667              fixed HDR asserts, rewrote HDR rle logic
1668       0.96 (2015-01-17)
1669              add HDR output
1670              fix monochrome BMP
1671       0.95 (2014-08-17)
1672              add monochrome TGA output
1673       0.94 (2014-05-31)
1674              rename private functions to avoid conflicts with stb_image.h
1675       0.93 (2014-05-27)
1676              warning fixes
1677       0.92 (2010-08-01)
1678              casts to unsigned char to fix warnings
1679       0.91 (2010-07-17)
1680              first public release
1681       0.90   first internal release
1682 */
1683 
1684 /*
1685 ------------------------------------------------------------------------------
1686 This software is available under 2 licenses -- choose whichever you prefer.
1687 ------------------------------------------------------------------------------
1688 ALTERNATIVE A - MIT License
1689 Copyright (c) 2017 Sean Barrett
1690 Permission is hereby granted, free of charge, to any person obtaining a copy of
1691 this software and associated documentation files (the "Software"), to deal in
1692 the Software without restriction, including without limitation the rights to
1693 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1694 of the Software, and to permit persons to whom the Software is furnished to do
1695 so, subject to the following conditions:
1696 The above copyright notice and this permission notice shall be included in all
1697 copies or substantial portions of the Software.
1698 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1699 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1700 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1701 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1702 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1703 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1704 SOFTWARE.
1705 ------------------------------------------------------------------------------
1706 ALTERNATIVE B - Public Domain (www.unlicense.org)
1707 This is free and unencumbered software released into the public domain.
1708 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1709 software, either in source code form or as a compiled binary, for any purpose,
1710 commercial or non-commercial, and by any means.
1711 In jurisdictions that recognize copyright laws, the author or authors of this
1712 software dedicate any and all copyright interest in the software to the public
1713 domain. We make this dedication for the benefit of the public at large and to
1714 the detriment of our heirs and successors. We intend this dedication to be an
1715 overt act of relinquishment in perpetuity of all present and future rights to
1716 this software under copyright law.
1717 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1718 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1719 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1720 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1721 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1722 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1723 ------------------------------------------------------------------------------
1724 */