gosu 0.10.5.pre1 → 0.10.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,6 @@
1
- /* stb_image_write - v0.98 - 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
-
1
+ /* stb_image_write - v1.00 - 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
5
4
 
6
5
  Before #including,
7
6
 
@@ -18,7 +17,7 @@ ABOUT:
18
17
 
19
18
  The PNG output is not optimal; it is 20-50% larger than the file
20
19
  written by a decent optimizing implementation. This library is designed
21
- for source code compactness and simplicitly, not optimal image file size
20
+ for source code compactness and simplicity, not optimal image file size
22
21
  or run-time performance.
23
22
 
24
23
  BUILDING:
@@ -37,6 +36,21 @@ USAGE:
37
36
  int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
38
37
  int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data);
39
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
+
40
54
  Each function returns 0 on failure and non-0 on success.
41
55
 
42
56
  The functions create an image file defined by the parameters. The image
@@ -63,6 +77,9 @@ USAGE:
63
77
  data, alpha (if provided) is discarded, and for monochrome data it is
64
78
  replicated across all three channels.
65
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
+
66
83
  CREDITS:
67
84
 
68
85
  PNG/BMP/TGA
@@ -73,8 +90,21 @@ CREDITS:
73
90
  Jean-Sebastien Guay
74
91
  misc enhancements:
75
92
  Tim Kelsey
93
+ TGA RLE
94
+ Alan Hickman
95
+ initial file IO callback implementation
96
+ Emmanuel Julien
76
97
  bugfixes:
77
98
  github:Chribba
99
+ Guillaume Chereau
100
+ github:jry2
101
+
102
+ LICENSE
103
+
104
+ This software is in the public domain. Where that dedication is not
105
+ recognized, you are granted a perpetual, irrevocable license to copy,
106
+ distribute, and modify this file as you see fit.
107
+
78
108
  */
79
109
 
80
110
  #ifndef INCLUDE_STB_IMAGE_WRITE_H
@@ -84,10 +114,26 @@ CREDITS:
84
114
  extern "C" {
85
115
  #endif
86
116
 
87
- extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
88
- extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
89
- extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
90
- extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
117
+ #ifdef STB_IMAGE_WRITE_STATIC
118
+ #define STBIWDEF static
119
+ #else
120
+ #define STBIWDEF extern
121
+ extern int stbi_write_tga_with_rle;
122
+ #endif
123
+
124
+ #ifndef STBI_WRITE_NO_STDIO
125
+ STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
126
+ STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
127
+ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
128
+ STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
129
+ #endif
130
+
131
+ typedef void stbi_write_func(void *context, void *data, int size);
132
+
133
+ 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);
134
+ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
135
+ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
136
+ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
91
137
 
92
138
  #ifdef __cplusplus
93
139
  }
@@ -97,9 +143,17 @@ extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const fl
97
143
 
98
144
  #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
99
145
 
146
+ #ifdef _WIN32
147
+ #define _CRT_SECURE_NO_WARNINGS
148
+ #define _CRT_NONSTDC_NO_DEPRECATE
149
+ #endif
150
+
151
+ #ifndef STBI_WRITE_NO_STDIO
152
+ #include <stdio.h>
153
+ #endif // STBI_WRITE_NO_STDIO
154
+
100
155
  #include <stdarg.h>
101
156
  #include <stdlib.h>
102
- #include <stdio.h>
103
157
  #include <string.h>
104
158
  #include <math.h>
105
159
 
@@ -126,22 +180,71 @@ extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const fl
126
180
  #define STBIW_ASSERT(x) assert(x)
127
181
  #endif
128
182
 
183
+ typedef struct
184
+ {
185
+ stbi_write_func *func;
186
+ void *context;
187
+ } stbi__write_context;
188
+
189
+ // initialize a callback-based context
190
+ static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
191
+ {
192
+ s->func = c;
193
+ s->context = context;
194
+ }
195
+
196
+ #ifndef STBI_WRITE_NO_STDIO
197
+
198
+ static void stbi__stdio_write(void *context, void *data, int size)
199
+ {
200
+ fwrite(data,1,size,(FILE*) context);
201
+ }
202
+
203
+ static int stbi__start_write_file(stbi__write_context *s, const char *filename)
204
+ {
205
+ FILE *f = fopen(filename, "wb");
206
+ stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
207
+ return f != NULL;
208
+ }
209
+
210
+ static void stbi__end_write_file(stbi__write_context *s)
211
+ {
212
+ fclose((FILE *)s->context);
213
+ }
214
+
215
+ #endif // !STBI_WRITE_NO_STDIO
216
+
129
217
  typedef unsigned int stbiw_uint32;
