Update stb libs to latest version

This commit is contained in:
raysan5 2016-04-06 17:45:25 +02:00
parent 1a2a44200a
commit 3b67a4cfba
7 changed files with 349 additions and 248 deletions

View File

@ -1,4 +1,4 @@
/* stb_image - v2.09 - public domain image loader - http://nothings.org/stb_image.h
/* stb_image - v2.12 - public domain image loader - http://nothings.org/stb_image.h
no warranty implied; use at your own risk
Do this:
@ -146,6 +146,12 @@
Latest revision history:
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
RGB-format JPEG; remove white matting in PSD;
allocate large structures on the stack;
correct channel count for PNG & BMP
2.10 (2016-01-22) avoid warning introduced in 2.09
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
2.07 (2015-09-13) partial animated GIF support
@ -166,10 +172,6 @@
STBI_MALLOC,STBI_REALLOC,STBI_FREE
STBI_NO_*, STBI_ONLY_*
GIF bugfix
1.48 (2014-12-14) fix incorrectly-named assert()
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
optimize PNG
fix bug in interlaced PNG with user-specified channel count
See end of file for full revision history.
@ -200,17 +202,17 @@
Janez Zemva John Bartholomew Michal Cichon svdijk@github
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
Aruelien Pocheville Thibault Reuille Cass Everitt
Ryamond Barbiero Paul Du Bois Engin Manap
Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
Ryamond Barbiero Paul Du Bois Engin Manap snagar@github
Michaelangel007@github Oriol Ferrer Mesia socks-the-fox
Blazej Dariusz Roszkowski
Michaelangel007@github
LICENSE
This software is in the public domain. Where that dedication is not
recognized, you are granted a perpetual, irrevocable license to copy,
distribute, and modify this file as you see fit.
This software is dual-licensed to the public domain and under the following
license: you are granted a perpetual, irrevocable license to copy, modify,
publish, and distribute this file as you see fit.
*/
@ -679,7 +681,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI_NO_SIMD
#endif
#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
#define STBI_SSE2
#include <emmintrin.h>
@ -1513,6 +1515,7 @@ typedef struct
int succ_high;
int succ_low;
int eob_run;
int rgb;
int scan_n, order[4];
int restart_interval, todo;
@ -2724,11 +2727,17 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
z->rgb = 0;
for (i=0; i < s->img_n; ++i) {
static unsigned char rgb[3] = { 'R', 'G', 'B' };
z->img_comp[i].id = stbi__get8(s);
if (z->img_comp[i].id != i+1) // JFIF requires
if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files!
if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files!
// somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
if (z->img_comp[i].id != rgb[i])
return stbi__err("bad component ID","Corrupt JPEG");
++z->rgb;
}
q = stbi__get8(s);
z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
@ -3390,7 +3399,17 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n >= 3) {
stbi_uc *y = coutput[0];
if (z->s->img_n == 3) {
if (z->rgb == 3) {
for (i=0; i < z->s->img_x; ++i) {
out[0] = y[i];
out[1] = coutput[1][i];
out[2] = coutput[2][i];
out[3] = 255;
out += n;
}
} else {
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
}
} else
for (i=0; i < z->s->img_x; ++i) {
out[0] = out[1] = out[2] = y[i];
@ -3415,10 +3434,13 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
stbi__jpeg j;
j.s = s;
stbi__setup_jpeg(&j);
return load_jpeg_image(&j, x,y,comp,req_comp);
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
j->s = s;
stbi__setup_jpeg(j);
result = load_jpeg_image(j, x,y,comp,req_comp);
STBI_FREE(j);
return result;
}
static int stbi__jpeg_test(stbi__context *s)
@ -3446,9 +3468,12 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
{
stbi__jpeg j;
j.s = s;
return stbi__jpeg_info_raw(&j, x, y, comp);
int result;
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
j->s = s;
result = stbi__jpeg_info_raw(j, x, y, comp);
STBI_FREE(j);
return result;
}
#endif
@ -3629,6 +3654,7 @@ static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room
while (cur + n > limit)
limit *= 2;
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
STBI_NOTUSED(old_limit);
if (q == NULL) return stbi__err("outofmem", "Out of memory");
z->zout_start = q;
z->zout = q + cur;
@ -3738,7 +3764,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
return 1;
}
static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
static int stbi__parse_uncompressed_block(stbi__zbuf *a)
{
stbi_uc header[4];
int len,nlen,k;
@ -3804,7 +3830,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
final = stbi__zreceive(a,1);
type = stbi__zreceive(a,2);
if (type == 0) {
if (!stbi__parse_uncomperssed_block(a)) return 0;
if (!stbi__parse_uncompressed_block(a)) return 0;
} else if (type == 3) {
return 0;
} else {
@ -3946,6 +3972,7 @@ typedef struct
{
stbi__context *s;
stbi_uc *idata, *expanded, *out;
int depth;
} stbi__png;
@ -3985,14 +4012,19 @@ static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x0
// create the png data from post-deflated data
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
{
int bytes = (depth == 16? 2 : 1);
stbi__context *s = a->s;
stbi__uint32 i,j,stride = x*out_n;
stbi__uint32 i,j,stride = x*out_n*bytes;
stbi__uint32 img_len, img_width_bytes;
int k;
int img_n = s->img_n; // copy it into a local for later
int output_bytes = out_n*bytes;
int filter_bytes = img_n*bytes;
int width = x;
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
a->out = (stbi_uc *) stbi__malloc(x * y * out_n); // extra bytes to write off the end into
a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // 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);
@ -4007,8 +4039,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
stbi_uc *cur = a->out + stride*j;
stbi_uc *prior = cur - stride;
int filter = *raw++;
int filter_bytes = img_n;
int width = x;
if (filter > 4)
return stbi__err("invalid filter","Corrupt PNG");
@ -4041,6 +4072,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
raw += img_n;
cur += out_n;
prior += out_n;
} else if (depth == 16) {
if (img_n != out_n) {
cur[filter_bytes] = 255; // first pixel top byte
cur[filter_bytes+1] = 255; // first pixel bottom byte
}
raw += filter_bytes;
cur += output_bytes;
prior += output_bytes;
} else {
raw += 1;
cur += 1;
@ -4049,7 +4088,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
// this is a little gross, so that we don't switch per-pixel or per-component
if (depth < 8 || img_n == out_n) {
int nk = (width - 1)*img_n;
int nk = (width - 1)*filter_bytes;
#define CASE(f) \
case f: \
for (k=0; k < nk; ++k)
@ -4069,18 +4108,27 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
STBI_ASSERT(img_n+1 == out_n);
#define CASE(f) \
case f: \
for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
for (k=0; k < img_n; ++k)
for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
for (k=0; k < filter_bytes; ++k)
switch (filter) {
CASE(STBI__F_none) cur[k] = raw[k]; break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break;
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break;
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break;
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break;
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break;
}
#undef CASE
// the loop above sets the high byte of the pixels' alpha, but for
// 16 bit png files we also need the low byte set. we'll do that here.
if (depth == 16) {
cur = a->out + stride*j; // start at the beginning of the row again
for (i=0; i < x; ++i,cur+=output_bytes) {
cur[filter_bytes+1] = 255;
}
}
}
}
@ -4156,6 +4204,17 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
}
}
}
} else if (depth == 16) {
// force the image data from big-endian to platform-native.
// this is done in a separate pass due to the decoding relying
// on the data being untouched, but could probably be done
// per-line during decode if care is taken.
stbi_uc *cur = a->out;
stbi__uint16 *cur16 = (stbi__uint16*)cur;
for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
*cur16 = (cur[0] << 8) | cur[1];
}
}
return 1;
@ -4228,6 +4287,31 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
return 1;
}
static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
{
stbi__context *s = z->s;
stbi__uint32 i, pixel_count = s->img_x * s->img_y;
stbi__uint16 *p = (stbi__uint16*) z->out;
// compute color-based transparency, assuming we've
// already got 65535 as the alpha value in the output
STBI_ASSERT(out_n == 2 || out_n == 4);
if (out_n == 2) {
for (i = 0; i < pixel_count; ++i) {
p[1] = (p[0] == tc[0] ? 0 : 65535);
p += 2;
}
} else {
for (i = 0; i < pixel_count; ++i) {
if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
p[3] = 0;
p += 4;
}
}
return 1;
}
static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
{
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
@ -4265,6 +4349,26 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
return 1;
}
static int stbi__reduce_png(stbi__png *p)
{
int i;
int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n;
stbi_uc *reduced;
stbi__uint16 *orig = (stbi__uint16*)p->out;
if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data
reduced = (stbi_uc *)stbi__malloc(img_len);
if (p == NULL) return stbi__err("outofmem", "Out of memory");
for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling
p->out = reduced;
STBI_FREE(orig);
return 1;
}
static int stbi__unpremultiply_on_load = 0;
static int stbi__de_iphone_flag = 0;
@ -4326,8 +4430,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
{
stbi_uc palette[1024], pal_img_n=0;
stbi_uc has_trans=0, tc[3];
stbi__uint16 tc16[3];
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
int first=1,k,interlace=0, color=0, is_iphone=0;
stbi__context *s = z->s;
z->expanded = NULL;
@ -4352,8 +4457,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
@ -4401,8 +4507,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
has_trans = 1;
for (k=0; k < s->img_n; ++k)
tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[depth]; // non 8-bit images will be larger
if (z->depth == 16) {
for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is
} else {
for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
}
}
break;
}
@ -4418,6 +4527,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
while (ioff + c.length > idata_limit)
idata_limit *= 2;
STBI_NOTUSED(idata_limit_old);
p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
z->idata = p;
}
@ -4432,7 +4542,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (scan != STBI__SCAN_load) return 1;
if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
// initial guess for decoded data size to avoid unnecessary reallocs
bpl = (s->img_x * depth + 7) / 8; // bytes per line, per component
bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
if (z->expanded == NULL) return 0; // zlib should set error
@ -4441,9 +4551,14 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
s->img_out_n = s->img_n+1;
else
s->img_out_n = s->img_n;
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
if (has_trans)
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
if (has_trans) {
if (z->depth == 16) {
if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
} else {
if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
}
}
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
stbi__de_iphone(z);
if (pal_img_n) {
@ -4485,6 +4600,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
unsigned char *result=NULL;
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
if (p->depth == 16) {
if (!stbi__reduce_png(p)) {
return result;
}
}
result = p->out;
p->out = NULL;
if (req_comp && req_comp != p->s->img_out_n) {
@ -4494,7 +4614,7 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
}
*x = p->s->img_x;
*y = p->s->img_y;
if (n) *n = p->s->img_out_n;
if (n) *n = p->s->img_n;
}
STBI_FREE(p->out); p->out = NULL;
STBI_FREE(p->expanded); p->expanded = NULL;
@ -4619,6 +4739,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
stbi__get16le(s); // discard reserved
info->offset = stbi__get32le(s);
info->hsz = hsz = stbi__get32le(s);
info->mr = info->mg = info->mb = info->ma = 0;
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) {
@ -4647,7 +4768,6 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
stbi__get32le(s);
}
if (info->bpp == 16 || info->bpp == 32) {
info->mr = info->mg = info->mb = 0;
if (compress == 0) {
if (info->bpp == 32) {
info->mr = 0xffu << 16;
@ -5342,6 +5462,21 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
}
}
if (channelCount >= 4) {
for (i=0; i < w*h; ++i) {
unsigned char *pixel = out + 4*i;
if (pixel[3] != 0 && pixel[3] != 255) {
// remove weird white matte from PSD
float a = pixel[3] / 255.0f;
float ra = 1.0f / a;
float inv_a = 255.0f * (1 - ra);
pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
}
}
}
if (req_comp && req_comp != 4) {
out = stbi__convert_format(out, 4, req_comp, w, h);
if (out == NULL) return out; // stbi__convert_format frees input on failure
@ -5654,13 +5789,15 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
{
stbi__gif g;
if (!stbi__gif_header(s, &g, comp, 1)) {
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
if (!stbi__gif_header(s, g, comp, 1)) {
STBI_FREE(g);
stbi__rewind( s );
return 0;
}
if (x) *x = g.w;
if (y) *y = g.h;
if (x) *x = g->w;
if (y) *y = g->h;
STBI_FREE(g);
return 1;
}
@ -5913,20 +6050,20 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
stbi_uc *u = 0;
stbi__gif g;
memset(&g, 0, sizeof(g));
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
memset(g, 0, sizeof(*g));
u = stbi__gif_load_next(s, &g, comp, req_comp);
u = stbi__gif_load_next(s, g, comp, req_comp);
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
if (u) {
*x = g.w;
*y = g.h;
*x = g->w;
*y = g->h;
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)
STBI_FREE(g.out);
else if (g->out)
STBI_FREE(g->out);
STBI_FREE(g);
return u;
}
@ -6464,6 +6601,14 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
revision history:
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) allocate large structures on the stack
remove white matting for transparent PSD
fix reported channel count for PNG & BMP
re-enable SSE2 in non-gcc 64-bit
support RGB-formatted JPEG
read 16-bit PNGs (only as 8-bit)
2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
2.09 (2016-01-16) allow comments in PNM files
16-bit-per-pixel TGA (not bit-per-component)
info() for TGA could break due to .hdr handling

View File

@ -1,4 +1,4 @@
/* stb_image_resize - v0.90 - public domain image resizing
/* stb_image_resize - v0.91 - public domain image resizing
by Jorge L Rodriguez (@VinoBS) - 2014
http://github.com/nothings/stb
@ -156,13 +156,14 @@
Sean Barrett: API design, optimizations
REVISIONS
0.91 (2016-04-02) fix warnings; fix handling of subpixel regions
0.90 (2014-09-17) first released version
LICENSE
This software is in the public domain. Where that dedication is not
recognized, you are granted a perpetual, irrevocable license to copy,
distribute, and modify this file as you see fit.
This software is dual-licensed to the public domain and under the following
license: you are granted a perpetual, irrevocable license to copy, modify,
publish, and distribute this file as you see fit.
TODO
Don't decode all of the image data when only processing a partial tile
@ -383,15 +384,6 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int
#define STBIR_ASSERT(x) assert(x)
#endif
#ifdef STBIR_DEBUG
#define STBIR__DEBUG_ASSERT STBIR_ASSERT
#else
#define STBIR__DEBUG_ASSERT
#endif
// If you hit this it means I haven't done it yet.
#define STBIR__UNIMPLEMENTED(x) STBIR_ASSERT(!(x))
// For memset
#include <string.h>
@ -758,7 +750,7 @@ static float stbir__filter_trapezoid(float x, float scale)
{
float halfscale = scale / 2;
float t = 0.5f + halfscale;
STBIR__DEBUG_ASSERT(scale <= 1);
STBIR_ASSERT(scale <= 1);
x = (float)fabs(x);
@ -776,7 +768,7 @@ static float stbir__filter_trapezoid(float x, float scale)
static float stbir__support_trapezoid(float scale)
{
STBIR__DEBUG_ASSERT(scale <= 1);
STBIR_ASSERT(scale <= 1);
return 0.5f + scale / 2;
}
@ -990,7 +982,7 @@ static int stbir__edge_wrap_slow(stbir_edge edge, int n, int max)
return n; // NOTREACHED
default:
STBIR__UNIMPLEMENTED("Unimplemented edge type");
STBIR_ASSERT(!"Unimplemented edge type");
return 0;
}
}
@ -1039,12 +1031,12 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
float total_filter = 0;
float filter_scale;
STBIR__DEBUG_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
STBIR_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
contributor->n0 = in_first_pixel;
contributor->n1 = in_last_pixel;
STBIR__DEBUG_ASSERT(contributor->n1 >= contributor->n0);
STBIR_ASSERT(contributor->n1 >= contributor->n0);
for (i = 0; i <= in_last_pixel - in_first_pixel; i++)
{
@ -1062,10 +1054,10 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
total_filter += coefficient_group[i];
}
STBIR__DEBUG_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0);
STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0);
STBIR__DEBUG_ASSERT(total_filter > 0.9);
STBIR__DEBUG_ASSERT(total_filter < 1.1f); // Make sure it's not way off.
STBIR_ASSERT(total_filter > 0.9);
STBIR_ASSERT(total_filter < 1.1f); // Make sure it's not way off.
// Make sure the sum of all coefficients is 1.
filter_scale = 1 / total_filter;
@ -1087,12 +1079,12 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
{
int i;
STBIR__DEBUG_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
STBIR_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
contributor->n0 = out_first_pixel;
contributor->n1 = out_last_pixel;
STBIR__DEBUG_ASSERT(contributor->n1 >= contributor->n0);
STBIR_ASSERT(contributor->n1 >= contributor->n0);
for (i = 0; i <= out_last_pixel - out_first_pixel; i++)
{
@ -1101,7 +1093,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio;
}
STBIR__DEBUG_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0);
STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0);
for (i = out_last_pixel - out_first_pixel; i >= 0; i--)
{
@ -1136,8 +1128,8 @@ static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, st
break;
}
STBIR__DEBUG_ASSERT(total > 0.9f);
STBIR__DEBUG_ASSERT(total < 1.1f);
STBIR_ASSERT(total > 0.9f);
STBIR_ASSERT(total < 1.1f);
scale = 1 / total;
@ -1364,7 +1356,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
break;
default:
STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
STBIR_ASSERT(!"Unknown type/colorspace/channels combination.");
break;
}
@ -1425,7 +1417,7 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
else
{
ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width;
STBIR__DEBUG_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index);
STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index);
}
ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float));
@ -1457,11 +1449,11 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
int coefficient_group = coefficient_width * x;
int coefficient_counter = 0;
STBIR__DEBUG_ASSERT(n1 >= n0);
STBIR__DEBUG_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin);
STBIR__DEBUG_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin);
STBIR__DEBUG_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
STBIR__DEBUG_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
STBIR_ASSERT(n1 >= n0);
STBIR_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin);
STBIR_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin);
STBIR_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
STBIR_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
switch (channels) {
case 1:
@ -1469,7 +1461,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
{
int in_pixel_index = k * 1;
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
}
break;
@ -1478,7 +1470,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
{
int in_pixel_index = k * 2;
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
}
@ -1488,7 +1480,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
{
int in_pixel_index = k * 3;
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
@ -1499,7 +1491,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
{
int in_pixel_index = k * 4;
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
@ -1512,7 +1504,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
int in_pixel_index = k * channels;
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
int c;
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
for (c = 0; c < channels; c++)
output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
}
@ -1535,7 +1527,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
int filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin;
int max_x = input_w + filter_pixel_margin * 2;
STBIR__DEBUG_ASSERT(!stbir__use_width_upsampling(stbir_info));
STBIR_ASSERT(!stbir__use_width_upsampling(stbir_info));
switch (channels) {
case 1:
@ -1553,7 +1545,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
{
int out_pixel_index = k * 1;
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
}
}
@ -1574,7 +1566,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
{
int out_pixel_index = k * 2;
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
}
@ -1596,7 +1588,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
{
int out_pixel_index = k * 3;
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
@ -1619,7 +1611,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
{
int out_pixel_index = k * 4;
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
@ -1644,7 +1636,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
int c;
int out_pixel_index = k * channels;
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
STBIR__DEBUG_ASSERT(coefficient != 0);
STBIR_ASSERT(coefficient != 0);
for (c = 0; c < channels; c++)
output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
}
@ -1856,7 +1848,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
break;
default:
STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
STBIR_ASSERT(!"Unknown type/colorspace/channels combination.");
break;
}
}
@ -1893,7 +1885,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
output_row_start = n * stbir_info->output_stride_bytes;
STBIR__DEBUG_ASSERT(stbir__use_height_upsampling(stbir_info));
STBIR_ASSERT(stbir__use_height_upsampling(stbir_info));
memset(encode_buffer, 0, output_w * sizeof(float) * channels);
@ -2003,7 +1995,7 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n,
n0 = vertical_contributors[contributor].n0;
n1 = vertical_contributors[contributor].n1;
STBIR__DEBUG_ASSERT(!stbir__use_height_upsampling(stbir_info));
STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info));
for (k = n0; k <= n1; k++)
{
@ -2068,7 +2060,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
float scale_ratio = stbir_info->vertical_scale;
float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio;
STBIR__DEBUG_ASSERT(stbir__use_height_upsampling(stbir_info));
STBIR_ASSERT(stbir__use_height_upsampling(stbir_info));
for (y = 0; y < stbir_info->output_h; y++)
{
@ -2077,7 +2069,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out);
STBIR__DEBUG_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width);
STBIR_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width);
if (stbir_info->ring_buffer_begin_index >= 0)
{
@ -2169,7 +2161,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
int pixel_margin = stbir_info->vertical_filter_pixel_margin;
int max_y = stbir_info->input_h + pixel_margin;
STBIR__DEBUG_ASSERT(!stbir__use_height_upsampling(stbir_info));
STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info));
for (y = -pixel_margin; y < max_y; y++)
{
@ -2178,7 +2170,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in);
STBIR__DEBUG_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width);
STBIR_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width);
if (out_last_scanline < 0 || out_first_scanline >= output_h)
continue;
@ -2229,8 +2221,8 @@ static void stbir__calculate_transform(stbir__info *info, float s0, float t0, fl
info->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0);
info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0);
info->horizontal_shift = s0 * info->input_w / (s1 - s0);
info->vertical_shift = t0 * info->input_h / (t1 - t0);
info->horizontal_shift = s0 * info->output_w / (s1 - s0);
info->vertical_shift = t0 * info->output_h / (t1 - t0);
}
}
@ -2380,7 +2372,7 @@ static int stbir__resize_allocated(stbir__info *info,
info->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float);
info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_buffer, float);
STBIR__DEBUG_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
}
else
{
@ -2388,7 +2380,7 @@ static int stbir__resize_allocated(stbir__info *info,
info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float);
info->encode_buffer = NULL;
STBIR__DEBUG_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
}
#undef STBIR__NEXT_MEMPTR
@ -2409,10 +2401,10 @@ static int stbir__resize_allocated(stbir__info *info,
STBIR_PROGRESS_REPORT(1);
#ifdef STBIR_DEBUG_OVERWRITE_TEST
STBIR__DEBUG_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
STBIR__DEBUG_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0);
STBIR__DEBUG_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
STBIR__DEBUG_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0);
STBIR_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
STBIR_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0);
STBIR_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
STBIR_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0);
#endif
return 1;

View File

@ -1,4 +1,4 @@
/* stb_image_write - v1.01 - public domain - http://nothings.org/stb/stb_image_write.h
/* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@ -102,12 +102,13 @@ CREDITS:
Sergio Gonzalez
Jonas Karlsson
Filip Wasil
Thatcher Ulrich
LICENSE
This software is in the public domain. Where that dedication is not
recognized, you are granted a perpetual, irrevocable license to copy,
distribute, and modify this file as you see fit.
This software is dual-licensed to the public domain and under the following
license: you are granted a perpetual, irrevocable license to copy, modify,
publish, and distribute this file as you see fit.
*/
@ -736,7 +737,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char **hash_table[stbiw__ZHASH]; // 64KB on the stack!
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
if (quality < 5) quality = 5;
stbiw__sbpush(out, 0x78); // DEFLATE 32K window
@ -808,6 +809,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
for (i=0; i < stbiw__ZHASH; ++i)
(void) stbiw__sbfree(hash_table[i]);
STBIW_FREE(hash_table);
{
// compute adler32 on input
@ -1015,6 +1017,8 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
1.02 (2016-04-02)
avoid allocating large structures on the stack
1.01 (2016-01-16)
STBIW_REALLOC_SIZED: support allocators with no realloc support
avoid race-condition in crc initialization

View File

@ -1,4 +1,4 @@
// stb_rect_pack.h - v0.06 - public domain - rectangle packing
// stb_rect_pack.h - v0.08 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
@ -28,14 +28,22 @@
// Minor features
// Martins Mozeiko
// Bugfixes / warning fixes
// [your name could be here]
// Jeremy Jaussaud
//
// Version history:
//
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
//
// LICENSE
//
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//////////////////////////////////////////////////////////////////////////////
//
@ -541,6 +549,9 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
@ -549,6 +560,7 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);

View File

@ -1,4 +1,4 @@
// stb_truetype.h - v1.09 - public domain
// stb_truetype.h - v1.11 - public domain
// authored from 2009-2015 by Sean Barrett / RAD Game Tools
//
// This library processes TrueType files:
@ -21,6 +21,10 @@
// Mikko Mononen: compound shape support, more cmap formats
// Tor Andersson: kerning, subpixel rendering
//
// Misc other:
// Ryan Gordon
// Simon Glass
//
// Bug/warning reports/fixes:
// "Zer" on mollyrocket (with fix)
// Cass Everitt
@ -45,11 +49,10 @@
// Thomas Fields
// Derek Vinyard
//
// Misc other:
// Ryan Gordon
//
// VERSION HISTORY
//
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
@ -68,9 +71,9 @@
//
// LICENSE
//
// This software is in the public domain. Where that dedication is not
// recognized, you are granted a perpetual, irrevocable license to copy,
// distribute, and modify this file as you see fit.
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//
// USAGE
//
@ -406,6 +409,11 @@ int main(int arg, char **argv)
#define STBTT_sqrt(x) sqrt(x)
#endif
#ifndef STBTT_fabs
#include <math.h>
#define STBTT_fabs(x) fabs(x)
#endif
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc
#include <stdlib.h>
@ -629,7 +637,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// The following structure is defined publically so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque.
typedef struct stbtt_fontinfo
struct stbtt_fontinfo
{
void * userdata;
unsigned char * data; // pointer to .ttf file
@ -640,7 +648,7 @@ typedef struct stbtt_fontinfo
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
} stbtt_fontinfo;
};
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds
@ -942,6 +950,12 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define STBTT_RASTERIZER_VERSION 2
#endif
#ifdef _MSC_VER
#define STBTT__NOTUSED(v) (void)(v)
#else
#define STBTT__NOTUSED(v) (void)sizeof(v)
#endif
//////////////////////////////////////////////////////////////////////////
//
// accessors to parse data from file
@ -1993,7 +2007,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
}
y_crossing += dy * (x2 - (x1+1));
STBTT_assert(fabs(area) <= 1.01f);
STBTT_assert(STBTT_fabs(area) <= 1.01f);
scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
@ -2071,6 +2085,8 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int y,j=0, i;
float scanline_data[129], *scanline, *scanline2;
STBTT__NOTUSED(vsubsample);
if (result->w > 64)
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
else
@ -2129,7 +2145,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int m;
sum += scanline2[i];
k = scanline[i] + sum;
k = (float) fabs(k)*255 + 0.5f;
k = (float) STBTT_fabs(k)*255 + 0.5f;
m = (int) k;
if (m > 255) m = 255;
result->pixels[j*result->stride + i] = (unsigned char) m;
@ -2430,7 +2446,10 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (scale_x == 0) scale_x = scale_y;
if (scale_y == 0) {
if (scale_x == 0) return NULL;
if (scale_x == 0) {
STBTT_free(vertices, info->userdata);
return NULL;
}
scale_y = scale_x;
}
@ -2586,11 +2605,6 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
//
#ifndef STB_RECT_PACK_VERSION
#ifdef _MSC_VER
#define STBTT__NOTUSED(v) (void)(v)
#else
#define STBTT__NOTUSED(v) (void)sizeof(v)
#endif
typedef int stbrp_coord;
@ -3205,6 +3219,10 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
// FULL VERSION HISTORY
//
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) allow user-defined fabs() replacement
// fix memory leak if fontsize=0.0
// fix warning from duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;

