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