|
|
@@ -1,4 +1,4 @@
|
|
|
-/* stb_image_write - v1.15 - public domain - http://nothings.org/stb
|
|
|
+/* stb_image_write - v1.16 - public domain - http://nothings.org/stb
|
|
|
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
|
|
|
no warranty implied; use at your own risk
|
|
|
|
|
|
@@ -140,6 +140,7 @@ CREDITS:
|
|
|
Ivan Tikhonov
|
|
|
github:ignotion
|
|
|
Adam Schackart
|
|
|
+ Andrew Kensler
|
|
|
|
|
|
LICENSE
|
|
|
|
|
|
@@ -166,9 +167,9 @@ LICENSE
|
|
|
#endif
|
|
|
|
|
|
#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
|
|
|
-extern int stbi_write_tga_with_rle;
|
|
|
-extern int stbi_write_png_compression_level;
|
|
|
-extern int stbi_write_force_png_filter;
|
|
|
+STBIWDEF int stbi_write_tga_with_rle;
|
|
|
+STBIWDEF int stbi_write_png_compression_level;
|
|
|
+STBIWDEF int stbi_write_force_png_filter;
|
|
|
#endif
|
|
|
|
|
|
#ifndef STBI_WRITE_NO_STDIO
|
|
|
@@ -178,7 +179,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const
|
|
|
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
|
|
|
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
|
|
|
|
|
|
-#ifdef STBI_WINDOWS_UTF8
|
|
|
+#ifdef STBIW_WINDOWS_UTF8
|
|
|
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
|
|
#endif
|
|
|
#endif
|
|
|
@@ -285,7 +286,7 @@ static void stbi__stdio_write(void *context, void *data, int size)
|
|
|
fwrite(data,1,size,(FILE*) context);
|
|
|
}
|
|
|
|
|
|
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
|
|
+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
|
|
|
#ifdef __cplusplus
|
|
|
#define STBIW_EXTERN extern "C"
|
|
|
#else
|
|
|
@@ -296,25 +297,25 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in
|
|
|
|
|
|
STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
|
|
{
|
|
|
- return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
|
|
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
static FILE *stbiw__fopen(char const *filename, char const *mode)
|
|
|
{
|
|
|
FILE *f;
|
|
|
-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
|
|
+#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
|
|
|
wchar_t wMode[64];
|
|
|
wchar_t wFilename[1024];
|
|
|
- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
|
|
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
|
|
|
return 0;
|
|
|
|
|
|
- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
|
|
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
|
|
|
return 0;
|
|
|
|
|
|
-#if _MSC_VER >= 1400
|
|
|
- if (0 != _wfopen_s(&f, wFilename, wMode))
|
|
|
- f = 0;
|
|
|
+#if defined(_MSC_VER) && _MSC_VER >= 1400
|
|
|
+ if (0 != _wfopen_s(&f, wFilename, wMode))
|
|
|
+ f = 0;
|
|
|
#else
|
|
|
f = _wfopen(wFilename, wMode);
|
|
|
#endif
|
|
|
@@ -397,7 +398,7 @@ static void stbiw__putc(stbi__write_context *s, unsigned char c)
|
|
|
|
|
|
static void stbiw__write1(stbi__write_context *s, unsigned char a)
|
|
|
{
|
|
|
- if (s->buf_used + 1 > sizeof(s->buffer))
|
|
|
+ if ((size_t)s->buf_used + 1 > sizeof(s->buffer))
|
|
|
stbiw__write_flush(s);
|
|
|
s->buffer[s->buf_used++] = a;
|
|
|
}
|
|
|
@@ -405,7 +406,7 @@ static void stbiw__write1(stbi__write_context *s, unsigned char a)
|
|
|
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
|
|
|
{
|
|
|
int n;
|
|
|
- if (s->buf_used + 3 > sizeof(s->buffer))
|
|
|
+ if ((size_t)s->buf_used + 3 > sizeof(s->buffer))
|
|
|
stbiw__write_flush(s);
|
|
|
n = s->buf_used;
|
|
|
s->buf_used = n+3;
|
|
|
@@ -490,11 +491,22 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x,
|
|
|
|
|
|
static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
|
|
|
{
|
|
|
- int pad = (-x*3) & 3;
|
|
|
- return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
|
|
|
- "11 4 22 4" "4 44 22 444444",
|
|
|
- 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
|
|
|
- 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
|
|
|
+ if (comp != 4) {
|
|
|
+ // write RGB bitmap
|
|
|
+ int pad = (-x*3) & 3;
|
|
|
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
|
|
|
+ "11 4 22 4" "4 44 22 444444",
|
|
|
+ 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
|
|
|
+ 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
|
|
|
+ } else {
|
|
|
+ // RGBA bitmaps need a v4 header
|
|
|
+ // use BI_BITFIELDS mode with 32bpp and alpha mask
|
|
|
+ // (straight BI_RGB with alpha mask doesn't work in most readers)
|
|
|
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0,
|
|
|
+ "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444",
|
|
|
+ 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header
|
|
|
+ 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
|
|
|
@@ -622,6 +634,8 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
|
|
|
|
|
|
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
|
|
|
|
|
|
+#ifndef STBI_WRITE_NO_STDIO
|
|
|
+
|
|
|
static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
|
|
{
|
|
|
int exponent;
|
|
|
@@ -756,7 +770,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
|
|
|
char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
|
|
|
s->func(s->context, header, sizeof(header)-1);
|
|
|
|
|
|
-#ifdef __STDC_WANT_SECURE_LIB__
|
|
|
+#ifdef __STDC_LIB_EXT1__
|
|
|
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
|
|
|
#else
|
|
|
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
|
|
|
@@ -777,7 +791,6 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x,
|
|
|
return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
|
|
|
}
|
|
|
|
|
|
-#ifndef STBI_WRITE_NO_STDIO
|
|
|
STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
|
|
|
{
|
|
|
stbi__write_context s = { 0 };
|
|
|
@@ -968,6 +981,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
|
|
|
(void) stbiw__sbfree(hash_table[i]);
|
|
|
STBIW_FREE(hash_table);
|
|
|
|
|
|
+ // store uncompressed instead if compression was worse
|
|
|
+ if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
|
|
|
+ stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1
|
|
|
+ for (j = 0; j < data_len;) {
|
|
|
+ int blocklen = data_len - j;
|
|
|
+ if (blocklen > 32767) blocklen = 32767;
|
|
|
+ stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
|
|
|
+ stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
|
|
|
+ stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
|
|
|
+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
|
|
|
+ stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
|
|
|
+ memcpy(out+stbiw__sbn(out), data+j, blocklen);
|
|
|
+ stbiw__sbn(out) += blocklen;
|
|
|
+ j += blocklen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
{
|
|
|
// compute adler32 on input
|
|
|
unsigned int s1=1, s2=0;
|
|
|
@@ -1598,6 +1628,10 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
|
|
|
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
|
|
|
|
|
/* Revision history
|
|
|
+ 1.16 (2021-07-11)
|
|
|
+ make Deflate code emit uncompressed blocks when it would otherwise expand
|
|
|
+ support writing BMPs with alpha channel
|
|
|
+ 1.15 (2020-07-13) unknown
|
|
|
1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
|
|
|
1.13
|
|
|
1.12
|
|
|
@@ -1635,7 +1669,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
|
|
|
add HDR output
|
|
|
fix monochrome BMP
|
|
|
0.95 (2014-08-17)
|
|
|
- add monochrome TGA output
|
|
|
+ add monochrome TGA output
|
|
|
0.94 (2014-05-31)
|
|
|
rename private functions to avoid conflicts with stb_image.h
|
|
|
0.93 (2014-05-27)
|
|
|
@@ -1688,4 +1722,3 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
------------------------------------------------------------------------------
|
|
|
*/
|
|
|
-
|