|
|
|
@ -573,6 +573,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch |
|
|
|
|
#include <stddef.h> // ptrdiff_t on osx |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <limits.h> |
|
|
|
|
|
|
|
|
|
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) |
|
|
|
|
#include <math.h> // ldexp |
|
|
|
@ -920,6 +921,77 @@ static void *stbi__malloc(size_t size) |
|
|
|
|
return STBI_MALLOC(size); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// stb_image uses ints pervasively, including for offset calculations.
|
|
|
|
|
// therefore the largest decoded image size we can support with the
|
|
|
|
|
// current code, even on 64-bit targets, is INT_MAX. this is not a
|
|
|
|
|
// significant limitation for the intended use case.
|
|
|
|
|
//
|
|
|
|
|
// we do, however, need to make sure our size calculations don't
|
|
|
|
|
// overflow. hence a few helper functions for size calculations that
|
|
|
|
|
// multiply integers together, making sure that they're non-negative
|
|
|
|
|
// and no overflow occurs.
|
|
|
|
|
|
|
|
|
|
// return 1 if the sum is valid, 0 on overflow.
|
|
|
|
|
// negative terms are considered invalid.
|
|
|
|
|
static int stbi__addsizes_valid(int a, int b) |
|
|
|
|
{ |
|
|
|
|
if (b < 0) return 0; |
|
|
|
|
// now 0 <= b <= INT_MAX, hence also
|
|
|
|
|
// 0 <= INT_MAX - b <= INTMAX.
|
|
|
|
|
// And "a + b <= INT_MAX" (which might overflow) is the
|
|
|
|
|
// same as a <= INT_MAX - b (no overflow)
|
|
|
|
|
return a <= INT_MAX - b; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// returns 1 if the product is valid, 0 on overflow.
|
|
|
|
|
// negative factors are considered invalid.
|
|
|
|
|
static int stbi__mul2sizes_valid(int a, int b) |
|
|
|
|
{ |
|
|
|
|
if (a < 0 || b < 0) return 0; |
|
|
|
|
if (b == 0) return 1; // mul-by-0 is always safe
|
|
|
|
|
// portable way to check for no overflows in a*b
|
|
|
|
|
return a <= INT_MAX/b; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
|
|
|
|
|
static int stbi__mad2sizes_valid(int a, int b, int add) |
|
|
|
|
{ |
|
|
|
|
return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
|
|
|
|
|
static int stbi__mad3sizes_valid(int a, int b, int c, int add) |
|
|
|
|
{ |
|
|
|
|
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && |
|
|
|
|
stbi__addsizes_valid(a*b*c, add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
|
|
|
|
|
static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) |
|
|
|
|
{ |
|
|
|
|
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && |
|
|
|
|
stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// mallocs with size overflow checking
|
|
|
|
|
static void *stbi__malloc_mad2(int a, int b, int add) |
|
|
|
|
{ |
|
|
|
|
if (!stbi__mad2sizes_valid(a, b, add)) return NULL; |
|
|
|
|
return stbi__malloc(a*b + add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *stbi__malloc_mad3(int a, int b, int c, int add) |
|
|
|
|
{ |
|
|
|
|
if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; |
|
|
|
|
return stbi__malloc(a*b*c + add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) |
|
|
|
|
{ |
|
|
|
|
if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; |
|
|
|
|
return stbi__malloc(a*b*c*d + add); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// stbi__err - error
|
|
|
|
|
// stbi__errpf - error returning pointer to float
|
|
|
|
|
// stbi__errpuc - error returning pointer to unsigned char
|
|
|
|
@ -1020,16 +1092,16 @@ static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int chan |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
int img_len = w * h * channels; |
|
|
|
|
stbi__uint16 *reduced; |
|
|
|
|
stbi__uint16 *enlarged; |
|
|
|
|
|
|
|
|
|
reduced = (stbi__uint16 *) stbi__malloc(img_len*2); |
|
|
|
|
if (reduced == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); |
|
|
|
|
if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < img_len; ++i) |
|
|
|
|
reduced[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
|
|
|
|
|
enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
|
|
|
|
|
|
|
|
|
|
STBI_FREE(orig); |
|
|
|
|
return reduced; |
|
|
|
|
return enlarged; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) |
|
|
|
@ -1479,7 +1551,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r |
|
|
|
|
if (req_comp == img_n) return data; |
|
|
|
|
STBI_ASSERT(req_comp >= 1 && req_comp <= 4); |
|
|
|
|
|
|
|
|
|
good = (unsigned char *) stbi__malloc(req_comp * x * y); |
|
|
|
|
good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); |
|
|
|
|
if (good == NULL) { |
|
|
|
|
STBI_FREE(data); |
|
|
|
|
return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
@ -1568,7 +1640,9 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r |
|
|
|
|
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) |
|
|
|
|
{ |
|
|
|
|
int i,k,n; |
|
|
|
|
float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); |
|
|
|
|
float *output; |
|
|
|
|
if (!data) return NULL; |
|
|
|
|
output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); |
|
|
|
|
if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } |
|
|
|
|
// compute number of non-alpha components
|
|
|
|
|
if (comp & 1) n = comp; else n = comp-1; |
|
|
|
@ -1588,7 +1662,9 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) |
|
|
|
|
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) |
|
|
|
|
{ |
|
|
|
|
int i,k,n; |
|
|
|
|
stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); |
|
|
|
|
stbi_uc *output; |
|
|
|
|
if (!data) return NULL; |
|
|
|
|
output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); |
|
|
|
|
if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } |
|
|
|
|
// compute number of non-alpha components
|
|
|
|
|
if (comp & 1) n = comp; else n = comp-1; |
|
|
|
@ -2883,6 +2959,28 @@ static int stbi__process_scan_header(stbi__jpeg *z) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
for (i=0; i < ncomp; ++i) { |
|
|
|
|
if (z->img_comp[i].raw_data) { |
|
|
|
|
STBI_FREE(z->img_comp[i].raw_data); |
|
|
|
|
z->img_comp[i].raw_data = NULL; |
|
|
|
|
z->img_comp[i].data = NULL; |
|
|
|
|
} |
|
|
|
|
if (z->img_comp[i].raw_coeff) { |
|
|
|
|
STBI_FREE(z->img_comp[i].raw_coeff); |
|
|
|
|
z->img_comp[i].raw_coeff = 0; |
|
|
|
|
z->img_comp[i].coeff = 0; |
|
|
|
|
} |
|
|
|
|
if (z->img_comp[i].linebuf) { |
|
|
|
|
STBI_FREE(z->img_comp[i].linebuf); |
|
|
|
|
z->img_comp[i].linebuf = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return why; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int stbi__process_frame_header(stbi__jpeg *z, int scan) |
|
|
|
|
{ |
|
|
|
|
stbi__context *s = z->s; |
|
|
|
@ -2920,7 +3018,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) |
|
|
|
|
|
|
|
|
|
if (scan != STBI__SCAN_load) return 1; |
|
|
|
|
|
|
|
|
|
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); |
|
|
|
|
if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); |
|
|
|
|
|
|
|
|
|
for (i=0; i < s->img_n; ++i) { |
|
|
|
|
if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; |
|
|
|
@ -2932,6 +3030,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) |
|
|
|
|
z->img_v_max = v_max; |
|
|
|
|
z->img_mcu_w = h_max * 8; |
|
|
|
|
z->img_mcu_h = v_max * 8; |
|
|
|
|
// these sizes can't be more than 17 bits
|
|
|
|
|
z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; |
|
|
|
|
z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; |
|
|
|
|
|
|
|
|
@ -2943,28 +3042,27 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) |
|
|
|
|
// the bogus oversized data from using interleaved MCUs and their
|
|
|
|
|
// big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
|
|
|
|
|
// discard the extra data until colorspace conversion
|
|
|
|
|
//
|
|
|
|
|
// img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
|
|
|
|
|
// so these muls can't overflow with 32-bit ints (which we require)
|
|
|
|
|
z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; |
|
|
|
|
z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; |
|
|
|
|
z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); |
|
|
|
|
|
|
|
|
|
if (z->img_comp[i].raw_data == NULL) { |
|
|
|
|
for(--i; i >= 0; --i) { |
|
|
|
|
STBI_FREE(z->img_comp[i].raw_data); |
|
|
|
|
z->img_comp[i].raw_data = NULL; |
|
|
|
|
} |
|
|
|
|
return stbi__err("outofmem", "Out of memory"); |
|
|
|
|
} |
|
|
|
|
z->img_comp[i].coeff = 0; |
|
|
|
|
z->img_comp[i].raw_coeff = 0; |
|
|
|
|
z->img_comp[i].linebuf = NULL; |
|
|
|
|
z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); |
|
|
|
|
if (z->img_comp[i].raw_data == NULL) |
|
|
|
|
return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); |
|
|
|
|
// align blocks for idct using mmx/sse
|
|
|
|
|
z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); |
|
|
|
|
z->img_comp[i].linebuf = NULL; |
|
|
|
|
if (z->progressive) { |
|
|
|
|
z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; |
|
|
|
|
z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; |
|
|
|
|
z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); |
|
|
|
|
// w2, h2 are multiples of 8 (see above)
|
|
|
|
|
z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; |
|
|
|
|
z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; |
|
|
|
|
z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); |
|
|
|
|
if (z->img_comp[i].raw_coeff == NULL) |
|
|
|
|
return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); |
|
|
|
|
z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); |
|
|
|
|
} else { |
|
|
|
|
z->img_comp[i].coeff = 0; |
|
|
|
|
z->img_comp[i].raw_coeff = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3470,23 +3568,7 @@ static void stbi__setup_jpeg(stbi__jpeg *j) |
|
|
|
|
// clean up the temporary component buffers
|
|
|
|
|
static void stbi__cleanup_jpeg(stbi__jpeg *j) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
for (i=0; i < j->s->img_n; ++i) { |
|
|
|
|
if (j->img_comp[i].raw_data) { |
|
|
|
|
STBI_FREE(j->img_comp[i].raw_data); |
|
|
|
|
j->img_comp[i].raw_data = NULL; |
|
|
|
|
j->img_comp[i].data = NULL; |
|
|
|
|
} |
|
|
|
|
if (j->img_comp[i].raw_coeff) { |
|
|
|
|
STBI_FREE(j->img_comp[i].raw_coeff); |
|
|
|
|
j->img_comp[i].raw_coeff = 0; |
|
|
|
|
j->img_comp[i].coeff = 0; |
|
|
|
|
} |
|
|
|
|
if (j->img_comp[i].linebuf) { |
|
|
|
|
STBI_FREE(j->img_comp[i].linebuf); |
|
|
|
|
j->img_comp[i].linebuf = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
stbi__free_jpeg_components(j, j->s->img_n, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct |
|
|
|
@ -3550,7 +3632,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// can't error after this so, this is safe
|
|
|
|
|
output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); |
|
|
|
|
output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); |
|
|
|
|
if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } |
|
|
|
|
|
|
|
|
|
// now go ahead and resample
|
|
|
|
@ -3903,6 +3985,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) |
|
|
|
|
int hlit = stbi__zreceive(a,5) + 257; |
|
|
|
|
int hdist = stbi__zreceive(a,5) + 1; |
|
|
|
|
int hclen = stbi__zreceive(a,4) + 4; |
|
|
|
|
int ntot = hlit + hdist; |
|
|
|
|
|
|
|
|
|
memset(codelength_sizes, 0, sizeof(codelength_sizes)); |
|
|
|
|
for (i=0; i < hclen; ++i) { |
|
|
|
@ -3912,27 +3995,29 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) |
|
|
|
|
if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; |
|
|
|
|
|
|
|
|
|
n = 0; |
|
|
|
|
while (n < hlit + hdist) { |
|
|
|
|
while (n < ntot) { |
|
|
|
|
int c = stbi__zhuffman_decode(a, &z_codelength); |
|
|
|
|
if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); |
|
|
|
|
if (c < 16) |
|
|
|
|
lencodes[n++] = (stbi_uc) c; |
|
|
|
|
else if (c == 16) { |
|
|
|
|
c = stbi__zreceive(a,2)+3; |
|
|
|
|
memset(lencodes+n, lencodes[n-1], c); |
|
|
|
|
n += c; |
|
|
|
|
} else if (c == 17) { |
|
|
|
|
c = stbi__zreceive(a,3)+3; |
|
|
|
|
memset(lencodes+n, 0, c); |
|
|
|
|
n += c; |
|
|
|
|
} else { |
|
|
|
|
STBI_ASSERT(c == 18); |
|
|
|
|
c = stbi__zreceive(a,7)+11; |
|
|
|
|
memset(lencodes+n, 0, c); |
|
|
|
|
else { |
|
|
|
|
stbi_uc fill = 0; |
|
|
|
|
if (c == 16) { |
|
|
|
|
c = stbi__zreceive(a,2)+3; |
|
|
|
|
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); |
|
|
|
|
fill = lencodes[n-1]; |
|
|
|
|
} else if (c == 17) |
|
|
|
|
c = stbi__zreceive(a,3)+3; |
|
|
|
|
else { |
|
|
|
|
STBI_ASSERT(c == 18); |
|
|
|
|
c = stbi__zreceive(a,7)+11; |
|
|
|
|
} |
|
|
|
|
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); |
|
|
|
|
memset(lencodes+n, fill, c); |
|
|
|
|
n += c; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); |
|
|
|
|
if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); |
|
|
|
|
if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; |
|
|
|
|
if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; |
|
|
|
|
return 1; |
|
|
|
@ -4198,7 +4283,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r |
|
|
|
|
int width = x; |
|
|
|
|
|
|
|
|
|
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); |
|
|
|
|
a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into
|
|
|
|
|
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
|
|
|
|
|
if (!a->out) return stbi__err("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3); |
|
|
|
@ -4396,13 +4481,15 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r |
|
|
|
|
|
|
|
|
|
static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) |
|
|
|
|
{ |
|
|
|
|
int bytes = (depth == 16 ? 2 : 1); |
|
|
|
|
int out_bytes = out_n * bytes; |
|
|
|
|
stbi_uc *final; |
|
|
|
|
int p; |
|
|
|
|
if (!interlaced) |
|
|
|
|
return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); |
|
|
|
|
|
|
|
|
|
// de-interlacing
|
|
|
|
|
final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); |
|
|
|
|
final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); |
|
|
|
|
for (p=0; p < 7; ++p) { |
|
|
|
|
int xorig[] = { 0,4,0,2,0,1,0 }; |
|
|
|
|
int yorig[] = { 0,0,4,0,2,0,1 }; |
|
|
|
@ -4422,8 +4509,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3 |
|
|
|
|
for (i=0; i < x; ++i) { |
|
|
|
|
int out_y = j*yspc[p]+yorig[p]; |
|
|
|
|
int out_x = i*xspc[p]+xorig[p]; |
|
|
|
|
memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, |
|
|
|
|
a->out + (j*x+i)*out_n, out_n); |
|
|
|
|
memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, |
|
|
|
|
a->out + (j*x+i)*out_bytes, out_bytes); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
STBI_FREE(a->out); |
|
|
|
@ -4491,7 +4578,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int |
|
|
|
|
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; |
|
|
|
|
stbi_uc *p, *temp_out, *orig = a->out; |
|
|
|
|
|
|
|
|
|
p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); |
|
|
|
|
p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); |
|
|
|
|
if (p == NULL) return stbi__err("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
// between here and free(out) below, exitting would leak
|
|
|
|
@ -5005,7 +5092,11 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
else |
|
|
|
|
target = s->img_n; // if they want monochrome, we'll post-convert
|
|
|
|
|
|
|
|
|
|
out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); |
|
|
|
|
// sanity-check size
|
|
|
|
|
if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) |
|
|
|
|
return stbi__errpuc("too large", "Corrupt BMP"); |
|
|
|
|
|
|
|
|
|
out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); |
|
|
|
|
if (!out) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
if (info.bpp < 16) { |
|
|
|
|
int z=0; |
|
|
|
@ -5306,7 +5397,10 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
*y = tga_height; |
|
|
|
|
if (comp) *comp = tga_comp; |
|
|
|
|
|
|
|
|
|
tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); |
|
|
|
|
if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) |
|
|
|
|
return stbi__errpuc("too large", "Corrupt TGA"); |
|
|
|
|
|
|
|
|
|
tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); |
|
|
|
|
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
// skip to the data's starting position (offset usually = 0)
|
|
|
|
@ -5325,7 +5419,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
// any data to skip? (offset usually = 0)
|
|
|
|
|
stbi__skip(s, tga_palette_start ); |
|
|
|
|
// load the palette
|
|
|
|
|
tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); |
|
|
|
|
tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); |
|
|
|
|
if (!tga_palette) { |
|
|
|
|
STBI_FREE(tga_data); |
|
|
|
|
return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
@ -5461,12 +5555,49 @@ static int stbi__psd_test(stbi__context *s) |
|
|
|
|
return r; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// @TODO: return 16-bit PSD data to 16-bit interface
|
|
|
|
|
static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) |
|
|
|
|
{ |
|
|
|
|
int count, nleft, len; |
|
|
|
|
|
|
|
|
|
count = 0; |
|
|
|
|
while ((nleft = pixelCount - count) > 0) { |
|
|
|
|
len = stbi__get8(s); |
|
|
|
|
if (len == 128) { |
|
|
|
|
// No-op.
|
|
|
|
|
} else if (len < 128) { |
|
|
|
|
// Copy next len+1 bytes literally.
|
|
|
|
|
len++; |
|
|
|
|
if (len > nleft) return 0; // corrupt data
|
|
|
|
|
count += len; |
|
|
|
|
while (len) { |
|
|
|
|
*p = stbi__get8(s); |
|
|
|
|
p += 4; |
|
|
|
|
len--; |
|
|
|
|
} |
|
|
|
|
} else if (len > 128) { |
|
|
|
|
stbi_uc val; |
|
|
|
|
// Next -len+1 bytes in the dest are replicated from next source byte.
|
|
|
|
|
// (Interpret len as a negative 8-bit int.)
|
|
|
|
|
len = 257 - len; |
|
|
|
|
if (len > nleft) return 0; // corrupt data
|
|
|
|
|
val = stbi__get8(s); |
|
|
|
|
count += len; |
|
|
|
|
while (len) { |
|
|
|
|
*p = val; |
|
|
|
|
p += 4; |
|
|
|
|
len--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) |
|
|
|
|
{ |
|
|
|
|
int pixelCount; |
|
|
|
|
int pixelCount; |
|
|
|
|
int channelCount, compression; |
|
|
|
|
int channel, i, count, len; |
|
|
|
|
int channel, i; |
|
|
|
|
int bitdepth; |
|
|
|
|
int w,h; |
|
|
|
|
stbi_uc *out; |
|
|
|
@ -5527,10 +5658,14 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
if (compression > 1) |
|
|
|
|
return stbi__errpuc("bad compression", "PSD has an unknown compression format"); |
|
|
|
|
|
|
|
|
|
// Check size
|
|
|
|
|
if (!stbi__mad3sizes_valid(4, w, h, 0)) |
|
|
|
|
return stbi__errpuc("too large", "Corrupt PSD"); |
|
|
|
|
|
|
|
|
|
// Create the destination image.
|
|
|
|
|
|
|
|
|
|
if (!compression && bitdepth == 16 && bpc == 16) { |
|
|
|
|
out = (stbi_uc *) stbi__malloc(4 * w*h * 2); |
|
|
|
|
out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); |
|
|
|
|
ri->bits_per_channel = 16; |
|
|
|
|
} else |
|
|
|
|
out = (stbi_uc *) stbi__malloc(4 * w*h); |
|
|
|
@ -5566,41 +5701,16 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
*p = (channel == 3 ? 255 : 0); |
|
|
|
|
} else { |
|
|
|
|
// Read the RLE data.
|
|
|
|
|
count = 0; |
|
|
|
|
while (count < pixelCount) { |
|
|
|
|
len = stbi__get8(s); |
|
|
|
|
if (len == 128) { |
|
|
|
|
// No-op.
|
|
|
|
|
} else if (len < 128) { |
|
|
|
|
// Copy next len+1 bytes literally.
|
|
|
|
|
len++; |
|
|
|
|
count += len; |
|
|
|
|
while (len) { |
|
|
|
|
*p = stbi__get8(s); |
|
|
|
|
p += 4; |
|
|
|
|
len--; |
|
|
|
|
} |
|
|
|
|
} else if (len > 128) { |
|
|
|
|
stbi_uc val; |
|
|
|
|
// Next -len+1 bytes in the dest are replicated from next source byte.
|
|
|
|
|
// (Interpret len as a negative 8-bit int.)
|
|
|
|
|
len ^= 0x0FF; |
|
|
|
|
len += 2; |
|
|
|
|
val = stbi__get8(s); |
|
|
|
|
count += len; |
|
|
|
|
while (len) { |
|
|
|
|
*p = val; |
|
|
|
|
p += 4; |
|
|
|
|
len--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!stbi__psd_decode_rle(s, p, pixelCount)) { |
|
|
|
|
STBI_FREE(out); |
|
|
|
|
return stbi__errpuc("corrupt", "bad RLE data"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
|
|
|
|
|
// where each channel consists of an 8-bit value for each pixel in the image.
|
|
|
|
|
// where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
|
|
|
|
|
|
|
|
|
|
// Read the data by channel.
|
|
|
|
|
for (channel = 0; channel < 4; channel++) { |
|
|
|
@ -5866,14 +5976,14 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c |
|
|
|
|
x = stbi__get16be(s); |
|
|
|
|
y = stbi__get16be(s); |
|
|
|
|
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); |
|
|
|
|
if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); |
|
|
|
|
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); |
|
|
|
|
|
|
|
|
|
stbi__get32be(s); //skip `ratio'
|
|
|
|
|
stbi__get16be(s); //skip `fields'
|
|
|
|
|
stbi__get16be(s); //skip `pad'
|
|
|
|
|
|
|
|
|
|
// intermediate buffer is RGBA
|
|
|
|
|
result = (stbi_uc *) stbi__malloc(x*y*4); |
|
|
|
|
result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); |
|
|
|
|
memset(result, 0xff, x*y*4); |
|
|
|
|
|
|
|
|
|
if (!stbi__pic_load_core(s,x,y,comp, result)) { |
|
|
|
@ -6132,8 +6242,11 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i |
|
|
|
|
if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) |
|
|
|
|
return 0; // stbi__g_failure_reason set by stbi__gif_header
|
|
|
|
|
|
|
|
|
|
if (!stbi__mad3sizes_valid(g->w, g->h, 4, 0)) |
|
|
|
|
return stbi__errpuc("too large", "GIF too large"); |
|
|
|
|
|
|
|
|
|
prev_out = g->out; |
|
|
|
|
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); |
|
|
|
|
g->out = (stbi_uc *) stbi__malloc_mad3(4, g->w, g->h, 0); |
|
|
|
|
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
switch ((g->eflags & 0x1C) >> 2) { |
|
|
|
@ -6381,8 +6494,13 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re |
|
|
|
|
if (comp) *comp = 3; |
|
|
|
|
if (req_comp == 0) req_comp = 3; |
|
|
|
|
|
|
|
|
|
if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) |
|
|
|
|
return stbi__errpf("too large", "HDR image is too large"); |
|
|
|
|
|
|
|
|
|
// Read data
|
|
|
|
|
hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); |
|
|
|
|
hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); |
|
|
|
|
if (!hdr_data) |
|
|
|
|
return stbi__errpf("outofmem", "Out of memory"); |
|
|
|
|
|
|
|
|
|
// Load image data
|
|
|
|
|
// image data is stored as some number of sca
|
|
|
|
@ -6421,20 +6539,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re |
|
|
|
|
len <<= 8; |
|
|
|
|
len |= stbi__get8(s); |
|
|
|
|
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } |
|
|
|
|
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); |
|
|
|
|
if (scanline == NULL) { |
|
|
|
|
scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); |
|
|
|
|
if (!scanline) { |
|
|
|
|
STBI_FREE(hdr_data); |
|
|
|
|
return stbi__errpf("outofmem", "Out of memory"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (k = 0; k < 4; ++k) { |
|
|
|
|
int nleft; |
|
|
|
|
i = 0; |
|
|
|
|
while (i < width) { |
|
|
|
|
while ((nleft = width - i) > 0) { |
|
|
|
|
count = stbi__get8(s); |
|
|
|
|
if (count > 128) { |
|
|
|
|
// Run
|
|
|
|
|
value = stbi__get8(s); |
|
|
|
|
count -= 128; |
|
|
|
|
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } |
|
|
|
|
for (z = 0; z < count; ++z) |
|
|
|
|
scanline[i++ * 4 + k] = value; |
|
|
|
|
} else { |
|
|
|
|
// Dump
|
|
|
|
|
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } |
|
|
|
|
for (z = 0; z < count; ++z) |
|
|
|
|
scanline[i++ * 4 + k] = stbi__get8(s); |
|
|
|
|
} |
|
|
|
@ -6443,7 +6570,8 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re |
|
|
|
|
for (i=0; i < width; ++i) |
|
|
|
|
stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); |
|
|
|
|
} |
|
|
|
|
STBI_FREE(scanline); |
|
|
|
|
if (scanline) |
|
|
|
|
STBI_FREE(scanline); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return hdr_data; |
|
|
|
@ -6633,7 +6761,10 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req |
|
|
|
|
*y = s->img_y; |
|
|
|
|
*comp = s->img_n; |
|
|
|
|
|
|
|
|
|
out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); |
|
|
|
|
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) |
|
|
|
|
return stbi__errpuc("too large", "PNM too large"); |
|
|
|
|
|
|
|
|
|
out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); |
|
|
|
|
if (!out) return stbi__errpuc("outofmem", "Out of memory"); |
|
|
|
|
stbi__getn(s, out, s->img_n * s->img_x * s->img_y); |
|
|
|
|
|
|
|
|
|