Merge pull request #511 from 0lvin/fixes

Small fixes
This commit is contained in:
Yamagi 2020-02-03 16:06:49 +01:00 committed by GitHub
commit 32b4e6f4a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 468 additions and 219 deletions

View file

@ -278,7 +278,7 @@ Sys_FindFirst(char *path, unsigned musthave, unsigned canhave)
{ {
if ((strcmp(d->d_name, ".") != 0) || (strcmp(d->d_name, "..") != 0)) if ((strcmp(d->d_name, ".") != 0) || (strcmp(d->d_name, "..") != 0))
{ {
sprintf(findpath, "%s/%s", findbase, d->d_name); snprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
return findpath; return findpath;
} }
} }
@ -303,7 +303,7 @@ Sys_FindNext(unsigned musthave, unsigned canhave)
{ {
if ((strcmp(d->d_name, ".") != 0) || (strcmp(d->d_name, "..") != 0)) if ((strcmp(d->d_name, ".") != 0) || (strcmp(d->d_name, "..") != 0))
{ {
sprintf(findpath, "%s/%s", findbase, d->d_name); snprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
return findpath; return findpath;
} }
} }

View file

@ -63,7 +63,7 @@ Sys_Error(char *error, ...)
Qcommon_Shutdown(); Qcommon_Shutdown();
va_start(argptr, error); va_start(argptr, error);
vsprintf(text, error, argptr); vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr); va_end(argptr);
fprintf(stderr, "Error: %s\n", text); fprintf(stderr, "Error: %s\n", text);

View file