View File

@ -168,6 +168,9 @@
#include <math.h>
#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh))
#include <malloc.h>
#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
#include <alloca.h>
#endif
#endif
#else // STB_VORBIS_NO_CRT
#define NULL 0
@ -1484,85 +1487,6 @@ static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **out
return TRUE;
}
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
static int codebook_decode_deinterleave_repeat_2(vorb *f, Codebook *c, float **outputs, int *c_inter_p, int *p_inter_p, int len, int total_decode)
{
int c_inter = *c_inter_p;
int p_inter = *p_inter_p;
int i,z, effective = c->dimensions;
// type 0 is only legal in a scalar context
if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream);
while (total_decode > 0) {
float last = CODEBOOK_ELEMENT_BASE(c);
DECODE_VQ(z,f,c);
if (z < 0) {
if (!f->bytes_in_seg)
if (f->last_seg) return FALSE;
return error(f, VORBIS_invalid_stream);
}
// if this will take us off the end of the buffers, stop short!
// we check by computing the length of the virtual interleaved
// 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*2 + effective > len * 2) {
effective = len*2 - (p_inter*2 - c_inter);
}
{
z *= c->dimensions;
if (c->sequence_p) {
// haven't optimized this case because I don't have any examples
for (i=0; i < effective; ++i) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == 2) { c_inter = 0; ++p_inter; }
last = val;
}
} else {
i=0;
if (c_inter == 1 && i < effective) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
c_inter = 0; ++p_inter;
++i;
}
{
float *z0 = outputs[0];
float *z1 = outputs[1];
for (; i+1 < effective;) {
float v0 = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
float v1 = CODEBOOK_ELEMENT_FAST(c,z+i+1) + last;
if (z0)
z0[p_inter] += v0;
if (z1)
z1[p_inter] += v1;
++p_inter;
i += 2;
}
}
if (i < effective) {
float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last;
if (outputs[c_inter])
outputs[c_inter][p_inter] += val;
if (++c_inter == 2) { c_inter = 0; ++p_inter; }
}
}
}
total_decode -= effective;
}
*c_inter_p = c_inter;
*p_inter_p = p_inter;
return TRUE;
}
#endif
static int predict_point(int x, int x0, int x1, int y0, int y1)
{
int dy = y1 - y0;
@ -1941,6 +1865,11 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
}
done:
CHECK(f);
#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
temp_free(f,part_classdata);
#else
temp_free(f,classifications);
#endif
temp_alloc_restore(f,temp_alloc_point);
}
@ -2586,6 +2515,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
}
}
temp_free(f,buf2);
temp_alloc_restore(f,save_point);
}
@ -3499,7 +3429,6 @@ static int start_decoder(vorb *f)
}
}
}
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
c->lookup_type = 2;
}
else
@ -3515,11 +3444,11 @@ static int start_decoder(vorb *f)
if (c->sequence_p)
last = val;
}
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
}
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
skip:;
#endif
setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values);
CHECK(f);
}
@ -4045,7 +3974,7 @@ int stb_vorbis_decode_frame_pushdata(
while (get8_packet(f) != EOP)
if (f->eof) break;
*samples = 0;
return f->stream - data;
return (int) (f->stream - data);
}
if (error == VORBIS_continued_packet_flag_invalid) {
if (f->previous_length == 0) {
@ -4055,7 +3984,7 @@ int stb_vorbis_decode_frame_pushdata(
while (get8_packet(f) != EOP)
if (f->eof) break;
*samples = 0;
return f->stream - data;
return (int) (f->stream - data);
}
}
// if we get an error while parsing, what to do?
@ -4075,7 +4004,7 @@ int stb_vorbis_decode_frame_pushdata(
if (channels) *channels = f->channels;
*samples = len;
*output = f->outputs;
return f->stream - data;
return (int) (f->stream - data);
}
stb_vorbis *stb_vorbis_open_pushdata(
@ -4098,7 +4027,7 @@ stb_vorbis *stb_vorbis_open_pushdata(
f = vorbis_alloc(&p);
if (f) {
*f = p;
*data_used = f->stream - data;
*data_used = (int) (f->stream - data);
*error = 0;
return f;
} else {
@ -4113,9 +4042,9 @@ unsigned int stb_vorbis_get_file_offset(stb_vorbis *f)
#ifndef STB_VORBIS_NO_PUSHDATA_API
if (f->push_mode) return 0;
#endif
if (USE_MEMORY(f)) return f->stream - f->stream_start;
if (USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start);
#ifndef STB_VORBIS_NO_STDIO
return ftell(f->f) - f->f_start;
return (unsigned int) (ftell(f->f) - f->f_start);
#endif
}
@ -4611,7 +4540,7 @@ stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *er
stb_vorbis *f, p;
vorbis_init(&p, alloc);
p.f = file;
p.f_start = ftell(file);
p.f_start = (uint32) ftell(file);
p.stream_len = length;
p.close_on_free = close_on_free;
if (start_decoder(&p)) {
@ -4630,9 +4559,9 @@ stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *er
stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc)
{
unsigned int len, start;
start = ftell(file);
start = (unsigned int) ftell(file);
fseek(file, 0, SEEK_END);
len = ftell(file) - start;
len = (unsigned int) (ftell(file) - start);
fseek(file, start, SEEK_SET);
return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len);
}
@ -5027,6 +4956,9 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
#endif // STB_VORBIS_NO_PULLDATA_API
/* Version history
1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
avoid discarding last frame of audio data
1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API
some more crash fixes when out of memory or with corrupt files
1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)

View File

@ -1,4 +1,4 @@
// Ogg Vorbis audio decoder - v1.07 - public domain
// Ogg Vorbis audio decoder - v1.09 - public domain
// http://nothings.org/stb_vorbis/
//
// Original version written by Sean Barrett in 2007.
@ -9,9 +9,9 @@
//
// LICENSE
//
// This software is in the public domain. Where that dedication is not
// recognized, you are granted a perpetual, irrevocable license to copy,
// distribute, and modify this file as you see fit.
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//
// No warranty for any purpose is expressed or implied by the author (nor
// by RAD Game Tools). Report bugs and send enhancements to the author.
@ -31,11 +31,14 @@
// Terje Mathisen Niklas Frykholm Andy Hill
// Casey Muratori John Bolton Gargaj
// Laurent Gomila Marc LeBlanc Ronny Chevalier
// Bernhard Wodo Evan Balster "alxprd"@github
// Bernhard Wodo Evan Balster alxprd@github
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
// Phillip Bennefall Rohit
// Phillip Bennefall Rohit Thiago Goulart
// manxorist@github saga musix
//
// Partial history:
// 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version
// 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame
// 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const
// 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
// some crash fixes when out of memory or with corrupt files
@ -72,11 +75,6 @@
#include "utils.h" // Android fopen function map
#endif
// RaySan: Added for Linux
#ifdef __linux
#include <alloca.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif