glfw/deps/stb_image_write.h
Go to the documentation of this file.
1 /* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h
2  writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
3  no warranty implied; use at your own risk
4 
5  Before #including,
6 
7  #define STB_IMAGE_WRITE_IMPLEMENTATION
8 
9  in the file that you want to have the implementation.
10 
11  Will probably not work correctly with strict-aliasing optimizations.
12 
13 ABOUT:
14 
15  This header file is a library for writing images to C stdio. It could be
16  adapted to write to memory or a general streaming interface; let me know.
17 
18  The PNG output is not optimal; it is 20-50% larger than the file
19  written by a decent optimizing implementation. This library is designed
20  for source code compactness and simplicity, not optimal image file size
21  or run-time performance.
22 
23 BUILDING:
24 
25  You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
26  You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
27  malloc,realloc,free.
28  You can define STBIW_MEMMOVE() to replace memmove()
29 
30 USAGE:
31 
32  There are four functions, one for each image file format:
33 
34  int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
35  int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
36  int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
37  int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
38 
39  There are also four equivalent functions that use an arbitrary write function. You are
40  expected to open/close your file-equivalent before and after calling these:
41 
42  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);
43  int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
44  int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
45  int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
46 
47  where the callback is:
48  void stbi_write_func(void *context, void *data, int size);
49 
50  You can define STBI_WRITE_NO_STDIO to disable the file variant of these
51  functions, so the library will not use stdio.h at all. However, this will
52  also disable HDR writing, because it requires stdio for formatted output.
53 
54  Each function returns 0 on failure and non-0 on success.
55 
56  The functions create an image file defined by the parameters. The image
57  is a rectangle of pixels stored from left-to-right, top-to-bottom.
58  Each pixel contains 'comp' channels of data stored interleaved with 8-bits
59  per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
60  monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
61  The *data pointer points to the first byte of the top-left-most pixel.
62  For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
63  a row of pixels to the first byte of the next row of pixels.
64 
65  PNG creates output files with the same number of components as the input.
66  The BMP format expands Y to RGB in the file format and does not
67  output alpha.
68 
69  PNG supports writing rectangles of data even when the bytes storing rows of
70  data are not consecutive in memory (e.g. sub-rectangles of a larger image),
71  by supplying the stride between the beginning of adjacent rows. The other
72  formats do not. (Thus you cannot write a native-format BMP through the BMP
73  writer, both because it is in BGR order and because it may have padding
74  at the end of the line.)
75 
76  HDR expects linear float data. Since the format is always 32-bit rgb(e)
77  data, alpha (if provided) is discarded, and for monochrome data it is
78  replicated across all three channels.
79 
80  TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
81  data, set the global variable 'stbi_write_tga_with_rle' to 0.
82 
83 CREDITS:
84 
85  PNG/BMP/TGA
86  Sean Barrett
87  HDR
88  Baldur Karlsson
89  TGA monochrome:
90  Jean-Sebastien Guay
91  misc enhancements:
92  Tim Kelsey
93  TGA RLE
94  Alan Hickman
95  initial file IO callback implementation
96  Emmanuel Julien
97  bugfixes:
98  github:Chribba
99  Guillaume Chereau
100  github:jry2
101  github:romigrou
102  Sergio Gonzalez
103  Jonas Karlsson
104  Filip Wasil
105  Thatcher Ulrich
106 
107 LICENSE
108 
109 This software is dual-licensed to the public domain and under the following
110 license: you are granted a perpetual, irrevocable license to copy, modify,
111 publish, and distribute this file as you see fit.
112 
113 */
114 
115 #ifndef INCLUDE_STB_IMAGE_WRITE_H
116 #define INCLUDE_STB_IMAGE_WRITE_H
117 
118 #ifdef __cplusplus
119 extern "C" {
120 #endif
121 
122 #ifdef STB_IMAGE_WRITE_STATIC
123 #define STBIWDEF static
124 #else
125 #define STBIWDEF extern
126 extern int stbi_write_tga_with_rle;
127 #endif
128 
129 #ifndef STBI_WRITE_NO_STDIO
130 STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
131 STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
132 STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
133 STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
134 #endif
135 
136 typedef void stbi_write_func(void *context, void *data, int size);
137 
138 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);
139 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
140 STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
141 STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
142 
143 #ifdef __cplusplus
144 }
145 #endif
146 
147 #endif//INCLUDE_STB_IMAGE_WRITE_H
148 
149 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
150 
151 #ifdef _WIN32
152  #ifndef _CRT_SECURE_NO_WARNINGS
153  #define _CRT_SECURE_NO_WARNINGS
154  #endif
155  #ifndef _CRT_NONSTDC_NO_DEPRECATE
156  #define _CRT_NONSTDC_NO_DEPRECATE
157  #endif
158 #endif
159 
160 #ifndef STBI_WRITE_NO_STDIO
161 #include <stdio.h>
162 #endif // STBI_WRITE_NO_STDIO
163 
164 #include <stdarg.h>
165 #include <stdlib.h>
166 #include <string.h>
167 #include <math.h>
168 
169 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
170 // ok
171 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
172 // ok
173 #else
174 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
175 #endif
176 
177 #ifndef STBIW_MALLOC
178 #define STBIW_MALLOC(sz) malloc(sz)
179 #define STBIW_REALLOC(p,newsz) realloc(p,newsz)
180 #define STBIW_FREE(p) free(p)
181 #endif
182 
183 #ifndef STBIW_REALLOC_SIZED
184 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
185 #endif
186 
187 
188 #ifndef STBIW_MEMMOVE
189 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
190 #endif
191 
192 
193 #ifndef STBIW_ASSERT
194 #include <assert.h>
195 #define STBIW_ASSERT(x) assert(x)
196 #endif
197 
198 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
199 
200 typedef struct
201 {
203  void *context;
204 } stbi__write_context;
205 
206 // initialize a callback-based context
207 static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
208 {
209  s->func = c;
210  s->context = context;
211 }
212 
213 #ifndef STBI_WRITE_NO_STDIO
214 
215 static void stbi__stdio_write(void *context, void *data, int size)
216 {
217  fwrite(data,1,size,(FILE*) context);
218 }
219 
220 static int stbi__start_write_file(stbi__write_context *s, const char *filename)
221 {
222  FILE *f = fopen(filename, "wb");
223  stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
224  return f != NULL;
225 }
226 
227 static void stbi__end_write_file(stbi__write_context *s)
228 {
229  fclose((FILE *)s->context);
230 }
231 
232 #endif // !STBI_WRITE_NO_STDIO
233 
234 typedef unsigned int stbiw_uint32;
235 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
236 
237 #ifdef STB_IMAGE_WRITE_STATIC
238 static int stbi_write_tga_with_rle = 1;
239 #else
240 int stbi_write_tga_with_rle = 1;
241 #endif
242 
243 static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
244 {
245  while (*fmt) {
246  switch (*fmt++) {
247  case ' ': break;
248  case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int));
249  s->func(s->context,&x,1);
250  break; }
251  case '2': { int x = va_arg(v,int);
252  unsigned char b[2];
253  b[0] = STBIW_UCHAR(x);
254  b[1] = STBIW_UCHAR(x>>8);
255  s->func(s->context,b,2);
256  break; }
257  case '4': { stbiw_uint32 x = va_arg(v,int);
258  unsigned char b[4];
259  b[0]=STBIW_UCHAR(x);
260  b[1]=STBIW_UCHAR(x>>8);
261  b[2]=STBIW_UCHAR(x>>16);
262  b[3]=STBIW_UCHAR(x>>24);
263  s->func(s->context,b,4);
264  break; }
265  default:
266  STBIW_ASSERT(0);
267  return;
268  }
269  }
270 }
271 
272 static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
273 {
274  va_list v;
275  va_start(v, fmt);
276  stbiw__writefv(s, fmt, v);
277  va_end(v);
278 }
279 
280 static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
281 {
282  unsigned char arr[3];
283  arr[0] = a, arr[1] = b, arr[2] = c;
284  s->func(s->context, arr, 3);
285 }
286 
287 static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
288 {
289  unsigned char bg[3] = { 255, 0, 255}, px[3];
290  int k;
291 
292  if (write_alpha < 0)
293  s->func(s->context, &d[comp - 1], 1);
294 
295  switch (comp) {
296  case 1:
297  s->func(s->context,d,1);
298  break;
299  case 2:
300  if (expand_mono)
301  stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
302  else
303  s->func(s->context, d, 1); // monochrome TGA
304  break;
305  case 4:
306  if (!write_alpha) {
307  // composite against pink background
308  for (k = 0; k < 3; ++k)
309  px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
310  stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
311  break;
312  }
313  /* FALLTHROUGH */
314  case 3:
315  stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
316  break;
317  }
318  if (write_alpha > 0)
319  s->func(s->context, &d[comp - 1], 1);
320 }
321 
322 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)
323 {
324  stbiw_uint32 zero = 0;
325  int i,j, j_end;
326 
327  if (y <= 0)
328  return;
329 
330  if (vdir < 0)
331  j_end = -1, j = y-1;
332  else
333  j_end = y, j = 0;
334 
335  for (; j != j_end; j += vdir) {
336  for (i=0; i < x; ++i) {
337  unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
338  stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
339  }
340  s->func(s->context, &zero, scanline_pad);
341  }
342 }
343 
344 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, ...)
345 {
346  if (y < 0 || x < 0) {
347  return 0;
348  } else {
349  va_list v;
350  va_start(v, fmt);
351  stbiw__writefv(s, fmt, v);
352  va_end(v);
353  stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
354  return 1;
355  }
356 }
357 
358 static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
359 {
360  int pad = (-x*3) & 3;
361  return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
362  "11 4 22 4" "4 44 22 444444",
363  'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
364  40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
365 }
366 
367 STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
368 {
369  stbi__write_context s;
370  stbi__start_write_callbacks(&s, func, context);
371  return stbi_write_bmp_core(&s, x, y, comp, data);
372 }
373 
374 #ifndef STBI_WRITE_NO_STDIO
375 STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
376 {
377  stbi__write_context s;
378  if (stbi__start_write_file(&s,filename)) {
379  int r = stbi_write_bmp_core(&s, x, y, comp, data);
380  stbi__end_write_file(&s);
381  return r;
382  } else
383  return 0;
384 }
385 #endif
386 
387 static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
388 {
389  int has_alpha = (comp == 2 || comp == 4);
390  int colorbytes = has_alpha ? comp-1 : comp;
391  int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
392 
393  if (y < 0 || x < 0)
394  return 0;
395 
396  if (!stbi_write_tga_with_rle) {
397  return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
398  "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
399  } else {
400  int i,j,k;
401 
402  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);
403 
404  for (j = y - 1; j >= 0; --j) {
405  unsigned char *row = (unsigned char *) data + j * x * comp;
406  int len;
407 
408  for (i = 0; i < x; i += len) {
409  unsigned char *begin = row + i * comp;
410  int diff = 1;
411  len = 1;
412 
413  if (i < x - 1) {
414  ++len;
415  diff = memcmp(begin, row + (i + 1) * comp, comp);
416  if (diff) {
417  const unsigned char *prev = begin;
418  for (k = i + 2; k < x && len < 128; ++k) {
419  if (memcmp(prev, row + k * comp, comp)) {
420  prev += comp;
421  ++len;
422  } else {
423  --len;
424  break;
425  }
426  }
427  } else {
428  for (k = i + 2; k < x && len < 128; ++k) {
429  if (!memcmp(begin, row + k * comp, comp)) {
430  ++len;
431  } else {
432  break;
433  }
434  }
435  }
436  }
437 
438  if (diff) {
439  unsigned char header = STBIW_UCHAR(len - 1);
440  s->func(s->context, &header, 1);
441  for (k = 0; k < len; ++k) {
442  stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
443  }
444  } else {
445  unsigned char header = STBIW_UCHAR(len - 129);
446  s->func(s->context, &header, 1);
447  stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
448  }
449  }
450  }
451  }
452  return 1;
453 }
454 
455 int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
456 {
457  stbi__write_context s;
458  stbi__start_write_callbacks(&s, func, context);
459  return stbi_write_tga_core(&s, x, y, comp, (void *) data);
460 }
461 
462 #ifndef STBI_WRITE_NO_STDIO
463 int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
464 {
465  stbi__write_context s;
466  if (stbi__start_write_file(&s,filename)) {
467  int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
468  stbi__end_write_file(&s);
469  return r;
470  } else
471  return 0;
472 }
473 #endif
474 
475 // *************************************************************************************************
476 // Radiance RGBE HDR writer
477 // by Baldur Karlsson
478 #ifndef STBI_WRITE_NO_STDIO
479 
480 #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
481 
482 void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
483 {
484  int exponent;
485  float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
486 
487  if (maxcomp < 1e-32f) {
488  rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
489  } else {
490  float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
491 
492  rgbe[0] = (unsigned char)(linear[0] * normalize);
493  rgbe[1] = (unsigned char)(linear[1] * normalize);
494  rgbe[2] = (unsigned char)(linear[2] * normalize);
495  rgbe[3] = (unsigned char)(exponent + 128);
496  }
497 }
498 
499 void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
500 {
501  unsigned char lengthbyte = STBIW_UCHAR(length+128);
502  STBIW_ASSERT(length+128 <= 255);
503  s->func(s->context, &lengthbyte, 1);
504  s->func(s->context, &databyte, 1);
505 }
506 
507 void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
508 {
509  unsigned char lengthbyte = STBIW_UCHAR(length);
510  STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
511  s->func(s->context, &lengthbyte, 1);
512  s->func(s->context, data, length);
513 }
514 
515 void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
516 {
517  unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
518  unsigned char rgbe[4];
519  float linear[3];
520  int x;
521 
522  scanlineheader[2] = (width&0xff00)>>8;
523  scanlineheader[3] = (width&0x00ff);
524 
525  /* skip RLE for images too small or large */
526  if (width < 8 || width >= 32768) {
527  for (x=0; x < width; x++) {
528  switch (ncomp) {
529  case 4: /* fallthrough */
530  case 3: linear[2] = scanline[x*ncomp + 2];
531  linear[1] = scanline[x*ncomp + 1];
532  linear[0] = scanline[x*ncomp + 0];
533  break;
534  default:
535  linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
536  break;
537  }
538  stbiw__linear_to_rgbe(rgbe, linear);
539  s->func(s->context, rgbe, 4);
540  }
541  } else {
542  int c,r;
543  /* encode into scratch buffer */
544  for (x=0; x < width; x++) {
545  switch(ncomp) {
546  case 4: /* fallthrough */
547  case 3: linear[2] = scanline[x*ncomp + 2];
548  linear[1] = scanline[x*ncomp + 1];
549  linear[0] = scanline[x*ncomp + 0];
550  break;
551  default:
552  linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
553  break;
554  }
555  stbiw__linear_to_rgbe(rgbe, linear);
556  scratch[x + width*0] = rgbe[0];
557  scratch[x + width*1] = rgbe[1];
558  scratch[x + width*2] = rgbe[2];
559  scratch[x + width*3] = rgbe[3];
560  }
561 
562  s->func(s->context, scanlineheader, 4);
563 
564  /* RLE each component separately */
565  for (c=0; c < 4; c++) {
566  unsigned char *comp = &scratch[width*c];
567 
568  x = 0;
569  while (x < width) {
570  // find first run
571  r = x;
572  while (r+2 < width) {
573  if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
574  break;
575  ++r;
576  }
577  if (r+2 >= width)
578  r = width;
579  // dump up to first run
580  while (x < r) {
581  int len = r-x;
582  if (len > 128) len = 128;
583  stbiw__write_dump_data(s, len, &comp[x]);
584  x += len;
585  }
586  // if there's a run, output it
587  if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
588  // find next byte after run
589  while (r < width && comp[r] == comp[x])
590  ++r;
591  // output run up to r
592  while (x < r) {
593  int len = r-x;
594  if (len > 127) len = 127;
595  stbiw__write_run_data(s, len, comp[x]);
596  x += len;
597  }
598  }
599  }
600  }
601  }
602 }
603 
604 static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
605 {
606  if (y <= 0 || x <= 0 || data == NULL)
607  return 0;
608  else {
609  // Each component is stored separately. Allocate scratch space for full output scanline.
610  unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
611  int i, len;
612  char buffer[128];
613  char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
614  s->func(s->context, header, sizeof(header)-1);
615 
616  len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
617  s->func(s->context, buffer, len);
618 
619  for(i=0; i < y; i++)
620  stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
621  STBIW_FREE(scratch);
622  return 1;
623  }
624 }
625 
626 int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
627 {
628  stbi__write_context s;
629  stbi__start_write_callbacks(&s, func, context);
630  return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
631 }
632 
633 int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
634 {
635  stbi__write_context s;
636  if (stbi__start_write_file(&s,filename)) {
637  int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
638  stbi__end_write_file(&s);
639  return r;
640  } else
641  return 0;
642 }
643 #endif // STBI_WRITE_NO_STDIO
644 
645 
647 //
648 // PNG writer
649 //
650 
651 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
652 #define stbiw__sbraw(a) ((int *) (a) - 2)
653 #define stbiw__sbm(a) stbiw__sbraw(a)[0]
654 #define stbiw__sbn(a) stbiw__sbraw(a)[1]
655 
656 #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
657 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
658 #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
659 
660 #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
661 #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
662 #define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
663 
664 static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
665 {
666  int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
667  void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
668  STBIW_ASSERT(p);
669  if (p) {
670  if (!*arr) ((int *) p)[1] = 0;
671  *arr = (void *) ((int *) p + 2);
672  stbiw__sbm(*arr) = m;
673  }
674  return *arr;
675 }
676 
677 static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
678 {
679  while (*bitcount >= 8) {
680  stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
681  *bitbuffer >>= 8;
682  *bitcount -= 8;
683  }
684  return data;
685 }
686 
687 static int stbiw__zlib_bitrev(int code, int codebits)
688 {
689  int res=0;
690  while (codebits--) {
691  res = (res << 1) | (code & 1);
692  code >>= 1;
693  }
694  return res;
695 }
696 
697 static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
698 {
699  int i;
700  for (i=0; i < limit && i < 258; ++i)
701  if (a[i] != b[i]) break;
702  return i;
703 }
704 
705 static unsigned int stbiw__zhash(unsigned char *data)
706 {
707  stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
708  hash ^= hash << 3;
709  hash += hash >> 5;
710  hash ^= hash << 4;
711  hash += hash >> 17;
712  hash ^= hash << 25;
713  hash += hash >> 6;
714  return hash;
715 }
716 
717 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
718 #define stbiw__zlib_add(code,codebits) \
719  (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
720 #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
721 // default huffman tables
722 #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
723 #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
724 #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
725 #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
726 #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))
727 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
728 
729 #define stbiw__ZHASH 16384
730 
731 unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
732 {
733  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 };
734  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 };
735  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 };
736  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 };
737  unsigned int bitbuf=0;
738  int i,j, bitcount=0;
739  unsigned char *out = NULL;
740  unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
741  if (quality < 5) quality = 5;
742 
743  stbiw__sbpush(out, 0x78); // DEFLATE 32K window
744  stbiw__sbpush(out, 0x5e); // FLEVEL = 1
745  stbiw__zlib_add(1,1); // BFINAL = 1
746  stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
747 
748  for (i=0; i < stbiw__ZHASH; ++i)
749  hash_table[i] = NULL;
750 
751  i=0;
752  while (i < data_len-3) {
753  // hash next 3 bytes of data to be compressed
754  int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
755  unsigned char *bestloc = 0;
756  unsigned char **hlist = hash_table[h];
757  int n = stbiw__sbcount(hlist);
758  for (j=0; j < n; ++j) {
759  if (hlist[j]-data > i-32768) { // if entry lies within window
760  int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
761  if (d >= best) best=d,bestloc=hlist[j];
762  }
763  }
764  // when hash table entry is too long, delete half the entries
765  if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
766  STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
767  stbiw__sbn(hash_table[h]) = quality;
768  }
769  stbiw__sbpush(hash_table[h],data+i);
770 
771  if (bestloc) {
772  // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
773  h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
774  hlist = hash_table[h];
775  n = stbiw__sbcount(hlist);
776  for (j=0; j < n; ++j) {
777  if (hlist[j]-data > i-32767) {
778  int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
779  if (e > best) { // if next match is better, bail on current match
780  bestloc = NULL;
781  break;
782  }
783  }
784  }
785  }
786 
787  if (bestloc) {
788  int d = (int) (data+i - bestloc); // distance back
789  STBIW_ASSERT(d <= 32767 && best <= 258);
790  for (j=0; best > lengthc[j+1]-1; ++j);
791  stbiw__zlib_huff(j+257);
792  if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
793  for (j=0; d > distc[j+1]-1; ++j);
794  stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
795  if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
796  i += best;
797  } else {
798  stbiw__zlib_huffb(data[i]);
799  ++i;
800  }
801  }
802  // write out final bytes
803  for (;i < data_len; ++i)
804  stbiw__zlib_huffb(data[i]);
805  stbiw__zlib_huff(256); // end of block
806  // pad with 0 bits to byte boundary
807  while (bitcount)
808  stbiw__zlib_add(0,1);
809 
810  for (i=0; i < stbiw__ZHASH; ++i)
811  (void) stbiw__sbfree(hash_table[i]);
812  STBIW_FREE(hash_table);
813 
814  {
815  // compute adler32 on input
816  unsigned int s1=1, s2=0;
817  int blocklen = (int) (data_len % 5552);
818  j=0;
819  while (j < data_len) {
820  for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
821  s1 %= 65521, s2 %= 65521;
822  j += blocklen;
823  blocklen = 5552;
824  }
825  stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
826  stbiw__sbpush(out, STBIW_UCHAR(s2));
827  stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
828  stbiw__sbpush(out, STBIW_UCHAR(s1));
829  }
830  *out_len = stbiw__sbn(out);
831  // make returned pointer freeable
832  STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
833  return (unsigned char *) stbiw__sbraw(out);
834 }
835 
836 static unsigned int stbiw__crc32(unsigned char *buffer, int len)
837 {
838  static unsigned int crc_table[256] =
839  {
840  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
841  0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
842  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
843  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
844  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
845  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
846  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
847  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
848  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
849  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
850  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
851  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
852  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
853  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
854  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
855  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
856  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
857  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
858  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
859  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
860  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
861  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
862  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
863  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
864  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
865  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
866  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
867  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
868  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
869  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
870  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
871  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
872  };
873 
874  unsigned int crc = ~0u;
875  int i;
876  for (i=0; i < len; ++i)
877  crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
878  return ~crc;
879 }
880 
881 #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)
882 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
883 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
884 
885 static void stbiw__wpcrc(unsigned char **data, int len)
886 {
887  unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
888  stbiw__wp32(*data, crc);
889 }
890 
891 static unsigned char stbiw__paeth(int a, int b, int c)
892 {
893  int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
894  if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
895  if (pb <= pc) return STBIW_UCHAR(b);
896  return STBIW_UCHAR(c);
897 }
898 
899 unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
900 {
901  int ctype[5] = { -1, 0, 4, 2, 6 };
902  unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
903  unsigned char *out,*o, *filt, *zlib;
904  signed char *line_buffer;
905  int i,j,k,p,zlen;
906 
907  if (stride_bytes == 0)
908  stride_bytes = x * n;
909 
910  filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
911  line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
912  for (j=0; j < y; ++j) {
913  static int mapping[] = { 0,1,2,3,4 };
914  static int firstmap[] = { 0,1,0,5,6 };
915  int *mymap = j ? mapping : firstmap;
916  int best = 0, bestval = 0x7fffffff;
917  for (p=0; p < 2; ++p) {
918  for (k= p?best:0; k < 5; ++k) {
919  int type = mymap[k],est=0;
920  unsigned char *z = pixels + stride_bytes*j;
921  for (i=0; i < n; ++i)
922  switch (type) {
923  case 0: line_buffer[i] = z[i]; break;
924  case 1: line_buffer[i] = z[i]; break;
925  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
926  case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
927  case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
928  case 5: line_buffer[i] = z[i]; break;
929  case 6: line_buffer[i] = z[i]; break;
930  }
931  for (i=n; i < x*n; ++i) {
932  switch (type) {
933  case 0: line_buffer[i] = z[i]; break;
934  case 1: line_buffer[i] = z[i] - z[i-n]; break;
935  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
936  case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
937  case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
938  case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
939  case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
940  }
941  }
942  if (p) break;
943  for (i=0; i < x*n; ++i)
944  est += abs((signed char) line_buffer[i]);
945  if (est < bestval) { bestval = est; best = k; }
946  }
947  }
948  // when we get here, best contains the filter type, and line_buffer contains the data
949  filt[j*(x*n+1)] = (unsigned char) best;
950  STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
951  }
952  STBIW_FREE(line_buffer);
953  zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
954  STBIW_FREE(filt);
955  if (!zlib) return 0;
956 
957  // each tag requires 12 bytes of overhead
958  out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
959  if (!out) return 0;
960  *out_len = 8 + 12+13 + 12+zlen + 12;
961 
962  o=out;
963  STBIW_MEMMOVE(o,sig,8); o+= 8;
964  stbiw__wp32(o, 13); // header length
965  stbiw__wptag(o, "IHDR");
966  stbiw__wp32(o, x);
967  stbiw__wp32(o, y);
968  *o++ = 8;
969  *o++ = STBIW_UCHAR(ctype[n]);
970  *o++ = 0;
971  *o++ = 0;
972  *o++ = 0;
973  stbiw__wpcrc(&o,13);
974 
975  stbiw__wp32(o, zlen);
976  stbiw__wptag(o, "IDAT");
977  STBIW_MEMMOVE(o, zlib, zlen);
978  o += zlen;
979  STBIW_FREE(zlib);
980  stbiw__wpcrc(&o, zlen);
981 
982  stbiw__wp32(o,0);
983  stbiw__wptag(o, "IEND");
984  stbiw__wpcrc(&o,0);
985 
986  STBIW_ASSERT(o == out + *out_len);
987 
988  return out;
989 }
990 
991 #ifndef STBI_WRITE_NO_STDIO
992 STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
993 {
994  FILE *f;
995  int len;
996  unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
997  if (png == NULL) return 0;
998  f = fopen(filename, "wb");
999  if (!f) { STBIW_FREE(png); return 0; }
1000  fwrite(png, 1, len, f);
1001  fclose(f);
1002  STBIW_FREE(png);
1003  return 1;
1004 }
1005 #endif
1006 
1007 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)
1008 {
1009  int len;
1010  unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1011  if (png == NULL) return 0;
1012  func(context, png, len);
1013  STBIW_FREE(png);
1014  return 1;
1015 }
1016 
1017 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1018 
1019 /* Revision history
1020  1.02 (2016-04-02)
1021  avoid allocating large structures on the stack
1022  1.01 (2016-01-16)
1023  STBIW_REALLOC_SIZED: support allocators with no realloc support
1024  avoid race-condition in crc initialization
1025  minor compile issues
1026  1.00 (2015-09-14)
1027  installable file IO function
1028  0.99 (2015-09-13)
1029  warning fixes; TGA rle support
1030  0.98 (2015-04-08)
1031  added STBIW_MALLOC, STBIW_ASSERT etc
1032  0.97 (2015-01-18)
1033  fixed HDR asserts, rewrote HDR rle logic
1034  0.96 (2015-01-17)
1035  add HDR output
1036  fix monochrome BMP
1037  0.95 (2014-08-17)
1038  add monochrome TGA output
1039  0.94 (2014-05-31)
1040  rename private functions to avoid conflicts with stb_image.h
1041  0.93 (2014-05-27)
1042  warning fixes
1043  0.92 (2010-08-01)
1044  casts to unsigned char to fix warnings
1045  0.91 (2010-07-17)
1046  first public release
1047  0.90 first internal release
1048 */
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data)
GLboolean GLboolean GLboolean b
GLint y
STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data)
GLenum GLenum GLsizei void * row
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data)
GLdouble s
GLfloat GLfloat p
Definition: glext.h:12687
const GLfloat * m
Definition: glext.h:6814
int stbi_write_tga_with_rle
GLdouble GLdouble GLdouble w
std_msgs::Header * header(M &m)
returns Header<M>::pointer(m);
d
Definition: rmse.py:171
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
GLdouble GLdouble z
GLdouble n
Definition: glext.h:1966
GLint limit
Definition: glext.h:9964
e
Definition: rmse.py:177
GLenum GLfloat * buffer
void stbi_write_func(void *context, void *data, int size)
GLboolean GLboolean GLboolean GLboolean a
GLenum GLsizei len
Definition: glext.h:3285
STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data)
not_this_one begin(...)
GLdouble f
GLfloat GLfloat GLfloat alpha
GLsizeiptr size
const GLubyte * c
Definition: glext.h:12690
GLdouble GLdouble r
GLdouble x
GLint GLint GLsizei GLint GLenum format
rs2_intrinsics normalize(const rs2_intrinsics &intr)
Definition: l500-color.cpp:272
GLint j
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:10805
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
GLenum func
STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data)
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data)
GLenum type
#define NULL
Definition: tinycthread.c:47
int i
GLenum GLuint GLenum GLsizei length
GLuint res
Definition: glext.h:8856
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:9721
GLboolean * data
GLdouble v
GLint * exponent
Definition: glext.h:5352
#define STBIWDEF
Definition: parser.hpp:150
GLint GLsizei width
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)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:10