Denis Pauk 2025-02-03 23:26:14 +02:00
parent 074c938c56
commit b55452f20c
3 changed files with 231 additions and 76 deletions

View file

@ -100,7 +100,7 @@ RECENT REVISION HISTORY:
Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
Phil Jordan Dave Moore Roy Eltham
Phil Jordan Henner Zeller Dave Moore Roy Eltham
Hayaki Saito Nathan Reed Won Chun
Luke Graham Johan Duparc Nick Verigakis the Horde3D community
Thomas Ruf Ronny Chevalier github:rlyeh
@ -111,7 +111,7 @@ RECENT REVISION HISTORY:
Cass Everitt Ryamond Barbiero github:grim210
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
Josh Tobin Nia Bickford Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
Brad Weinberger Matvey Cherevko github:mosra
@ -373,6 +373,15 @@ RECENT REVISION HISTORY:
#define STBI_VERSION 1
#if defined(__has_attribute)
# if __has_attribute(fallthrough)
# define STBI_FALLTHROUGH __attribute__((fallthrough));
# endif
#endif
#if !defined(STBI_FALLTHROUGH)
# define STBI_FALLTHROUGH
#endif
enum
{
STBI_default = 0, // only used for desired_channels
@ -1209,7 +1218,7 @@ static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int chan
int img_len = w * h * channels;
stbi__uint16 *enlarged;
enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
enlarged = (stbi__uint16 *) stbi__malloc(((size_t)img_len)*2);
if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
for (i = 0; i < img_len; ++i)
@ -1269,7 +1278,12 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
if (ri.bits_per_channel != 8) {
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
stbi_uc *converted = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
if (converted == NULL) {
STBI_FREE(result);
return NULL;
}
result = converted;
ri.bits_per_channel = 8;
}
@ -1295,7 +1309,12 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
if (ri.bits_per_channel != 16) {
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
stbi__uint16 * converted = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
if (converted == NULL) {
STBI_FREE(result);
return NULL;
}
result = converted;
ri.bits_per_channel = 16;
}
@ -1381,7 +1400,12 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
if (result) {
// need to 'unget' all the characters in the IO buffer
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) {
// fseek() failed; we can no longer maintain the file cursor position
// guarantee of this function, so return null.
STBI_FREE(result);
return stbi__errpuc("bad file", "fseek() failed; seek position unreliable");
}
}
return result;
}
@ -1394,7 +1418,12 @@ STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp,
result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
if (result) {
// need to 'unget' all the characters in the IO buffer
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) {
// fseek() failed; we can no longer maintain the file cursor position
// guarantee of this function, so return null.
STBI_FREE(result);
return (stbi__uint16 *) stbi__errpuc("bad file", "fseek() failed; seek position unreliable");
}
}
return result;
}
@ -1448,8 +1477,9 @@ STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int *
stbi__start_mem(&s,buffer,len);
result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
if (stbi__vertically_flip_on_load) {
stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
if (stbi__vertically_flip_on_load && result) {
int channels = req_comp ? req_comp : *comp;
stbi__vertical_flip_slices( result, *x, *y, *z, channels );
}
return result;
@ -1542,12 +1572,13 @@ STBIDEF int stbi_is_hdr (char const *filename)
STBIDEF int stbi_is_hdr_from_file(FILE *f)
{
#ifndef STBI_NO_HDR
long pos = ftell(f);
int res;
long pos = ftell(f);
if (pos < 0) return stbi__err("bad file", "ftell() failed");
stbi__context s;
stbi__start_file(&s,f);
res = stbi__hdr_test(&s);
fseek(f, pos, SEEK_SET);
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
return res;
#else
STBI_NOTUSED(f);
@ -1757,6 +1788,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
int i,j;
unsigned char *good;
if (data == NULL) return data;
if (req_comp == img_n) return data;
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
@ -1797,7 +1829,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
}
#endif
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM)
// nothing
#else
static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
@ -1806,7 +1838,7 @@ static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
}
#endif
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD)
#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM)
// nothing
#else
static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
@ -2223,8 +2255,8 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * dequant[0]);
if ((dc > SHRT_MAX) || (dequant[0] > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, (short) dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) ((size_t)dc * dequant[0]);
// decode AC components, see JPEG spec
k = 1;
@ -2280,7 +2312,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
if ((dc > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * (1 << j->succ_low));
} else {
// refinement scan for DC coefficient
@ -5556,7 +5588,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
if (info.hsz == 12) {
if (info.bpp < 24)
psize = (info.offset - info.extra_read - 24) / 3;
psize = (info.offset - info.extra_read - info.hsz) / 3;
} else {
if (info.bpp < 16)
psize = (info.offset - info.extra_read - info.hsz) >> 2;
@ -5743,7 +5775,7 @@ static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
switch(bits_per_pixel) {
case 8: return STBI_grey;
case 16: if(is_grey) return STBI_grey_alpha;
// fallthrough
STBI_FALLTHROUGH;
case 15: if(is_rgb16) *is_rgb16 = 1;
return STBI_rgb;
case 24: // fallthrough
@ -5934,7 +5966,10 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
for (i=0; i < tga_height; ++i) {
int row = tga_inverted ? tga_height -i - 1 : i;
stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
stbi__getn(s, tga_row, tga_width * tga_comp);
if(!stbi__getn(s, tga_row, tga_width * tga_comp)) {
STBI_FREE(tga_data);
return stbi__errpuc("bad palette", "Corrupt TGA");
}
}
} else {
// do I need to load a palette?
@ -6528,7 +6563,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
if (!stbi__pic_load_core(s,x,y,comp, result)) {
STBI_FREE(result);
result=0;
return 0;
}
*px = x;
*py = y;
@ -6991,9 +7026,20 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
stride = g.w * g.h * 4;
if (out) {
if (stride == 0) {
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
return ret;
}
if (!stbi__mul2sizes_valid(layers, stride)) {
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
return ret;
}
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
if (!tmp)
return stbi__load_gif_main_outofmem(&g, out, delays);
if (!tmp) {
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
if (delays && *delays) *delays = 0;
return ret;
}
else {
out = (stbi_uc*) tmp;
out_size = layers * stride;
@ -7007,9 +7053,16 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
delays_size = layers * sizeof(int);
}
} else {
if (!stbi__mul2sizes_valid(layers, stride)) {
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
return ret;
}
out = (stbi_uc*)stbi__malloc( layers * stride );
if (!out)
return stbi__load_gif_main_outofmem(&g, out, delays);
if (!out) {
void *ret = stbi__load_gif_main_outofmem(&g, out, delays);
if (delays && *delays) *delays = 0;
return ret;
}
out_size = layers * stride;
if (delays) {
*delays = (int*) stbi__malloc( layers * sizeof(int) );
@ -7020,7 +7073,7 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
}
memcpy( out + ((layers - 1) * stride), u, stride );
if (layers >= 2) {
two_back = out - 2 * stride;
two_back = out + (layers - 2) * stride;
}
if (delays) {
@ -7145,10 +7198,10 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
if (req_comp == 4) output[3] = 1;
} else {
switch (req_comp) {
case 4: output[3] = 1; /* fallthrough */
case 4: output[3] = 1; STBI_FALLTHROUGH;
case 3: output[0] = output[1] = output[2] = 0;
break;
case 2: output[1] = 1; /* fallthrough */
case 2: output[1] = 1; STBI_FALLTHROUGH;
case 1: output[0] = 0;
break;
}
@ -7219,7 +7272,10 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
for (i=0; i < width; ++i) {
stbi_uc rgbe[4];
main_decode_loop:
stbi__getn(s, rgbe, 4);
if (!stbi__getn(s, rgbe, 4)) {
STBI_FREE(hdr_data);
return stbi__errpf("invalid decoded scanline length", "corrupt HDR");
}
stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
}
}
@ -7703,9 +7759,10 @@ STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
int r;
stbi__context s;
long pos = ftell(f);
if (pos < 0) return stbi__err("bad file", "ftell() failed");
stbi__start_file(&s, f);
r = stbi__info_main(&s,x,y,comp);
fseek(f,pos,SEEK_SET);
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
return r;
}
@ -7724,9 +7781,10 @@ STBIDEF int stbi_is_16_bit_from_file(FILE *f)
int r;
stbi__context s;
long pos = ftell(f);
if (pos < 0) return stbi__err("bad file", "ftell() failed");
stbi__start_file(&s, f);
r = stbi__is_16_main(&s);
fseek(f,pos,SEEK_SET);
if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed");
return r;
}
#endif // !STBI_NO_STDIO

View file

@ -21,6 +21,7 @@
//
// Feature contributors:
// Dougall Johnson (sample-exact seeking)
// Vitaly Novichkov (sample-accurate tell)
//
// Bugfix/warning contributors:
// Terje Mathisen Niklas Frykholm Andy Hill
@ -34,6 +35,7 @@
// github:audinowho Dougall Johnson David Reid
// github:Clownacy Pedro J. Estebanez Remi Verschelde
// AnthoFoxo github:morlat Gabriel Ravier
// Seb de Graffenried Alice Rowan
//
// Partial history:
// 1.22 - 2021-07-11 - various small fixes
@ -648,6 +650,17 @@ typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
#ifdef __has_feature
#if __has_feature(undefined_behavior_sanitizer)
#define HAS_UBSAN
#endif
#endif
#ifdef HAS_UBSAN
#define STB_NO_SANITIZE(s) __attribute__((no_sanitize(s)))
#else
#define STB_NO_SANITIZE(s)
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
@ -752,11 +765,11 @@ typedef struct
typedef struct
{
uint16 coupling_steps;
MappingChannel *chan;
uint16 coupling_steps;
uint8 submaps;
uint8 submap_floor[15]; // varies
uint8 submap_residue[15]; // varies
uint8 submap_floor[16]; // varies
uint8 submap_residue[16]; // varies
} Mapping;
typedef struct
@ -898,6 +911,12 @@ struct stb_vorbis
// sample-access
int channel_buffer_start;
int channel_buffer_end;
// temporary buffers
void *temp_lengths;
void *temp_codewords;
void *temp_values;
void *temp_mults;
};
#if defined(STB_VORBIS_NO_PUSHDATA_API)
@ -949,9 +968,12 @@ static void *make_block_array(void *mem, int count, int size)
static void *setup_malloc(vorb *f, int sz)
{
if (INT_MAX - 7 < sz) return NULL;
if (sz < 0) return NULL;
sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
f->setup_memory_required += sz;
if (f->alloc.alloc_buffer) {
if (sz == 0) return NULL;
void *p = (char *) f->alloc.alloc_buffer + f->setup_offset;
if (f->setup_offset + sz > f->temp_offset) return NULL;
f->setup_offset += sz;
@ -977,8 +999,10 @@ static void *setup_temp_malloc(vorb *f, int sz)
return malloc(sz);
}
static void setup_temp_free(vorb *f, void *p, int sz)
static void setup_temp_free(vorb *f, void **_p, int sz)
{
void *p = *_p;
*_p = NULL;
if (f->alloc.alloc_buffer) {
f->temp_offset += (sz+7)&~7;
return;
@ -1238,6 +1262,10 @@ static int vorbis_validate(uint8 *data)
// called from setup only, once per code book
// (formula implied by specification)
//
// suppress an UBSan error caused by invalid input data.
// upstream: https://github.com/nothings/stb/issues/1168.
STB_NO_SANITIZE("float-cast-overflow")
static int lookup1_values(int entries, int dim)
{
int r = (int) floor(exp((float) log((float) entries) / dim));
@ -1583,8 +1611,8 @@ static int get32_packet(vorb *f)
{
uint32 x;
x = get8_packet(f);
x += get8_packet(f) << 8;
x += get8_packet(f) << 16;
x += (uint32) get8_packet(f) << 8;
x += (uint32) get8_packet(f) << 16;
x += (uint32) get8_packet(f) << 24;
return x;
}
@ -1696,7 +1724,7 @@ static int codebook_decode_scalar_raw(vorb *f, Codebook *c)
assert(!c->sparse);
for (i=0; i < c->entries; ++i) {
if (c->codeword_lengths[i] == NO_CODE) continue;
if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i])-1))) {
if (c->codewords[i] == (f->acc & ((1U << c->codeword_lengths[i])-1))) {
if (f->valid_bits >= c->codeword_lengths[i]) {
f->acc >>= c->codeword_lengths[i];
f->valid_bits -= c->codeword_lengths[i];
@ -1753,7 +1781,7 @@ static int codebook_decode_scalar(vorb *f, Codebook *c)
#define DECODE(var,f,c) \
DECODE_RAW(var,f,c) \
if (c->sparse) var = c->sorted_values[var];
if (c->sparse && var >= 0) var = c->sorted_values[var];
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
#define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c)
@ -1888,7 +1916,7 @@ static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **out
// buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter),
// and the length we'll be using (effective)
if (c_inter + p_inter*ch + effective > len * ch) {
effective = len*ch - (p_inter*ch - c_inter);
effective = len*ch - (p_inter*ch + c_inter);
}
#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK
@ -2067,7 +2095,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
ady -= abs(base) * adx;
if (x1 > n) x1 = n;
if (x < x1) {
LINE_OP(output[x], inverse_db_table[y&255]);
LINE_OP(output[x], inverse_db_table[(uint32)y&255]);
for (++x; x < x1; ++x) {
err += ady;
if (err >= adx) {
@ -2075,7 +2103,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
y += sy;
} else
y += base;
LINE_OP(output[x], inverse_db_table[y&255]);
LINE_OP(output[x], inverse_db_table[(uint32)y&255]);
}
}
}
@ -3058,7 +3086,7 @@ void inverse_mdct_naive(float *buffer, int n)
static float *get_window(vorb *f, int len)
{
len <<= 1;
len = (unsigned int)len << 1;
if (len == f->blocksize_0) return f->window[0];
if (len == f->blocksize_1) return f->window[1];
return NULL;
@ -3650,7 +3678,7 @@ static int start_decoder(vorb *f)
if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
//file vendor
len = get32_packet(f);
f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1));
f->vendor = (INT_MAX == len) ? NULL : (char*)setup_malloc(f, sizeof(char) * (len+1));
if (f->vendor == NULL) return error(f, VORBIS_outofmem);
for(i=0; i < len; ++i) {
f->vendor[i] = get8_packet(f);
@ -3661,14 +3689,25 @@ static int start_decoder(vorb *f)
f->comment_list = NULL;
if (f->comment_list_length > 0)
{
if (INT_MAX / sizeof(char*) < f->comment_list_length) {
f->comment_list_length = 0;
return error(f, VORBIS_outofmem);
}
f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length));
if (f->comment_list == NULL) return error(f, VORBIS_outofmem);
if (f->comment_list == NULL)
{
f->comment_list_length = 0;
return error(f, VORBIS_outofmem);
}
memset(f->comment_list, 0, sizeof(char*) * f->comment_list_length);
}
for(i=0; i < f->comment_list_length; ++i) {
len = get32_packet(f);
f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1));
if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem);
f->comment_list[i] = (INT_MAX == len) ? NULL : (char*)setup_malloc(f, sizeof(char) * (len+1));
if (f->comment_list[i] == NULL) {
return error(f, VORBIS_outofmem);
}
for(j=0; j < len; ++j) {
f->comment_list[i][j] = get8_packet(f);
@ -3713,6 +3752,7 @@ static int start_decoder(vorb *f)
// codebooks
f->codebook_count = get_bits(f,8) + 1;
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count);
if (f->codebooks == NULL) return error(f, VORBIS_outofmem);
memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count);
@ -3735,10 +3775,12 @@ static int start_decoder(vorb *f)
c->sparse = ordered ? 0 : get_bits(f,1);
if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup);
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (c->sparse)
if (c->sparse) {
lengths = (uint8 *) setup_temp_malloc(f, c->entries);
else
f->temp_lengths = lengths;
} else
lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
if (!lengths) return error(f, VORBIS_outofmem);
@ -3749,8 +3791,9 @@ static int start_decoder(vorb *f)
while (current_entry < c->entries) {
int limit = c->entries - current_entry;
int n = get_bits(f, ilog(limit));
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
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);
current_entry += n;
++current_length;
@ -3758,11 +3801,14 @@ static int start_decoder(vorb *f)
} else {
for (j=0; j < c->entries; ++j) {
int present = c->sparse ? get_bits(f,1) : 1;
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (present) {
lengths[j] = get_bits(f, 5) + 1;
++total;
if (lengths[j] == 32)
return error(f, VORBIS_invalid_setup);
if (lengths[j] == 32) {
if (c->sparse) setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_invalid_setup);
}
} else {
lengths[j] = NO_CODE;
}
@ -3775,9 +3821,12 @@ static int start_decoder(vorb *f)
f->setup_temp_memory_required = c->entries;
c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem);
if (c->codeword_lengths == NULL) {
setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
memcpy(c->codeword_lengths, lengths, c->entries);
setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs!
setup_temp_free(f, &f->temp_lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs!
lengths = c->codeword_lengths;
c->sparse = 0;
}
@ -3805,11 +3854,22 @@ static int start_decoder(vorb *f)
unsigned int size;
if (c->sorted_entries) {
c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries);
if (!c->codeword_lengths) return error(f, VORBIS_outofmem);
if (!c->codeword_lengths) {
setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries);
if (!c->codewords) return error(f, VORBIS_outofmem);
f->temp_codewords = c->codewords;
if (!c->codewords) {
setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries);
if (!values) return error(f, VORBIS_outofmem);
f->temp_values = values;
if (!values) {
setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
}
size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries;
if (size > f->setup_temp_memory_required)
@ -3817,27 +3877,32 @@ static int start_decoder(vorb *f)
}
if (!compute_codewords(c, lengths, c->entries, values)) {
if (c->sparse) setup_temp_free(f, values, 0);
return error(f, VORBIS_invalid_setup);
}
if (c->sorted_entries) {
// allocate an extra slot for sentinels
c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1));
if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem);
if (c->sorted_codewords == NULL) {
if (c->sparse) setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
// allocate an extra slot at the front so that c->sorted_values[-1] is defined
// so that we can catch that case without an extra if
c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1));
if (c->sorted_values == NULL) return error(f, VORBIS_outofmem);
if (c->sorted_values == NULL) {
if (c->sparse) setup_temp_free(f, &f->temp_lengths, c->entries);
return error(f, VORBIS_outofmem);
}
++c->sorted_values;
c->sorted_values[-1] = -1;
compute_sorted_huffman(c, lengths, values);
}
if (c->sparse) {
setup_temp_free(f, values, sizeof(*values)*c->sorted_entries);
setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries);
setup_temp_free(f, lengths, c->entries);
setup_temp_free(f, &f->temp_values, sizeof(*values)*c->sorted_entries);
setup_temp_free(f, &f->temp_codewords, sizeof(*c->codewords)*c->sorted_entries);
setup_temp_free(f, &f->temp_lengths, c->entries);
c->codewords = NULL;
}
@ -3857,14 +3922,22 @@ static int start_decoder(vorb *f)
if (values < 0) return error(f, VORBIS_invalid_setup);
c->lookup_values = (uint32) values;
} else {
/* If this overflows, the file's not valid.
* See https://github.com/nothings/stb/issues/1168. */
if (c->entries != 0 && c->dimensions > INT_MAX / c->entries) return error(f, VORBIS_invalid_setup);
c->lookup_values = c->entries * c->dimensions;
}
if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup);
// Before we allocate the lookup table, verify that it can be read
// from the file. Otherwise, c->lookup_values can be arbitrarily
// large, and we run out of memory.
if (c->lookup_values > (8 * f->stream_len) / c->value_bits) return error(f, VORBIS_invalid_setup);
mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values);
f->temp_mults = mults;
if (mults == NULL) return error(f, VORBIS_outofmem);
for (j=0; j < (int) c->lookup_values; ++j) {
int q = get_bits(f, c->value_bits);
if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); }
if (f->valid_bits < 0) return error(f, VORBIS_invalid_setup);
mults[j] = q;
}
@ -3878,7 +3951,7 @@ static int start_decoder(vorb *f)
c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
} else
c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions);
if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); }
if (c->multiplicands == NULL) return error(f, VORBIS_outofmem);
len = sparse ? c->sorted_entries : c->entries;
for (j=0; j < len; ++j) {
unsigned int z = sparse ? c->sorted_values[j] : j;
@ -3891,7 +3964,6 @@ static int start_decoder(vorb *f)
last = val;
if (k+1 < c->dimensions) {
if (div > UINT_MAX / (unsigned int) c->lookup_values) {
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
return error(f, VORBIS_invalid_setup);
}
div *= c->lookup_values;
@ -3906,7 +3978,7 @@ static int start_decoder(vorb *f)
float last=0;
CHECK(f);
c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values);
if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); }
if (c->multiplicands == NULL) return error(f, VORBIS_outofmem);
for (j=0; j < (int) c->lookup_values; ++j) {
float val = mults[j] * c->delta_value + c->minimum_value + last;
c->multiplicands[j] = val;
@ -3917,7 +3989,7 @@ static int start_decoder(vorb *f)
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
skip:;
#endif
setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values);
setup_temp_free(f, &f->temp_mults, sizeof(mults[0])*c->lookup_values);
CHECK(f);
}
@ -3934,6 +4006,7 @@ static int start_decoder(vorb *f)
// Floors
f->floor_count = get_bits(f, 6)+1;
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config));
if (f->floor_config == NULL) return error(f, VORBIS_outofmem);
for (i=0; i < f->floor_count; ++i) {
@ -3963,6 +4036,7 @@ static int start_decoder(vorb *f)
for (j=0; j <= max_class; ++j) {
g->class_dimensions[j] = get_bits(f, 3)+1;
g->class_subclasses[j] = get_bits(f, 2);
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (g->class_subclasses[j]) {
g->class_masterbooks[j] = get_bits(f, 8);
if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
@ -4010,6 +4084,7 @@ static int start_decoder(vorb *f)
// Residue
f->residue_count = get_bits(f, 6)+1;
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0]));
if (f->residue_config == NULL) return error(f, VORBIS_outofmem);
memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0]));
@ -4024,6 +4099,7 @@ static int start_decoder(vorb *f)
r->part_size = get_bits(f,24)+1;
r->classifications = get_bits(f,6)+1;
r->classbook = get_bits(f,8);
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup);
for (j=0; j < r->classifications; ++j) {
uint8 high_bits=0;
@ -4032,12 +4108,14 @@ static int start_decoder(vorb *f)
high_bits = get_bits(f,5);
residue_cascade[j] = high_bits*8 + low_bits;
}
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications);
if (r->residue_books == NULL) return error(f, VORBIS_outofmem);
for (j=0; j < r->classifications; ++j) {
for (k=0; k < 8; ++k) {
if (residue_cascade[j] & (1 << k)) {
r->residue_books[j][k] = get_bits(f, 8);
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
} else {
r->residue_books[j][k] = -1;
@ -4062,6 +4140,7 @@ static int start_decoder(vorb *f)
}
f->mapping_count = get_bits(f,6)+1;
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping));
if (f->mapping == NULL) return error(f, VORBIS_outofmem);
memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping));
@ -4083,6 +4162,7 @@ static int start_decoder(vorb *f)
for (k=0; k < m->coupling_steps; ++k) {
m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
m->chan[k].angle = get_bits(f, ilog(f->channels-1));
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup);
if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup);
if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup);
@ -4119,6 +4199,7 @@ static int start_decoder(vorb *f)
m->windowtype = get_bits(f,16);
m->transformtype = get_bits(f,16);
m->mapping = get_bits(f,8);
if (f->valid_bits < 0) return error(f, VORBIS_unexpected_eof);
if (m->windowtype != 0) return error(f, VORBIS_invalid_setup);
if (m->transformtype != 0) return error(f, VORBIS_invalid_setup);
if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup);
@ -4161,7 +4242,8 @@ static int start_decoder(vorb *f)
int i,max_part_read=0;
for (i=0; i < f->residue_count; ++i) {
Residue *r = f->residue_config + i;
unsigned int actual_size = f->blocksize_1 / 2;
unsigned int rtype = f->residue_types[i];
unsigned int actual_size = rtype == 2 ? f->blocksize_1 : f->blocksize_1 / 2;
unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size;
unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size;
int n_read = limit_r_end - limit_r_begin;
@ -4233,7 +4315,8 @@ static void vorbis_deinit(stb_vorbis *p)
Codebook *c = p->codebooks + i;
setup_free(p, c->codeword_lengths);
setup_free(p, c->multiplicands);
setup_free(p, c->codewords);
if (c->codewords != p->temp_codewords) // Might be the temporary buffer-allocated array.
setup_free(p, c->codewords);
setup_free(p, c->sorted_codewords);
// c->sorted_values[-1] is the first entry in the array
setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL);
@ -4263,6 +4346,12 @@ static void vorbis_deinit(stb_vorbis *p)
setup_free(p, p->window[i]);
setup_free(p, p->bit_reverse[i]);
}
if (!p->alloc.alloc_buffer) {
setup_temp_free(p, &p->temp_lengths, 0);
setup_temp_free(p, &p->temp_codewords, 0);
setup_temp_free(p, &p->temp_values, 0);
setup_temp_free(p, &p->temp_mults, 0);
}
#ifndef STB_VORBIS_NO_STDIO
if (p->close_on_free) fclose(p->f);
#endif
@ -4649,10 +4738,12 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
z->page_start = stb_vorbis_get_file_offset(f);
// parse the header
getn(f, header, 27);
if (!getn(f, header, 27))
return 0;
if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S')
return 0;
getn(f, lacing, header[26]);
if (!getn(f, lacing, header[26]))
return 0;
// determine the length of the payload
len = 0;
@ -5147,7 +5238,9 @@ static int8 channel_position[7][6] =
#ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT
typedef union {
float f;
int i;
// changed this to unsigned to suppress an UBSan error.
// upstream: https://github.com/nothings/stb/issues/1168.
unsigned int i;
} float_conv;
typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4];
#define FASTDEF(x) float_conv x
@ -5169,7 +5262,7 @@ static void copy_samples(short *dest, float *src, int len)
for (i=0; i < len; ++i) {
FASTDEF(temp);
int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15);
if ((unsigned int) (v + 32768) > 65535)
if (((unsigned int)v + 32768) > 65535)
v = v < 0 ? -32768 : 32767;
dest[i] = v;
}
@ -5193,7 +5286,7 @@ static void compute_samples(int mask, short *output, int num_c, float **data, in
for (i=0; i < n; ++i) {
FASTDEF(temp);
int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15);
if ((unsigned int) (v + 32768) > 65535)
if (((unsigned int)v + 32768) > 65535)
v = v < 0 ? -32768 : 32767;
output[o+i] = v;
}
@ -5233,7 +5326,7 @@ static void compute_stereo_samples(short *output, int num_c, float **data, int d
for (i=0; i < (n<<1); ++i) {
FASTDEF(temp);
int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15);
if ((unsigned int) (v + 32768) > 65535)
if (((unsigned int)v + 32768) > 65535)
v = v < 0 ? -32768 : 32767;
output[o2+i] = v;
}
@ -5283,7 +5376,7 @@ static void convert_channels_short_interleaved(int buf_c, short *buffer, int dat
FASTDEF(temp);
float f = data[i][d_offset+j];
int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15);
if ((unsigned int) (v + 32768) > 65535)
if (((unsigned int)v + 32768) > 65535)
v = v < 0 ? -32768 : 32767;
*buffer++ = v;
}

View file

@ -765,6 +765,8 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
else {
// Each component is stored separately. Allocate scratch space for full output scanline.
unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
if (NULL == scratch)
return 0;
int i, len;
char buffer[128];
char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
@ -772,6 +774,8 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
#ifdef __STDC_LIB_EXT1__
len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
len = snprintf(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);
#endif