56 #ifndef INCLUDE_STB_IMAGE_WRITE_H
57 #define INCLUDE_STB_IMAGE_WRITE_H
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);
71 #endif//INCLUDE_STB_IMAGE_WRITE_H
73 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
82 #define STBI_ASSERT(x) assert(x)
85 typedef unsigned int stbiw_uint32;
86 typedef int stb_image_write_test[
sizeof(stbiw_uint32)==4 ? 1 : -1];
88 static void writefv(FILE *f,
const char *fmt, va_list v)
93 case '1': {
unsigned char x = (
unsigned char) va_arg(v,
int); fputc(x,f);
break; }
94 case '2': {
int x = va_arg(v,
int);
unsigned char b[2];
95 b[0] = (
unsigned char) x; b[1] = (
unsigned char) (x>>8);
96 fwrite(b,2,1,f);
break; }
97 case '4': { stbiw_uint32 x = va_arg(v,
int);
unsigned char b[4];
98 b[0]=(
unsigned char)x; b[1]=(
unsigned char)(x>>8);
99 b[2]=(
unsigned char)(x>>16); b[3]=(
unsigned char)(x>>24);
100 fwrite(b,4,1,f);
break; }
108 static void write3(FILE *f,
unsigned char a,
unsigned char b,
unsigned char c)
110 unsigned char arr[3];
111 arr[0] = a, arr[1] = b, arr[2] = c;
112 fwrite(arr, 3, 1, f);
115 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)
117 unsigned char bg[3] = { 255, 0, 255}, px[3];
118 stbiw_uint32 zero = 0;
129 for (; j != j_end; j += vdir) {
130 for (i=0; i < x; ++i) {
131 unsigned char *d = (
unsigned char *) data + (j*x+i)*comp;
133 fwrite(&d[comp-1], 1, 1, f);
136 case 2: fwrite(d, 1, 1, f);
141 for (k=0; k < 3; ++k)
142 px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
143 write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
148 write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
152 fwrite(&d[comp-1], 1, 1, f);
154 fwrite(&zero,scanline_pad,1,f);
158 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, ...)
161 if (y < 0 || x < 0)
return 0;
162 f = fopen(filename,
"wb");
168 write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
174 int stbi_write_bmp(
char const *filename,
int x,
int y,
int comp,
const void *data)
176 int pad = (-x*3) & 3;
177 return outfile(filename,-1,-1,x,y,comp,(
void *) data,0,pad,
178 "11 4 22 4" "4 44 22 444444",
179 'B',
'M', 14+40+(x*3+pad)*y, 0,0, 14+40,
180 40, x,y, 1,24, 0,0,0,0,0,0);
183 int stbi_write_tga(
char const *filename,
int x,
int y,
int comp,
const void *data)
185 int has_alpha = (comp == 2 || comp == 4);
186 int colorbytes = has_alpha ? comp-1 : comp;
187 int format = colorbytes < 2 ? 3 : 2;
188 return outfile(filename, -1,-1, x, y, comp, (
void *) data, has_alpha, 0,
189 "111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8);
193 #define stbiw__sbraw(a) ((int *) (a) - 2)
194 #define stbiw__sbm(a) stbiw__sbraw(a)[0]
195 #define stbiw__sbn(a) stbiw__sbraw(a)[1]
197 #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
198 #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
199 #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
201 #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
202 #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
203 #define stbiw__sbfree(a) ((a) ? free(stbiw__sbraw(a)),0 : 0)
205 static void *stbiw__sbgrowf(
void **arr,
int increment,
int itemsize)
207 int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
208 void *p = realloc(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m +
sizeof(
int)*2);
211 if (!*arr) ((
int *) p)[1] = 0;
212 *arr = (
void *) ((
int *) p + 2);
213 stbiw__sbm(*arr) = m;
218 static unsigned char *stbiw__zlib_flushf(
unsigned char *data,
unsigned int *bitbuffer,
int *bitcount)
220 while (*bitcount >= 8) {
221 stbiw__sbpush(data, (
unsigned char) *bitbuffer);
228 static int stbiw__zlib_bitrev(
int code,
int codebits)
232 res = (res << 1) | (code & 1);
238 static unsigned int stbiw__zlib_countm(
unsigned char *a,
unsigned char *b,
int limit)
241 for (i=0; i < limit && i < 258; ++i)
242 if (a[i] != b[i])
break;
246 static unsigned int stbiw__zhash(
unsigned char *data)
248 stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
258 #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
259 #define stbiw__zlib_add(code,codebits) \
260 (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
261 #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
263 #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
264 #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
265 #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
266 #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
267 #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))
268 #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
270 #define stbiw__ZHASH 16384
272 unsigned char * stbi_zlib_compress(
unsigned char *data,
int data_len,
int *out_len,
int quality)
274 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 };
275 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 };
276 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 };
277 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 };
278 unsigned int bitbuf=0;
280 unsigned char *out = NULL;
281 unsigned char **hash_table[stbiw__ZHASH];
282 if (quality < 5) quality = 5;
284 stbiw__sbpush(out, 0x78);
285 stbiw__sbpush(out, 0x5e);
286 stbiw__zlib_add(1,1);
287 stbiw__zlib_add(1,2);
289 for (i=0; i < stbiw__ZHASH; ++i)
290 hash_table[i] = NULL;
293 while (i < data_len-3) {
295 int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
296 unsigned char *bestloc = 0;
297 unsigned char **hlist = hash_table[h];
298 int n = stbiw__sbcount(hlist);
299 for (j=0; j < n; ++j) {
300 if (hlist[j]-data > i-32768) {
301 int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
302 if (d >= best) best=d,bestloc=hlist[j];
306 if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
307 memcpy(hash_table[h], hash_table[h]+quality,
sizeof(hash_table[h][0])*quality);
308 stbiw__sbn(hash_table[h]) = quality;
310 stbiw__sbpush(hash_table[h],data+i);
314 h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
315 hlist = hash_table[h];
316 n = stbiw__sbcount(hlist);
317 for (j=0; j < n; ++j) {
318 if (hlist[j]-data > i-32767) {
319 int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
329 int d = (int) (data+i - bestloc);
331 for (j=0; best > lengthc[j+1]-1; ++j);
332 stbiw__zlib_huff(j+257);
333 if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
334 for (j=0; d > distc[j+1]-1; ++j);
335 stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
336 if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
339 stbiw__zlib_huffb(data[i]);
344 for (;i < data_len; ++i)
345 stbiw__zlib_huffb(data[i]);
346 stbiw__zlib_huff(256);
349 stbiw__zlib_add(0,1);
351 for (i=0; i < stbiw__ZHASH; ++i)
352 (
void) stbiw__sbfree(hash_table[i]);
356 unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
358 while (j < data_len) {
359 for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
360 s1 %= 65521, s2 %= 65521;
364 stbiw__sbpush(out, (
unsigned char) (s2 >> 8));
365 stbiw__sbpush(out, (
unsigned char) s2);
366 stbiw__sbpush(out, (
unsigned char) (s1 >> 8));
367 stbiw__sbpush(out, (
unsigned char) s1);
369 *out_len = stbiw__sbn(out);
371 memmove(stbiw__sbraw(out), out, *out_len);
372 return (
unsigned char *) stbiw__sbraw(out);
375 unsigned int stbiw__crc32(
unsigned char *buffer,
int len)
377 static unsigned int crc_table[256];
378 unsigned int crc = ~0u;
380 if (crc_table[1] == 0)
381 for(i=0; i < 256; i++)
382 for (crc_table[i]=i, j=0; j < 8; ++j)
383 crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
384 for (i=0; i < len; ++i)
385 crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
389 #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)
390 #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
391 #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
393 static void stbiw__wpcrc(
unsigned char **data,
int len)
395 unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
396 stbiw__wp32(*data, crc);
399 static unsigned char stbiw__paeth(
int a,
int b,
int c)
401 int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
402 if (pa <= pb && pa <= pc)
return (
unsigned char) a;
403 if (pb <= pc)
return (
unsigned char) b;
404 return (
unsigned char) c;
407 unsigned char *stbi_write_png_to_mem(
unsigned char *pixels,
int stride_bytes,
int x,
int y,
int n,
int *out_len)
409 int ctype[5] = { -1, 0, 4, 2, 6 };
410 unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
411 unsigned char *out,*o, *filt, *zlib;
412 signed char *line_buffer;
415 if (stride_bytes == 0)
416 stride_bytes = x * n;
418 filt = (
unsigned char *) malloc((x*n+1) * y);
if (!filt)
return 0;
419 line_buffer = (
signed char *) malloc(x * n);
if (!line_buffer) { free(filt);
return 0; }
420 for (j=0; j < y; ++j) {
421 static int mapping[] = { 0,1,2,3,4 };
422 static int firstmap[] = { 0,1,0,5,6 };
423 int *mymap = j ? mapping : firstmap;
424 int best = 0, bestval = 0x7fffffff;
425 for (p=0; p < 2; ++p) {
426 for (k= p?best:0; k < 5; ++k) {
427 int type = mymap[k],est=0;
428 unsigned char *z = pixels + stride_bytes*j;
429 for (i=0; i < n; ++i)
431 case 0: line_buffer[i] = z[i];
break;
432 case 1: line_buffer[i] = z[i];
break;
433 case 2: line_buffer[i] = z[i] - z[i-stride_bytes];
break;
434 case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1);
break;
435 case 4: line_buffer[i] = (
signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0));
break;
436 case 5: line_buffer[i] = z[i];
break;
437 case 6: line_buffer[i] = z[i];
break;
439 for (i=n; i < x*n; ++i) {
441 case 0: line_buffer[i] = z[i];
break;
442 case 1: line_buffer[i] = z[i] - z[i-n];
break;
443 case 2: line_buffer[i] = z[i] - z[i-stride_bytes];
break;
444 case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1);
break;
445 case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]);
break;
446 case 5: line_buffer[i] = z[i] - (z[i-n]>>1);
break;
447 case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0);
break;
451 for (i=0; i < x*n; ++i)
452 est += abs((
signed char) line_buffer[i]);
453 if (est < bestval) { bestval = est; best = k; }
457 filt[j*(x*n+1)] = (
unsigned char) best;
458 memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
461 zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8);
466 out = (
unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
468 *out_len = 8 + 12+13 + 12+zlen + 12;
471 memcpy(o,sig,8); o+= 8;
473 stbiw__wptag(o,
"IHDR");
477 *o++ = (
unsigned char) ctype[n];
483 stbiw__wp32(o, zlen);
484 stbiw__wptag(o,
"IDAT");
485 memcpy(o, zlib, zlen); o += zlen; free(zlib);
486 stbiw__wpcrc(&o, zlen);
489 stbiw__wptag(o,
"IEND");
497 int stbi_write_png(
char const *filename,
int x,
int y,
int comp,
const void *data,
int stride_bytes)
501 unsigned char *png = stbi_write_png_to_mem((
unsigned char *) data, stride_bytes, x, y, comp, &len);
503 f = fopen(filename,
"wb");
504 if (!f) { free(png);
return 0; }
505 fwrite(png, 1, len, f);
510 #endif // STB_IMAGE_WRITE_IMPLEMENTATION
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data)
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data)