@ -1,4 +1,4 @@
/* stb_image - v2.19 - public domain image loader - http://nothings.org/stb /* stb_image - v2.23 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk no warranty implied; use at your own risk
Do this: Do this:
@ -48,6 +48,10 @@ LICENSE
RECENT REVISION HISTORY: RECENT REVISION HISTORY:
2.23 (2019-08-11) fix clang static analysis warning
2.22 (2019-03-04) gif fixes, fix warnings
2.21 (2019-02-25) fix typo in comment
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
2.19 (2018-02-11) fix warning 2.19 (2018-02-11) fix warning
2.18 (2018-01-30) fix warnings 2.18 (2018-01-30) fix warnings
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
@ -84,6 +88,7 @@ RECENT REVISION HISTORY:
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
Arseny Kapoulkine Arseny Kapoulkine
John-Mark Allen John-Mark Allen
Carmelo J Fdez-Aguera
Bug & warning fixes Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko Marc LeBlanc David Woo Guillaume George Martins Mozeiko
@ -99,7 +104,7 @@ RECENT REVISION HISTORY:
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
Christian Floisand Kevin Schmidt github:darealshinji Christian Floisand Kevin Schmidt JR Smith github:darealshinji
Blazej Dariusz Roszkowski github:Michaelangel007 Blazej Dariusz Roszkowski github:Michaelangel007
*/ */
@ -161,6 +166,16 @@ RECENT REVISION HISTORY:
// //
// =========================================================================== // ===========================================================================
// //
// UNICODE:
//
// If compiling for Windows and you wish to use Unicode filenames, compile
// with
// #define STBI_WINDOWS_UTF8
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
// Windows wchar_t filenames to utf8.
//
// ===========================================================================
//
// Philosophy // Philosophy
// //
// stb libraries are designed with the following priorities: // stb libraries are designed with the following priorities:
@ -171,12 +186,12 @@ RECENT REVISION HISTORY:
// //
// Sometimes I let "good performance" creep up in priority over "easy to maintain", // Sometimes I let "good performance" creep up in priority over "easy to maintain",
// and for best performance I may provide less-easy-to-use APIs that give higher // and for best performance I may provide less-easy-to-use APIs that give higher
// performance, in addition to the easy to use ones. Nevertheless, it's important // performance, in addition to the easy-to-use ones. Nevertheless, it's important
// to keep in mind that from the standpoint of you, a client of this library, // to keep in mind that from the standpoint of you, a client of this library,
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. // all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
// //
// Some secondary priorities arise directly from the first two, some of which // Some secondary priorities arise directly from the first two, some of which
// make more explicit reasons why performance can't be emphasized. // provide more explicit reasons why performance can't be emphasized.
// //
// - Portable ("ease of use") // - Portable ("ease of use")
// - Small source code footprint ("easy to maintain") // - Small source code footprint ("easy to maintain")
@ -219,11 +234,10 @@ RECENT REVISION HISTORY:
// //
// HDR image support (disable by defining STBI_NO_HDR) // HDR image support (disable by defining STBI_NO_HDR)
// //
// stb_image now supports loading HDR images in general, and currently // stb_image supports loading HDR images in general, and currently the Radiance
// the Radiance .HDR file format, although the support is provided // .HDR file format specifically. You can still load any file through the existing
// generically. You can still load any file through the existing interface; // interface; if you attempt to load an HDR file, it will be automatically remapped
// if you attempt to load an HDR file, it will be automatically remapped to // to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
// both of these constants can be reconfigured through this interface: // both of these constants can be reconfigured through this interface:
// //
// stbi_hdr_to_ldr_gamma(2.2f); // stbi_hdr_to_ldr_gamma(2.2f);
@ -257,7 +271,7 @@ RECENT REVISION HISTORY:
// //
// By default we convert iphone-formatted PNGs back to RGB, even though // By default we convert iphone-formatted PNGs back to RGB, even though
// they are internally encoded differently. You can disable this conversion // they are internally encoded differently. You can disable this conversion
// by by calling stbi_convert_iphone_png_to_rgb(0), in which case // by calling stbi_convert_iphone_png_to_rgb(0), in which case
// you will always just get the native iphone "format" through (which // you will always just get the native iphone "format" through (which
// is BGR stored in RGB). // is BGR stored in RGB).
// //
@ -319,6 +333,7 @@ enum
STBI_rgb_alpha = 4 STBI_rgb_alpha = 4
}; };
#include <stdlib.h>
typedef unsigned char stbi_uc; typedef unsigned char stbi_uc;
typedef unsigned short stbi_us; typedef unsigned short stbi_us;
@ -326,11 +341,13 @@ typedef unsigned short stbi_us;
extern "C" { extern "C" {
#endif #endif
#ifndef STBIDEF
#ifdef STB_IMAGE_STATIC #ifdef STB_IMAGE_STATIC
#define STBIDEF static #define STBIDEF static
#else #else
#define STBIDEF extern #define STBIDEF extern
#endif #endif
#endif
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
@ -355,10 +372,6 @@ typedef struct
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
#ifndef STBI_NO_GIF
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
#endif
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
@ -366,6 +379,14 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in
// for stbi_load_from_file, file pointer is left pointing immediately after image // for stbi_load_from_file, file pointer is left pointing immediately after image
#endif #endif
#ifndef STBI_NO_GIF
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
#endif
#ifdef STBI_WINDOWS_UTF8
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
#endif
//////////////////////////////////// ////////////////////////////////////
// //
// 16-bits-per-channel interface // 16-bits-per-channel interface
@ -525,6 +546,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#define STBI_ASSERT(x) assert(x) #define STBI_ASSERT(x) assert(x)
#endif #endif
#ifdef __cplusplus
#define STBI_EXTERN extern "C"
#else
#define STBI_EXTERN extern
#endif
#ifndef _MSC_VER #ifndef _MSC_VER
#ifdef __cplusplus #ifdef __cplusplus
@ -649,14 +676,18 @@ static int stbi__cpuid3(void)
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
static int stbi__sse2_available(void) static int stbi__sse2_available(void)
{ {
int info3 = stbi__cpuid3(); int info3 = stbi__cpuid3();
return ((info3 >> 26) & 1) != 0; return ((info3 >> 26) & 1) != 0;
} }
#endif
#else // assume GCC-style if not VC++ #else // assume GCC-style if not VC++
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
static int stbi__sse2_available(void) static int stbi__sse2_available(void)
{ {
// If we're even attempting to compile this on GCC/Clang, that means // If we're even attempting to compile this on GCC/Clang, that means
@ -664,6 +695,8 @@ static int stbi__sse2_available(void)
// instructions at will, and so are we. // instructions at will, and so are we.
return 1; return 1;
} }
#endif
#endif #endif
#endif #endif
@ -1070,6 +1103,7 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
} }
} }
#ifndef STBI_NO_GIF
static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
{ {
int slice; int slice;
@ -1081,6 +1115,7 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt
bytes += slice_size; bytes += slice_size;
} }
} }
#endif
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{ {
@ -1131,7 +1166,7 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
return (stbi__uint16 *) result; return (stbi__uint16 *) result;
} }
#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR) #if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
{ {
if (stbi__vertically_flip_on_load && result != NULL) { if (stbi__vertically_flip_on_load && result != NULL) {
@ -1143,10 +1178,38 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
STBI_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);
#endif
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
STBIDEF int stbi_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);
}
#endif
static FILE *stbi__fopen(char const *filename, char const *mode) static FILE *stbi__fopen(char const *filename, char const *mode)
{ {
FILE *f; FILE *f;
#if defined(_MSC_VER) && _MSC_VER >= 1400 #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)) if (0 != fopen_s(&f, filename, mode))
f=0; f=0;
#else #else
@ -1539,18 +1602,18 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
// convert source image with img_n components to one with req_comp components; // convert source image with img_n components to one with req_comp components;
// avoid switch per pixel, so use switch per scanline and massive macros // avoid switch per pixel, so use switch per scanline and massive macros
switch (STBI__COMBO(img_n, req_comp)) { switch (STBI__COMBO(img_n, req_comp)) {
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break;
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break;
STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break;
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break;
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break;
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
default: STBI_ASSERT(0); default: STBI_ASSERT(0);
} }
#undef STBI__CASE #undef STBI__CASE
@ -1588,18 +1651,18 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
// convert source image with img_n components to one with req_comp components; // convert source image with img_n components to one with req_comp components;
// avoid switch per pixel, so use switch per scanline and massive macros // avoid switch per pixel, so use switch per scanline and massive macros
switch (STBI__COMBO(img_n, req_comp)) { switch (STBI__COMBO(img_n, req_comp)) {
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break;
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break;
STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break;
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break;
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
default: STBI_ASSERT(0); default: STBI_ASSERT(0);
} }
#undef STBI__CASE #undef STBI__CASE
@ -1623,7 +1686,11 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
for (k=0; k < n; ++k) { for (k=0; k < n; ++k) {
output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
} }
if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; }
if (n < comp) {
for (i=0; i < x*y; ++i) {
output[i*comp + n] = data[i*comp + n]/255.0f;
}
} }
STBI_FREE(data); STBI_FREE(data);
return output; return output;
@ -3596,7 +3663,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
int k; int k;
unsigned int i,j; unsigned int i,j;
stbi_uc *output; stbi_uc *output;
stbi_uc *coutput[4]; stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
stbi__resample res_comp[4]; stbi__resample res_comp[4];
@ -3717,7 +3784,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n == 1) if (n == 1)
for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
else else
for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
} }
} }
} }
@ -4731,7 +4798,7 @@ static void stbi__de_iphone(stbi__png *z)
static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
{ {
stbi_uc palette[1024], pal_img_n=0; stbi_uc palette[1024], pal_img_n=0;
stbi_uc has_trans=0, tc[3]; stbi_uc has_trans=0, tc[3]={0};
stbi__uint16 tc16[3]; stbi__uint16 tc16[3];
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
int first=1,k,interlace=0, color=0, is_iphone=0; int first=1,k,interlace=0, color=0, is_iphone=0;
@ -5009,11 +5076,11 @@ static int stbi__high_bit(unsigned int z)
{ {
int n=0; int n=0;
if (z == 0) return -1; if (z == 0) return -1;
if (z >= 0x10000) n += 16, z >>= 16; if (z >= 0x10000) { n += 16; z >>= 16; }
if (z >= 0x00100) n += 8, z >>= 8; if (z >= 0x00100) { n += 8; z >>= 8; }
if (z >= 0x00010) n += 4, z >>= 4; if (z >= 0x00010) { n += 4; z >>= 4; }
if (z >= 0x00004) n += 2, z >>= 2; if (z >= 0x00004) { n += 2; z >>= 2; }
if (z >= 0x00002) n += 1, z >>= 1; if (z >= 0x00002) { n += 1;/* >>= 1;*/ }
return n; return n;
} }
@ -5030,7 +5097,7 @@ static int stbi__bitcount(unsigned int a)
// extract an arbitrarily-aligned N-bit value (N=bits) // extract an arbitrarily-aligned N-bit value (N=bits)
// from v, and then make it 8-bits long and fractionally // from v, and then make it 8-bits long and fractionally
// extend it to full full range. // extend it to full full range.
static int stbi__shiftsigned(int v, int shift, int bits) static int stbi__shiftsigned(unsigned int v, int shift, int bits)
{ {
static unsigned int mul_table[9] = { static unsigned int mul_table[9] = {
0, 0,
@ -5171,7 +5238,10 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - 14 - info.hsz) >> 2; psize = (info.offset - 14 - info.hsz) >> 2;
} }
s->img_n = ma ? 4 : 3; if (info.bpp == 24 && ma == 0xff000000)
s->img_n = 3;
else
s->img_n = ma ? 4 : 3;
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
target = req_comp; target = req_comp;
else else
@ -5207,6 +5277,8 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
out[z++] = pal[color][0]; out[z++] = pal[color][0];
out[z++] = pal[color][1]; out[z++] = pal[color][1];
out[z++] = pal[color][2]; out[z++] = pal[color][2];
if (target == 4) out[z++] = 255;
if (i+1 == (int) s->img_x) break;
if((--bit_offset) < 0) { if((--bit_offset) < 0) {
bit_offset = 7; bit_offset = 7;
v = stbi__get8(s); v = stbi__get8(s);
@ -5299,7 +5371,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi_uc *p1 = out + j *s->img_x*target; stbi_uc *p1 = out + j *s->img_x*target;
stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
for (i=0; i < (int) s->img_x*target; ++i) { for (i=0; i < (int) s->img_x*target; ++i) {
t = p1[i], p1[i] = p2[i], p2[i] = t; t = p1[i]; p1[i] = p2[i]; p2[i] = t;
} }
} }
} }
@ -5479,6 +5551,8 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
int RLE_repeating = 0; int RLE_repeating = 0;
int read_next_pixel = 1; int read_next_pixel = 1;
STBI_NOTUSED(ri); STBI_NOTUSED(ri);
STBI_NOTUSED(tga_x_origin); // @TODO
STBI_NOTUSED(tga_y_origin); // @TODO
// do a tiny bit of precessing // do a tiny bit of precessing
if ( tga_image_type >= 8 ) if ( tga_image_type >= 8 )
@ -5642,6 +5716,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
// Microsoft's C compilers happy... [8^( // Microsoft's C compilers happy... [8^(
tga_palette_start = tga_palette_len = tga_palette_bits = tga_palette_start = tga_palette_len = tga_palette_bits =
tga_x_origin = tga_y_origin = 0; tga_x_origin = tga_y_origin = 0;
STBI_NOTUSED(tga_palette_start);
// OK, done // OK, done
return tga_data; return tga_data;
} }
@ -5789,7 +5864,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
// Else if n is 128, noop. // Else if n is 128, noop.
// Endloop // Endloop
// The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, // The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
// which we're going to just skip. // which we're going to just skip.
stbi__skip(s, h * channelCount * 2 ); stbi__skip(s, h * channelCount * 2 );
@ -6342,22 +6417,27 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
int first_frame; int first_frame;
int pi; int pi;
int pcount; int pcount;
STBI_NOTUSED(req_comp);
// on first frame, any non-written pixels get the background colour (non-transparent) // on first frame, any non-written pixels get the background colour (non-transparent)
first_frame = 0; first_frame = 0;
if (g->out == 0) { if (g->out == 0) {
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h); return stbi__errpuc("too large", "GIF image is too large");
g->history = (stbi_uc *) stbi__malloc(g->w * g->h); pcount = g->w * g->h;
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); g->out = (stbi_uc *) stbi__malloc(4 * pcount);
g->background = (stbi_uc *) stbi__malloc(4 * pcount);
g->history = (stbi_uc *) stbi__malloc(pcount);
if (!g->out || !g->background || !g->history)
return stbi__errpuc("outofmem", "Out of memory");
// image is treated as "tranparent" at the start - ie, nothing overwrites the current background; // image is treated as "transparent" at the start - ie, nothing overwrites the current background;
// background colour is only used for pixels that are not rendered first frame, after that "background" // background colour is only used for pixels that are not rendered first frame, after that "background"
// color refers to teh color that was there the previous frame. // color refers to the color that was there the previous frame.
memset( g->out, 0x00, 4 * g->w * g->h ); memset(g->out, 0x00, 4 * pcount);
memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent) memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame memset(g->history, 0x00, pcount); // pixels that were affected previous frame
first_frame = 1; first_frame = 1;
} else { } else {
// second frame - how do we dispoase of the previous one? // second frame - how do we dispoase of the previous one?
@ -6418,6 +6498,13 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
g->cur_x = g->start_x; g->cur_x = g->start_x;
g->cur_y = g->start_y; g->cur_y = g->start_y;
// if the width of the specified rectangle is 0, that means
// we may not see *any* pixels or the image is malformed;
// to make sure this is caught, move the current y down to
// max_y (which is what out_gif_code checks).
if (w == 0)
g->cur_y = g->max_y;
g->lflags = stbi__get8(s); g->lflags = stbi__get8(s);
if (g->lflags & 0x40) { if (g->lflags & 0x40) {
@ -6437,7 +6524,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
return stbi__errpuc("missing color table", "Corrupt GIF"); return stbi__errpuc("missing color table", "Corrupt GIF");
o = stbi__process_gif_raster(s, g); o = stbi__process_gif_raster(s, g);
if (o == NULL) return NULL; if (!o) return NULL;
// if this was the first frame, // if this was the first frame,
pcount = g->w * g->h; pcount = g->w * g->h;
@ -6565,6 +6652,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi_uc *u = 0; stbi_uc *u = 0;
stbi__gif g; stbi__gif g;
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
STBI_NOTUSED(ri);
u = stbi__gif_load_next(s, &g, comp, req_comp, 0); u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
@ -6576,6 +6664,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
// can be done for multiple frames. // can be done for multiple frames.
if (req_comp && req_comp != 4) if (req_comp && req_comp != 4)
u = stbi__convert_format(u, 4, req_comp, g.w, g.h); u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
} else if (g.out) {
// if there was an error and we allocated an image buffer, free it!
STBI_FREE(g.out);
} }
// free buffers needed for multiple frame loading; // free buffers needed for multiple frame loading;
@ -6852,7 +6943,12 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
return 0; return 0;
if (x) *x = s->img_x; if (x) *x = s->img_x;
if (y) *y = s->img_y; if (y) *y = s->img_y;
if (comp) *comp = info.ma ? 4 : 3; if (comp) {
if (info.bpp == 24 && info.ma == 0xff000000)
*comp = 3;
else
*comp = info.ma ? 4 : 3;
}
return 1; return 1;
} }
#endif #endif
@ -7238,6 +7334,7 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
/* /*
revision history: revision history:
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
2.19 (2018-02-11) fix warning 2.19 (2018-02-11) fix warning
2.18 (2018-01-30) fix warnings 2.18 (2018-01-30) fix warnings
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug

View file

@ -1,4 +1,4 @@
/* stb_image_resize - v0.95 - public domain image resizing /* stb_image_resize - v0.96 - public domain image resizing
by Jorge L Rodriguez (@VinoBS) - 2014 by Jorge L Rodriguez (@VinoBS) - 2014
http://github.com/nothings/stb http://github.com/nothings/stb
@ -159,6 +159,7 @@
Nathan Reed: warning fixes Nathan Reed: warning fixes
REVISIONS REVISIONS
0.96 (2019-03-04) fixed warnings
0.95 (2017-07-23) fixed warnings 0.95 (2017-07-23) fixed warnings
0.94 (2017-03-18) fixed warnings 0.94 (2017-03-18) fixed warnings
0.93 (2017-03-03) fixed bug with certain combinations of heights 0.93 (2017-03-03) fixed bug with certain combinations of heights
@ -193,6 +194,7 @@ typedef uint16_t stbir_uint16;
typedef uint32_t stbir_uint32; typedef uint32_t stbir_uint32;
#endif #endif
#ifndef STBIRDEF
#ifdef STB_IMAGE_RESIZE_STATIC #ifdef STB_IMAGE_RESIZE_STATIC
#define STBIRDEF static #define STBIRDEF static
#else #else
@ -202,7 +204,7 @@ typedef uint32_t stbir_uint32;
#define STBIRDEF extern #define STBIRDEF extern
#endif #endif
#endif #endif
#endif
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
@ -2324,8 +2326,9 @@ static int stbir__resize_allocated(stbir__info *info,
if (alpha_channel < 0) if (alpha_channel < 0)
flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED; flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED;
if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) {
STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels); STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels);
}
if (alpha_channel >= info->channels) if (alpha_channel >= info->channels)
return 0; return 0;

View file

@ -1952,7 +1952,7 @@ Sys_Error(char *error, ...)
char text[4096]; // MAXPRINTMSG == 4096 char text[4096]; // MAXPRINTMSG == 4096
va_start(argptr, error); va_start(argptr, error);
vsprintf(text, error, argptr); vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr); va_end(argptr);
ri.Sys_Error(ERR_FATAL, "%s", text); ri.Sys_Error(ERR_FATAL, "%s", text);

View file

@ -1898,7 +1898,7 @@ Sys_Error(char *error, ...)
char text[4096]; // MAXPRINTMSG == 4096 char text[4096]; // MAXPRINTMSG == 4096
va_start(argptr, error); va_start(argptr, error);
vsprintf(text, error, argptr); vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr); va_end(argptr);
ri.Sys_Error(ERR_FATAL, "%s", text); ri.Sys_Error(ERR_FATAL, "%s", text);

View file

@ -413,6 +413,7 @@ R_UnRegister (void)
static void RE_ShutdownContext(void); static void RE_ShutdownContext(void);
static void SWimp_CreateRender(void); static void SWimp_CreateRender(void);
static int RE_InitContext(void *win); static int RE_InitContext(void *win);
static qboolean RE_SetMode(void);
/* /*
=============== ===============
@ -441,8 +442,18 @@ RE_Init(void)
Draw_GetPalette (); Draw_GetPalette ();
/* set our "safe" mode */
sw_state.prev_mode = 4;
/* create the window and set up the context */
if (!RE_SetMode())
{
R_Printf(PRINT_ALL, "%s() could not R_SetMode()\n", __func__);
return false;
}
// create the window // create the window
RE_BeginFrame( 0 ); ri.Vid_MenuInit();
R_Printf(PRINT_ALL, "ref_soft version: "REF_VERSION"\n"); R_Printf(PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
@ -1399,6 +1410,11 @@ static rserr_t SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen
static void static void
RE_BeginFrame( float camera_separation ) RE_BeginFrame( float camera_separation )
{ {
while (r_mode->modified || vid_fullscreen->modified || r_vsync->modified)
{
RE_SetMode();
}
/* /*
** rebuild the gamma correction palette if necessary ** rebuild the gamma correction palette if necessary
*/ */
@ -1414,53 +1430,85 @@ RE_BeginFrame( float camera_separation )
vid_gamma->modified = false; vid_gamma->modified = false;
sw_overbrightbits->modified = false; sw_overbrightbits->modified = false;
} }
}
while (r_mode->modified || vid_fullscreen->modified || r_vsync->modified) /*
==================
R_SetMode
==================
*/
static qboolean
RE_SetMode(void)
{
int err;
int fullscreen;
fullscreen = (int)vid_fullscreen->value;
vid_fullscreen->modified = false;
r_mode->modified = false;
r_vsync->modified = false;
/* a bit hackish approach to enable custom resolutions:
Glimp_SetMode needs these values set for mode -1 */
vid.width = r_customwidth->value;
vid.height = r_customheight->value;
/*
** if this returns rserr_invalid_fullscreen then it set the mode but not as a
** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
*/
if ((err = SWimp_SetMode(&vid.width, &vid.height, r_mode->value, fullscreen)) == rserr_ok)
{ {
rserr_t err; R_InitGraphics( vid.width, vid.height );
if (r_mode->value == -1) if (r_mode->value == -1)
{ {
vid.width = r_customwidth->value; sw_state.prev_mode = 4; /* safe default for custom mode */
vid.height = r_customheight->value;
}
/*
** if this returns rserr_invalid_fullscreen then it set the mode but not as a
** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
*/
if ((err = SWimp_SetMode( &vid.width, &vid.height, r_mode->value, vid_fullscreen->value)) == rserr_ok )
{
R_InitGraphics( vid.width, vid.height );
sw_state.prev_mode = r_mode->value;
vid_fullscreen->modified = false;
r_mode->modified = false;
r_vsync->modified = false;
} }
else else
{ {
if ( err == rserr_invalid_mode ) sw_state.prev_mode = r_mode->value;
{
ri.Cvar_SetValue( "r_mode", sw_state.prev_mode );
R_Printf(PRINT_ALL, "%s: could not set mode", __func__);
}
else if ( err == rserr_invalid_fullscreen )
{
R_InitGraphics( vid.width, vid.height );
ri.Cvar_SetValue( "vid_fullscreen", 0);
R_Printf(PRINT_ALL, "%s: fullscreen unavailable in this mode",
__func__);
sw_state.prev_mode = r_mode->value;
}
else
{
ri.Sys_Error(ERR_FATAL, "%s: Catastrophic mode change failure",
__func__);
}
} }
} }
else
{
if (err == rserr_invalid_fullscreen)
{
R_InitGraphics( vid.width, vid.height );
ri.Cvar_SetValue("vid_fullscreen", 0);
vid_fullscreen->modified = false;
R_Printf(PRINT_ALL, "%s() - fullscreen unavailable in this mode\n", __func__);
if ((err = SWimp_SetMode(&vid.width, &vid.height, r_mode->value, 0)) == rserr_ok)
{
return true;
}
}
else if (err == rserr_invalid_mode)
{
R_Printf(PRINT_ALL, "%s() - invalid mode\n", __func__);
if(r_mode->value == sw_state.prev_mode)
{
// trying again would result in a crash anyway, give up already
// (this would happen if your initing fails at all and your resolution already was 640x480)
return false;
}
ri.Cvar_SetValue("r_mode", sw_state.prev_mode);
r_mode->modified = false;
}
/* try setting it back to something safe */
if ((err = SWimp_SetMode(&vid.width, &vid.height, sw_state.prev_mode, 0)) != rserr_ok)
{
R_Printf(PRINT_ALL, "%s() - could not revert to safe mode\n", __func__);
return false;
}
}
return true;
} }
/* /*
@ -2247,26 +2295,22 @@ void
Sys_Error (char *error, ...) Sys_Error (char *error, ...)
{ {
va_list argptr; va_list argptr;
char text[1024]; char text[4096]; // MAXPRINTMSG == 4096
va_start (argptr, error); va_start(argptr, error);
vsprintf (text, error, argptr); vsnprintf(text, sizeof(text), error, argptr);
va_end (argptr); va_end(argptr);
ri.Sys_Error (ERR_FATAL, "%s", text); ri.Sys_Error (ERR_FATAL, "%s", text);
} }
void void
Com_Printf (char *fmt, ...) Com_Printf(char *msg, ...)
{ {
va_list argptr; va_list argptr;
char text[1024]; va_start(argptr, msg);
ri.Com_VPrintf(PRINT_ALL, msg, argptr);
va_start (argptr, fmt); va_end(argptr);
vsprintf (text, fmt, argptr);
va_end (argptr);
R_Printf(PRINT_ALL, "%s", text);
} }
/* /*

View file

@ -1,4 +1,4 @@
// Ogg Vorbis audio decoder - v1.14 - public domain // Ogg Vorbis audio decoder - v1.17 - public domain
// http://nothings.org/stb_vorbis/ // http://nothings.org/stb_vorbis/
// //
// Original version written by Sean Barrett in 2007. // Original version written by Sean Barrett in 2007.
@ -30,9 +30,12 @@
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot // Tom Beaumont Ingo Leitgeb Nicolas Guillemot
// Phillip Bennefall Rohit Thiago Goulart // Phillip Bennefall Rohit Thiago Goulart
// manxorist@github saga musix github:infatum // manxorist@github saga musix github:infatum
// Timur Gagiev // Timur Gagiev Maxwell Koo
// //
// Partial history: // Partial history:
// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
// 1.16 - 2019-03-04 - fix warnings
// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
// 1.14 - 2018-02-11 - delete bogus dealloca usage // 1.14 - 2018-02-11 - delete bogus dealloca usage
// 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) // 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
// 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files // 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
@ -253,7 +256,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
// create an ogg vorbis decoder from an open FILE *, looking for a stream at // create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell). on failure, returns NULL and sets *error. // the _current_ seek point (ftell). on failure, returns NULL and sets *error.
// note that stb_vorbis must "own" this stream; if you seek it in between // note that stb_vorbis must "own" this stream; if you seek it in between
// calls to stb_vorbis, it will become confused. Morever, if you attempt to // calls to stb_vorbis, it will become confused. Moreover, if you attempt to
// perform stb_vorbis_seek_*() operations on this file, it will assume it // perform stb_vorbis_seek_*() operations on this file, it will assume it
// owns the _entire_ rest of the file after the start point. Use the next // owns the _entire_ rest of the file after the start point. Use the next
// function, stb_vorbis_open_file_section(), to limit it. // function, stb_vorbis_open_file_section(), to limit it.
@ -374,7 +377,8 @@ enum STBVorbisError
VORBIS_invalid_first_page, VORBIS_invalid_first_page,
VORBIS_bad_packet_type, VORBIS_bad_packet_type,
VORBIS_cant_find_last_page, VORBIS_cant_find_last_page,
VORBIS_seek_failed VORBIS_seek_failed,
VORBIS_ogg_skeleton_not_supported
}; };
@ -1073,7 +1077,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
assert(z >= 0 && z < 32); assert(z >= 0 && z < 32);
available[z] = 0; available[z] = 0;
add_entry(c, bit_reverse(res), i, m++, len[i], values); add_entry(c, bit_reverse(res), i, m++, len[i], values);
// propogate availability up the tree // propagate availability up the tree
if (z != len[i]) { if (z != len[i]) {
assert(len[i] >= 0 && len[i] < 32); assert(len[i] >= 0 && len[i] < 32);
for (y=len[i]; y > z; --y) { for (y=len[i]; y > z; --y) {
@ -1199,8 +1203,10 @@ static int lookup1_values(int entries, int dim)
int r = (int) floor(exp((float) log((float) entries) / dim)); int r = (int) floor(exp((float) log((float) entries) / dim));
if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning;
++r; // floor() to avoid _ftol() when non-CRT ++r; // floor() to avoid _ftol() when non-CRT
assert(pow((float) r+1, dim) > entries); if (pow((float) r+1, dim) <= entries)
assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above return -1;
if ((int) floor(pow((float) r, dim)) > entries)
return -1;
return r; return r;
} }
@ -2010,7 +2016,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
ady -= abs(base) * adx; ady -= abs(base) * adx;
if (x1 > n) x1 = n; if (x1 > n) x1 = n;
if (x < x1) { if (x < x1) {
LINE_OP(output[x], inverse_db_table[y]); LINE_OP(output[x], inverse_db_table[y&255]);
for (++x; x < x1; ++x) { for (++x; x < x1; ++x) {
err += ady; err += ady;
if (err >= adx) { if (err >= adx) {
@ -2018,7 +2024,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
y += sy; y += sy;
} else } else
y += base; y += base;
LINE_OP(output[x], inverse_db_table[y]); LINE_OP(output[x], inverse_db_table[y&255]);
} }
} }
} }
@ -2637,7 +2643,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
// once I combined the passes. // once I combined the passes.
// so there's a missing 'times 2' here (for adding X to itself). // so there's a missing 'times 2' here (for adding X to itself).
// this propogates through linearly to the end, where the numbers // this propagates through linearly to the end, where the numbers
// are 1/2 too small, and need to be compensated for. // are 1/2 too small, and need to be compensated for.
{ {
@ -3045,7 +3051,6 @@ static float *get_window(vorb *f, int len)
len <<= 1; len <<= 1;
if (len == f->blocksize_0) return f->window[0]; if (len == f->blocksize_0) return f->window[0];
if (len == f->blocksize_1) return f->window[1]; if (len == f->blocksize_1) return f->window[1];
assert(0);
return NULL; return NULL;
} }
@ -3451,6 +3456,7 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
if (f->previous_length) { if (f->previous_length) {
int i,j, n = f->previous_length; int i,j, n = f->previous_length;
float *w = get_window(f, n); float *w = get_window(f, n);
if (w == NULL) return 0;
for (i=0; i < f->channels; ++i) { for (i=0; i < f->channels; ++i) {
for (j=0; j < n; ++j) for (j=0; j < n; ++j)
f->channel_buffers[i][left+j] = f->channel_buffers[i][left+j] =
@ -3578,7 +3584,22 @@ static int start_decoder(vorb *f)
if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page);
// check for expected packet length // check for expected packet length
if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page);
if (f->segments[0] != 30) return error(f, VORBIS_invalid_first_page); if (f->segments[0] != 30) {
// check for the Ogg skeleton fishead identifying header to refine our error
if (f->segments[0] == 64 &&
getn(f, header, 6) &&
header[0] == 'f' &&
header[1] == 'i' &&
header[2] == 's' &&
header[3] == 'h' &&
header[4] == 'e' &&
header[5] == 'a' &&
get8(f) == 'd' &&
get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported);
else
return error(f, VORBIS_invalid_first_page);
}
// read packet // read packet
// check packet header // check packet header
if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page);
@ -3677,6 +3698,7 @@ static int start_decoder(vorb *f)
while (current_entry < c->entries) { while (current_entry < c->entries) {
int limit = c->entries - current_entry; int limit = c->entries - current_entry;
int n = get_bits(f, ilog(limit)); int n = get_bits(f, ilog(limit));
if (current_length >= 32) return error(f, VORBIS_invalid_setup);
if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); }
memset(lengths + current_entry, current_length, n); memset(lengths + current_entry, current_length, n);
current_entry += n; current_entry += n;
@ -3780,7 +3802,9 @@ static int start_decoder(vorb *f)
c->value_bits = get_bits(f, 4)+1; c->value_bits = get_bits(f, 4)+1;
c->sequence_p = get_bits(f,1); c->sequence_p = get_bits(f,1);
if (c->lookup_type == 1) { if (c->lookup_type == 1) {
c->lookup_values = lookup1_values(c->entries, c->dimensions); int values = lookup1_values(c->entries, c->dimensions);
if (values < 0) return error(f, VORBIS_invalid_setup);
c->lookup_values = (uint32) values;
} else { } else {
c->lookup_values = c->entries * c->dimensions; c->lookup_values = c->entries * c->dimensions;
} }
@ -3916,6 +3940,9 @@ static int start_decoder(vorb *f)
p[j].id = j; p[j].id = j;
} }
qsort(p, g->values, sizeof(p[0]), point_compare); qsort(p, g->values, sizeof(p[0]), point_compare);
for (j=0; j < g->values-1; ++j)
if (p[j].x == p[j+1].x)
return error(f, VORBIS_invalid_setup);
for (j=0; j < g->values; ++j) for (j=0; j < g->values; ++j)
g->sorted_order[j] = (uint8) p[j].id; g->sorted_order[j] = (uint8) p[j].id;
// precompute the neighbors // precompute the neighbors
@ -4002,6 +4029,7 @@ static int start_decoder(vorb *f)
max_submaps = m->submaps; max_submaps = m->submaps;
if (get_bits(f,1)) { if (get_bits(f,1)) {
m->coupling_steps = get_bits(f,8)+1; m->coupling_steps = get_bits(f,8)+1;
if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup);
for (k=0; k < m->coupling_steps; ++k) { for (k=0; k < m->coupling_steps; ++k) {
m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
m->chan[k].angle = get_bits(f, ilog(f->channels-1)); m->chan[k].angle = get_bits(f, ilog(f->channels-1));
@ -4566,7 +4594,7 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
return 1; return 1;
} }
// rarely used function to seek back to the preceeding page while finding the // rarely used function to seek back to the preceding page while finding the
// start of a packet // start of a packet
static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset) static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset)
{ {
@ -4973,7 +5001,13 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con
stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc)
{ {
FILE *f = fopen(filename, "rb"); FILE *f;
#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
if (0 != fopen_s(&f, filename, "rb"))
f = NULL;
#else
f = fopen(filename, "rb");
#endif
if (f) if (f)
return stb_vorbis_open_file(f, TRUE, error, alloc); return stb_vorbis_open_file(f, TRUE, error, alloc);
if (error) *error = VORBIS_file_open_failure; if (error) *error = VORBIS_file_open_failure;
@ -5362,6 +5396,12 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
#endif // STB_VORBIS_NO_PULLDATA_API #endif // STB_VORBIS_NO_PULLDATA_API
/* Version history /* Version history
1.17 - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223
found with Mayhem by ForAllSecure
1.16 - 2019-03-04 - fix warnings
1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
1.14 - 2018-02-11 - delete bogus dealloca usage
1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
1.11 - 2017-07-23 - fix MinGW compilation 1.11 - 2017-07-23 - fix MinGW compilation
1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory

View file

@ -324,6 +324,11 @@ OGG_Stream(void)
void void
OGG_PlayTrack(int trackNo) OGG_PlayTrack(int trackNo)
{ {
if (sound_started == SS_NOT)
{
return; // sound is not initialized
}
// Track 0 means "stop music". // Track 0 means "stop music".
if(trackNo == 0) if(trackNo == 0)
{ {

View file

@ -1,4 +1,4 @@
/* stb_image_write - v1.08 - public domain - http://nothings.org/stb/stb_image_write.h /* stb_image_write - v1.13 - public domain - http://nothings.org/stb
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk no warranty implied; use at your own risk
@ -10,15 +10,9 @@
Will probably not work correctly with strict-aliasing optimizations. Will probably not work correctly with strict-aliasing optimizations.
If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
compilation warnings or even errors. To avoid this, also before #including,
#define STBI_MSC_SECURE_CRT
ABOUT: ABOUT:
This header file is a library for writing images to C stdio. It could be This header file is a library for writing images to C stdio or a callback.
adapted to write to memory or a general streaming interface; let me know.
The PNG output is not optimal; it is 20-50% larger than the file The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation; though providing a custom written by a decent optimizing implementation; though providing a custom
@ -38,6 +32,14 @@ BUILDING:
The returned data will be freed with STBIW_FREE() (free() by default), The returned data will be freed with STBIW_FREE() (free() by default),
so it must be heap allocated with STBIW_MALLOC() (malloc() 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: USAGE:
There are five functions, one for each image file format: There are five functions, one for each image file format:
@ -45,8 +47,8 @@ USAGE:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 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); int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data, int quality);
void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
@ -95,7 +97,7 @@ USAGE:
at the end of the line.) at the end of the line.)
PNG allows you to set the deflate compression level by setting the global PNG allows you to set the deflate compression level by setting the global
variable 'stbi_write_png_level' (it defaults to 8). variable 'stbi_write_png_compression_level' (it defaults to 8).
HDR expects linear float data. Since the format is always 32-bit rgb(e) HDR expects linear float data. Since the format is always 32-bit rgb(e)
data, alpha (if provided) is discarded, and for monochrome data it is data, alpha (if provided) is discarded, and for monochrome data it is
@ -133,6 +135,11 @@ CREDITS:
github:poppolopoppo github:poppolopoppo
Patrick Boettcher Patrick Boettcher
github:xeekworx github:xeekworx
Cap Petschulat
Simon Rodriguez
Ivan Tikhonov
github:ignotion
Adam Schackart
LICENSE LICENSE
@ -143,19 +150,26 @@ LICENSE
#ifndef INCLUDE_STB_IMAGE_WRITE_H #ifndef INCLUDE_STB_IMAGE_WRITE_H
#define INCLUDE_STB_IMAGE_WRITE_H #define INCLUDE_STB_IMAGE_WRITE_H
#ifdef __cplusplus #include <stdlib.h>
extern "C" {
#endif
// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
#ifndef STBIWDEF
#ifdef STB_IMAGE_WRITE_STATIC #ifdef STB_IMAGE_WRITE_STATIC
#define STBIWDEF static #define STBIWDEF static
#else #else
#define STBIWDEF extern #ifdef __cplusplus
#define STBIWDEF extern "C"
#else
#define STBIWDEF extern
#endif
#endif
#endif #endif
STBIWDEF int stbi_write_tga_with_rle; #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
STBIWDEF int stbi_write_png_compression_level; extern int stbi_write_tga_with_rle;
STBIWDEF int stbi_write_force_png_filter; extern int stbi_write_png_compression_level;
extern int stbi_write_force_png_filter;
#endif
#ifndef STBI_WRITE_NO_STDIO #ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
@ -163,6 +177,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_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_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); 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 #endif
typedef void stbi_write_func(void *context, void *data, int size); typedef void stbi_write_func(void *context, void *data, int size);
@ -175,10 +193,6 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
#ifdef __cplusplus
}
#endif
#endif//INCLUDE_STB_IMAGE_WRITE_H #endif//INCLUDE_STB_IMAGE_WRITE_H
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
@ -233,8 +247,8 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
#ifdef STB_IMAGE_WRITE_STATIC #ifdef STB_IMAGE_WRITE_STATIC
static stbi__flip_vertically_on_write=0; static int stbi__flip_vertically_on_write=0;
static int stbi_write_png_compression level = 8; static int stbi_write_png_compression_level = 8;
static int stbi_write_tga_with_rle = 1; static int stbi_write_tga_with_rle = 1;
static int stbi_write_force_png_filter = -1; static int stbi_write_force_png_filter = -1;
#else #else
@ -269,15 +283,52 @@ static void stbi__stdio_write(void *context, void *data, int size)
fwrite(data,1,size,(FILE*) context); 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, (int) bufferlen, NULL, NULL);
}
#endif
static FILE *stbiw__fopen(char const *filename, char const *mode)
{ {
FILE *f; FILE *f;
#ifdef STBI_MSC_SECURE_CRT #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
if (fopen_s(&f, filename, "wb")) wchar_t wMode[64];
f = NULL; 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 #else
f = Q_fopen(filename, "wb"); f = _wfopen(wFilename, wMode);
#endif #endif
#elif defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != fopen_s(&f, filename, mode))
f=0;
#else
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); stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
return f != NULL; return f != NULL;
} }
@ -337,7 +388,7 @@ static void stbiw__putc(stbi__write_context *s, unsigned char c)
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
{ {
unsigned char arr[3]; unsigned char arr[3];
arr[0] = a, arr[1] = b, arr[2] = c; arr[0] = a; arr[1] = b; arr[2] = c;
s->func(s->context, arr, 3); s->func(s->context, arr, 3);
} }
@ -385,10 +436,11 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
if (stbi__flip_vertically_on_write) if (stbi__flip_vertically_on_write)
vdir *= -1; vdir *= -1;
if (vdir < 0) if (vdir < 0) {
j_end = -1, j = y-1; j_end = -1; j = y-1;
else } else {
j_end = y, j = 0; j_end = y; j = 0;
}
for (; j != j_end; j += vdir) { for (; j != j_end; j += vdir) {
for (i=0; i < x; ++i) { for (i=0; i < x; ++i) {
@ -546,7 +598,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)) #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; int exponent;
float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
@ -563,7 +615,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); unsigned char lengthbyte = STBIW_UCHAR(length+128);
STBIW_ASSERT(length+128 <= 255); STBIW_ASSERT(length+128 <= 255);
@ -571,7 +623,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat
s->func(s->context, &databyte, 1); 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); unsigned char lengthbyte = STBIW_UCHAR(length);
STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
@ -579,7 +631,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d
s->func(s->context, data, length); 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 scanlineheader[4] = { 2, 2, 0, 0 };
unsigned char rgbe[4]; unsigned char rgbe[4];
@ -680,15 +732,15 @@ 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"; char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
s->func(s->context, header, sizeof(header)-1); s->func(s->context, header, sizeof(header)-1);
#ifdef STBI_MSC_SECURE_CRT #ifdef __STDC_WANT_SECURE_LIB__
len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#else #else
len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#endif #endif
s->func(s->context, buffer, len); s->func(s->context, buffer, len);
for(i=0; i < y; i++) 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); STBIW_FREE(scratch);
return 1; return 1;
} }
@ -803,7 +855,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
#endif // STBIW_ZLIB_COMPRESS #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 #ifdef STBIW_ZLIB_COMPRESS
// user provided a zlib compress implementation, use that // user provided a zlib compress implementation, use that
@ -816,7 +868,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
unsigned int bitbuf=0; unsigned int bitbuf=0;
int i,j, bitcount=0; int i,j, bitcount=0;
unsigned char *out = NULL; unsigned char *out = NULL;
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**)); unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
if (hash_table == NULL) if (hash_table == NULL)
return NULL; return NULL;
if (quality < 5) quality = 5; if (quality < 5) quality = 5;
@ -839,7 +891,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
for (j=0; j < n; ++j) { for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j]; if (d >= best) { best=d; bestloc=hlist[j]; }
} }
} }
// when hash table entry is too long, delete half the entries // when hash table entry is too long, delete half the entries
@ -898,8 +950,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
int blocklen = (int) (data_len % 5552); int blocklen = (int) (data_len % 5552);
j=0; j=0;
while (j < data_len) { while (j < data_len) {
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
s1 %= 65521, s2 %= 65521; s1 %= 65521; s2 %= 65521;
j += blocklen; j += blocklen;
blocklen = 5552; blocklen = 5552;
} }
@ -917,6 +969,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) 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] = static unsigned int crc_table[256] =
{ {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
@ -958,6 +1013,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len)
for (i=0; i < len; ++i) for (i=0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
return ~crc; 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) #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)
@ -987,31 +1043,35 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
int i; int i;
int type = mymap[filter_type]; int type = mymap[filter_type];
unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); 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) { for (i = 0; i < n; ++i) {
switch (type) { switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i]; break; case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break; case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
case 5: line_buffer[i] = z[i]; break; case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break; case 6: line_buffer[i] = z[i]; break;
} }
} }
for (i=n; i < width*n; ++i) { switch (type) {
switch (type) { case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
case 0: line_buffer[i] = z[i]; break; case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
case 1: line_buffer[i] = z[i] - z[i-n]; 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 2: line_buffer[i] = z[i] - z[i-stride_bytes]; 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 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); 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;
}
} }
} }
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 force_filter = stbi_write_force_png_filter;
int ctype[5] = { -1, 0, 4, 2, 6 }; int ctype[5] = { -1, 0, 4, 2, 6 };
@ -1033,11 +1093,11 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
int filter_type; int filter_type;
if (force_filter > -1) { if (force_filter > -1) {
filter_type = force_filter; 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: } else { // Estimate the best filter by running through all of them:
int best_filter = 0, best_filter_val = 0x7fffffff, est, i; int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
for (filter_type = 0; filter_type < 5; filter_type++) { 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. // Estimate the entropy of the line using this filter; the less, the better.
est = 0; est = 0;
@ -1050,7 +1110,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 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; filter_type = best_filter;
} }
} }
@ -1102,14 +1162,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
{ {
FILE *f; FILE *f;
int len; 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; if (png == NULL) return 0;
#ifdef STBI_MSC_SECURE_CRT
if (fopen_s(&f, filename, "wb")) f = stbiw__fopen(filename, "wb");
f = NULL;
#else
f = Q_fopen(filename, "wb");
#endif
if (!f) { STBIW_FREE(png); return 0; } if (!f) { STBIW_FREE(png); return 0; }
fwrite(png, 1, len, f); fwrite(png, 1, len, f);
fclose(f); fclose(f);
@ -1121,7 +1177,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) 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; 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; if (png == NULL) return 0;
func(context, png, len); func(context, png, len);
STBIW_FREE(png); STBIW_FREE(png);
@ -1416,15 +1472,13 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
for(x = 0; x < width; x += 8) { for(x = 0; x < width; x += 8) {
float YDU[64], UDU[64], VDU[64]; float YDU[64], UDU[64], VDU[64];
for(row = y, pos = 0; row < y+8; ++row) { for(row = y, pos = 0; row < y+8; ++row) {
// row >= height => use last input row
int clamped_row = (row < height) ? row : height - 1;
int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
for(col = x; col < x+8; ++col, ++pos) { 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; float r, g, b;
if(row >= height) { // if col >= width => use pixel from last input column
p -= width*comp*(row+1 - height); int p = base_p + ((col < width) ? col : (width-1))*comp;
}
if(col >= width) {
p -= comp*(col+1 - width);
}
r = imageData[p+0]; r = imageData[p+0];
g = imageData[p+ofsG]; g = imageData[p+ofsG];
@ -1476,6 +1530,12 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
#endif // STB_IMAGE_WRITE_IMPLEMENTATION #endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history /* Revision history
1.11 (2019-08-11)
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) 1.08 (2018-01-29)
add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
1.07 (2017-07-24) 1.07 (2017-07-24)

View file

@ -156,7 +156,7 @@ Sys_Error(char *error, ...)
char text[1024]; char text[1024];
va_start(argptr, error); va_start(argptr, error);
vsprintf(text, error, argptr); vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr); va_end(argptr);
gi.error("%s", text); gi.error("%s", text);
@ -169,7 +169,7 @@ Com_Printf(char *msg, ...)
char text[1024]; char text[1024];
va_start(argptr, msg); va_start(argptr, msg);
vsprintf(text, msg, argptr); vsnprintf(text, sizeof(text), msg, argptr);
va_end(argptr); va_end(argptr);
gi.dprintf("%s", text); gi.dprintf("%s", text);

View file

@ -78,7 +78,7 @@ PF_dprintf(char *fmt, ...)
va_list argptr; va_list argptr;
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
Com_Printf("%s", msg); Com_Printf("%s", msg);
@ -107,7 +107,7 @@ PF_cprintf(edict_t *ent, int level, char *fmt, ...)
} }
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
if (ent) if (ent)
@ -138,7 +138,7 @@ PF_centerprintf(edict_t *ent, char *fmt, ...)
} }
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
MSG_WriteByte(&sv.multicast, svc_centerprint); MSG_WriteByte(&sv.multicast, svc_centerprint);
@ -156,7 +156,7 @@ PF_error(char *fmt, ...)
va_list argptr; va_list argptr;
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
Com_Error(ERR_DROP, "Game Error: %s", msg); Com_Error(ERR_DROP, "Game Error: %s", msg);

View file

@ -58,7 +58,7 @@ SV_ClientPrintf(client_t *cl, int level, char *fmt, ...)
} }
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(string, fmt, argptr); vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr); va_end(argptr);
MSG_WriteByte(&cl->netchan.message, svc_print); MSG_WriteByte(&cl->netchan.message, svc_print);
@ -78,7 +78,7 @@ SV_BroadcastPrintf(int level, char *fmt, ...)
int i; int i;
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(string, fmt, argptr); vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr); va_end(argptr);
/* echo to console */ /* echo to console */
@ -130,7 +130,7 @@ SV_BroadcastCommand(char *fmt, ...)
} }
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(string, fmt, argptr); vsnprintf(string, sizeof(string), fmt, argptr);
va_end(argptr); va_end(argptr);
MSG_WriteByte(&sv.multicast, svc_stufftext); MSG_WriteByte(&sv.multicast, svc_stufftext);