54#ifndef INCLUDE_STB_IMAGE_WRITE_H
55#define INCLUDE_STB_IMAGE_WRITE_H
61extern int stbi_write_png(
char const *filename,
int w,
int h,
int comp,
const void *data,
int stride_in_bytes);
62extern int stbi_write_bmp(
char const *filename,
int w,
int h,
int comp,
const void *data);
63extern int stbi_write_tga(
char const *filename,
int w,
int h,
int comp,
const void *data);
71#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
79typedef unsigned int stbiw_uint32;
80typedef int stb_image_write_test[
sizeof(stbiw_uint32)==4 ? 1 : -1];
82static void writefv(FILE *f,
const char *fmt, va_list v)
87 case '1': {
unsigned char x = (
unsigned char) va_arg(v,
int); fputc(x,f);
break; }
88 case '2': {
int x = va_arg(v,
int);
unsigned char b[2];
89 b[0] = (
unsigned char) x;
b[1] = (
unsigned char) (x>>8);
90 fwrite(b,2,1,f);
break; }
91 case '4': { stbiw_uint32
x = va_arg(v,
int);
unsigned char b[4];
92 b[0]=(
unsigned char)x;
b[1]=(
unsigned char)(x>>8);
93 b[2]=(
unsigned char)(x>>16);
b[3]=(
unsigned char)(x>>24);
94 fwrite(b,4,1,f);
break; }
102static void write3(FILE *f,
unsigned char a,
unsigned char b,
unsigned char c)
104 unsigned char arr[3];
105 arr[0] =
a, arr[1] =
b, arr[2] =
c;
106 fwrite(arr, 3, 1, f);
109static void write_pixels(FILE *f,
int rgb_dir,
int vdir,
int x,
int y,
int comp,
void *data,
int write_alpha,
int scanline_pad)
111 unsigned char bg[3] = { 255, 0, 255}, px[3];
112 stbiw_uint32 zero = 0;
123 for (;
j != j_end;
j += vdir) {
124 for (
i=0;
i <
x; ++
i) {
125 unsigned char *
d = (
unsigned char *) data + (
j*x+
i)*comp;
127 fwrite(&d[comp-1], 1, 1, f);
130 case 2: write3(f, d[0],d[0],d[0]);
135 for (
k=0;
k < 3; ++
k)
136 px[
k] = bg[
k] + ((d[
k] - bg[
k]) * d[3])/255;
137 write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
142 write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
146 fwrite(&d[comp-1], 1, 1, f);
148 fwrite(&zero,scanline_pad,1,f);
152static 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 if (y < 0 || x < 0)
return 0;
156 f = fopen(filename,
"wb");
162 write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
168int stbi_write_bmp(
char const *filename,
int x,
int y,
int comp,
const void *data)
170 int pad = (-
x*3) & 3;
171 return outfile(filename,-1,-1,x,y,comp,(
void *) data,0,pad,
172 "11 4 22 4" "4 44 22 444444",
173 'B',
'M', 14+40+(x*3+pad)*y, 0,0, 14+40,
174 40, x,y, 1,24, 0,0,0,0,0,0);
177int stbi_write_tga(
char const *filename,
int x,
int y,
int comp,
const void *data)
179 int has_alpha = !(comp & 1);
180 return outfile(filename, -1,-1, x, y, comp, (
void *) data, has_alpha, 0,
181 "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
185#define stbi__sbraw(a) ((int *) (a) - 2)
186#define stbi__sbm(a) stbi__sbraw(a)[0]
187#define stbi__sbn(a) stbi__sbraw(a)[1]
189#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
190#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
191#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
193#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
194#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0)
195#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0)
197static void *stbi__sbgrowf(
void **arr,
int increment,
int itemsize)
200 void *
p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m +
sizeof(
int)*2);
203 if (!*arr) ((
int *) p)[1] = 0;
204 *arr = (
void *) ((
int *) p + 2);
210static unsigned char *stbi__zlib_flushf(
unsigned char *data,
unsigned int *bitbuffer,
int *bitcount)
212 while (*bitcount >= 8) {
213 stbi__sbpush(data, (
unsigned char) *bitbuffer);
220static int stbi__zlib_bitrev(
int code,
int codebits)
224 res = (
res << 1) | (code & 1);
230static unsigned int stbi__zlib_countm(
unsigned char *a,
unsigned char *b,
int limit)
233 for (
i=0;
i < limit &&
i < 258; ++
i)
234 if (a[
i] != b[
i])
break;
238static unsigned int stbi__zhash(
unsigned char *data)
240 stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
250#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
251#define stbi__zlib_add(code,codebits) \
252 (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
253#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
255#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8)
256#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9)
257#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7)
258#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8)
259#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
260#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
262#define stbi__ZHASH 16384
264unsigned char * stbi_zlib_compress(
unsigned char *data,
int data_len,
int *out_len,
int quality)
266 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 };
267 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 };
268 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 };
269 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 };
270 unsigned int bitbuf=0;
272 unsigned char *out = NULL;
273 unsigned char **hash_table[stbi__ZHASH];
276 stbi__sbpush(out, 0x78);
277 stbi__sbpush(out, 0x5e);
281 for (
i=0;
i < stbi__ZHASH; ++
i)
282 hash_table[
i] = NULL;
285 while (
i < data_len-3) {
287 int h = stbi__zhash(data+
i)&(stbi__ZHASH-1), best=3;
288 unsigned char *bestloc = 0;
289 unsigned char **hlist = hash_table[h];
290 int n = stbi__sbcount(hlist);
291 for (
j=0;
j <
n; ++
j) {
292 if (hlist[
j]-data >
i-32768) {
293 int d = stbi__zlib_countm(hlist[
j], data+
i, data_len-
i);
294 if (d >= best) best=
d,bestloc=hlist[
j];
298 if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
299 memcpy(hash_table[h], hash_table[h]+quality,
sizeof(hash_table[h][0])*quality);
300 stbi__sbn(hash_table[h]) =
quality;
302 stbi__sbpush(hash_table[h],data+
i);
306 h = stbi__zhash(data+
i+1)&(stbi__ZHASH-1);
307 hlist = hash_table[h];
308 n = stbi__sbcount(hlist);
309 for (
j=0;
j <
n; ++
j) {
310 if (hlist[
j]-data >
i-32767) {
311 int e = stbi__zlib_countm(hlist[
j], data+
i+1, data_len-
i-1);
321 int d = data+
i - bestloc;
322 assert(d <= 32767 && best <= 258);
323 for (
j=0; best > lengthc[
j+1]-1; ++
j);
324 stbi__zlib_huff(
j+257);
325 if (lengtheb[
j]) stbi__zlib_add(best - lengthc[
j], lengtheb[
j]);
326 for (
j=0;
d > distc[
j+1]-1; ++
j);
327 stbi__zlib_add(stbi__zlib_bitrev(
j,5),5);
328 if (disteb[
j]) stbi__zlib_add(d - distc[
j], disteb[
j]);
331 stbi__zlib_huffb(data[
i]);
336 for (;
i < data_len; ++
i)
337 stbi__zlib_huffb(data[
i]);
338 stbi__zlib_huff(256);
343 for (
i=0;
i < stbi__ZHASH; ++
i)
344 (
void) stbi__sbfree(hash_table[
i]);
348 unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
350 while (
j < data_len) {
351 for (
i=0;
i < blocklen; ++
i) s1 += data[
j+
i], s2 += s1;
352 s1 %= 65521, s2 %= 65521;
356 stbi__sbpush(out, (
unsigned char) (s2 >> 8));
357 stbi__sbpush(out, (
unsigned char) s2);
358 stbi__sbpush(out, (
unsigned char) (s1 >> 8));
359 stbi__sbpush(out, (
unsigned char) s1);
361 *out_len = stbi__sbn(out);
363 memmove(stbi__sbraw(out), out, *out_len);
364 return (
unsigned char *) stbi__sbraw(out);
367unsigned int stbi__crc32(
unsigned char *buffer,
int len)
369 static unsigned int crc_table[256];
370 unsigned int crc = ~0u;
372 if (crc_table[1] == 0)
373 for(
i=0;
i < 256;
i++)
374 for (crc_table[
i]=
i,
j=0;
j < 8; ++
j)
375 crc_table[
i] = (crc_table[
i] >> 1) ^ (crc_table[
i] & 1 ? 0xedb88320 : 0);
376 for (
i=0;
i < len; ++
i)
377 crc = (crc >> 8) ^ crc_table[buffer[
i] ^ (crc & 0xff)];
381#define stbi__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)
382#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
383#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
385static void stbi__wpcrc(
unsigned char **data,
int len)
387 unsigned int crc = stbi__crc32(*data - len - 4, len+4);
388 stbi__wp32(*data, crc);
391static unsigned char stbi__paeth(
int a,
int b,
int c)
394 if (pa <= pb && pa <=
pc)
return (
unsigned char)
a;
395 if (pb <=
pc)
return (
unsigned char)
b;
396 return (
unsigned char)
c;
399unsigned char *stbi_write_png_to_mem(
unsigned char *pixels,
int stride_bytes,
int x,
int y,
int n,
int *out_len)
401 int ctype[5] = { -1, 0, 4, 2, 6 };
402 unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
403 unsigned char *out,*o, *filt, *zlib;
404 signed char *line_buffer;
407 if (stride_bytes == 0)
408 stride_bytes =
x *
n;
410 filt = (
unsigned char *) malloc((x*n+1) * y);
if (!filt)
return 0;
411 line_buffer = (
signed char *) malloc(x * n);
if (!line_buffer) { free(filt);
return 0; }
412 for (
j=0;
j < y; ++
j) {
413 static int mapping[] = { 0,1,2,3,4 };
414 static int firstmap[] = { 0,1,0,5,6 };
415 int *mymap =
j ?
mapping : firstmap;
416 int best = 0, bestval = 0x7fffffff;
417 for (p=0;
p < 2; ++
p) {
418 for (
k= p?best:0;
k < 5; ++
k) {
419 int type = mymap[
k],est=0;
420 unsigned char *
z = pixels + stride_bytes*
j;
421 for (
i=0;
i <
n; ++
i)
423 case 0: line_buffer[
i] =
z[
i];
break;
424 case 1: line_buffer[
i] =
z[
i];
break;
425 case 2: line_buffer[
i] =
z[
i] -
z[
i-stride_bytes];
break;
426 case 3: line_buffer[
i] =
z[
i] - (
z[
i-stride_bytes]>>1);
break;
427 case 4: line_buffer[
i] = (
signed char) (z[
i] - stbi__paeth(0,z[
i-stride_bytes],0));
break;
428 case 5: line_buffer[
i] =
z[
i];
break;
429 case 6: line_buffer[
i] =
z[
i];
break;
431 for (
i=n;
i <
x*
n; ++
i) {
433 case 0: line_buffer[
i] =
z[
i];
break;
434 case 1: line_buffer[
i] =
z[
i] -
z[
i-
n];
break;
435 case 2: line_buffer[
i] =
z[
i] -
z[
i-stride_bytes];
break;
436 case 3: line_buffer[
i] =
z[
i] - ((
z[
i-
n] +
z[
i-stride_bytes])>>1);
break;
437 case 4: line_buffer[
i] =
z[
i] - stbi__paeth(z[
i-n], z[
i-stride_bytes], z[
i-stride_bytes-n]);
break;
438 case 5: line_buffer[
i] =
z[
i] - (
z[
i-
n]>>1);
break;
439 case 6: line_buffer[
i] =
z[
i] - stbi__paeth(z[
i-n], 0,0);
break;
443 for (
i=0;
i <
x*
n; ++
i)
444 est +=
abs((
signed char) line_buffer[
i]);
445 if (est < bestval) { bestval = est; best =
k; }
449 filt[
j*(
x*
n+1)] = (
unsigned char) best;
450 memcpy(filt+
j*(x*n+1)+1, line_buffer, x*n);
453 zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8);
458 out = (
unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
460 *out_len = 8 + 12+13 + 12+zlen + 12;
463 memcpy(o,sig,8); o+= 8;
465 stbi__wptag(o,
"IHDR");
469 *o++ = (
unsigned char) ctype[n];
476 stbi__wptag(o,
"IDAT");
477 memcpy(o, zlib, zlen); o += zlen; free(zlib);
478 stbi__wpcrc(&o, zlen);
481 stbi__wptag(o,
"IEND");
484 assert(o == out + *out_len);
489int stbi_write_png(
char const *filename,
int x,
int y,
int comp,
const void *data,
int stride_bytes)
493 unsigned char *png = stbi_write_png_to_mem((
unsigned char *) data, stride_bytes, x, y, comp, &len);
495 f = fopen(filename,
"wb");
496 if (!f) { free(png);
return 0; }
497 fwrite(png, 1, len, f);
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)
static ARCH_HOSTDEV VecSimple< T > abs(const VecSimple< T > &l)