130
218
  typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
131
219
 
132
- static void writefv(FILE *f, const char *fmt, va_list v)
220
+ #ifdef STB_IMAGE_WRITE_STATIC
221
+ static int stbi_write_tga_with_rle = 1;
222
+ #else
223
+ int stbi_write_tga_with_rle = 1;
224
+ #endif
225
+
226
+ static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
133
227
  {
134
228
  while (*fmt) {
135
229
  switch (*fmt++) {
136
230
  case ' ': break;
137
- case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
138
- case '2': { int x = va_arg(v,int); unsigned char b[2];
139
- b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
140
- fwrite(b,2,1,f); break; }
141
- case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
142
- b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
143
- b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
144
- fwrite(b,4,1,f); break; }
231
+ case '1': { unsigned char x = (unsigned char) va_arg(v, int);
232
+ s->func(s->context,&x,1);
233
+ break; }
234
+ case '2': { int x = va_arg(v,int);
235
+ unsigned char b[2];
236
+ b[0] = (unsigned char) x;
237
+ b[1] = (unsigned char) (x>>8);
238
+ s->func(s->context,b,2);
239
+ break; }
240
+ case '4': { stbiw_uint32 x = va_arg(v,int);
241
+ unsigned char b[4];
242
+ b[0]=(unsigned char)x;
243
+ b[1]=(unsigned char)(x>>8);
244
+ b[2]=(unsigned char)(x>>16);
245
+ b[3]=(unsigned char)(x>>24);
246
+ s->func(s->context,b,4);
247
+ break; }
145
248
  default:
146
249
  STBIW_ASSERT(0);
147
250
  return;
@@ -149,18 +252,60 @@ static void writefv(FILE *f, const char *fmt, va_list v)
149
252
  }
150
253
  }
151
254
 
152
- static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
255
+ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
256
+ {
257
+ va_list v;
258
+ va_start(v, fmt);
259
+ stbiw__writefv(s, fmt, v);
260
+ va_end(v);
261
+ }
262
+
263
+ static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
153
264
  {
154
265
  unsigned char arr[3];
155
266
  arr[0] = a, arr[1] = b, arr[2] = c;
156
- fwrite(arr, 3, 1, f);
267
+ s->func(s->context, arr, 3);
157
268
  }
158
269
 
159
- 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, int expand_mono)
270
+ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
160
271
  {
161
272
  unsigned char bg[3] = { 255, 0, 255}, px[3];
273
+ int k;
274
+
275
+ if (write_alpha < 0)
276
+ s->func(s->context, &d[comp - 1], 1);
277
+
278
+ switch (comp) {
279
+ case 1:
280
+ s->func(s->context,d,1);
281
+ break;
282
+ case 2:
283
+ if (expand_mono)
284
+ stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
285
+ else
286
+ s->func(s->context, d, 1); // monochrome TGA
287
+ break;
288
+ case 4:
289
+ if (!write_alpha) {
290
+ // composite against pink background
291
+ for (k = 0; k < 3; ++k)
292
+ px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
293
+ stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
294
+ break;
295
+ }
296
+ /* FALLTHROUGH */
297
+ case 3:
298
+ stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
299
+ break;
300
+ }
301
+ if (write_alpha > 0)
302
+ s->func(s->context, &d[comp - 1], 1);
303
+ }
304
+
305
+ 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)
306
+ {
162
307
  stbiw_uint32 zero = 0;
163
- int i,j,k, j_end;
308
+ int i,j, j_end;
164
309
 
165
310
  if (y <= 0)
166
311
  return;
@@ -173,73 +318,148 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
173
318
  for (; j != j_end; j += vdir) {
174
319
  for (i=0; i < x; ++i) {
175
320
  unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
176
- if (write_alpha < 0)
177
- fwrite(&d[comp-1], 1, 1, f);
178
- switch (comp) {
179
- case 1: fwrite(d, 1, 1, f);
180
- break;
181
- case 2: if (expand_mono)
182
- write3(f, d[0],d[0],d[0]); // monochrome bmp
183
- else
184
- fwrite(d, 1, 1, f); // monochrome TGA
185
- break;
186
- case 4:
187
- if (!write_alpha) {
188
- // composite against pink background
189
- for (k=0; k < 3; ++k)
190
- px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
191
- write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
192
- break;
193
- }
194
- /* FALLTHROUGH */
195
- case 3:
196
- write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
197
- break;
198
- }
199
- if (write_alpha > 0)
200
- fwrite(&d[comp-1], 1, 1, f);
321
+ stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
201
322
  }
202
- fwrite(&zero,scanline_pad,1,f);
323
+ s->func(s->context, &zero, scanline_pad);
203
324
  }
204
325
  }
