summaryrefslogtreecommitdiffhomepage
path: root/src/external/stb_image_write.h
diff options
context:
space:
mode:
authorRay <[email protected]>2019-02-12 00:25:21 +0100
committerRay <[email protected]>2019-02-12 00:25:21 +0100
commitd00b8f9ffc7c83bd9a5089a6b94e74400b72c0be (patch)
treed588600ba397752c5191098399e8b41a53923f44 /src/external/stb_image_write.h
parente996fe2ff511a60ac67b56996ac04a7e69fe8a69 (diff)
downloadraylib-d00b8f9ffc7c83bd9a5089a6b94e74400b72c0be.tar.gz
raylib-d00b8f9ffc7c83bd9a5089a6b94e74400b72c0be.zip
Updated external libraries
Diffstat (limited to 'src/external/stb_image_write.h')
-rw-r--r--src/external/stb_image_write.h145
1 files changed, 101 insertions, 44 deletions
diff --git a/src/external/stb_image_write.h b/src/external/stb_image_write.h
index c05e9581..00ab092a 100644
--- a/src/external/stb_image_write.h
+++ b/src/external/stb_image_write.h
@@ -1,4 +1,4 @@
-/* stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h
+/* stb_image_write - v1.10 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@@ -17,8 +17,7 @@
ABOUT:
- This header file is a library for writing images to C stdio. It could be
- adapted to write to memory or a general streaming interface; let me know.
+ This header file is a library for writing images to C stdio or a callback.
The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation; though providing a custom
@@ -38,6 +37,14 @@ BUILDING:
The returned data will be freed with STBIW_FREE() (free() by default),
so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
+UNICODE:
+
+ If compiling for Windows and you wish to use Unicode filenames, compile
+ with
+ #define STBIW_WINDOWS_UTF8
+ and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
+ Windows wchar_t filenames to utf8.
+
USAGE:
There are five functions, one for each image file format:
@@ -148,6 +155,8 @@ LICENSE
#ifndef INCLUDE_STB_IMAGE_WRITE_H
#define INCLUDE_STB_IMAGE_WRITE_H
+#include <stdlib.h>
+
// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
#ifndef STBIWDEF
#ifdef STB_IMAGE_WRITE_STATIC
@@ -173,6 +182,10 @@ STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const
STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
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
+STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
+#endif
#endif
typedef void stbi_write_func(void *context, void *data, int size);
@@ -275,15 +288,52 @@ static void stbi__stdio_write(void *context, void *data, int size)
fwrite(data,1,size,(FILE*) context);
}
-static int stbi__start_write_file(stbi__write_context *s, const char *filename)
+#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+#ifdef __cplusplus
+#define STBIW_EXTERN extern "C"
+#else
+#define STBIW_EXTERN extern
+#endif
+STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
+STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
+
+STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
+{
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL);
+}
+#endif
+
+static FILE *stbiw__fopen(char const *filename, char const *mode)
{
FILE *f;
-#ifdef STBI_MSC_SECURE_CRT
- if (fopen_s(&f, filename, "wb"))
- f = NULL;
+#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
+ wchar_t wMode[64];
+ wchar_t wFilename[1024];
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
+ return 0;
+
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
+ return 0;
+
+#if _MSC_VER >= 1400
+ if (0 != _wfopen_s(&f, wFilename, wMode))
+ f = 0;
+#else
+ f = _wfopen(wFilename, wMode);
+#endif
+
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+ if (0 != fopen_s(&f, filename, mode))
+ f=0;
#else
- f = fopen(filename, "wb");
+ f = fopen(filename, mode);
#endif
+ return f;
+}
+
+static int stbi__start_write_file(stbi__write_context *s, const char *filename)
+{
+ FILE *f = stbiw__fopen(filename, "wb");
stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
return f != NULL;
}
@@ -552,7 +602,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
-void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
+static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
{
int exponent;
float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
@@ -569,7 +619,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
}
}
-void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
+static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
{
unsigned char lengthbyte = STBIW_UCHAR(length+128);
STBIW_ASSERT(length+128 <= 255);
@@ -577,7 +627,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat
s->func(s->context, &databyte, 1);
}
-void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
+static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
{
unsigned char lengthbyte = STBIW_UCHAR(length);
STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
@@ -585,7 +635,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d
s->func(s->context, data, length);
}
-void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
+static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
{
unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
unsigned char rgbe[4];
@@ -694,7 +744,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
s->func(s->context, buffer, len);
for(i=0; i < y; i++)
- stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
STBIW_FREE(scratch);
return 1;
}
@@ -809,7 +859,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
#endif // STBIW_ZLIB_COMPRESS
-unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
+STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
{
#ifdef STBIW_ZLIB_COMPRESS
// user provided a zlib compress implementation, use that
@@ -923,6 +973,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
static unsigned int stbiw__crc32(unsigned char *buffer, int len)
{
+#ifdef STBIW_CRC32
+ return STBIW_CRC32(buffer, len);
+#else
static unsigned int crc_table[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
@@ -964,6 +1017,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len)
for (i=0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
return ~crc;
+#endif
}
#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)
@@ -994,9 +1048,15 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
int type = mymap[filter_type];
unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
+
+ if (type==0) {
+ memcpy(line_buffer, z, width*n);
+ return;
+ }
+
+ // first loop isn't optimized since it's just one pixel
for (i = 0; i < n; ++i) {
switch (type) {
- case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
@@ -1005,20 +1065,17 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
case 6: line_buffer[i] = z[i]; break;
}
}
- for (i=n; i < width*n; ++i) {
- switch (type) {
- case 0: line_buffer[i] = z[i]; break;
- case 1: line_buffer[i] = z[i] - z[i-n]; break;
- case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
- case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
- case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
- case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
- case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
- }
+ switch (type) {
+ case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
+ case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
+ case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
+ 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;
+ case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
+ case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
}
}
-unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
+STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int force_filter = stbi_write_force_png_filter;
int ctype[5] = { -1, 0, 4, 2, 6 };
@@ -1040,11 +1097,11 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
int filter_type;
if (force_filter > -1) {
filter_type = force_filter;
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
} else { // Estimate the best filter by running through all of them:
int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
for (filter_type = 0; filter_type < 5; filter_type++) {
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
// Estimate the entropy of the line using this filter; the less, the better.
est = 0;
@@ -1057,7 +1114,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
}
}
if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
filter_type = best_filter;
}
}
@@ -1109,14 +1166,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
{
FILE *f;
int len;
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
if (png == NULL) return 0;
-#ifdef STBI_MSC_SECURE_CRT
- if (fopen_s(&f, filename, "wb"))
- f = NULL;
-#else
- f = fopen(filename, "wb");
-#endif
+
+ f = stbiw__fopen(filename, "wb");
if (!f) { STBIW_FREE(png); return 0; }
fwrite(png, 1, len, f);
fclose(f);
@@ -1128,7 +1181,7 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
{
int len;
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
if (png == NULL) return 0;
func(context, png, len);
STBIW_FREE(png);
@@ -1423,15 +1476,17 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
for(x = 0; x < width; x += 8) {
float YDU[64], UDU[64], VDU[64];
for(row = y, pos = 0; row < y+8; ++row) {
+ int p;
+ if(row < height) {
+ p = (stbi__flip_vertically_on_write ? (height-1-row) : row)*width*comp;
+ } else {
+ // row >= height => use last input row (=> first if flipping)
+ p = stbi__flip_vertically_on_write ? 0 : ((height-1)*width*comp);
+ }
for(col = x; col < x+8; ++col, ++pos) {
- int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
float r, g, b;
- if(row >= height) {
- p -= width*comp*(row+1 - height);
- }
- if(col >= width) {
- p -= comp*(col+1 - width);
- }
+ // if col >= width => use pixel from last input column
+ p += ((col < width) ? col : (width-1))*comp;
r = imageData[p+0];
g = imageData[p+ofsG];
@@ -1483,6 +1538,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
+ 1.10 (2019-02-07)
+ support utf8 filenames in Windows; fix warnings and platform ifdefs
1.09 (2018-02-11)
fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1.08 (2018-01-29)