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