1 /* stb_image_write - v1.14 - public domain - http://nothings.org/stb
2    writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
3                                      no warranty implied; use at your own risk
4 
5    Before #including,
6 
7        #define STB_IMAGE_WRITE_IMPLEMENTATION
8 
9    in the file that you want to have the implementation.
10 
11    Will probably not work correctly with strict-aliasing optimizations.
12 
13 ABOUT:
14 
15    This header file is a library for writing images to C stdio or a callback.
16 
17    The PNG output is not optimal; it is 20-50% larger than the file
18    written by a decent optimizing implementation; though providing a custom
19    zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that.
20    This library is designed for source code compactness and simplicity,
21    not optimal image file size or run-time performance.
22 
23 BUILDING:
24 
25    You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
26    You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
27    malloc,realloc,free.
28    You can #define STBIW_MEMMOVE() to replace memmove()
29    You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function
30    for PNG compression (instead of the builtin one), it must have the following signature:
31    unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality);
32    The returned data will be freed with STBIW_FREE() (free() by default),
33    so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
34 
35 UNICODE:
36 
37    If compiling for Windows and you wish to use Unicode filenames, compile
38    with
39        #define STBIW_WINDOWS_UTF8
40    and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
41    Windows wchar_t filenames to utf8.
42 
43 USAGE:
44 
45    There are five functions, one for each image file format:
46 
47      int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
48      int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
49      int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
50      int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
51      int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
52 
53      void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
54 
55    There are also five equivalent functions that use an arbitrary write function. You are
56    expected to open/close your file-equivalent before and after calling these:
57 
58      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);
59      int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
60      int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
61      int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
62      int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality);
63 
64    where the callback is:
65       void stbi_write_func(void *context, void *data, int size);
66 
67    You can configure it with these global variables:
68       int stbi_write_tga_with_rle;             // defaults to true; set to 0 to disable RLE
69       int stbi_write_png_compression_level;    // defaults to 8; set to higher for more compression
70       int stbi_write_force_png_filter;         // defaults to -1; set to 0..5 to force a filter mode
71 
72 
73    You can define STBI_WRITE_NO_STDIO to disable the file variant of these
74    functions, so the library will not use stdio.h at all. However, this will
75    also disable HDR writing, because it requires stdio for formatted output.
76 
77    Each function returns 0 on failure and non-0 on success.
78 
79    The functions create an image file defined by the parameters. The image
80    is a rectangle of pixels stored from left-to-right, top-to-bottom.
81    Each pixel contains 'comp' channels of data stored interleaved with 8-bits
82    per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
83    monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
84    The *data pointer points to the first byte of the top-left-most pixel.
85    For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
86    a row of pixels to the first byte of the next row of pixels.
87 
88    PNG creates output files with the same number of components as the input.
89    The BMP format expands Y to RGB in the file format and does not
90    output alpha.
91 
92    PNG supports writing rectangles of data even when the bytes storing rows of
93    data are not consecutive in memory (e.g. sub-rectangles of a larger image),
94    by supplying the stride between the beginning of adjacent rows. The other
95    formats do not. (Thus you cannot write a native-format BMP through the BMP
96    writer, both because it is in BGR order and because it may have padding
97    at the end of the line.)
98 
99    PNG allows you to set the deflate compression level by setting the global
100    variable 'stbi_write_png_compression_level' (it defaults to 8).
101 
102    HDR expects linear float data. Since the format is always 32-bit rgb(e)
103    data, alpha (if provided) is discarded, and for monochrome data it is
104    replicated across all three channels.
105 
106    TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
107    data, set the global variable 'stbi_write_tga_with_rle' to 0.
108 
109    JPEG does ignore alpha channels in input data; quality is between 1 and 100.
110    Higher quality looks better but results in a bigger image.
111    JPEG baseline (no JPEG progressive).
112 
113 CREDITS:
114 
115 
116    Sean Barrett           -    PNG/BMP/TGA
117    Baldur Karlsson        -    HDR
118    Jean-Sebastien Guay    -    TGA monochrome
119    Tim Kelsey             -    misc enhancements
120    Alan Hickman           -    TGA RLE
121    Emmanuel Julien        -    initial file IO callback implementation
122    Jon Olick              -    original jo_jpeg.cpp code
123    Daniel Gibson          -    integrate JPEG, allow external zlib
124    Aarni Koskela          -    allow choosing PNG filter
125 
126    bugfixes:
127       github:Chribba
128       Guillaume Chereau
129       github:jry2
130       github:romigrou
131       Sergio Gonzalez
132       Jonas Karlsson
133       Filip Wasil
134       Thatcher Ulrich
135       github:poppolopoppo
136       Patrick Boettcher
137       github:xeekworx
138       Cap Petschulat
139       Simon Rodriguez
140       Ivan Tikhonov
141       github:ignotion
142       Adam Schackart
143 
144 LICENSE
145 
146   See end of file for license information.
147 
148 */
149 
150 #ifndef INCLUDE_STB_IMAGE_WRITE_H
151 #define INCLUDE_STB_IMAGE_WRITE_H
152 
153 #include <stdlib.h>
154 
155 // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
156 #ifndef STBIWDEF
157 #ifdef STB_IMAGE_WRITE_STATIC
158 #define STBIWDEF  static
159 #else
160 #ifdef __cplusplus
161 #define STBIWDEF  extern "C"
162 #else
163 #define STBIWDEF  extern
164 #endif
165 #endif
166 #endif
167 
168 #ifndef STB_IMAGE_WRITE_STATIC  // C++ forbids static forward declarations
169 extern int stbi_write_tga_with_rle;
170 extern int stbi_write_png_compression_level;
171 extern int stbi_write_force_png_filter;
172 #endif
173 
174 #ifndef STBI_WRITE_NO_STDIO
175 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void  *data, int stride_in_bytes);
176 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void  *data);
177 STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void  *data);
178 STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
179 STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void  *data, int quality);
180 
181 #ifdef STBI_WINDOWS_UTF8
182 STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
183 #endif
184 #endif
185 
186 typedef void stbi_write_func(void *context, void *data, int size);
187 
188 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);
189 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
190 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void  *data);
191 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
192 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void  *data, int quality);
193 
194 STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
195 
196 #endif//INCLUDE_STB_IMAGE_WRITE_H
197 
198 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
199 
200 #ifdef _WIN32
201    #ifndef _CRT_SECURE_NO_WARNINGS
202    #define _CRT_SECURE_NO_WARNINGS
203    #endif
204    #ifndef _CRT_NONSTDC_NO_DEPRECATE
205    #define _CRT_NONSTDC_NO_DEPRECATE
206    #endif
207 #endif
208 
209 #ifndef STBI_WRITE_NO_STDIO
210 #include <stdio.h>
211 #endif // STBI_WRITE_NO_STDIO
212 
213 #include <stdarg.h>
214 #include <stdlib.h>
215 #include <string.h>
216 #include <math.h>
217 
218 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
219 // ok
220 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
221 // ok
222 #else
223 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
224 #endif
225 
226 #ifndef STBIW_MALLOC
227 #define STBIW_MALLOC(sz)        malloc(sz)
228 #define STBIW_REALLOC(p,newsz)  realloc(p,newsz)
229 #define STBIW_FREE(p)           free(p)
230 #endif
231 
232 #ifndef STBIW_REALLOC_SIZED
233 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
234 #endif
235 
236 
237 #ifndef STBIW_MEMMOVE
238 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
239 #endif
240 
241 
242 #ifndef STBIW_ASSERT
243 #include <assert.h>
244 #define STBIW_ASSERT(x) assert(x)
245 #endif
246 
247 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
248 
249 #ifdef STB_IMAGE_WRITE_STATIC
250 static int stbi_write_png_compression_level = 8;
251 static int stbi_write_tga_with_rle = 1;
252 static int stbi_write_force_png_filter = -1;
253 #else
254 int stbi_write_png_compression_level = 8;
255 int stbi_write_tga_with_rle = 1;
256 int stbi_write_force_png_filter = -1;
257 #endif
258 
259 static int stbi__flip_vertically_on_write = 0;
260 
stbi_flip_vertically_on_write(int flag)261 STBIWDEF void stbi_flip_vertically_on_write(int flag)
262 {
263    stbi__flip_vertically_on_write = flag;
264 }
265 
266 typedef struct
267 {
268    stbi_write_func *func;
269    void *context;
270 } stbi__write_context;
271 
272 // initialize a callback-based context
stbi__start_write_callbacks(stbi__write_context * s,stbi_write_func * c,void * context)273 static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
274 {
275    s->func    = c;
276    s->context = context;
277 }
278 
279 #ifndef STBI_WRITE_NO_STDIO
280 
stbi__stdio_write(void * context,void * data,int size)281 static void stbi__stdio_write(void *context, void *data, int size)
282 {
283    fwrite(data,1,size,(FILE*) context);
284 }
285 
286 #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
287 #ifdef __cplusplus
288 #define STBIW_EXTERN extern "C"
289 #else
290 #define STBIW_EXTERN extern
291 #endif
292 STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
293 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);
294 
stbiw_convert_wchar_to_utf8(char * buffer,size_t bufferlen,const wchar_t * input)295 STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
296 {
297 	return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
298 }
299 #endif
300 
stbiw__fopen(char const * filename,char const * mode)301 static FILE *stbiw__fopen(char const *filename, char const *mode)
302 {
303    FILE *f;
304 #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
305    wchar_t wMode[64];
306    wchar_t wFilename[1024];
307 	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
308       return 0;
309 
310 	if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
311       return 0;
312 
313 #if _MSC_VER >= 1400
314 	if (0 != _wfopen_s(&f, wFilename, wMode))
315 		f = 0;
316 #else
317    f = _wfopen(wFilename, wMode);
318 #endif
319 
320 #elif defined(_MSC_VER) && _MSC_VER >= 1400
321    if (0 != fopen_s(&f, filename, mode))
322       f=0;
323 #else
324    f = fopen(filename, mode);
325 #endif
326    return f;
327 }
328 
stbi__start_write_file(stbi__write_context * s,const char * filename)329 static int stbi__start_write_file(stbi__write_context *s, const char *filename)
330 {
331    FILE *f = stbiw__fopen(filename, "wb");
332    stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
333    return f != NULL;
334 }
335 
stbi__end_write_file(stbi__write_context * s)336 static void stbi__end_write_file(stbi__write_context *s)
337 {
338    fclose((FILE *)s->context);
339 }
340 
341 #endif // !STBI_WRITE_NO_STDIO
342 
343 typedef unsigned int stbiw_uint32;
344 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
345 
stbiw__writefv(stbi__write_context * s,const char * fmt,va_list v)346 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
347 {
348    while (*fmt) {
349       switch (*fmt++) {
350          case ' ': break;
351          case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int));
352                      s->func(s->context,&x,1);
353                      break; }
354          case '2': { int x = va_arg(v,int);
355                      unsigned char b[2];
356                      b[0] = STBIW_UCHAR(x);
357                      b[1] = STBIW_UCHAR(x>>8);
358                      s->func(s->context,b,2);
359                      break; }
360          case '4': { stbiw_uint32 x = va_arg(v,int);
361                      unsigned char b[4];
362                      b[0]=STBIW_UCHAR(x);
363                      b[1]=STBIW_UCHAR(x>>8);
364                      b[2]=STBIW_UCHAR(x>>16);
365                      b[3]=STBIW_UCHAR(x>>24);
366                      s->func(s->context,b,4);
367                      break; }
368          default:
369             STBIW_ASSERT(0);
370             return;
371       }
372    }
373 }
374 
stbiw__writef(stbi__write_context * s,const char * fmt,...)375 static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
376 {
377    va_list v;
378    va_start(v, fmt);
379    stbiw__writefv(s, fmt, v);
380    va_end(v);
381 }
382 
stbiw__putc(stbi__write_context * s,unsigned char c)383 static void stbiw__putc(stbi__write_context *s, unsigned char c)
384 {
385    s->func(s->context, &c, 1);
386 }
387 
stbiw__write3(stbi__write_context * s,unsigned char a,unsigned char b,unsigned char c)388 static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
389 {
390    unsigned char arr[3];
391    arr[0] = a; arr[1] = b; arr[2] = c;
392    s->func(s->context, arr, 3);
393 }
394 
stbiw__write_pixel(stbi__write_context * s,int rgb_dir,int comp,int write_alpha,int expand_mono,unsigned char * d)395 static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
396 {
397    unsigned char bg[3] = { 255, 0, 255}, px[3];
398    int k;
399 
400    if (write_alpha < 0)
401       s->func(s->context, &d[comp - 1], 1);
402 
403    switch (comp) {
404       case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
405       case 1:
406          if (expand_mono)
407             stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
408          else
409             s->func(s->context, d, 1);  // monochrome TGA
410          break;
411       case 4:
412          if (!write_alpha) {
413             // composite against pink background
414             for (k = 0; k < 3; ++k)
415                px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
416             stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
417             break;
418          }
419          /* FALLTHROUGH */
420       case 3:
421          stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
422          break;
423    }
424    if (write_alpha > 0)
425       s->func(s->context, &d[comp - 1], 1);
426 }
427 
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)428 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)
429 {
430    stbiw_uint32 zero = 0;
431    int i,j, j_end;
432 
433    if (y <= 0)
434       return;
435 
436    if (stbi__flip_vertically_on_write)
437       vdir *= -1;
438 
439    if (vdir < 0) {
440       j_end = -1; j = y-1;
441    } else {
442       j_end =  y; j = 0;
443    }
444 
445    for (; j != j_end; j += vdir) {
446       for (i=0; i < x; ++i) {
447          unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
448          stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
449       }
450       s->func(s->context, &zero, scanline_pad);
451    }
452 }
453 
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,...)454 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, ...)
455 {
456    if (y < 0 || x < 0) {
457       return 0;
458    } else {
459       va_list v;
460       va_start(v, fmt);
461       stbiw__writefv(s, fmt, v);
462       va_end(v);
463       stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
464       return 1;
465    }
466 }
467 
stbi_write_bmp_core(stbi__write_context * s,int x,int y,int comp,const void * data)468 static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
469 {
470    int pad = (-x*3) & 3;
471    return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
472            "11 4 22 4" "4 44 22 444444",
473            'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40,  // file header
474             40, x,y, 1,24, 0,0,0,0,0,0);             // bitmap header
475 }
476 
stbi_write_bmp_to_func(stbi_write_func * func,void * context,int x,int y,int comp,const void * data)477 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
478 {
479    stbi__write_context s;
480    stbi__start_write_callbacks(&s, func, context);
481    return stbi_write_bmp_core(&s, x, y, comp, data);
482 }
483 
484 #ifndef STBI_WRITE_NO_STDIO
stbi_write_bmp(char const * filename,int x,int y,int comp,const void * data)485 STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
486 {
487    stbi__write_context s;
488    if (stbi__start_write_file(&s,filename)) {
489       int r = stbi_write_bmp_core(&s, x, y, comp, data);
490       stbi__end_write_file(&s);
491       return r;
492    } else
493       return 0;
494 }
495 #endif //!STBI_WRITE_NO_STDIO
496 
stbi_write_tga_core(stbi__write_context * s,int x,int y,int comp,void * data)497 static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
498 {
499    int has_alpha = (comp == 2 || comp == 4);
500    int colorbytes = has_alpha ? comp-1 : comp;
501    int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
502 
503    if (y < 0 || x < 0)
504       return 0;
505 
506    if (!stbi_write_tga_with_rle) {
507       return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
508          "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
509    } else {
510       int i,j,k;
511       int jend, jdir;
512 
513       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);
514 
515       if (stbi__flip_vertically_on_write) {
516          j = 0;
517          jend = y;
518          jdir = 1;
519       } else {
520          j = y-1;
521          jend = -1;
522          jdir = -1;
523       }
524       for (; j != jend; j += jdir) {
525          unsigned char *row = (unsigned char *) data + j * x * comp;
526          int len;
527 
528          for (i = 0; i < x; i += len) {
529             unsigned char *begin = row + i * comp;
530             int diff = 1;
531             len = 1;
532 
533             if (i < x - 1) {
534                ++len;
535                diff = memcmp(begin, row + (i + 1) * comp, comp);
536                if (diff) {
537                   const unsigned char *prev = begin;
538                   for (k = i + 2; k < x && len < 128; ++k) {
539                      if (memcmp(prev, row + k * comp, comp)) {
540                         prev += comp;
541                         ++len;
542                      } else {
543                         --len;
544                         break;
545                      }
546                   }
547                } else {
548                   for (k = i + 2; k < x && len < 128; ++k) {
549                      if (!memcmp(begin, row + k * comp, comp)) {
550                         ++len;
551                      } else {
552                         break;
553                      }
554                   }
555                }
556             }
557 
558             if (diff) {
559                unsigned char header = STBIW_UCHAR(len - 1);
560                s->func(s->context, &header, 1);
561                for (k = 0; k < len; ++k) {
562                   stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
563                }
564             } else {
565                unsigned char header = STBIW_UCHAR(len - 129);
566                s->func(s->context, &header, 1);
567                stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
568             }
569          }
570       }
571    }
572    return 1;
573 }
574 
stbi_write_tga_to_func(stbi_write_func * func,void * context,int x,int y,int comp,const void * data)575 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
576 {
577    stbi__write_context s;
578    stbi__start_write_callbacks(&s, func, context);
579    return stbi_write_tga_core(&s, x, y, comp, (void *) data);
580 }
581 
582 #ifndef STBI_WRITE_NO_STDIO
stbi_write_tga(char const * filename,int x,int y,int comp,const void * data)583 STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
584 {
585    stbi__write_context s;
586    if (stbi__start_write_file(&s,filename)) {
587       int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
588       stbi__end_write_file(&s);
589       return r;
590    } else
591       return 0;
592 }
593 #endif
594 
595 // *************************************************************************************************
596 // Radiance RGBE HDR writer
597 // by Baldur Karlsson
598 
599 #define stbiw__max(a, b)  ((a) > (b) ? (a) : (b))
600 
stbiw__linear_to_rgbe(unsigned char * rgbe,float * linear)601 static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
602 {
603    int exponent;
604    float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
605 
606    if (maxcomp < 1e-32f) {
607       rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
608    } else {
609       float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
610 
611       rgbe[0] = (unsigned char)(linear[0] * normalize);
612       rgbe[1] = (unsigned char)(linear[1] * normalize);
613       rgbe[2] = (unsigned char)(linear[2] * normalize);
614       rgbe[3] = (unsigned char)(exponent + 128);
615    }
616 }
617 
stbiw__write_run_data(stbi__write_context * s,int length,unsigned char databyte)618 static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
619 {
620    unsigned char lengthbyte = STBIW_UCHAR(length+128);
621    STBIW_ASSERT(length+128 <= 255);
622    s->func(s->context, &lengthbyte, 1);
623    s->func(s->context, &databyte, 1);
624 }
625 
stbiw__write_dump_data(stbi__write_context * s,int length,unsigned char * data)626 static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
627 {
628    unsigned char lengthbyte = STBIW_UCHAR(length);
629    STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
630    s->func(s->context, &lengthbyte, 1);
631    s->func(s->context, data, length);
632 }
633 
stbiw__write_hdr_scanline(stbi__write_context * s,int width,int ncomp,unsigned char * scratch,float * scanline)634 static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
635 {
636    unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
637    unsigned char rgbe[4];
638    float linear[3];
639    int x;
640 
641    scanlineheader[2] = (width&0xff00)>>8;
642    scanlineheader[3] = (width&0x00ff);
643 
644    /* skip RLE for images too small or large */
645    if (width < 8 || width >= 32768) {
646       for (x=0; x < width; x++) {
647          switch (ncomp) {
648             case 4: /* fallthrough */
649             case 3: linear[2] = scanline[x*ncomp + 2];
650                     linear[1] = scanline[x*ncomp + 1];
651                     linear[0] = scanline[x*ncomp + 0];
652                     break;
653             default:
654                     linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
655                     break;
656          }
657          stbiw__linear_to_rgbe(rgbe, linear);
658          s->func(s->context, rgbe, 4);
659       }
660    } else {
661       int c,r;
662       /* encode into scratch buffer */
663       for (x=0; x < width; x++) {
664          switch(ncomp) {
665             case 4: /* fallthrough */
666             case 3: linear[2] = scanline[x*ncomp + 2];
667                     linear[1] = scanline[x*ncomp + 1];
668                     linear[0] = scanline[x*ncomp + 0];
669                     break;
670             default:
671                     linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
672                     break;
673          }
674          stbiw__linear_to_rgbe(rgbe, linear);
675          scratch[x + width*0] = rgbe[0];
676          scratch[x + width*1] = rgbe[1];
677          scratch[x + width*2] = rgbe[2];
678          scratch[x + width*3] = rgbe[3];
679       }
680 
681       s->func(s->context, scanlineheader, 4);
682 
683       /* RLE each component separately */
684       for (c=0; c < 4; c++) {
685          unsigned char *comp = &scratch[width*c];
686 
687          x = 0;
688          while (x < width) {
689             // find first run
690             r = x;
691             while (r+2 < width) {
692                if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
693                   break;
694                ++r;
695             }
696             if (r+2 >= width)
697                r = width;
698             // dump up to first run
699             while (x < r) {
700                int len = r-x;
701                if (len > 128) len = 128;
702                stbiw__write_dump_data(s, len, &comp[x]);
703                x += len;
704             }
705             // if there's a run, output it
706             if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
707                // find next byte after run
708                while (r < width && comp[r] == comp[x])
709                   ++r;
710                // output run up to r
711                while (x < r) {
712                   int len = r-x;
713                   if (len > 127) len = 127;
714                   stbiw__write_run_data(s, len, comp[x]);
715                   x += len;
716                }
717             }
718          }
719       }
720    }
721 }
722 
stbi_write_hdr_core(stbi__write_context * s,int x,int y,int comp,float * data)723 static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
724 {
725    if (y <= 0 || x <= 0 || data == NULL)
726       return 0;
727    else {
728       // Each component is stored separately. Allocate scratch space for full output scanline.
729       unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
730       int i, len;
731       char buffer[128];
732       char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
733       s->func(s->context, header, sizeof(header)-1);
734 
735 #ifdef __STDC_WANT_SECURE_LIB__
736       len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
737 #else
738       len = sprintf(buffer, "EXPOSURE=          1.0000000000000\n\n-Y %d +X %d\n", y, x);
739 #endif
740       s->func(s->context, buffer, len);
741 
742       for(i=0; i < y; i++)
743          stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
744       STBIW_FREE(scratch);
745       return 1;
746    }
747 }
748 
stbi_write_hdr_to_func(stbi_write_func * func,void * context,int x,int y,int comp,const float * data)749 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
750 {
751    stbi__write_context s;
752    stbi__start_write_callbacks(&s, func, context);
753    return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
754 }
755 
756 #ifndef STBI_WRITE_NO_STDIO
stbi_write_hdr(char const * filename,int x,int y,int comp,const float * data)757 STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
758 {
759    stbi__write_context s;
760    if (stbi__start_write_file(&s,filename)) {
761       int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
762       stbi__end_write_file(&s);
763       return r;
764    } else
765       return 0;
766 }
767 #endif // STBI_WRITE_NO_STDIO
768 
769 
770 //////////////////////////////////////////////////////////////////////////////
771 //
772 // PNG writer
773 //
774 
775 #ifndef STBIW_ZLIB_COMPRESS
776 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
777 #define stbiw__sbraw(a) ((int *) (void *) (a) - 2)
778 #define stbiw__sbm(a)   stbiw__sbraw(a)[0]
779 #define stbiw__sbn(a)   stbiw__sbraw(a)[1]
780 
781 #define stbiw__sbneedgrow(a,n)  ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
782 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
783 #define stbiw__sbgrow(a,n)  stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
784 
785 #define stbiw__sbpush(a, v)      (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
786 #define stbiw__sbcount(a)        ((a) ? stbiw__sbn(a) : 0)
787 #define stbiw__sbfree(a)         ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
788 
stbiw__sbgrowf(void ** arr,int increment,int itemsize)789 static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
790 {
791    int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
792    void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
793    STBIW_ASSERT(p);
794    if (p) {
795       if (!*arr) ((int *) p)[1] = 0;
796       *arr = (void *) ((int *) p + 2);
797       stbiw__sbm(*arr) = m;
798    }
799    return *arr;
800 }
801 
stbiw__zlib_flushf(unsigned char * data,unsigned int * bitbuffer,int * bitcount)802 static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
803 {
804    while (*bitcount >= 8) {
805       stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
806       *bitbuffer >>= 8;
807       *bitcount -= 8;
808    }
809    return data;
810 }
811 
stbiw__zlib_bitrev(int code,int codebits)812 static int stbiw__zlib_bitrev(int code, int codebits)
813 {
814    int res=0;
815    while (codebits--) {
816       res = (res << 1) | (code & 1);
817       code >>= 1;
818    }
819    return res;
820 }
821 
stbiw__zlib_countm(unsigned char * a,unsigned char * b,int limit)822 static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
823 {
824    int i;
825    for (i=0; i < limit && i < 258; ++i)
826       if (a[i] != b[i]) break;
827    return i;
828 }
829 
stbiw__zhash(unsigned char * data)830 static unsigned int stbiw__zhash(unsigned char *data)
831 {
832    stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
833    hash ^= hash << 3;
834    hash += hash >> 5;
835    hash ^= hash << 4;
836    hash += hash >> 17;
837    hash ^= hash << 25;
838    hash += hash >> 6;
839    return hash;
840 }
841 
842 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
843 #define stbiw__zlib_add(code,codebits) \
844       (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
845 #define stbiw__zlib_huffa(b,c)  stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
846 // default huffman tables
847 #define stbiw__zlib_huff1(n)  stbiw__zlib_huffa(0x30 + (n), 8)
848 #define stbiw__zlib_huff2(n)  stbiw__zlib_huffa(0x190 + (n)-144, 9)
849 #define stbiw__zlib_huff3(n)  stbiw__zlib_huffa(0 + (n)-256,7)
850 #define stbiw__zlib_huff4(n)  stbiw__zlib_huffa(0xc0 + (n)-280,8)
851 #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))
852 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
853 
854 #define stbiw__ZHASH   16384
855 
856 #endif // STBIW_ZLIB_COMPRESS
857 
stbi_zlib_compress(unsigned char * data,int data_len,int * out_len,int quality)858 STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
859 {
860 #ifdef STBIW_ZLIB_COMPRESS
861    // user provided a zlib compress implementation, use that
862    return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
863 #else // use builtin
864    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 };
865    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 };
866    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 };
867    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 };
868    unsigned int bitbuf=0;
869    int i,j, bitcount=0;
870    unsigned char *out = NULL;
871    unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
872    if (hash_table == NULL)
873       return NULL;
874    if (quality < 5) quality = 5;
875 
876    stbiw__sbpush(out, 0x78);   // DEFLATE 32K window
877    stbiw__sbpush(out, 0x5e);   // FLEVEL = 1
878    stbiw__zlib_add(1,1);  // BFINAL = 1
879    stbiw__zlib_add(1,2);  // BTYPE = 1 -- fixed huffman
880 
881    for (i=0; i < stbiw__ZHASH; ++i)
882       hash_table[i] = NULL;
883 
884    i=0;
885    while (i < data_len-3) {
886       // hash next 3 bytes of data to be compressed
887       int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
888       unsigned char *bestloc = 0;
889       unsigned char **hlist = hash_table[h];
890       int n = stbiw__sbcount(hlist);
891       for (j=0; j < n; ++j) {
892          if (hlist[j]-data > i-32768) { // if entry lies within window
893             int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
894             if (d >= best) { best=d; bestloc=hlist[j]; }
895          }
896       }
897       // when hash table entry is too long, delete half the entries
898       if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
899          STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
900          stbiw__sbn(hash_table[h]) = quality;
901       }
902       stbiw__sbpush(hash_table[h],data+i);
903 
904       if (bestloc) {
905          // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
906          h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
907          hlist = hash_table[h];
908          n = stbiw__sbcount(hlist);
909          for (j=0; j < n; ++j) {
910             if (hlist[j]-data > i-32767) {
911                int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
912                if (e > best) { // if next match is better, bail on current match
913                   bestloc = NULL;
914                   break;
915                }
916             }
917          }
918       }
919 
920       if (bestloc) {
921          int d = (int) (data+i - bestloc); // distance back
922          STBIW_ASSERT(d <= 32767 && best <= 258);
923          for (j=0; best > lengthc[j+1]-1; ++j);
924          stbiw__zlib_huff(j+257);
925          if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
926          for (j=0; d > distc[j+1]-1; ++j);
927          stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
928          if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
929          i += best;
930       } else {
931          stbiw__zlib_huffb(data[i]);
932          ++i;
933       }
934    }
935    // write out final bytes
936    for (;i < data_len; ++i)
937       stbiw__zlib_huffb(data[i]);
938    stbiw__zlib_huff(256); // end of block
939    // pad with 0 bits to byte boundary
940    while (bitcount)
941       stbiw__zlib_add(0,1);
942 
943    for (i=0; i < stbiw__ZHASH; ++i)
944       (void) stbiw__sbfree(hash_table[i]);
945    STBIW_FREE(hash_table);
946 
947    {
948       // compute adler32 on input
949       unsigned int s1=1, s2=0;
950       int blocklen = (int) (data_len % 5552);
951       j=0;
952       while (j < data_len) {
953          for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
954          s1 %= 65521; s2 %= 65521;
955          j += blocklen;
956          blocklen = 5552;
957       }
958       stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
959       stbiw__sbpush(out, STBIW_UCHAR(s2));
960       stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
961       stbiw__sbpush(out, STBIW_UCHAR(s1));
962    }
963    *out_len = stbiw__sbn(out);
964    // make returned pointer freeable
965    STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
966    return (unsigned char *) stbiw__sbraw(out);
967 #endif // STBIW_ZLIB_COMPRESS
968 }
969 
stbiw__crc32(unsigned char * buffer,int len)970 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
971 {
972 #ifdef STBIW_CRC32
973     return STBIW_CRC32(buffer, len);
974 #else
975    static unsigned int crc_table[256] =
976    {
977       0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
978       0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
979       0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
980       0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
981       0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
982       0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
983       0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
984       0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
985       0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
986       0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
987       0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
988       0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
989       0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
990       0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
991       0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
992       0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
993       0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
994       0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
995       0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
996       0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
997       0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
998       0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
999       0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
1000       0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1001       0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
1002       0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
1003       0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1004       0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
1005       0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
1006       0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1007       0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
1008       0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
1009    };
1010 
1011    unsigned int crc = ~0u;
1012    int i;
1013    for (i=0; i < len; ++i)
1014       crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
1015    return ~crc;
1016 #endif
1017 }
1018 
1019 #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)
1020 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
1021 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
1022 
stbiw__wpcrc(unsigned char ** data,int len)1023 static void stbiw__wpcrc(unsigned char **data, int len)
1024 {
1025    unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
1026    stbiw__wp32(*data, crc);
1027 }
1028 
stbiw__paeth(int a,int b,int c)1029 static unsigned char stbiw__paeth(int a, int b, int c)
1030 {
1031    int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
1032    if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
1033    if (pb <= pc) return STBIW_UCHAR(b);
1034    return STBIW_UCHAR(c);
1035 }
1036 
1037 // @OPTIMIZE: provide an option that always forces left-predict or paeth predict
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)1038 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)
1039 {
1040    static int mapping[] = { 0,1,2,3,4 };
1041    static int firstmap[] = { 0,1,0,5,6 };
1042    int *mymap = (y != 0) ? mapping : firstmap;
1043    int i;
1044    int type = mymap[filter_type];
1045    unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
1046    int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
1047 
1048    if (type==0) {
1049       memcpy(line_buffer, z, width*n);
1050       return;
1051    }
1052 
1053    // first loop isn't optimized since it's just one pixel
1054    for (i = 0; i < n; ++i) {
1055       switch (type) {
1056          case 1: line_buffer[i] = z[i]; break;
1057          case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1058          case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
1059          case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
1060          case 5: line_buffer[i] = z[i]; break;
1061          case 6: line_buffer[i] = z[i]; break;
1062       }
1063    }
1064    switch (type) {
1065       case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
1066       case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
1067       case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1068       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;
1069       case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
1070       case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1071    }
1072 }
1073 
stbi_write_png_to_mem(const unsigned char * pixels,int stride_bytes,int x,int y,int n,int * out_len)1074 STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1075 {
1076    int force_filter = stbi_write_force_png_filter;
1077    int ctype[5] = { -1, 0, 4, 2, 6 };
1078    unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
1079    unsigned char *out,*o, *filt, *zlib;
1080    signed char *line_buffer;
1081    int j,zlen;
1082 
1083    if (stride_bytes == 0)
1084       stride_bytes = x * n;
1085 
1086    if (force_filter >= 5) {
1087       force_filter = -1;
1088    }
1089 
1090    filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
1091    line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
1092    for (j=0; j < y; ++j) {
1093       int filter_type;
1094       if (force_filter > -1) {
1095          filter_type = force_filter;
1096          stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
1097       } else { // Estimate the best filter by running through all of them:
1098          int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1099          for (filter_type = 0; filter_type < 5; filter_type++) {
1100             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
1101 
1102             // Estimate the entropy of the line using this filter; the less, the better.
1103             est = 0;
1104             for (i = 0; i < x*n; ++i) {
1105                est += abs((signed char) line_buffer[i]);
1106             }
1107             if (est < best_filter_val) {
1108                best_filter_val = est;
1109                best_filter = filter_type;
1110             }
1111          }
1112          if (filter_type != best_filter) {  // If the last iteration already got us the best filter, don't redo it
1113             stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
1114             filter_type = best_filter;
1115          }
1116       }
1117       // when we get here, filter_type contains the filter type, and line_buffer contains the data
1118       filt[j*(x*n+1)] = (unsigned char) filter_type;
1119       STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
1120    }
1121    STBIW_FREE(line_buffer);
1122    zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level);
1123    STBIW_FREE(filt);
1124    if (!zlib) return 0;
1125 
1126    // each tag requires 12 bytes of overhead
1127    out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
1128    if (!out) return 0;
1129    *out_len = 8 + 12+13 + 12+zlen + 12;
1130 
1131    o=out;
1132    STBIW_MEMMOVE(o,sig,8); o+= 8;
1133    stbiw__wp32(o, 13); // header length
1134    stbiw__wptag(o, "IHDR");
1135    stbiw__wp32(o, x);
1136    stbiw__wp32(o, y);
1137    *o++ = 8;
1138    *o++ = STBIW_UCHAR(ctype[n]);
1139    *o++ = 0;
1140    *o++ = 0;
1141    *o++ = 0;
1142    stbiw__wpcrc(&o,13);
1143 
1144    stbiw__wp32(o, zlen);
1145    stbiw__wptag(o, "IDAT");
1146    STBIW_MEMMOVE(o, zlib, zlen);
1147    o += zlen;
1148    STBIW_FREE(zlib);
1149    stbiw__wpcrc(&o, zlen);
1150 
1151    stbiw__wp32(o,0);
1152    stbiw__wptag(o, "IEND");
1153    stbiw__wpcrc(&o,0);
1154 
1155    STBIW_ASSERT(o == out + *out_len);
1156 
1157    return out;
1158 }
1159 
1160 #ifndef STBI_WRITE_NO_STDIO
stbi_write_png(char const * filename,int x,int y,int comp,const void * data,int stride_bytes)1161 STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
1162 {
1163    FILE *f;
1164    int len;
1165    unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1166    if (png == NULL) return 0;
1167 
1168    f = stbiw__fopen(filename, "wb");
1169    if (!f) { STBIW_FREE(png); return 0; }
1170    fwrite(png, 1, len, f);
1171    fclose(f);
1172    STBIW_FREE(png);
1173    return 1;
1174 }
1175 #endif
1176 
stbi_write_png_to_func(stbi_write_func * func,void * context,int x,int y,int comp,const void * data,int stride_bytes)1177 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)
1178 {
1179    int len;
1180    unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1181    if (png == NULL) return 0;
1182    func(context, png, len);
1183    STBIW_FREE(png);
1184    return 1;
1185 }
1186 
1187 
1188 /* ***************************************************************************
1189  *
1190  * JPEG writer
1191  *
1192  * This is based on Jon Olick's jo_jpeg.cpp:
1193  * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html
1194  */
1195 
1196 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,
1197       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 };
1198 
stbiw__jpg_writeBits(stbi__write_context * s,int * bitBufP,int * bitCntP,const unsigned short * bs)1199 static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) {
1200    int bitBuf = *bitBufP, bitCnt = *bitCntP;
1201    bitCnt += bs[1];
1202    bitBuf |= bs[0] << (24 - bitCnt);
1203    while(bitCnt >= 8) {
1204       unsigned char c = (bitBuf >> 16) & 255;
1205       stbiw__putc(s, c);
1206       if(c == 255) {
1207          stbiw__putc(s, 0);
1208       }
1209       bitBuf <<= 8;
1210       bitCnt -= 8;
1211    }
1212    *bitBufP = bitBuf;
1213    *bitCntP = bitCnt;
1214 }
1215 
stbiw__jpg_DCT(float * d0p,float * d1p,float * d2p,float * d3p,float * d4p,float * d5p,float * d6p,float * d7p)1216 static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) {
1217    float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
1218    float z1, z2, z3, z4, z5, z11, z13;
1219 
1220    float tmp0 = d0 + d7;
1221    float tmp7 = d0 - d7;
1222    float tmp1 = d1 + d6;
1223    float tmp6 = d1 - d6;
1224    float tmp2 = d2 + d5;
1225    float tmp5 = d2 - d5;
1226    float tmp3 = d3 + d4;
1227    float tmp4 = d3 - d4;
1228 
1229    // Even part
1230    float tmp10 = tmp0 + tmp3;   // phase 2
1231    float tmp13 = tmp0 - tmp3;
1232    float tmp11 = tmp1 + tmp2;
1233    float tmp12 = tmp1 - tmp2;
1234 
1235    d0 = tmp10 + tmp11;       // phase 3
1236    d4 = tmp10 - tmp11;
1237 
1238    z1 = (tmp12 + tmp13) * 0.707106781f; // c4
1239    d2 = tmp13 + z1;       // phase 5
1240    d6 = tmp13 - z1;
1241 
1242    // Odd part
1243    tmp10 = tmp4 + tmp5;       // phase 2
1244    tmp11 = tmp5 + tmp6;
1245    tmp12 = tmp6 + tmp7;
1246 
1247    // The rotator is modified from fig 4-8 to avoid extra negations.
1248    z5 = (tmp10 - tmp12) * 0.382683433f; // c6
1249    z2 = tmp10 * 0.541196100f + z5; // c2-c6
1250    z4 = tmp12 * 1.306562965f + z5; // c2+c6
1251    z3 = tmp11 * 0.707106781f; // c4
1252 
1253    z11 = tmp7 + z3;      // phase 5
1254    z13 = tmp7 - z3;
1255 
1256    *d5p = z13 + z2;         // phase 6
1257    *d3p = z13 - z2;
1258    *d1p = z11 + z4;
1259    *d7p = z11 - z4;
1260 
1261    *d0p = d0;  *d2p = d2;  *d4p = d4;  *d6p = d6;
1262 }
1263 
stbiw__jpg_calcBits(int val,unsigned short bits[2])1264 static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) {
1265    int tmp1 = val < 0 ? -val : val;
1266    val = val < 0 ? val-1 : val;
1267    bits[1] = 1;
1268    while(tmp1 >>= 1) {
1269       ++bits[1];
1270    }
1271    bits[0] = val & ((1<<bits[1])-1);
1272 }
1273 
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])1274 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]) {
1275    const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
1276    const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
1277    int dataOff, i, j, n, diff, end0pos, x, y;
1278    int DU[64];
1279 
1280    // DCT rows
1281    for(dataOff=0, n=du_stride*8; dataOff<n; dataOff+=du_stride) {
1282       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]);
1283    }
1284    // DCT columns
1285    for(dataOff=0; dataOff<8; ++dataOff) {
1286       stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+du_stride], &CDU[dataOff+du_stride*2], &CDU[dataOff+du_stride*3], &CDU[dataOff+du_stride*4],
1287                      &CDU[dataOff+du_stride*5], &CDU[dataOff+du_stride*6], &CDU[dataOff+du_stride*7]);
1288    }
1289    // Quantize/descale/zigzag the coefficients
1290    for(y = 0, j=0; y < 8; ++y) {
1291       for(x = 0; x < 8; ++x,++j) {
1292          float v;
1293          i = y*du_stride+x;
1294          v = CDU[i]*fdtbl[j];
1295          // DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
1296          // ceilf() and floorf() are C99, not C89, but I /think/ they're not needed here anyway?
1297          DU[stbiw__jpg_ZigZag[j]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
1298       }
1299    }
1300 
1301    // Encode DC
1302    diff = DU[0] - DC;
1303    if (diff == 0) {
1304       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
1305    } else {
1306       unsigned short bits[2];
1307       stbiw__jpg_calcBits(diff, bits);
1308       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
1309       stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1310    }
1311    // Encode ACs
1312    end0pos = 63;
1313    for(; (end0pos>0)&&(DU[end0pos]==0); --end0pos) {
1314    }
1315    // end0pos = first element in reverse order !=0
1316    if(end0pos == 0) {
1317       stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1318       return DU[0];
1319    }
1320    for(i = 1; i <= end0pos; ++i) {
1321       int startpos = i;
1322       int nrzeroes;
1323       unsigned short bits[2];
1324       for (; DU[i]==0 && i<=end0pos; ++i) {
1325       }
1326       nrzeroes = i-startpos;
1327       if ( nrzeroes >= 16 ) {
1328          int lng = nrzeroes>>4;
1329          int nrmarker;
1330          for (nrmarker=1; nrmarker <= lng; ++nrmarker)
1331             stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
1332          nrzeroes &= 15;
1333       }
1334       stbiw__jpg_calcBits(DU[i], bits);
1335       stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]);
1336       stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1337    }
1338    if(end0pos != 63) {
1339       stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1340    }
1341    return DU[0];
1342 }
1343 
stbi_write_jpg_core(stbi__write_context * s,int width,int height,int comp,const void * data,int quality)1344 static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) {
1345    // Constants that don't pollute global namespace
1346    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};
1347    static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1348    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};
1349    static const unsigned char std_ac_luminance_values[] = {
1350       0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
1351       0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
1352       0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
1353       0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1354       0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
1355       0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
1356       0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1357    };
1358    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};
1359    static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1360    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};
1361    static const unsigned char std_ac_chrominance_values[] = {
1362       0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
1363       0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
1364       0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
1365       0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
1366       0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
1367       0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
1368       0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1369    };
1370    // Huffman tables
1371    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}};
1372    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}};
1373    static const unsigned short YAC_HT[256][2] = {
1374       {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},
1375       {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},
1376       {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},
1377       {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},
1378       {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},
1379       {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},
1380       {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},
1381       {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},
1382       {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},
1383       {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},
1384       {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},
1385       {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},
1386       {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},
1387       {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},
1388       {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},
1389       {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}
1390    };
1391    static const unsigned short UVAC_HT[256][2] = {
1392       {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},
1393       {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},
1394       {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},
1395       {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},
1396       {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},
1397       {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},
1398       {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},
1399       {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},
1400       {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},
1401       {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},
1402       {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},
1403       {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},
1404       {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},
1405       {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},
1406       {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},
1407       {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}
1408    };
1409    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,
1410                              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};
1411    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,
1412                               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};
1413    static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1414                                  1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
1415 
1416    int row, col, i, k, subsample;
1417    float fdtbl_Y[64], fdtbl_UV[64];
1418    unsigned char YTable[64], UVTable[64];
1419 
1420    if(!data || !width || !height || comp > 4 || comp < 1) {
1421       return 0;
1422    }
1423 
1424    quality = quality ? quality : 90;
1425    subsample = quality <= 90 ? 1 : 0;
1426    quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
1427    quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
1428 
1429    for(i = 0; i < 64; ++i) {
1430       int uvti, yti = (YQT[i]*quality+50)/100;
1431       YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti);
1432       uvti = (UVQT[i]*quality+50)/100;
1433       UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
1434    }
1435 
1436    for(row = 0, k = 0; row < 8; ++row) {
1437       for(col = 0; col < 8; ++col, ++k) {
1438          fdtbl_Y[k]  = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1439          fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1440       }
1441    }
1442 
1443    // Write Headers
1444    {
1445       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 };
1446       static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
1447       const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width),
1448                                       3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1449       s->func(s->context, (void*)head0, sizeof(head0));
1450       s->func(s->context, (void*)YTable, sizeof(YTable));
1451       stbiw__putc(s, 1);
1452       s->func(s->context, UVTable, sizeof(UVTable));
1453       s->func(s->context, (void*)head1, sizeof(head1));
1454       s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1);
1455       s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values));
1456       stbiw__putc(s, 0x10); // HTYACinfo
1457       s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1);
1458       s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values));
1459       stbiw__putc(s, 1); // HTUDCinfo
1460       s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1);
1461       s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values));
1462       stbiw__putc(s, 0x11); // HTUACinfo
1463       s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1);
1464       s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values));
1465       s->func(s->context, (void*)head2, sizeof(head2));
1466    }
1467 
1468    // Encode 8x8 macroblocks
1469    {
1470       static const unsigned short fillBits[] = {0x7F, 7};
1471       int DCY=0, DCU=0, DCV=0;
1472       int bitBuf=0, bitCnt=0;
1473       // comp == 2 is grey+alpha (alpha is ignored)
1474       int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
1475       const unsigned char *dataR = (const unsigned char *)data;
1476       const unsigned char *dataG = dataR + ofsG;
1477       const unsigned char *dataB = dataR + ofsB;
1478       int x, y, pos;
1479       if(subsample) {
1480          for(y = 0; y < height; y += 16) {
1481             for(x = 0; x < width; x += 16) {
1482                float Y[256], U[256], V[256];
1483                for(row = y, pos = 0; row < y+16; ++row) {
1484                   // row >= height => use last input row
1485                   int clamped_row = (row < height) ? row : height - 1;
1486                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1487                   for(col = x; col < x+16; ++col, ++pos) {
1488                      // if col >= width => use pixel from last input column
1489                      int p = base_p + ((col < width) ? col : (width-1))*comp;
1490                      float r = dataR[p], g = dataG[p], b = dataB[p];
1491                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1492                      U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1493                      V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1494                   }
1495                }
1496                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0,   16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1497                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8,   16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1498                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1499                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1500 
1501                // subsample U,V
1502                {
1503                   float subU[64], subV[64];
1504                   int yy, xx;
1505                   for(yy = 0, pos = 0; yy < 8; ++yy) {
1506                      for(xx = 0; xx < 8; ++xx, ++pos) {
1507                         int j = yy*32+xx*2;
1508                         subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f;
1509                         subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f;
1510                      }
1511                   }
1512                   DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1513                   DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1514                }
1515             }
1516          }
1517       } else {
1518          for(y = 0; y < height; y += 8) {
1519             for(x = 0; x < width; x += 8) {
1520                float Y[64], U[64], V[64];
1521                for(row = y, pos = 0; row < y+8; ++row) {
1522                   // row >= height => use last input row
1523                   int clamped_row = (row < height) ? row : height - 1;
1524                   int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1525                   for(col = x; col < x+8; ++col, ++pos) {
1526                      // if col >= width => use pixel from last input column
1527                      int p = base_p + ((col < width) ? col : (width-1))*comp;
1528                      float r = dataR[p], g = dataG[p], b = dataB[p];
1529                      Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128;
1530                      U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b;
1531                      V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b;
1532                   }
1533                }
1534 
1535                DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y,  DCY, YDC_HT, YAC_HT);
1536                DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1537                DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1538             }
1539          }
1540       }
1541 
1542       // Do the bit alignment of the EOI marker
1543       stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
1544    }
1545 
1546    // EOI
1547    stbiw__putc(s, 0xFF);
1548    stbiw__putc(s, 0xD9);
1549 
1550    return 1;
1551 }
1552 
stbi_write_jpg_to_func(stbi_write_func * func,void * context,int x,int y,int comp,const void * data,int quality)1553 STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
1554 {
1555    stbi__write_context s;
1556    stbi__start_write_callbacks(&s, func, context);
1557    return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
1558 }
1559 
1560 
1561 #ifndef STBI_WRITE_NO_STDIO
stbi_write_jpg(char const * filename,int x,int y,int comp,const void * data,int quality)1562 STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
1563 {
1564    stbi__write_context s;
1565    if (stbi__start_write_file(&s,filename)) {
1566       int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
1567       stbi__end_write_file(&s);
1568       return r;
1569    } else
1570       return 0;
1571 }
1572 #endif
1573 
1574 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1575 
1576 /* Revision history
1577       1.14  (2020-02-02) updated JPEG writer to downsample chroma channels
1578       1.13
1579       1.12
1580       1.11  (2019-08-11)
1581 
1582       1.10  (2019-02-07)
1583              support utf8 filenames in Windows; fix warnings and platform ifdefs
1584       1.09  (2018-02-11)
1585              fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1586       1.08  (2018-01-29)
1587              add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
1588       1.07  (2017-07-24)
1589              doc fix
1590       1.06 (2017-07-23)
1591              writing JPEG (using Jon Olick's code)
1592       1.05   ???
1593       1.04 (2017-03-03)
1594              monochrome BMP expansion
1595       1.03   ???
1596       1.02 (2016-04-02)
1597              avoid allocating large structures on the stack
1598       1.01 (2016-01-16)
1599              STBIW_REALLOC_SIZED: support allocators with no realloc support
1600              avoid race-condition in crc initialization
1601              minor compile issues
1602       1.00 (2015-09-14)
1603              installable file IO function
1604       0.99 (2015-09-13)
1605              warning fixes; TGA rle support
1606       0.98 (2015-04-08)
1607              added STBIW_MALLOC, STBIW_ASSERT etc
1608       0.97 (2015-01-18)
1609              fixed HDR asserts, rewrote HDR rle logic
1610       0.96 (2015-01-17)
1611              add HDR output
1612              fix monochrome BMP
1613       0.95 (2014-08-17)
1614 		       add monochrome TGA output
1615       0.94 (2014-05-31)
1616              rename private functions to avoid conflicts with stb_image.h
1617       0.93 (2014-05-27)
1618              warning fixes
1619       0.92 (2010-08-01)
1620              casts to unsigned char to fix warnings
1621       0.91 (2010-07-17)
1622              first public release
1623       0.90   first internal release
1624 */
1625 
1626 /*
1627 ------------------------------------------------------------------------------
1628 This software is available under 2 licenses -- choose whichever you prefer.
1629 ------------------------------------------------------------------------------
1630 ALTERNATIVE A - MIT License
1631 Copyright (c) 2017 Sean Barrett
1632 Permission is hereby granted, free of charge, to any person obtaining a copy of
1633 this software and associated documentation files (the "Software"), to deal in
1634 the Software without restriction, including without limitation the rights to
1635 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1636 of the Software, and to permit persons to whom the Software is furnished to do
1637 so, subject to the following conditions:
1638 The above copyright notice and this permission notice shall be included in all
1639 copies or substantial portions of the Software.
1640 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1641 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1642 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1643 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1644 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1645 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1646 SOFTWARE.
1647 ------------------------------------------------------------------------------
1648 ALTERNATIVE B - Public Domain (www.unlicense.org)
1649 This is free and unencumbered software released into the public domain.
1650 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
1651 software, either in source code form or as a compiled binary, for any purpose,
1652 commercial or non-commercial, and by any means.
1653 In jurisdictions that recognize copyright laws, the author or authors of this
1654 software dedicate any and all copyright interest in the software to the public
1655 domain. We make this dedication for the benefit of the public at large and to
1656 the detriment of our heirs and successors. We intend this dedication to be an
1657 overt act of relinquishment in perpetuity of all present and future rights to
1658 this software under copyright law.
1659 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1660 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1661 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1662 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1663 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1664 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1665 ------------------------------------------------------------------------------
1666 */
1667