205
326
 
206
- static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
327
+ 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, ...)
207
328
  {
208
- FILE *f;
209
- if (y < 0 || x < 0) return 0;
210
- f = fopen(filename, "wb");
211
- if (f) {
329
+ if (y < 0 || x < 0) {
330
+ return 0;
331
+ } else {
212
332
  va_list v;
213
333
  va_start(v, fmt);
214
- writefv(f, fmt, v);
334
+ stbiw__writefv(s, fmt, v);
215
335
  va_end(v);
216
- write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad,expand_mono);
217
- fclose(f);
336
+ stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
337
+ return 1;
218
338
  }
219
- return f != NULL;
220
339
  }
221
340
 
222
- int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
341
+ static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
223
342
  {
224
343
  int pad = (-x*3) & 3;
225
- return outfile(filename,-1,-1,x,y,comp,1,(void *) data,0,pad,
344
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
226
345
  "11 4 22 4" "4 44 22 444444",
227
346
  'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
228
347
  40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
229
348
  }
230
349
 
231
- int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
350
+ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
351
+ {
352
+ stbi__write_context s;
353
+ stbi__start_write_callbacks(&s, func, context);
354
+ return stbi_write_bmp_core(&s, x, y, comp, data);
355
+ }
356
+
357
+ #ifndef STBI_WRITE_NO_STDIO
358
+ STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
359
+ {
360
+ stbi__write_context s;
361
+ if (stbi__start_write_file(&s,filename)) {
362
+ int r = stbi_write_bmp_core(&s, x, y, comp, data);
363
+ stbi__end_write_file(&s);
364
+ return r;
365
+ } else
366
+ return 0;
367
+ }
368
+ #endif //!STBI_WRITE_NO_STDIO
369
+
370
+ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
232
371
  {
233
372
  int has_alpha = (comp == 2 || comp == 4);
234
373
  int colorbytes = has_alpha ? comp-1 : comp;
235
374
  int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
236
- return outfile(filename, -1,-1, x, y, comp, 0, (void *) data, has_alpha, 0,
237
- "111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8);
375
+
376
+ if (y < 0 || x < 0)
377
+ return 0;
378
+
379
+ if (!stbi_write_tga_with_rle) {
380
+ return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
381
+ "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
382
+ } else {
383
+ int i,j,k;
384
+
385
+ 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);
386
+
387
+ for (j = y - 1; j >= 0; --j) {
388
+ unsigned char *row = (unsigned char *) data + j * x * comp;
389
+ int len;
390
+
391
+ for (i = 0; i < x; i += len) {
392
+ unsigned char *begin = row + i * comp;
393
+ int diff = 1;
394
+ len = 1;
395
+
396
+ if (i < x - 1) {
397
+ ++len;
398
+ diff = memcmp(begin, row + (i + 1) * comp, comp);
399
+ if (diff) {
400
+ const unsigned char *prev = begin;
401
+ for (k = i + 2; k < x && len < 128; ++k) {
402
+ if (memcmp(prev, row + k * comp, comp)) {
403
+ prev += comp;
404
+ ++len;
405
+ } else {
406
+ --len;
407
+ break;
408
+ }
409
+ }
410
+ } else {
411
+ for (k = i + 2; k < x && len < 128; ++k) {
412
+ if (!memcmp(begin, row + k * comp, comp)) {
413
+ ++len;
414
+ } else {
415
+ break;
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ if (diff) {
422
+ unsigned char header = (unsigned char) (len - 1);
423
+ s->func(s->context, &header, 1);
424
+ for (k = 0; k < len; ++k) {
425
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
426
+ }
427
+ } else {
428
+ unsigned char header = (unsigned char) (len - 129);
429
+ s->func(s->context, &header, 1);
430
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
431
+ }
432
+ }
433
+ }
434
+ }
435
+ return 1;
436
+ }
437
+
438
+ int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
439
+ {
440
+ stbi__write_context s;
441
+ stbi__start_write_callbacks(&s, func, context);
442
+ return stbi_write_tga_core(&s, x, y, comp, (void *) data);
443
+ }
444
+
445
+ #ifndef STBI_WRITE_NO_STDIO
446
+ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
447
+ {
448
+ stbi__write_context s;
449
+ if (stbi__start_write_file(&s,filename)) {
450
+ int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
451
+ stbi__end_write_file(&s);
452
+ return r;
453
+ } else
454
+ return 0;
238
455
  }
456
+ #endif
239
457
 
240
458
  // *************************************************************************************************
241
459
  // Radiance RGBE HDR writer
242
460
  // by Baldur Karlsson
461
+ #ifndef STBI_WRITE_NO_STDIO
462
+
243
463
  #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
244
464
 
245
465
  void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
@@ -259,23 +479,23 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
259
479
  }
260
480
  }
261
481
 
262
- void stbiw__write_run_data(FILE *f, int length, unsigned char databyte)
482
+ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
263
483
  {
264
484
  unsigned char lengthbyte = (unsigned char) (length+128);
265
485
  STBIW_ASSERT(length+128 <= 255);
266
- fwrite(&lengthbyte, 1, 1, f);
267
- fwrite(&databyte, 1, 1, f);
486
+ s->func(s->context, &lengthbyte, 1);
487
+ s->func(s->context, &databyte, 1);
268
488
  }
269
489
 
270
- void stbiw__write_dump_data(FILE *f, int length, unsigned char *data)
490
+ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
271
491
  {
272
492
  unsigned char lengthbyte = (unsigned char )(length & 0xff);
273
493
  STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
274
- fwrite(&lengthbyte, 1, 1, f);
275
- fwrite(data, length, 1, f);
494
+ s->func(s->context, &lengthbyte, 1);
495
+ s->func(s->context, data, length);
276
496
  }
277
497
 
278
- void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scratch, const float *scanline)
498
+ void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
279
499
  {
280
500
  unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
281
501
  unsigned char rgbe[4];
@@ -288,31 +508,31 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra
288
508
  /* skip RLE for images too small or large */
289
509
  if (width < 8 || width >= 32768) {
290
510
  for (x=0; x < width; x++) {
291
- switch (comp) {
511
+ switch (ncomp) {
292
512
  case 4: /* fallthrough */
293
- case 3: linear[2] = scanline[x*comp + 2];
294
- linear[1] = scanline[x*comp + 1];
295
- linear[0] = scanline[x*comp + 0];
513
+ case 3: linear[2] = scanline[x*ncomp + 2];
514
+ linear[1] = scanline[x*ncomp + 1];
515
+ linear[0] = scanline[x*ncomp + 0];
296
516
  break;
297
- case 2: /* fallthrough */
298
- case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
517
+ default:
518
+ linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
299
519
  break;
300
520
  }
301
521
  stbiw__linear_to_rgbe(rgbe, linear);
302
- fwrite(rgbe, 4, 1, f);
522
+ s->func(s->context, rgbe, 4);
303
523
  }
304
524
  } else {
305
525
  int c,r;
306
526
  /* encode into scratch buffer */
307
527
  for (x=0; x < width; x++) {
308
- switch(comp) {
528
+ switch(ncomp) {
309
529
  case 4: /* fallthrough */
310
- case 3: linear[2] = scanline[x*comp + 2];
311
- linear[1] = scanline[x*comp + 1];
312
- linear[0] = scanline[x*comp + 0];
530
+ case 3: linear[2] = scanline[x*ncomp + 2];
531
+ linear[1] = scanline[x*ncomp + 1];
532
+ linear[0] = scanline[x*ncomp + 0];
313
533
  break;
314
- case 2: /* fallthrough */
315
- case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
534
+ default:
535
+ linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
316
536
  break;
317
537
  }
318
538
  stbiw__linear_to_rgbe(rgbe, linear);
@@ -322,7 +542,7 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra
322
542
  scratch[x + width*3] = rgbe[3];
323
543
  }
324
544
 
325
- fwrite(scanlineheader, 4, 1, f);
545
+ s->func(s->context, scanlineheader, 4);
326
546
 
327
547
  /* RLE each component separately */
328
548
  for (c=0; c < 4; c++) {
@@ -343,7 +563,7 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra
343
563
  while (x < r) {
344
564
  int len = r-x;
345
565
  if (len > 128) len = 128;
346
- stbiw__write_dump_data(f, len, &comp[x]);
566
+ stbiw__write_dump_data(s, len, &comp[x]);
347
567
  x += len;
348
568
  }
349
569
  // if there's a run, output it
@@ -355,7 +575,7 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra
355
575
  while (x < r) {
356
576
  int len = r-x;
357
577
  if (len > 127) len = 127;
358
- stbiw__write_run_data(f, len, comp[x]);
578
+ stbiw__write_run_data(s, len, comp[x]);
359
579
  x += len;
360
580
  }
361
581
  }
@@ -364,27 +584,52 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra
364
584
  }
365
585
  }
366
586
 
367
- int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
587
+ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
368
588
  {
369
- int i;
370
- FILE *f;
371
- if (y <= 0 || x <= 0 || data == NULL) return 0;
372
- f = fopen(filename, "wb");
373
- if (f) {
374
- /* Each component is stored separately. Allocate scratch space for full output scanline. */
589
+ if (y <= 0 || x <= 0 || data == NULL)
590
+ return 0;
591
+ else {
592
+ // Each component is stored separately. Allocate scratch space for full output scanline.
375
593
  unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
376
- fprintf(f, "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n" );
377
- fprintf(f, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n" , y, x);
594
+ int i, len;
595
+ char buffer[128];
596
+ char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
597
+ s->func(s->context, header, sizeof(header)-1);
598
+
599
+ len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
600
+ s->func(s->context, buffer, len);
601
+
378
602
  for(i=0; i < y; i++)
379
- stbiw__write_hdr_scanline(f, x, comp, scratch, data + comp*i*x);
603
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
380
604
  STBIW_FREE(scratch);
381
- fclose(f);
605
+ return 1;
382
606
  }
383
- return f != NULL;
384
607
  }
385
608
 
386
- /////////////////////////////////////////////////////////
387
- // PNG
609
+ int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
610
+ {
611
+ stbi__write_context s;
612
+ stbi__start_write_callbacks(&s, func, context);
613
+ return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
614
+ }
615
+
616
+ int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
617
+ {
618
+ stbi__write_context s;
619
+ if (stbi__start_write_file(&s,filename)) {
620
+ int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
621
+ stbi__end_write_file(&s);
622
+ return r;
623
+ } else
624
+ return 0;
625
+ }
626
+ #endif // STBI_WRITE_NO_STDIO
627
+
628
+
629
+ //////////////////////////////////////////////////////////////////////////////
630
+ //
631
+ // PNG writer
632
+ //
388
633
 
389
634
  // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
390
635
  #define stbiw__sbraw(a) ((int *) (a) - 2)
@@ -550,8 +795,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
550
795
 
551
796
  {
552
797
  // compute adler32 on input
553
- unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
554
- int j=0;
798
+ unsigned int k=0, s1=1, s2=0;
799
+ int blocklen = (int) (data_len % 5552);
800
+ j=0;
555
801
  while (j < data_len) {
556
802
  for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
557
803
  s1 %= 65521, s2 %= 65521;
@@ -693,12 +939,13 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
693
939
  return out;
694
940
  }
695
941
 
696
- int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
942
+ #ifndef STBI_WRITE_NO_STDIO
943
+ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
697
944
  {
698
945
  FILE *f;
699
946
  int len;
700
947
  unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
701
- if (!png) return 0;
948
+ if (png == NULL) return 0;
702
949
  f = fopen(filename, "wb");
703
950
  if (!f) { STBIW_FREE(png); return 0; }
704
951
  fwrite(png, 1, len, f);
@@ -706,9 +953,25 @@ int stbi_write_png(char const *filename, int x, int y, int comp, const void *dat
706
953
  STBIW_FREE(png);
707
954
  return 1;
708
955
  }
956
+ #endif
957
+
958
+ 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)
959
+ {
960
+ int len;
961
+ unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
962
+ if (png == NULL) return 0;
963
+ func(context, png, len);
964
+ STBIW_FREE(png);
965
+ return 1;
966
+ }
967
+
709
968
  #endif // STB_IMAGE_WRITE_IMPLEMENTATION
710
969
 
711
970
  /* Revision history
971
+ 1.00 (2015-09-14)
972
+ installable file IO function
973
+ 0.99 (2015-09-13)
974
+ warning fixes; TGA rle support
712
975
  0.98 (2015-04-08)
713
976
  added STBIW_MALLOC, STBIW_ASSERT etc
714
977
  0.97 (2015-01-18)