150#ifndef INCLUDE_STB_IMAGE_WRITE_H
151#define INCLUDE_STB_IMAGE_WRITE_H
157#ifdef STB_IMAGE_WRITE_STATIC
158#define STBIWDEF static
161#define STBIWDEF extern "C"
163#define STBIWDEF extern
168#ifndef STB_IMAGE_WRITE_STATIC
174#ifndef STBI_WRITE_NO_STDIO
175STBIWDEF
int stbi_write_png(
char const *filename,
int w,
int h,
int comp,
const void *data,
int stride_in_bytes);
176STBIWDEF
int stbi_write_bmp(
char const *filename,
int w,
int h,
int comp,
const void *data);
177STBIWDEF
int stbi_write_tga(
char const *filename,
int w,
int h,
int comp,
const void *data);
178STBIWDEF
int stbi_write_hdr(
char const *filename,
int w,
int h,
int comp,
const float *data);
179STBIWDEF
int stbi_write_jpg(
char const *filename,
int x,
int y,
int comp,
const void *data,
int quality);
181#ifdef STBI_WINDOWS_UTF8
198#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
201 #ifndef _CRT_SECURE_NO_WARNINGS
202 #define _CRT_SECURE_NO_WARNINGS
204 #ifndef _CRT_NONSTDC_NO_DEPRECATE
205 #define _CRT_NONSTDC_NO_DEPRECATE
209#ifndef STBI_WRITE_NO_STDIO
218#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
220#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
223#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
227#define STBIW_MALLOC(sz) malloc(sz)
228#define STBIW_REALLOC(p,newsz) realloc(p,newsz)
229#define STBIW_FREE(p) free(p)
232#ifndef STBIW_REALLOC_SIZED
233#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
238#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
244#define STBIW_ASSERT(x) assert(x)
247#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
249#ifdef STB_IMAGE_WRITE_STATIC
250static int stbi__flip_vertically_on_write=0;
256int stbi__flip_vertically_on_write=0;
263 stbi__flip_vertically_on_write = flag;
279#ifndef STBI_WRITE_NO_STDIO
281static void stbi__stdio_write(
void *context,
void *data,
int size)
283 fwrite(data,1,size,(FILE*) context);
286#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
288#define STBIW_EXTERN extern "C"
290#define STBIW_EXTERN extern
297 return WideCharToMultiByte(65001 , 0, input, -1, buffer, (
int) bufferlen, NULL, NULL);
301static FILE *stbiw__fopen(
char const *filename,
char const *mode)
304#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
306 wchar_t wFilename[1024];
307 if (0 == MultiByteToWideChar(65001 , 0, filename, -1, wFilename,
sizeof(wFilename)))
310 if (0 == MultiByteToWideChar(65001 , 0, mode, -1, wMode,
sizeof(wMode)))
314 if (0 != _wfopen_s(&f, wFilename, wMode))
317 f = _wfopen(wFilename, wMode);
320#elif defined(_MSC_VER) && _MSC_VER >= 1400
321 if (0 != fopen_s(&f, filename, mode))
324 f = fopen(filename, mode);
331 FILE *f = stbiw__fopen(filename,
"wb");
332 stbi__start_write_callbacks(s, stbi__stdio_write, (
void *) f);
351 case '1': {
unsigned char x = STBIW_UCHAR(va_arg(v,
int));
354 case '2': {
int x = va_arg(v,
int);
356 b[0] = STBIW_UCHAR(x);
357 b[1] = STBIW_UCHAR(x>>8);
363 b[1]=STBIW_UCHAR(x>>8);
364 b[2]=STBIW_UCHAR(x>>16);
365 b[3]=STBIW_UCHAR(x>>24);
379 stbiw__writefv(s, fmt, v);
388static void stbiw__write3(
stbi__write_context *s,
unsigned char a,
unsigned char b,
unsigned char c)
390 unsigned char arr[3];
391 arr[0] = a; arr[1] = b; arr[2] = c;
395static void stbiw__write_pixel(
stbi__write_context *s,
int rgb_dir,
int comp,
int write_alpha,
int expand_mono,
unsigned char *d)
397 unsigned char bg[3] = { 255, 0, 255}, px[3];
407 stbiw__write3(s, d[0], d[0], d[0]);
414 for (k = 0; k < 3; ++k)
415 px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
416 stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
421 stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
428static 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)
436 if (stbi__flip_vertically_on_write)
445 for (; j != j_end; j += vdir) {
446 for (i=0; i < x; ++i) {
447 unsigned char *d = (
unsigned char *) data + (j*x+i)*comp;
448 stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
454static 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, ...)
456 if (y < 0 || x < 0) {
461 stbiw__writefv(s, fmt, v);
463 stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
468static int stbi_write_bmp_core(
stbi__write_context *s,
int x,
int y,
int comp,
const void *data)
470 int pad = (-x*3) & 3;
471 return stbiw__outfile(s,-1,-1,x,y,comp,1,(
void *) data,0,pad,
472 "11 4 22 4" "4 44 22 444444",
473 'B',
'M', 14+40+(x*3+pad)*y, 0,0, 14+40,
474 40, x,y, 1,24, 0,0,0,0,0,0);
480 stbi__start_write_callbacks(&s, func, context);
481 return stbi_write_bmp_core(&s, x, y, comp, data);
484#ifndef STBI_WRITE_NO_STDIO
485STBIWDEF
int stbi_write_bmp(
char const *filename,
int x,
int y,
int comp,
const void *data)
488 if (stbi__start_write_file(&s,filename)) {
489 int r = stbi_write_bmp_core(&s, x, y, comp, data);
490 stbi__end_write_file(&s);
499 int has_alpha = (comp == 2 || comp == 4);
500 int colorbytes = has_alpha ? comp-1 : comp;
501 int format = colorbytes < 2 ? 3 : 2;
507 return stbiw__outfile(s, -1, -1, x, y, comp, 0, (
void *) data, has_alpha, 0,
508 "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
513 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);
515 if (stbi__flip_vertically_on_write) {
524 for (; j != jend; j += jdir) {
525 unsigned char *row = (
unsigned char *) data + j * x * comp;
528 for (i = 0; i < x; i += len) {
529 unsigned char *begin = row + i * comp;
535 diff = memcmp(begin, row + (i + 1) * comp, comp);
537 const unsigned char *prev = begin;
538 for (k = i + 2; k < x && len < 128; ++k) {
539 if (memcmp(prev, row + k * comp, comp)) {
548 for (k = i + 2; k < x && len < 128; ++k) {
549 if (!memcmp(begin, row + k * comp, comp)) {
559 unsigned char header = STBIW_UCHAR(len - 1);
561 for (k = 0; k < len; ++k) {
562 stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
565 unsigned char header = STBIW_UCHAR(len - 129);
567 stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
578 stbi__start_write_callbacks(&s, func, context);
579 return stbi_write_tga_core(&s, x, y, comp, (
void *) data);
582#ifndef STBI_WRITE_NO_STDIO
583STBIWDEF
int stbi_write_tga(
char const *filename,
int x,
int y,
int comp,
const void *data)
586 if (stbi__start_write_file(&s,filename)) {
587 int r = stbi_write_tga_core(&s, x, y, comp, (
void *) data);
588 stbi__end_write_file(&s);
599#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
601static void stbiw__linear_to_rgbe(
unsigned char *rgbe,
float *linear)
604 float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
606 if (maxcomp < 1e-32f) {
607 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
609 float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
611 rgbe[0] = (
unsigned char)(linear[0] * normalize);
612 rgbe[1] = (
unsigned char)(linear[1] * normalize);
613 rgbe[2] = (
unsigned char)(linear[2] * normalize);
614 rgbe[3] = (
unsigned char)(exponent + 128);
618static void stbiw__write_run_data(
stbi__write_context *s,
int length,
unsigned char databyte)
620 unsigned char lengthbyte = STBIW_UCHAR(length+128);
621 STBIW_ASSERT(length+128 <= 255);
628 unsigned char lengthbyte = STBIW_UCHAR(length);
629 STBIW_ASSERT(length <= 128);
634static void stbiw__write_hdr_scanline(
stbi__write_context *s,
int width,
int ncomp,
unsigned char *scratch,
float *scanline)
636 unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
637 unsigned char rgbe[4];
641 scanlineheader[2] = (width&0xff00)>>8;
642 scanlineheader[3] = (width&0x00ff);
645 if (width < 8 || width >= 32768) {
646 for (x=0; x < width; x++) {
649 case 3: linear[2] = scanline[x*ncomp + 2];
650 linear[1] = scanline[x*ncomp + 1];
651 linear[0] = scanline[x*ncomp + 0];
654 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
657 stbiw__linear_to_rgbe(rgbe, linear);
663 for (x=0; x < width; x++) {
666 case 3: linear[2] = scanline[x*ncomp + 2];
667 linear[1] = scanline[x*ncomp + 1];
668 linear[0] = scanline[x*ncomp + 0];
671 linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
674 stbiw__linear_to_rgbe(rgbe, linear);
675 scratch[x + width*0] = rgbe[0];
676 scratch[x + width*1] = rgbe[1];
677 scratch[x + width*2] = rgbe[2];
678 scratch[x + width*3] = rgbe[3];
684 for (c=0; c < 4; c++) {
685 unsigned char *comp = &scratch[width*c];
691 while (r+2 < width) {
692 if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
701 if (len > 128) len = 128;
702 stbiw__write_dump_data(s, len, &comp[x]);
708 while (r < width && comp[r] == comp[x])
713 if (len > 127) len = 127;
714 stbiw__write_run_data(s, len, comp[x]);
725 if (y <= 0 || x <= 0 || data == NULL)
729 unsigned char *scratch = (
unsigned char *) STBIW_MALLOC(x*4);
732 char header[] =
"#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
735#ifdef __STDC_WANT_SECURE_LIB__
736 len = sprintf_s(buffer,
sizeof(buffer),
"EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
738 len = sprintf(buffer,
"EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
743 stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
752 stbi__start_write_callbacks(&s, func, context);
753 return stbi_write_hdr_core(&s, x, y, comp, (
float *) data);
756#ifndef STBI_WRITE_NO_STDIO
757STBIWDEF
int stbi_write_hdr(
char const *filename,
int x,
int y,
int comp,
const float *data)
760 if (stbi__start_write_file(&s,filename)) {
761 int r = stbi_write_hdr_core(&s, x, y, comp, (
float *) data);
762 stbi__end_write_file(&s);
775#ifndef STBIW_ZLIB_COMPRESS
777#define stbiw__sbraw(a) ((int *) (a) - 2)
778#define stbiw__sbm(a) stbiw__sbraw(a)[0]
779#define stbiw__sbn(a) stbiw__sbraw(a)[1]
781#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
782#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
783#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
785#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
786#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
787#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
789static void *stbiw__sbgrowf(
void **arr,
int increment,
int itemsize)
791 int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
792 void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
795 if (!*arr) ((
int *) p)[1] = 0;
796 *arr = (
void *) ((
int *) p + 2);
797 stbiw__sbm(*arr) = m;
802static unsigned char *stbiw__zlib_flushf(
unsigned char *data,
unsigned int *bitbuffer,
int *bitcount)
804 while (*bitcount >= 8) {
805 stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
812static int stbiw__zlib_bitrev(
int code,
int codebits)
816 res = (res << 1) | (code & 1);
822static unsigned int stbiw__zlib_countm(
unsigned char *a,
unsigned char *b,
int limit)
825 for (i=0; i < limit && i < 258; ++i)
826 if (a[i] != b[i])
break;
830static unsigned int stbiw__zhash(
unsigned char *data)
832 stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
842#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
843#define stbiw__zlib_add(code,codebits) \
844 (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
845#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
847#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
848#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
849#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
850#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
851#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))
852#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
854#define stbiw__ZHASH 16384
858STBIWDEF
unsigned char *
stbi_zlib_compress(
unsigned char *data,
int data_len,
int *out_len,
int quality)
860#ifdef STBIW_ZLIB_COMPRESS
862 return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality);
864 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 };
865 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 };
866 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 };
867 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 };
868 unsigned int bitbuf=0;
870 unsigned char *out = NULL;
871 unsigned char ***hash_table = (
unsigned char***) STBIW_MALLOC(stbiw__ZHASH *
sizeof(
unsigned char**));
872 if (hash_table == NULL)
874 if (quality < 5) quality = 5;
876 stbiw__sbpush(out, 0x78);
877 stbiw__sbpush(out, 0x5e);
878 stbiw__zlib_add(1,1);
879 stbiw__zlib_add(1,2);
881 for (i=0; i < stbiw__ZHASH; ++i)
882 hash_table[i] = NULL;
885 while (i < data_len-3) {
887 int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
888 unsigned char *bestloc = 0;
889 unsigned char **hlist = hash_table[h];
890 int n = stbiw__sbcount(hlist);
891 for (j=0; j < n; ++j) {
892 if (hlist[j]-data > i-32768) {
893 int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
894 if (d >= best) { best=d; bestloc=hlist[j]; }
898 if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
899 STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality,
sizeof(hash_table[h][0])*quality);
900 stbiw__sbn(hash_table[h]) = quality;
902 stbiw__sbpush(hash_table[h],data+i);
906 h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
907 hlist = hash_table[h];
908 n = stbiw__sbcount(hlist);
909 for (j=0; j < n; ++j) {
910 if (hlist[j]-data > i-32767) {
911 int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
921 int d = (int) (data+i - bestloc);
922 STBIW_ASSERT(d <= 32767 && best <= 258);
923 for (j=0; best > lengthc[j+1]-1; ++j);
924 stbiw__zlib_huff(j+257);
925 if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
926 for (j=0; d > distc[j+1]-1; ++j);
927 stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
928 if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
931 stbiw__zlib_huffb(data[i]);
936 for (;i < data_len; ++i)
937 stbiw__zlib_huffb(data[i]);
938 stbiw__zlib_huff(256);
941 stbiw__zlib_add(0,1);
943 for (i=0; i < stbiw__ZHASH; ++i)
944 (
void) stbiw__sbfree(hash_table[i]);
945 STBIW_FREE(hash_table);
949 unsigned int s1=1, s2=0;
950 int blocklen = (int) (data_len % 5552);
952 while (j < data_len) {
953 for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
954 s1 %= 65521; s2 %= 65521;
958 stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
959 stbiw__sbpush(out, STBIW_UCHAR(s2));
960 stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
961 stbiw__sbpush(out, STBIW_UCHAR(s1));
963 *out_len = stbiw__sbn(out);
965 STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
966 return (
unsigned char *) stbiw__sbraw(out);
970static unsigned int stbiw__crc32(
unsigned char *buffer,
int len)
973 return STBIW_CRC32(buffer, len);
975 static unsigned int crc_table[256] =
977 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
978 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
979 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
980 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
981 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
982 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
983 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
984 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
985 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
986 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
987 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
988 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
989 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
990 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
991 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
992 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
993 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
994 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
995 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
996 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
997 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
998 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
999 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
1000 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1001 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
1002 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
1003 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1004 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
1005 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
1006 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1007 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
1008 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
1011 unsigned int crc = ~0u;
1013 for (i=0; i < len; ++i)
1014 crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
1019#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)
1020#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
1021#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
1023static void stbiw__wpcrc(
unsigned char **data,
int len)
1025 unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
1026 stbiw__wp32(*data, crc);
1029static unsigned char stbiw__paeth(
int a,
int b,
int c)
1031 int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
1032 if (pa <= pb && pa <= pc)
return STBIW_UCHAR(a);
1033 if (pb <= pc)
return STBIW_UCHAR(b);
1034 return STBIW_UCHAR(c);
1038static void stbiw__encode_png_line(
unsigned char *pixels,
int stride_bytes,
int width,
int height,
int y,
int n,
int filter_type,
signed char *line_buffer)
1040 static int mapping[] = { 0,1,2,3,4 };
1041 static int firstmap[] = { 0,1,0,5,6 };
1042 int *mymap = (y != 0) ? mapping : firstmap;
1044 int type = mymap[filter_type];
1045 unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
1046 int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
1049 memcpy(line_buffer, z, width*n);
1054 for (i = 0; i < n; ++i) {
1056 case 1: line_buffer[i] = z[i];
break;
1057 case 2: line_buffer[i] = z[i] - z[i-signed_stride];
break;
1058 case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1);
break;
1059 case 4: line_buffer[i] = (
signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0));
break;
1060 case 5: line_buffer[i] = z[i];
break;
1061 case 6: line_buffer[i] = z[i];
break;
1065 case 1:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n];
break;
1066 case 2:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride];
break;
1067 case 3:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1);
break;
1068 case 4:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]);
break;
1069 case 5:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1);
break;
1070 case 6:
for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0);
break;
1074STBIWDEF
unsigned char *
stbi_write_png_to_mem(
const unsigned char *pixels,
int stride_bytes,
int x,
int y,
int n,
int *out_len)
1077 int ctype[5] = { -1, 0, 4, 2, 6 };
1078 unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
1079 unsigned char *out,*o, *filt, *zlib;
1080 signed char *line_buffer;
1083 if (stride_bytes == 0)
1084 stride_bytes = x * n;
1086 if (force_filter >= 5) {
1090 filt = (
unsigned char *) STBIW_MALLOC((x*n+1) * y);
if (!filt)
return 0;
1091 line_buffer = (
signed char *) STBIW_MALLOC(x * n);
if (!line_buffer) { STBIW_FREE(filt);
return 0; }
1092 for (j=0; j < y; ++j) {
1094 if (force_filter > -1) {
1095 filter_type = force_filter;
1096 stbiw__encode_png_line((
unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
1098 int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1099 for (filter_type = 0; filter_type < 5; filter_type++) {
1100 stbiw__encode_png_line((
unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
1104 for (i = 0; i < x*n; ++i) {
1105 est += abs((
signed char) line_buffer[i]);
1107 if (est < best_filter_val) {
1108 best_filter_val = est;
1109 best_filter = filter_type;
1112 if (filter_type != best_filter) {
1113 stbiw__encode_png_line((
unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
1114 filter_type = best_filter;
1118 filt[j*(x*n+1)] = (
unsigned char) filter_type;
1119 STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
1121 STBIW_FREE(line_buffer);
1124 if (!zlib)
return 0;
1127 out = (
unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
1129 *out_len = 8 + 12+13 + 12+zlen + 12;
1132 STBIW_MEMMOVE(o,sig,8); o+= 8;
1134 stbiw__wptag(o,
"IHDR");
1138 *o++ = STBIW_UCHAR(ctype[n]);
1142 stbiw__wpcrc(&o,13);
1144 stbiw__wp32(o, zlen);
1145 stbiw__wptag(o,
"IDAT");
1146 STBIW_MEMMOVE(o, zlib, zlen);
1149 stbiw__wpcrc(&o, zlen);
1152 stbiw__wptag(o,
"IEND");
1155 STBIW_ASSERT(o == out + *out_len);
1160#ifndef STBI_WRITE_NO_STDIO
1161STBIWDEF
int stbi_write_png(
char const *filename,
int x,
int y,
int comp,
const void *data,
int stride_bytes)
1165 unsigned char *png =
stbi_write_png_to_mem((
const unsigned char *) data, stride_bytes, x, y, comp, &len);
1166 if (png == NULL)
return 0;
1168 f = stbiw__fopen(filename,
"wb");
1169 if (!f) { STBIW_FREE(png);
return 0; }
1170 fwrite(png, 1, len, f);
1180 unsigned char *png =
stbi_write_png_to_mem((
const unsigned char *) data, stride_bytes, x, y, comp, &len);
1181 if (png == NULL)
return 0;
1182 func(context, png, len);
1196static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,
1197 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 };
1199static void stbiw__jpg_writeBits(
stbi__write_context *s,
int *bitBufP,
int *bitCntP,
const unsigned short *bs) {
1200 int bitBuf = *bitBufP, bitCnt = *bitCntP;
1202 bitBuf |= bs[0] << (24 - bitCnt);
1203 while(bitCnt >= 8) {
1204 unsigned char c = (bitBuf >> 16) & 255;
1216static void stbiw__jpg_DCT(
float *d0p,
float *d1p,
float *d2p,
float *d3p,
float *d4p,
float *d5p,
float *d6p,
float *d7p) {
1217 float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p;
1218 float z1, z2, z3, z4, z5, z11, z13;
1220 float tmp0 = d0 + d7;
1221 float tmp7 = d0 - d7;
1222 float tmp1 = d1 + d6;
1223 float tmp6 = d1 - d6;
1224 float tmp2 = d2 + d5;
1225 float tmp5 = d2 - d5;
1226 float tmp3 = d3 + d4;
1227 float tmp4 = d3 - d4;
1230 float tmp10 = tmp0 + tmp3;
1231 float tmp13 = tmp0 - tmp3;
1232 float tmp11 = tmp1 + tmp2;
1233 float tmp12 = tmp1 - tmp2;
1238 z1 = (tmp12 + tmp13) * 0.707106781f;
1243 tmp10 = tmp4 + tmp5;
1244 tmp11 = tmp5 + tmp6;
1245 tmp12 = tmp6 + tmp7;
1248 z5 = (tmp10 - tmp12) * 0.382683433f;
1249 z2 = tmp10 * 0.541196100f + z5;
1250 z4 = tmp12 * 1.306562965f + z5;
1251 z3 = tmp11 * 0.707106781f;
1261 *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6;
1264static void stbiw__jpg_calcBits(
int val,
unsigned short bits[2]) {
1265 int tmp1 = val < 0 ? -val : val;
1266 val = val < 0 ? val-1 : val;
1271 bits[0] = val & ((1<<bits[1])-1);
1274static int stbiw__jpg_processDU(
stbi__write_context *s,
int *bitBuf,
int *bitCnt,
float *CDU,
float *fdtbl,
int DC,
const unsigned short HTDC[256][2],
const unsigned short HTAC[256][2]) {
1275 const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] };
1276 const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] };
1277 int dataOff, i, diff, end0pos;
1281 for(dataOff=0; dataOff<64; dataOff+=8) {
1282 stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+1], &CDU[dataOff+2], &CDU[dataOff+3], &CDU[dataOff+4], &CDU[dataOff+5], &CDU[dataOff+6], &CDU[dataOff+7]);
1285 for(dataOff=0; dataOff<8; ++dataOff) {
1286 stbiw__jpg_DCT(&CDU[dataOff], &CDU[dataOff+8], &CDU[dataOff+16], &CDU[dataOff+24], &CDU[dataOff+32], &CDU[dataOff+40], &CDU[dataOff+48], &CDU[dataOff+56]);
1289 for(i=0; i<64; ++i) {
1290 float v = CDU[i]*fdtbl[i];
1293 DU[stbiw__jpg_ZigZag[i]] = (int)(v < 0 ? v - 0.5f : v + 0.5f);
1299 stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[0]);
1301 unsigned short bits[2];
1302 stbiw__jpg_calcBits(diff, bits);
1303 stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTDC[bits[1]]);
1304 stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1308 for(; (end0pos>0)&&(DU[end0pos]==0); --end0pos) {
1312 stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1315 for(i = 1; i <= end0pos; ++i) {
1318 unsigned short bits[2];
1319 for (; DU[i]==0 && i<=end0pos; ++i) {
1321 nrzeroes = i-startpos;
1322 if ( nrzeroes >= 16 ) {
1323 int lng = nrzeroes>>4;
1325 for (nrmarker=1; nrmarker <= lng; ++nrmarker)
1326 stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes);
1329 stbiw__jpg_calcBits(DU[i], bits);
1330 stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]);
1331 stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits);
1334 stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB);
1339static int stbi_write_jpg_core(
stbi__write_context *s,
int width,
int height,
int comp,
const void* data,
int quality) {
1341 static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};
1342 static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1343 static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d};
1344 static const unsigned char std_ac_luminance_values[] = {
1345 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
1346 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
1347 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
1348 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
1349 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
1350 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
1351 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1353 static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};
1354 static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11};
1355 static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};
1356 static const unsigned char std_ac_chrominance_values[] = {
1357 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
1358 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
1359 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
1360 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
1361 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
1362 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
1363 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa
1366 static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}};
1367 static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}};
1368 static const unsigned short YAC_HT[256][2] = {
1369 {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1370 {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1371 {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1372 {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1373 {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1374 {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1375 {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1376 {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1377 {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1378 {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1379 {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1380 {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1381 {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1382 {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1383 {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1384 {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1386 static const unsigned short UVAC_HT[256][2] = {
1387 {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1388 {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1389 {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1390 {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1391 {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1392 {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1393 {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1394 {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1395 {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1396 {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1397 {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1398 {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1399 {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1400 {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
1401 {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0},
1402 {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0}
1404 static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,
1405 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
1406 static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,
1407 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99};
1408 static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f,
1409 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f };
1412 float fdtbl_Y[64], fdtbl_UV[64];
1413 unsigned char YTable[64], UVTable[64];
1415 if(!data || !width || !height || comp > 4 || comp < 1) {
1419 quality = quality ? quality : 90;
1420 quality = quality < 1 ? 1 : quality > 100 ? 100 : quality;
1421 quality = quality < 50 ? 5000 / quality : 200 - quality * 2;
1423 for(i = 0; i < 64; ++i) {
1424 int uvti, yti = (YQT[i]*quality+50)/100;
1425 YTable[stbiw__jpg_ZigZag[i]] = (
unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti);
1426 uvti = (UVQT[i]*quality+50)/100;
1427 UVTable[stbiw__jpg_ZigZag[i]] = (
unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti);
1430 for(row = 0, k = 0; row < 8; ++row) {
1431 for(col = 0; col < 8; ++col, ++k) {
1432 fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1433 fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]);
1439 static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,
'J',
'F',
'I',
'F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 };
1440 static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 };
1441 const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(
unsigned char)(height>>8),STBIW_UCHAR(height),(
unsigned char)(width>>8),STBIW_UCHAR(width),
1442 3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 };
1444 s->
func(s->
context, (
void*)YTable,
sizeof(YTable));
1448 s->
func(s->
context, (
void*)(std_dc_luminance_nrcodes+1),
sizeof(std_dc_luminance_nrcodes)-1);
1449 s->
func(s->
context, (
void*)std_dc_luminance_values,
sizeof(std_dc_luminance_values));
1450 stbiw__putc(s, 0x10);
1451 s->
func(s->
context, (
void*)(std_ac_luminance_nrcodes+1),
sizeof(std_ac_luminance_nrcodes)-1);
1452 s->
func(s->
context, (
void*)std_ac_luminance_values,
sizeof(std_ac_luminance_values));
1454 s->
func(s->
context, (
void*)(std_dc_chrominance_nrcodes+1),
sizeof(std_dc_chrominance_nrcodes)-1);
1455 s->
func(s->
context, (
void*)std_dc_chrominance_values,
sizeof(std_dc_chrominance_values));
1456 stbiw__putc(s, 0x11);
1457 s->
func(s->
context, (
void*)(std_ac_chrominance_nrcodes+1),
sizeof(std_ac_chrominance_nrcodes)-1);
1458 s->
func(s->
context, (
void*)std_ac_chrominance_values,
sizeof(std_ac_chrominance_values));
1464 static const unsigned short fillBits[] = {0x7F, 7};
1465 const unsigned char *imageData = (
const unsigned char *)data;
1466 int DCY=0, DCU=0, DCV=0;
1467 int bitBuf=0, bitCnt=0;
1469 int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0;
1471 for(y = 0; y < height; y += 8) {
1472 for(x = 0; x < width; x += 8) {
1473 float YDU[64], UDU[64], VDU[64];
1474 for(row = y, pos = 0; row < y+8; ++row) {
1476 int clamped_row = (row < height) ? row : height - 1;
1477 int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1478 for(col = x; col < x+8; ++col, ++pos) {
1481 int p = base_p + ((col < width) ? col : (width-1))*comp;
1484 g = imageData[p+ofsG];
1485 b = imageData[p+ofsB];
1486 YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128;
1487 UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b;
1488 VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b;
1492 DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
1493 DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
1494 DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
1499 stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits);
1503 stbiw__putc(s, 0xFF);
1504 stbiw__putc(s, 0xD9);
1512 stbi__start_write_callbacks(&s, func, context);
1513 return stbi_write_jpg_core(&s, x, y, comp, (
void *) data, quality);
1517#ifndef STBI_WRITE_NO_STDIO
1518STBIWDEF
int stbi_write_jpg(
char const *filename,
int x,
int y,
int comp,
const void *data,
int quality)
1521 if (stbi__start_write_file(&s,filename)) {
1522 int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
1523 stbi__end_write_file(&s);
SCOL_EXPORT int cbmachine w
STBIW_EXTERN unsigned long const char int wchar_t int cchwide
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data)
void stbi_write_func(void *context, void *data, int size)
STBIW_EXTERN unsigned long const char * str
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 :-1]
STBIW_EXTERN unsigned long const char int wchar_t * widestr
STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data)
STBIW_EXTERN unsigned long const wchar_t int char int const char * defchar
STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean)
STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data)
STBIW_EXTERN unsigned long const char int cbmb
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)
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t *input)
int stbi_write_tga_with_rle
STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
STBIW_EXTERN unsigned long const wchar_t int char int const char int * used_default
STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data)
unsigned int stbiw_uint32
int stbi_write_png_compression_level
STBIWDEF unsigned char * stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data)
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data)
int stbi_write_force_png_filter
STBIW_EXTERN unsigned long flags
STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)