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