The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
stb_image_write.h
Go to the documentation of this file.
1 /* stb_image_write - v0.94 - public domain - http://nothings.org/stb/stb_image_write.h
2  writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
3  no warranty implied; use at your own risk
4 
5 
6 Before including,
7 
8  #define STB_IMAGE_WRITE_IMPLEMENTATION
9 
10 in the file that you want to have the implementation.
11 
12 Will probably not work correctly with strict-aliasing optimizations.
13 
14 
15 ABOUT:
16 
17  This header file is a library for writing images to C stdio. It could be
18  adapted to write to memory or a general streaming interface; let me know.
19 
20  The PNG output is not optimal; it is 20-50% larger than the file
21  written by a decent optimizing implementation. This library is designed
22  for source code compactness and simplicitly, not optimal image file size
23  or run-time performance.
24 
25 USAGE:
26 
27  There are three functions, one for each image file format:
28 
29  int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
30  int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
31  int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
32 
33  Each function returns 0 on failure and non-0 on success.
34 
35  The functions create an image file defined by the parameters. The image
36  is a rectangle of pixels stored from left-to-right, top-to-bottom.
37  Each pixel contains 'comp' channels of data stored interleaved with 8-bits
38  per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
39  monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
40  The *data pointer points to the first byte of the top-left-most pixel.
41  For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
42  a row of pixels to the first byte of the next row of pixels.
43 
44  PNG creates output files with the same number of components as the input.
45  The BMP and TGA formats expand Y to RGB in the file format. BMP does not
46  output alpha.
47 
48  PNG supports writing rectangles of data even when the bytes storing rows of
49  data are not consecutive in memory (e.g. sub-rectangles of a larger image),
50  by supplying the stride between the beginning of adjacent rows. The other
51  formats do not. (Thus you cannot write a native-format BMP through the BMP
52  writer, both because it is in BGR order and because it may have padding
53  at the end of the line.)
54 */
55 
56 #ifndef INCLUDE_STB_IMAGE_WRITE_H
57 #define INCLUDE_STB_IMAGE_WRITE_H
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 
63 extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
64 extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
65 extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
66 
67 #ifdef __cplusplus
68 }
69 #endif
70 
71 #endif//INCLUDE_STB_IMAGE_WRITE_H
72 
73 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
74 
75 #include <stdarg.h>
76 #include <stdlib.h>
77 #include <stdio.h>
78 #include <string.h>
79 #include <assert.h>
80 
81 typedef unsigned int stbiw_uint32;
82 typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
83 
84 static void writefv(FILE *f, const char *fmt, va_list v)
85 {
86  while (*fmt) {
87  switch (*fmt++) {
88  case ' ': break;
89  case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
90  case '2': { int x = va_arg(v,int); unsigned char b[2];
91  b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
92  fwrite(b,2,1,f); break; }
93  case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
94  b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
95  b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
96  fwrite(b,4,1,f); break; }
97  default:
98  assert(0);
99  return;
100  }
101  }
102 }
103 
104 static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
105 {
106  unsigned char arr[3];
107  arr[0] = a, arr[1] = b, arr[2] = c;
108  fwrite(arr, 3, 1, f);
109 }
110 
111 static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
112 {
113  unsigned char bg[3] = { 255, 0, 255}, px[3];
114  stbiw_uint32 zero = 0;
115  int i,j,k, j_end;
116 
117  if (y <= 0)
118  return;
119 
120  if (vdir < 0)
121  j_end = -1, j = y-1;
122  else
123  j_end = y, j = 0;
124 
125  for (; j != j_end; j += vdir) {
126  for (i=0; i < x; ++i) {
127  unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
128  if (write_alpha < 0)
129  fwrite(&d[comp-1], 1, 1, f);
130  switch (comp) {
131  case 1:
132  case 2: write3(f, d[0],d[0],d[0]);
133  break;
134  case 4:
135  if (!write_alpha) {
136  // composite against pink background
137  for (k=0; k < 3; ++k)
138  px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
139  write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
140  break;
141  }
142  /* FALLTHROUGH */
143  case 3:
144  write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
145  break;
146  }
147  if (write_alpha > 0)
148  fwrite(&d[comp-1], 1, 1, f);
149  }
150  fwrite(&zero,scanline_pad,1,f);
151  }
152 }
153 
154 static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
155 {
156  FILE *f;
157  if (y < 0 || x < 0) return 0;
158  f = fopen(filename, "wb");
159  if (f) {
160  va_list v;
161  va_start(v, fmt);
162  writefv(f, fmt, v);
163  va_end(v);
164  write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
165  fclose(f);
166  }
167  return f != NULL;
168 }
169 
170 int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
171 {
172  int pad = (-x*3) & 3;
173  return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
174  "11 4 22 4" "4 44 22 444444",
175  'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
176  40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
177 }
178 
179 int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
180 {
181  int has_alpha = !(comp & 1);
182  return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
183  "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
184 }
185 
186 // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
187 #define stbiw__sbraw(a) ((int *) (a) - 2)
188 #define stbiw__sbm(a) stbiw__sbraw(a)[0]
189 #define stbiw__sbn(a) stbiw__sbraw(a)[1]
190 
191 #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
192 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
193 #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
194 
195 #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
196 #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
197 #define stbiw__sbfree(a) ((a) ? free(stbiw__sbraw(a)),0 : 0)
198 
199 static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
200 {
201  int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
202  void *p = realloc(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
203  assert(p);
204  if (p) {
205  if (!*arr) ((int *) p)[1] = 0;
206  *arr = (void *) ((int *) p + 2);
207  stbiw__sbm(*arr) = m;
208  }
209  return *arr;
210 }
211 
212 static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
213 {
214  while (*bitcount >= 8) {
215  stbiw__sbpush(data, (unsigned char) *bitbuffer);
216  *bitbuffer >>= 8;
217  *bitcount -= 8;
218  }
219  return data;
220 }
221 
222 static int stbiw__zlib_bitrev(int code, int codebits)
223 {
224  int res=0;
225  while (codebits--) {
226  res = (res << 1) | (code & 1);
227  code >>= 1;
228  }
229  return res;
230 }
231 
232 static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
233 {
234  int i;
235  for (i=0; i < limit && i < 258; ++i)
236  if (a[i] != b[i]) break;
237  return i;
238 }
239 
240 static unsigned int stbiw__zhash(unsigned char *data)
241 {
242  stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
243  hash ^= hash << 3;
244  hash += hash >> 5;
245  hash ^= hash << 4;
246  hash += hash >> 17;
247  hash ^= hash << 25;
248  hash += hash >> 6;
249  return hash;
250 }
251 
252 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
253 #define stbiw__zlib_add(code,codebits) \
254  (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
255 #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
256 // default huffman tables
257 #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
258 #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
259 #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
260 #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
261 #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))
262 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
263 
264 #define stbiw__ZHASH 16384
265 
266 unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
267 {
268  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 };
269  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 };
270  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 };
271  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 };
272  unsigned int bitbuf=0;
273  int i,j, bitcount=0;
274  unsigned char *out = NULL;
275  unsigned char **hash_table[stbiw__ZHASH]; // 64KB on the stack!
276  if (quality < 5) quality = 5;
277 
278  stbiw__sbpush(out, 0x78); // DEFLATE 32K window
279  stbiw__sbpush(out, 0x5e); // FLEVEL = 1
280  stbiw__zlib_add(1,1); // BFINAL = 1
281  stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
282 
283  for (i=0; i < stbiw__ZHASH; ++i)
284  hash_table[i] = NULL;
285 
286  i=0;
287  while (i < data_len-3) {
288  // hash next 3 bytes of data to be compressed
289  int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
290  unsigned char *bestloc = 0;
291  unsigned char **hlist = hash_table[h];
292  int n = stbiw__sbcount(hlist);
293  for (j=0; j < n; ++j) {
294  if (hlist[j]-data > i-32768) { // if entry lies within window
295  int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
296  if (d >= best) best=d,bestloc=hlist[j];
297  }
298  }
299  // when hash table entry is too long, delete half the entries
300  if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
301  memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
302  stbiw__sbn(hash_table[h]) = quality;
303  }
304  stbiw__sbpush(hash_table[h],data+i);
305 
306  if (bestloc) {
307  // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
308  h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
309  hlist = hash_table[h];
310  n = stbiw__sbcount(hlist);
311  for (j=0; j < n; ++j) {
312  if (hlist[j]-data > i-32767) {
313  int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
314  if (e > best) { // if next match is better, bail on current match
315  bestloc = NULL;
316  break;
317  }
318  }
319  }
320  }
321 
322  if (bestloc) {
323  int d = (int) (data+i - bestloc); // distance back
324  assert(d <= 32767 && best <= 258);
325  for (j=0; best > lengthc[j+1]-1; ++j);
326  stbiw__zlib_huff(j+257);
327  if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
328  for (j=0; d > distc[j+1]-1; ++j);
329  stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
330  if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
331  i += best;
332  } else {
333  stbiw__zlib_huffb(data[i]);
334  ++i;
335  }
336  }
337  // write out final bytes
338  for (;i < data_len; ++i)
339  stbiw__zlib_huffb(data[i]);
340  stbiw__zlib_huff(256); // end of block
341  // pad with 0 bits to byte boundary
342  while (bitcount)
343  stbiw__zlib_add(0,1);
344 
345  for (i=0; i < stbiw__ZHASH; ++i)
346  (void) stbiw__sbfree(hash_table[i]);
347 
348  {
349  // compute adler32 on input
350  unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
351  int j=0;
352  while (j < data_len) {
353  for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
354  s1 %= 65521, s2 %= 65521;
355  j += blocklen;
356  blocklen = 5552;
357  }
358  stbiw__sbpush(out, (unsigned char) (s2 >> 8));
359  stbiw__sbpush(out, (unsigned char) s2);
360  stbiw__sbpush(out, (unsigned char) (s1 >> 8));
361  stbiw__sbpush(out, (unsigned char) s1);
362  }
363  *out_len = stbiw__sbn(out);
364  // make returned pointer freeable
365  memmove(stbiw__sbraw(out), out, *out_len);
366  return (unsigned char *) stbiw__sbraw(out);
367 }
368 
369 unsigned int stbiw__crc32(unsigned char *buffer, int len)
370 {
371  static unsigned int crc_table[256];
372  unsigned int crc = ~0u;
373  int i,j;
374  if (crc_table[1] == 0)
375  for(i=0; i < 256; i++)
376  for (crc_table[i]=i, j=0; j < 8; ++j)
377  crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
378  for (i=0; i < len; ++i)
379  crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
380  return ~crc;
381 }
382 
383 #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
384 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
385 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
386 
387 static void stbiw__wpcrc(unsigned char **data, int len)
388 {
389  unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
390  stbiw__wp32(*data, crc);
391 }
392 
393 static unsigned char stbiw__paeth(int a, int b, int c)
394 {
395  int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
396  if (pa <= pb && pa <= pc) return (unsigned char) a;
397  if (pb <= pc) return (unsigned char) b;
398  return (unsigned char) c;
399 }
400 
401 unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
402 {
403  int ctype[5] = { -1, 0, 4, 2, 6 };
404  unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
405  unsigned char *out,*o, *filt, *zlib;
406  signed char *line_buffer;
407  int i,j,k,p,zlen;
408 
409  if (stride_bytes == 0)
410  stride_bytes = x * n;
411 
412  filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
413  line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
414  for (j=0; j < y; ++j) {
415  static int mapping[] = { 0,1,2,3,4 };
416  static int firstmap[] = { 0,1,0,5,6 };
417  int *mymap = j ? mapping : firstmap;
418  int best = 0, bestval = 0x7fffffff;
419  for (p=0; p < 2; ++p) {
420  for (k= p?best:0; k < 5; ++k) {
421  int type = mymap[k],est=0;
422  unsigned char *z = pixels + stride_bytes*j;
423  for (i=0; i < n; ++i)
424  switch (type) {
425  case 0: line_buffer[i] = z[i]; break;
426  case 1: line_buffer[i] = z[i]; break;
427  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
428  case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
429  case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
430  case 5: line_buffer[i] = z[i]; break;
431  case 6: line_buffer[i] = z[i]; break;
432  }
433  for (i=n; i < x*n; ++i) {
434  switch (type) {
435  case 0: line_buffer[i] = z[i]; break;
436  case 1: line_buffer[i] = z[i] - z[i-n]; break;
437  case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
438  case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
439  case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
440  case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
441  case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
442  }
443  }
444  if (p) break;
445  for (i=0; i < x*n; ++i)
446  est += abs((signed char) line_buffer[i]);
447  if (est < bestval) { bestval = est; best = k; }
448  }
449  }
450  // when we get here, best contains the filter type, and line_buffer contains the data
451  filt[j*(x*n+1)] = (unsigned char) best;
452  memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
453  }
454  free(line_buffer);
455  zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
456  free(filt);
457  if (!zlib) return 0;
458 
459  // each tag requires 12 bytes of overhead
460  out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
461  if (!out) return 0;
462  *out_len = 8 + 12+13 + 12+zlen + 12;
463 
464  o=out;
465  memcpy(o,sig,8); o+= 8;
466  stbiw__wp32(o, 13); // header length
467  stbiw__wptag(o, "IHDR");
468  stbiw__wp32(o, x);
469  stbiw__wp32(o, y);
470  *o++ = 8;
471  *o++ = (unsigned char) ctype[n];
472  *o++ = 0;
473  *o++ = 0;
474  *o++ = 0;
475  stbiw__wpcrc(&o,13);
476 
477  stbiw__wp32(o, zlen);
478  stbiw__wptag(o, "IDAT");
479  memcpy(o, zlib, zlen); o += zlen; free(zlib);
480  stbiw__wpcrc(&o, zlen);
481 
482  stbiw__wp32(o,0);
483  stbiw__wptag(o, "IEND");
484  stbiw__wpcrc(&o,0);
485 
486  assert(o == out + *out_len);
487 
488  return out;
489 }
490 
491 int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
492 {
493  FILE *f;
494  int len;
495  unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
496  if (!png) return 0;
497  f = fopen(filename, "wb");
498  if (!f) { free(png); return 0; }
499  fwrite(png, 1, len, f);
500  fclose(f);
501  free(png);
502  return 1;
503 }
504 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
505 
506 /* Revision history
507 
508  0.94 (2014-05-31)
509  rename private functions to avoid conflicts with stb_image.h
510  0.93 (2014-05-27)
511  warning fixes
512  0.92 (2010-08-01)
513  casts to unsigned char to fix warnings
514  0.91 (2010-07-17)
515  first public release
516  0.90 first internal release
517 */
GLdouble GLdouble z
Definition: glew.h:1527
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: glew.h:1222
const GLfloat * c
Definition: glew.h:12741
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data)
#define h
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
#define d
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
GLint limit
Definition: glew.h:10112
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
const GLdouble * v
Definition: glew.h:1359
GLenum GLsizei len
Definition: glew.h:5662
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1488
GLfloat GLfloat p
Definition: glew.h:12766
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
GLenum GLenum GLenum GLenum mapping
Definition: glew.h:10668
GLuint buffer
Definition: glew.h:1648
GLuint res
Definition: glew.h:9258
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
size_t i
Definition: function.cpp:1057
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
GLclampd n
Definition: glew.h:5903
const GLdouble * m
Definition: glew.h:6968
#define c
Definition: glew.h:12743
#define e
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data)
GLclampf f
Definition: glew.h:3024