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