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


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:17