114 #ifndef INCLUDE_STB_IMAGE_WRITE_H 115 #define INCLUDE_STB_IMAGE_WRITE_H 121 #ifdef STB_IMAGE_WRITE_STATIC 122 #define STBIWDEF static 124 #define STBIWDEF extern 128 #ifndef STBI_WRITE_NO_STDIO 146 #endif//INCLUDE_STB_IMAGE_WRITE_H 148 #ifdef STB_IMAGE_WRITE_IMPLEMENTATION 151 #ifndef _CRT_SECURE_NO_WARNINGS 152 #define _CRT_SECURE_NO_WARNINGS 154 #ifndef _CRT_NONSTDC_NO_DEPRECATE 155 #define _CRT_NONSTDC_NO_DEPRECATE 159 #ifndef STBI_WRITE_NO_STDIO 161 #endif // STBI_WRITE_NO_STDIO 168 #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) 170 #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) 173 #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." 177 #define STBIW_MALLOC(sz) malloc(sz) 178 #define STBIW_REALLOC(p,newsz) realloc(p,newsz) 179 #define STBIW_FREE(p) free(p) 182 #ifndef STBIW_REALLOC_SIZED 183 #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) 187 #ifndef STBIW_MEMMOVE 188 #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) 194 #define STBIW_ASSERT(x) assert(x) 197 #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) 203 } stbi__write_context;
206 static void stbi__start_write_callbacks(stbi__write_context *
s,
stbi_write_func *
c,
void *context)
209 s->context = context;
212 #ifndef STBI_WRITE_NO_STDIO 214 static void stbi__stdio_write(
void *context,
void *
data,
int size)
216 fwrite(data,1,size,(FILE*) context);
219 static int stbi__start_write_file(stbi__write_context *
s,
const char *filename)
221 FILE *
f = fopen(filename,
"wb");
222 stbi__start_write_callbacks(s, stbi__stdio_write, (
void *) f);
226 static void stbi__end_write_file(stbi__write_context *s)
228 fclose((FILE *)s->context);
231 #endif // !STBI_WRITE_NO_STDIO 233 typedef unsigned int stbiw_uint32;
234 typedef int stb_image_write_test[
sizeof(stbiw_uint32)==4 ? 1 : -1];
236 #ifdef STB_IMAGE_WRITE_STATIC 239 int stbi_write_tga_with_rle = 1;
242 static void stbiw__writefv(stbi__write_context *s,
const char *fmt, va_list
v)
247 case '1': {
unsigned char x = STBIW_UCHAR(va_arg(v,
int));
248 s->func(s->context,&x,1);
250 case '2': {
int x = va_arg(v,
int);
252 b[0] = STBIW_UCHAR(x);
253 b[1] = STBIW_UCHAR(x>>8);
254 s->func(s->context,b,2);
256 case '4': { stbiw_uint32 x = va_arg(v,
int);
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);
271 static void stbiw__writef(stbi__write_context *s,
const char *fmt, ...)
275 stbiw__writefv(s, fmt, v);
279 static void stbiw__write3(stbi__write_context *s,
unsigned char a,
unsigned char b,
unsigned char c)
281 unsigned char arr[3];
282 arr[0] =
a, arr[1] =
b, arr[2] =
c;
283 s->func(s->context, arr, 3);
286 static void stbiw__write_pixel(stbi__write_context *s,
int rgb_dir,
int comp,
int write_alpha,
int expand_mono,
unsigned char *d)
288 unsigned char bg[3] = { 255, 0, 255}, px[3];
292 s->func(s->context, &d[comp - 1], 1);
296 s->func(s->context,d,1);
300 stbiw__write3(s, d[0], d[0], d[0]);
302 s->func(s->context, d, 1);
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]);
314 stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
318 s->func(s->context, &d[comp - 1], 1);
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)
323 stbiw_uint32 zero = 0;
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);
339 s->func(s->context, &zero, scanline_pad);
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, ...)
345 if (y < 0 || x < 0) {
350 stbiw__writefv(s, fmt, v);
352 stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
357 static int stbi_write_bmp_core(stbi__write_context *s,
int x,
int y,
int comp,
const void *data)
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,
363 40, x,y, 1,24, 0,0,0,0,0,0);
368 stbi__write_context
s;
369 stbi__start_write_callbacks(&s, func, context);
370 return stbi_write_bmp_core(&s, x, y, comp, data);
373 #ifndef STBI_WRITE_NO_STDIO 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);
386 static int stbi_write_tga_core(stbi__write_context *s,
int x,
int y,
int comp,
void *data)
388 int has_alpha = (comp == 2 || comp == 4);
389 int colorbytes = has_alpha ? comp-1 : comp;
390 int format = colorbytes < 2 ? 3 : 2;
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);
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);
403 for (j = y - 1; j >= 0; --j) {
404 unsigned char *
row = (
unsigned char *) data + j * x * comp;
407 for (i = 0; i <
x; i +=
len) {
408 unsigned char *begin = row + i * comp;
414 diff = memcmp(begin, row + (i + 1) * comp, comp);
416 const unsigned char *prev = begin;
417 for (k = i + 2; k < x && len < 128; ++k) {
418 if (memcmp(prev, row + k * comp, comp)) {
427 for (k = i + 2; k < x && len < 128; ++k) {
428 if (!memcmp(begin, row + k * comp, comp)) {
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);
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);
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);
461 #ifndef STBI_WRITE_NO_STDIO 462 int stbi_write_tga(
char const *filename,
int x,
int y,
int comp,
const void *data)
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);
477 #ifndef STBI_WRITE_NO_STDIO 479 #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) 481 void stbiw__linear_to_rgbe(
unsigned char *rgbe,
float *linear)
484 float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
486 if (maxcomp < 1
e-32f) {
487 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
489 float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
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);
498 void stbiw__write_run_data(stbi__write_context *s,
int length,
unsigned char databyte)
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);
506 void stbiw__write_dump_data(stbi__write_context *s,
int length,
unsigned char *data)
508 unsigned char lengthbyte = STBIW_UCHAR(length);
509 STBIW_ASSERT(length <= 128);
510 s->func(s->context, &lengthbyte, 1);
511 s->func(s->context, data, length);
514 void stbiw__write_hdr_scanline(stbi__write_context *s,
int width,
int ncomp,
unsigned char *scratch,
float *scanline)
516 unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
517 unsigned char rgbe[4];
521 scanlineheader[2] = (width&0xff00)>>8;
522 scanlineheader[3] = (width&0x00ff);
526 for (x=0; x <
width; x++) {
529 case 3: linear[2] = scanline[x*ncomp + 2];
530 linear[1] = scanline[x*ncomp + 1];
531 linear[0] = scanline[x*ncomp + 0];
534 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
537 stbiw__linear_to_rgbe(rgbe, linear);
538 s->func(s->context, rgbe, 4);
543 for (x=0; x <
width; x++) {
546 case 3: linear[2] = scanline[x*ncomp + 2];
547 linear[1] = scanline[x*ncomp + 1];
548 linear[0] = scanline[x*ncomp + 0];
551 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
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];
561 s->func(s->context, scanlineheader, 4);
564 for (c=0; c < 4; c++) {
565 unsigned char *comp = &scratch[width*
c];
571 while (r+2 < width) {
572 if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
581 if (len > 128) len = 128;
582 stbiw__write_dump_data(s, len, &comp[x]);
588 while (r < width && comp[r] == comp[x])
593 if (len > 127) len = 127;
594 stbiw__write_run_data(s, len, comp[x]);
603 static int stbi_write_hdr_core(stbi__write_context *s,
int x,
int y,
int comp,
float *data)
605 if (y <= 0 || x <= 0 || data == NULL)
609 unsigned char *scratch = (
unsigned char *) STBIW_MALLOC(x*4);
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);
615 len = sprintf(buffer,
"EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
616 s->func(s->context, buffer, len);
619 stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
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);
632 int stbi_write_hdr(
char const *filename,
int x,
int y,
int comp,
const float *data)
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);
642 #endif // STBI_WRITE_NO_STDIO 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] 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))) 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) 663 static void *stbiw__sbgrowf(
void **arr,
int increment,
int itemsize)
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);
669 if (!*arr) ((
int *) p)[1] = 0;
670 *arr = (
void *) ((
int *) p + 2);
671 stbiw__sbm(*arr) =
m;
676 static unsigned char *stbiw__zlib_flushf(
unsigned char *data,
unsigned int *bitbuffer,
int *bitcount)
678 while (*bitcount >= 8) {
679 stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
686 static int stbiw__zlib_bitrev(
int code,
int codebits)
690 res = (res << 1) | (code & 1);
696 static unsigned int stbiw__zlib_countm(
unsigned char *a,
unsigned char *b,
int limit)
699 for (i=0; i < limit && i < 258; ++i)
700 if (a[i] != b[i])
break;
704 static unsigned int stbiw__zhash(
unsigned char *data)
706 stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
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) 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)) 728 #define stbiw__ZHASH 16384 730 unsigned char * stbi_zlib_compress(
unsigned char *data,
int data_len,
int *out_len,
int quality)
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;
738 unsigned char *out = NULL;
739 unsigned char **hash_table[stbiw__ZHASH];
740 if (quality < 5) quality = 5;
742 stbiw__sbpush(out, 0x78);
743 stbiw__sbpush(out, 0x5e);
744 stbiw__zlib_add(1,1);
745 stbiw__zlib_add(1,2);
747 for (i=0; i < stbiw__ZHASH; ++i)
748 hash_table[i] = NULL;
751 while (i < data_len-3) {
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) {
759 int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
760 if (d >= best) best=d,bestloc=hlist[j];
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;
768 stbiw__sbpush(hash_table[h],data+i);
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);
787 int d = (
int) (data+i - bestloc);
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]);
797 stbiw__zlib_huffb(data[i]);
802 for (;i < data_len; ++i)
803 stbiw__zlib_huffb(data[i]);
804 stbiw__zlib_huff(256);
807 stbiw__zlib_add(0,1);
809 for (i=0; i < stbiw__ZHASH; ++i)
810 (
void) stbiw__sbfree(hash_table[i]);
814 unsigned int s1=1, s2=0;
815 int blocklen = (
int) (data_len % 5552);
817 while (j < data_len) {
818 for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
819 s1 %= 65521, s2 %= 65521;
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));
828 *out_len = stbiw__sbn(out);
830 STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
831 return (
unsigned char *) stbiw__sbraw(out);
834 static unsigned int stbiw__crc32(
unsigned char *buffer,
int len)
836 static unsigned int crc_table[256] =
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
872 unsigned int crc = ~0u;
874 for (i=0; i <
len; ++i)
875 crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
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]) 883 static void stbiw__wpcrc(
unsigned char **data,
int len)
885 unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
886 stbiw__wp32(*data, crc);
889 static unsigned char stbiw__paeth(
int a,
int b,
int c)
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);
897 unsigned char *stbi_write_png_to_mem(
unsigned char *
pixels,
int stride_bytes,
int x,
int y,
int n,
int *out_len)
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;
905 if (stride_bytes == 0)
906 stride_bytes = x *
n;
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)
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;
929 for (i=n; i < x*
n; ++i) {
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;
941 for (i=0; i < x*
n; ++i)
942 est += abs((
signed char) line_buffer[i]);
943 if (est < bestval) { bestval = est; best = k; }
947 filt[j*(x*n+1)] = (
unsigned char) best;
948 STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
950 STBIW_FREE(line_buffer);
951 zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8);
956 out = (
unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
958 *out_len = 8 + 12+13 + 12+zlen + 12;
961 STBIW_MEMMOVE(o,sig,8); o+= 8;
963 stbiw__wptag(o,
"IHDR");
967 *o++ = STBIW_UCHAR(ctype[n]);
973 stbiw__wp32(o, zlen);
974 stbiw__wptag(o,
"IDAT");
975 STBIW_MEMMOVE(o, zlib, zlen);
978 stbiw__wpcrc(&o, zlen);
981 stbiw__wptag(o,
"IEND");
984 STBIW_ASSERT(o == out + *out_len);
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)
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);
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);
1015 #endif // STB_IMAGE_WRITE_IMPLEMENTATION GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const void * pixels
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)
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data)
GLint GLint GLint GLint GLint GLint y
STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data)
STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data)
GLfloat GLfloat GLfloat GLfloat h
GLfloat GLfloat GLfloat alpha
GLenum GLenum GLsizei void * row
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
GLenum GLenum GLenum GLenum mapping
GLboolean GLboolean GLboolean GLboolean a
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data)
GLboolean GLboolean GLboolean b
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
GLint GLint GLsizei width
GLuint GLsizei GLsizei * length
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
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 GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLdouble GLdouble GLdouble r
GLint GLint GLint GLint GLint x
GLubyte GLubyte GLubyte GLubyte w
int stbi_write_tga_with_rle
GLuint GLuint GLsizei GLenum type