Update stb libs to latest version
This commit is contained in:
parent
1a2a44200a
commit
3b67a4cfba
263
src/stb_image.h
263
src/stb_image.h
@ -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
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
@ -146,6 +146,12 @@
|
|||||||
|
|
||||||
|
|
||||||
Latest revision history:
|
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.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.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
|
||||||
2.07 (2015-09-13) partial animated GIF support
|
2.07 (2015-09-13) partial animated GIF support
|
||||||
@ -166,10 +172,6 @@
|
|||||||
STBI_MALLOC,STBI_REALLOC,STBI_FREE
|
STBI_MALLOC,STBI_REALLOC,STBI_FREE
|
||||||
STBI_NO_*, STBI_ONLY_*
|
STBI_NO_*, STBI_ONLY_*
|
||||||
GIF bugfix
|
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.
|
See end of file for full revision history.
|
||||||
|
|
||||||
@ -200,17 +202,17 @@
|
|||||||
Janez Zemva John Bartholomew Michal Cichon svdijk@github
|
Janez Zemva John Bartholomew Michal Cichon svdijk@github
|
||||||
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
|
Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
|
||||||
Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
|
Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
|
||||||
Aruelien Pocheville Thibault Reuille Cass Everitt
|
Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
|
||||||
Ryamond Barbiero Paul Du Bois Engin Manap
|
Ryamond Barbiero Paul Du Bois Engin Manap snagar@github
|
||||||
|
Michaelangel007@github Oriol Ferrer Mesia socks-the-fox
|
||||||
Blazej Dariusz Roszkowski
|
Blazej Dariusz Roszkowski
|
||||||
Michaelangel007@github
|
|
||||||
|
|
||||||
|
|
||||||
LICENSE
|
LICENSE
|
||||||
|
|
||||||
This software is in the public domain. Where that dedication is not
|
This software is dual-licensed to the public domain and under the following
|
||||||
recognized, you are granted a perpetual, irrevocable license to copy,
|
license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||||
distribute, and modify this file as you see fit.
|
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
|
#define STBI_NO_SIMD
|
||||||
#endif
|
#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
|
#define STBI_SSE2
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
|
||||||
@ -1513,6 +1515,7 @@ typedef struct
|
|||||||
int succ_high;
|
int succ_high;
|
||||||
int succ_low;
|
int succ_low;
|
||||||
int eob_run;
|
int eob_run;
|
||||||
|
int rgb;
|
||||||
|
|
||||||
int scan_n, order[4];
|
int scan_n, order[4];
|
||||||
int restart_interval, todo;
|
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");
|
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) {
|
for (i=0; i < s->img_n; ++i) {
|
||||||
|
static unsigned char rgb[3] = { 'R', 'G', 'B' };
|
||||||
z->img_comp[i].id = stbi__get8(s);
|
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+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!
|
||||||
return stbi__err("bad component ID","Corrupt JPEG");
|
// 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);
|
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].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");
|
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) {
|
if (n >= 3) {
|
||||||
stbi_uc *y = coutput[0];
|
stbi_uc *y = coutput[0];
|
||||||
if (z->s->img_n == 3) {
|
if (z->s->img_n == 3) {
|
||||||
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
|
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
|
} else
|
||||||
for (i=0; i < z->s->img_x; ++i) {
|
for (i=0; i < z->s->img_x; ++i) {
|
||||||
out[0] = out[1] = out[2] = y[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)
|
static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||||
{
|
{
|
||||||
stbi__jpeg j;
|
unsigned char* result;
|
||||||
j.s = s;
|
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
|
||||||
stbi__setup_jpeg(&j);
|
j->s = s;
|
||||||
return load_jpeg_image(&j, x,y,comp,req_comp);
|
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)
|
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)
|
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
|
||||||
{
|
{
|
||||||
stbi__jpeg j;
|
int result;
|
||||||
j.s = s;
|
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
|
||||||
return stbi__jpeg_info_raw(&j, x, y, comp);
|
j->s = s;
|
||||||
|
result = stbi__jpeg_info_raw(j, x, y, comp);
|
||||||
|
STBI_FREE(j);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3629,6 +3654,7 @@ static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room
|
|||||||
while (cur + n > limit)
|
while (cur + n > limit)
|
||||||
limit *= 2;
|
limit *= 2;
|
||||||
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
|
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");
|
if (q == NULL) return stbi__err("outofmem", "Out of memory");
|
||||||
z->zout_start = q;
|
z->zout_start = q;
|
||||||
z->zout = q + cur;
|
z->zout = q + cur;
|
||||||
@ -3738,7 +3764,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
|
static int stbi__parse_uncompressed_block(stbi__zbuf *a)
|
||||||
{
|
{
|
||||||
stbi_uc header[4];
|
stbi_uc header[4];
|
||||||
int len,nlen,k;
|
int len,nlen,k;
|
||||||
@ -3804,7 +3830,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|||||||
final = stbi__zreceive(a,1);
|
final = stbi__zreceive(a,1);
|
||||||
type = stbi__zreceive(a,2);
|
type = stbi__zreceive(a,2);
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
if (!stbi__parse_uncomperssed_block(a)) return 0;
|
if (!stbi__parse_uncompressed_block(a)) return 0;
|
||||||
} else if (type == 3) {
|
} else if (type == 3) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -3946,6 +3972,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
stbi__context *s;
|
stbi__context *s;
|
||||||
stbi_uc *idata, *expanded, *out;
|
stbi_uc *idata, *expanded, *out;
|
||||||
|
int depth;
|
||||||
} stbi__png;
|
} 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
|
// 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)
|
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__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;
|
stbi__uint32 img_len, img_width_bytes;
|
||||||
int k;
|
int k;
|
||||||
int img_n = s->img_n; // copy it into a local for later
|
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);
|
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");
|
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
||||||
|
|
||||||
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
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 *cur = a->out + stride*j;
|
||||||
stbi_uc *prior = cur - stride;
|
stbi_uc *prior = cur - stride;
|
||||||
int filter = *raw++;
|
int filter = *raw++;
|
||||||
int filter_bytes = img_n;
|
|
||||||
int width = x;
|
|
||||||
if (filter > 4)
|
if (filter > 4)
|
||||||
return stbi__err("invalid filter","Corrupt PNG");
|
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;
|
raw += img_n;
|
||||||
cur += out_n;
|
cur += out_n;
|
||||||
prior += 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 {
|
} else {
|
||||||
raw += 1;
|
raw += 1;
|
||||||
cur += 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
|
// this is a little gross, so that we don't switch per-pixel or per-component
|
||||||
if (depth < 8 || img_n == out_n) {
|
if (depth < 8 || img_n == out_n) {
|
||||||
int nk = (width - 1)*img_n;
|
int nk = (width - 1)*filter_bytes;
|
||||||
#define CASE(f) \
|
#define CASE(f) \
|
||||||
case f: \
|
case f: \
|
||||||
for (k=0; k < nk; ++k)
|
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);
|
STBI_ASSERT(img_n+1 == out_n);
|
||||||
#define CASE(f) \
|
#define CASE(f) \
|
||||||
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 (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
|
||||||
for (k=0; k < img_n; ++k)
|
for (k=0; k < filter_bytes; ++k)
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
CASE(STBI__F_none) cur[k] = raw[k]; break;
|
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_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_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-out_n],prior[k],prior[k-out_n])); 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-out_n] >> 1)); 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-out_n],0,0)); break;
|
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break;
|
||||||
}
|
}
|
||||||
#undef CASE
|
#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;
|
return 1;
|
||||||
@ -4228,6 +4287,31 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
|
|||||||
return 1;
|
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)
|
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;
|
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;
|
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__unpremultiply_on_load = 0;
|
||||||
static int stbi__de_iphone_flag = 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 palette[1024], pal_img_n=0;
|
||||||
stbi_uc has_trans=0, tc[3];
|
stbi_uc has_trans=0, tc[3];
|
||||||
|
stbi__uint16 tc16[3];
|
||||||
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
||||||
int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
|
int first=1,k,interlace=0, color=0, is_iphone=0;
|
||||||
stbi__context *s = z->s;
|
stbi__context *s = z->s;
|
||||||
|
|
||||||
z->expanded = NULL;
|
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");
|
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_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?)");
|
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");
|
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");
|
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");
|
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");
|
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 (!(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");
|
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
|
||||||
has_trans = 1;
|
has_trans = 1;
|
||||||
for (k=0; k < s->img_n; ++k)
|
if (z->depth == 16) {
|
||||||
tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[depth]; // non 8-bit images will be larger
|
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;
|
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;
|
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
|
||||||
while (ioff + c.length > idata_limit)
|
while (ioff + c.length > idata_limit)
|
||||||
idata_limit *= 2;
|
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");
|
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;
|
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 (scan != STBI__SCAN_load) return 1;
|
||||||
if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
|
if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
|
||||||
// initial guess for decoded data size to avoid unnecessary reallocs
|
// 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 */;
|
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);
|
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
|
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;
|
s->img_out_n = s->img_n+1;
|
||||||
else
|
else
|
||||||
s->img_out_n = s->img_n;
|
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 (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
|
||||||
if (has_trans)
|
if (has_trans) {
|
||||||
if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
|
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)
|
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
|
||||||
stbi__de_iphone(z);
|
stbi__de_iphone(z);
|
||||||
if (pal_img_n) {
|
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;
|
unsigned char *result=NULL;
|
||||||
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
|
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 (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
|
||||||
|
if (p->depth == 16) {
|
||||||
|
if (!stbi__reduce_png(p)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
result = p->out;
|
result = p->out;
|
||||||
p->out = NULL;
|
p->out = NULL;
|
||||||
if (req_comp && req_comp != p->s->img_out_n) {
|
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;
|
*x = p->s->img_x;
|
||||||
*y = p->s->img_y;
|
*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->out); p->out = NULL;
|
||||||
STBI_FREE(p->expanded); p->expanded = 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
|
stbi__get16le(s); // discard reserved
|
||||||
info->offset = stbi__get32le(s);
|
info->offset = stbi__get32le(s);
|
||||||
info->hsz = hsz = 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 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
|
||||||
if (hsz == 12) {
|
if (hsz == 12) {
|
||||||
@ -4647,7 +4768,6 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
|
|||||||
stbi__get32le(s);
|
stbi__get32le(s);
|
||||||
}
|
}
|
||||||
if (info->bpp == 16 || info->bpp == 32) {
|
if (info->bpp == 16 || info->bpp == 32) {
|
||||||
info->mr = info->mg = info->mb = 0;
|
|
||||||
if (compress == 0) {
|
if (compress == 0) {
|
||||||
if (info->bpp == 32) {
|
if (info->bpp == 32) {
|
||||||
info->mr = 0xffu << 16;
|
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) {
|
if (req_comp && req_comp != 4) {
|
||||||
out = stbi__convert_format(out, 4, req_comp, w, h);
|
out = stbi__convert_format(out, 4, req_comp, w, h);
|
||||||
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
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)
|
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
|
||||||
{
|
{
|
||||||
stbi__gif g;
|
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
|
||||||
if (!stbi__gif_header(s, &g, comp, 1)) {
|
if (!stbi__gif_header(s, g, comp, 1)) {
|
||||||
|
STBI_FREE(g);
|
||||||
stbi__rewind( s );
|
stbi__rewind( s );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (x) *x = g.w;
|
if (x) *x = g->w;
|
||||||
if (y) *y = g.h;
|
if (y) *y = g->h;
|
||||||
|
STBI_FREE(g);
|
||||||
return 1;
|
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)
|
static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||||
{
|
{
|
||||||
stbi_uc *u = 0;
|
stbi_uc *u = 0;
|
||||||
stbi__gif g;
|
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
|
||||||
memset(&g, 0, sizeof(g));
|
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 == (stbi_uc *) s) u = 0; // end of animated gif marker
|
||||||
if (u) {
|
if (u) {
|
||||||
*x = g.w;
|
*x = g->w;
|
||||||
*y = g.h;
|
*y = g->h;
|
||||||
if (req_comp && req_comp != 4)
|
if (req_comp && req_comp != 4)
|
||||||
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
|
u = stbi__convert_format(u, 4, req_comp, g->w, g->h);
|
||||||
}
|
}
|
||||||
else if (g.out)
|
else if (g->out)
|
||||||
STBI_FREE(g.out);
|
STBI_FREE(g->out);
|
||||||
|
STBI_FREE(g);
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6464,6 +6601,14 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
revision history:
|
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
|
2.09 (2016-01-16) allow comments in PNM files
|
||||||
16-bit-per-pixel TGA (not bit-per-component)
|
16-bit-per-pixel TGA (not bit-per-component)
|
||||||
info() for TGA could break due to .hdr handling
|
info() for TGA could break due to .hdr handling
|
||||||
|
@ -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
|
by Jorge L Rodriguez (@VinoBS) - 2014
|
||||||
http://github.com/nothings/stb
|
http://github.com/nothings/stb
|
||||||
|
|
||||||
@ -156,13 +156,14 @@
|
|||||||
Sean Barrett: API design, optimizations
|
Sean Barrett: API design, optimizations
|
||||||
|
|
||||||
REVISIONS
|
REVISIONS
|
||||||
|
0.91 (2016-04-02) fix warnings; fix handling of subpixel regions
|
||||||
0.90 (2014-09-17) first released version
|
0.90 (2014-09-17) first released version
|
||||||
|
|
||||||
LICENSE
|
LICENSE
|
||||||
|
|
||||||
This software is in the public domain. Where that dedication is not
|
This software is dual-licensed to the public domain and under the following
|
||||||
recognized, you are granted a perpetual, irrevocable license to copy,
|
license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||||
distribute, and modify this file as you see fit.
|
publish, and distribute this file as you see fit.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
Don't decode all of the image data when only processing a partial tile
|
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)
|
#define STBIR_ASSERT(x) assert(x)
|
||||||
#endif
|
#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
|
// For memset
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -758,7 +750,7 @@ static float stbir__filter_trapezoid(float x, float scale)
|
|||||||
{
|
{
|
||||||
float halfscale = scale / 2;
|
float halfscale = scale / 2;
|
||||||
float t = 0.5f + halfscale;
|
float t = 0.5f + halfscale;
|
||||||
STBIR__DEBUG_ASSERT(scale <= 1);
|
STBIR_ASSERT(scale <= 1);
|
||||||
|
|
||||||
x = (float)fabs(x);
|
x = (float)fabs(x);
|
||||||
|
|
||||||
@ -776,7 +768,7 @@ static float stbir__filter_trapezoid(float x, float scale)
|
|||||||
|
|
||||||
static float stbir__support_trapezoid(float scale)
|
static float stbir__support_trapezoid(float scale)
|
||||||
{
|
{
|
||||||
STBIR__DEBUG_ASSERT(scale <= 1);
|
STBIR_ASSERT(scale <= 1);
|
||||||
return 0.5f + scale / 2;
|
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
|
return n; // NOTREACHED
|
||||||
|
|
||||||
default:
|
default:
|
||||||
STBIR__UNIMPLEMENTED("Unimplemented edge type");
|
STBIR_ASSERT(!"Unimplemented edge type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1039,12 +1031,12 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
|
|||||||
float total_filter = 0;
|
float total_filter = 0;
|
||||||
float filter_scale;
|
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->n0 = in_first_pixel;
|
||||||
contributor->n1 = in_last_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++)
|
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];
|
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_ASSERT(total_filter > 0.9);
|
||||||
STBIR__DEBUG_ASSERT(total_filter < 1.1f); // Make sure it's not way off.
|
STBIR_ASSERT(total_filter < 1.1f); // Make sure it's not way off.
|
||||||
|
|
||||||
// Make sure the sum of all coefficients is 1.
|
// Make sure the sum of all coefficients is 1.
|
||||||
filter_scale = 1 / total_filter;
|
filter_scale = 1 / total_filter;
|
||||||
@ -1087,12 +1079,12 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
|
|||||||
{
|
{
|
||||||
int i;
|
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->n0 = out_first_pixel;
|
||||||
contributor->n1 = out_last_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++)
|
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;
|
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--)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
STBIR__DEBUG_ASSERT(total > 0.9f);
|
STBIR_ASSERT(total > 0.9f);
|
||||||
STBIR__DEBUG_ASSERT(total < 1.1f);
|
STBIR_ASSERT(total < 1.1f);
|
||||||
|
|
||||||
scale = 1 / total;
|
scale = 1 / total;
|
||||||
|
|
||||||
@ -1364,7 +1356,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
|
STBIR_ASSERT(!"Unknown type/colorspace/channels combination.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1425,7 +1417,7 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
|
|||||||
else
|
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;
|
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));
|
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_group = coefficient_width * x;
|
||||||
int coefficient_counter = 0;
|
int coefficient_counter = 0;
|
||||||
|
|
||||||
STBIR__DEBUG_ASSERT(n1 >= n0);
|
STBIR_ASSERT(n1 >= n0);
|
||||||
STBIR__DEBUG_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin);
|
STBIR_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin);
|
||||||
STBIR__DEBUG_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin);
|
STBIR_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin);
|
||||||
STBIR__DEBUG_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
|
STBIR_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 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
|
||||||
|
|
||||||
switch (channels) {
|
switch (channels) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -1469,7 +1461,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
|
|||||||
{
|
{
|
||||||
int in_pixel_index = k * 1;
|
int in_pixel_index = k * 1;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
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 + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1478,7 +1470,7 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
|
|||||||
{
|
{
|
||||||
int in_pixel_index = k * 2;
|
int in_pixel_index = k * 2;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
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 + 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 + 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;
|
int in_pixel_index = k * 3;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
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 + 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 + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
|
||||||
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * 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;
|
int in_pixel_index = k * 4;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
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 + 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 + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
|
||||||
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * 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;
|
int in_pixel_index = k * channels;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
|
||||||
int c;
|
int c;
|
||||||
STBIR__DEBUG_ASSERT(coefficient != 0);
|
STBIR_ASSERT(coefficient != 0);
|
||||||
for (c = 0; c < channels; c++)
|
for (c = 0; c < channels; c++)
|
||||||
output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
|
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 filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin;
|
||||||
int max_x = input_w + filter_pixel_margin * 2;
|
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) {
|
switch (channels) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -1553,7 +1545,7 @@ static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n
|
|||||||
{
|
{
|
||||||
int out_pixel_index = k * 1;
|
int out_pixel_index = k * 1;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
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 + 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;
|
int out_pixel_index = k * 2;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
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 + 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 + 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;
|
int out_pixel_index = k * 3;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
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 + 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 + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
|
||||||
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * 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;
|
int out_pixel_index = k * 4;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
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 + 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 + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
|
||||||
output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * 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 c;
|
||||||
int out_pixel_index = k * channels;
|
int out_pixel_index = k * channels;
|
||||||
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
float coefficient = horizontal_coefficients[coefficient_group + k - n0];
|
||||||
STBIR__DEBUG_ASSERT(coefficient != 0);
|
STBIR_ASSERT(coefficient != 0);
|
||||||
for (c = 0; c < channels; c++)
|
for (c = 0; c < channels; c++)
|
||||||
output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
|
STBIR_ASSERT(!"Unknown type/colorspace/channels combination.");
|
||||||
break;
|
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;
|
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);
|
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;
|
n0 = vertical_contributors[contributor].n0;
|
||||||
n1 = vertical_contributors[contributor].n1;
|
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++)
|
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 scale_ratio = stbir_info->vertical_scale;
|
||||||
float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio;
|
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++)
|
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__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)
|
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 pixel_margin = stbir_info->vertical_filter_pixel_margin;
|
||||||
int max_y = stbir_info->input_h + 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++)
|
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__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)
|
if (out_last_scanline < 0 || out_first_scanline >= output_h)
|
||||||
continue;
|
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->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0);
|
||||||
info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0);
|
info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0);
|
||||||
|
|
||||||
info->horizontal_shift = s0 * info->input_w / (s1 - s0);
|
info->horizontal_shift = s0 * info->output_w / (s1 - s0);
|
||||||
info->vertical_shift = t0 * info->input_h / (t1 - t0);
|
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->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float);
|
||||||
info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_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
|
else
|
||||||
{
|
{
|
||||||
@ -2388,7 +2380,7 @@ static int stbir__resize_allocated(stbir__info *info,
|
|||||||
info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float);
|
info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float);
|
||||||
info->encode_buffer = NULL;
|
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
|
#undef STBIR__NEXT_MEMPTR
|
||||||
@ -2409,10 +2401,10 @@ static int stbir__resize_allocated(stbir__info *info,
|
|||||||
STBIR_PROGRESS_REPORT(1);
|
STBIR_PROGRESS_REPORT(1);
|
||||||
|
|
||||||
#ifdef STBIR_DEBUG_OVERWRITE_TEST
|
#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_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_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_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_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -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
|
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
@ -102,12 +102,13 @@ CREDITS:
|
|||||||
Sergio Gonzalez
|
Sergio Gonzalez
|
||||||
Jonas Karlsson
|
Jonas Karlsson
|
||||||
Filip Wasil
|
Filip Wasil
|
||||||
|
Thatcher Ulrich
|
||||||
|
|
||||||
LICENSE
|
LICENSE
|
||||||
|
|
||||||
This software is in the public domain. Where that dedication is not
|
This software is dual-licensed to the public domain and under the following
|
||||||
recognized, you are granted a perpetual, irrevocable license to copy,
|
license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||||
distribute, and modify this file as you see fit.
|
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;
|
unsigned int bitbuf=0;
|
||||||
int i,j, bitcount=0;
|
int i,j, bitcount=0;
|
||||||
unsigned char *out = NULL;
|
unsigned char *out = NULL;
|
||||||
unsigned char **hash_table[stbiw__ZHASH]; // 64KB on the stack!
|
unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
|
||||||
if (quality < 5) quality = 5;
|
if (quality < 5) quality = 5;
|
||||||
|
|
||||||
stbiw__sbpush(out, 0x78); // DEFLATE 32K window
|
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)
|
for (i=0; i < stbiw__ZHASH; ++i)
|
||||||
(void) stbiw__sbfree(hash_table[i]);
|
(void) stbiw__sbfree(hash_table[i]);
|
||||||
|
STBIW_FREE(hash_table);
|
||||||
|
|
||||||
{
|
{
|
||||||
// compute adler32 on input
|
// 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
|
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
|
||||||
/* Revision history
|
/* Revision history
|
||||||
|
1.02 (2016-04-02)
|
||||||
|
avoid allocating large structures on the stack
|
||||||
1.01 (2016-01-16)
|
1.01 (2016-01-16)
|
||||||
STBIW_REALLOC_SIZED: support allocators with no realloc support
|
STBIW_REALLOC_SIZED: support allocators with no realloc support
|
||||||
avoid race-condition in crc initialization
|
avoid race-condition in crc initialization
|
||||||
|
@ -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
|
// Sean Barrett 2014
|
||||||
//
|
//
|
||||||
// Useful for e.g. packing rectangular textures into an atlas.
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||||||
@ -28,14 +28,22 @@
|
|||||||
// Minor features
|
// Minor features
|
||||||
// Martins Mozeiko
|
// Martins Mozeiko
|
||||||
// Bugfixes / warning fixes
|
// Bugfixes / warning fixes
|
||||||
// [your name could be here]
|
// Jeremy Jaussaud
|
||||||
//
|
//
|
||||||
// Version history:
|
// 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.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||||
// 0.01: initial release
|
// 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,12 +549,16 @@ 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);
|
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||||
|
|
||||||
for (i=0; i < num_rects; ++i) {
|
for (i=0; i < num_rects; ++i) {
|
||||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||||
if (fr.prev_link) {
|
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||||
rects[i].x = (stbrp_coord) fr.x;
|
|
||||||
rects[i].y = (stbrp_coord) fr.y;
|
|
||||||
} else {
|
} else {
|
||||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
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;
|
||||||
|
rects[i].y = (stbrp_coord) fr.y;
|
||||||
|
} else {
|
||||||
|
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
// authored from 2009-2015 by Sean Barrett / RAD Game Tools
|
||||||
//
|
//
|
||||||
// This library processes TrueType files:
|
// This library processes TrueType files:
|
||||||
@ -21,6 +21,10 @@
|
|||||||
// Mikko Mononen: compound shape support, more cmap formats
|
// Mikko Mononen: compound shape support, more cmap formats
|
||||||
// Tor Andersson: kerning, subpixel rendering
|
// Tor Andersson: kerning, subpixel rendering
|
||||||
//
|
//
|
||||||
|
// Misc other:
|
||||||
|
// Ryan Gordon
|
||||||
|
// Simon Glass
|
||||||
|
//
|
||||||
// Bug/warning reports/fixes:
|
// Bug/warning reports/fixes:
|
||||||
// "Zer" on mollyrocket (with fix)
|
// "Zer" on mollyrocket (with fix)
|
||||||
// Cass Everitt
|
// Cass Everitt
|
||||||
@ -45,11 +49,10 @@
|
|||||||
// Thomas Fields
|
// Thomas Fields
|
||||||
// Derek Vinyard
|
// Derek Vinyard
|
||||||
//
|
//
|
||||||
// Misc other:
|
|
||||||
// Ryan Gordon
|
|
||||||
//
|
|
||||||
// VERSION HISTORY
|
// 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.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.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;
|
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
|
||||||
@ -68,9 +71,9 @@
|
|||||||
//
|
//
|
||||||
// LICENSE
|
// LICENSE
|
||||||
//
|
//
|
||||||
// This software is in the public domain. Where that dedication is not
|
// This software is dual-licensed to the public domain and under the following
|
||||||
// recognized, you are granted a perpetual, irrevocable license to copy,
|
// license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||||
// distribute, and modify this file as you see fit.
|
// publish, and distribute this file as you see fit.
|
||||||
//
|
//
|
||||||
// USAGE
|
// USAGE
|
||||||
//
|
//
|
||||||
@ -406,6 +409,11 @@ int main(int arg, char **argv)
|
|||||||
#define STBTT_sqrt(x) sqrt(x)
|
#define STBTT_sqrt(x) sqrt(x)
|
||||||
#endif
|
#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
|
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
|
||||||
#ifndef STBTT_malloc
|
#ifndef STBTT_malloc
|
||||||
#include <stdlib.h>
|
#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 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.
|
// the stack or as a global or etc, but you should treat it as opaque.
|
||||||
typedef struct stbtt_fontinfo
|
struct stbtt_fontinfo
|
||||||
{
|
{
|
||||||
void * userdata;
|
void * userdata;
|
||||||
unsigned char * data; // pointer to .ttf file
|
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 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 index_map; // a cmap mapping for our chosen character encoding
|
||||||
int indexToLocFormat; // format needed to map from glyph index to glyph
|
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);
|
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
|
// 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
|
#define STBTT_RASTERIZER_VERSION 2
|
||||||
#endif
|
#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
|
// 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));
|
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);
|
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;
|
int y,j=0, i;
|
||||||
float scanline_data[129], *scanline, *scanline2;
|
float scanline_data[129], *scanline, *scanline2;
|
||||||
|
|
||||||
|
STBTT__NOTUSED(vsubsample);
|
||||||
|
|
||||||
if (result->w > 64)
|
if (result->w > 64)
|
||||||
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
|
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
|
||||||
else
|
else
|
||||||
@ -2129,7 +2145,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
|
|||||||
int m;
|
int m;
|
||||||
sum += scanline2[i];
|
sum += scanline2[i];
|
||||||
k = scanline[i] + sum;
|
k = scanline[i] + sum;
|
||||||
k = (float) fabs(k)*255 + 0.5f;
|
k = (float) STBTT_fabs(k)*255 + 0.5f;
|
||||||
m = (int) k;
|
m = (int) k;
|
||||||
if (m > 255) m = 255;
|
if (m > 255) m = 255;
|
||||||
result->pixels[j*result->stride + i] = (unsigned char) m;
|
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_x == 0) scale_x = scale_y;
|
||||||
if (scale_y == 0) {
|
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;
|
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
|
#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;
|
typedef int stbrp_coord;
|
||||||
|
|
||||||
@ -3205,6 +3219,10 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
|
|||||||
|
|
||||||
// FULL VERSION HISTORY
|
// 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.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.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;
|
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
|
||||||
|
112
src/stb_vorbis.c
112
src/stb_vorbis.c
@ -168,6 +168,9 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh))
|
#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh))
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#else // STB_VORBIS_NO_CRT
|
#else // STB_VORBIS_NO_CRT
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
@ -1484,85 +1487,6 @@ static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **out
|
|||||||
return TRUE;
|
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)
|
static int predict_point(int x, int x0, int x1, int y0, int y1)
|
||||||
{
|
{
|
||||||
int dy = y1 - y0;
|
int dy = y1 - y0;
|
||||||
@ -1941,6 +1865,11 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
|
|||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
CHECK(f);
|
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);
|
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);
|
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;
|
c->lookup_type = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3515,11 +3444,11 @@ static int start_decoder(vorb *f)
|
|||||||
if (c->sequence_p)
|
if (c->sequence_p)
|
||||||
last = val;
|
last = val;
|
||||||
}
|
}
|
||||||
setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
|
|
||||||
}
|
}
|
||||||
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
|
#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK
|
||||||
skip:;
|
skip:;
|
||||||
#endif
|
#endif
|
||||||
|
setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values);
|
||||||
|
|
||||||
CHECK(f);
|
CHECK(f);
|
||||||
}
|
}
|
||||||
@ -4045,7 +3974,7 @@ int stb_vorbis_decode_frame_pushdata(
|
|||||||
while (get8_packet(f) != EOP)
|
while (get8_packet(f) != EOP)
|
||||||
if (f->eof) break;
|
if (f->eof) break;
|
||||||
*samples = 0;
|
*samples = 0;
|
||||||
return f->stream - data;
|
return (int) (f->stream - data);
|
||||||
}
|
}
|
||||||
if (error == VORBIS_continued_packet_flag_invalid) {
|
if (error == VORBIS_continued_packet_flag_invalid) {
|
||||||
if (f->previous_length == 0) {
|
if (f->previous_length == 0) {
|
||||||
@ -4055,7 +3984,7 @@ int stb_vorbis_decode_frame_pushdata(
|
|||||||
while (get8_packet(f) != EOP)
|
while (get8_packet(f) != EOP)
|
||||||
if (f->eof) break;
|
if (f->eof) break;
|
||||||
*samples = 0;
|
*samples = 0;
|
||||||
return f->stream - data;
|
return (int) (f->stream - data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if we get an error while parsing, what to do?
|
// 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;
|
if (channels) *channels = f->channels;
|
||||||
*samples = len;
|
*samples = len;
|
||||||
*output = f->outputs;
|
*output = f->outputs;
|
||||||
return f->stream - data;
|
return (int) (f->stream - data);
|
||||||
}
|
}
|
||||||
|
|
||||||
stb_vorbis *stb_vorbis_open_pushdata(
|
stb_vorbis *stb_vorbis_open_pushdata(
|
||||||
@ -4098,7 +4027,7 @@ stb_vorbis *stb_vorbis_open_pushdata(
|
|||||||
f = vorbis_alloc(&p);
|
f = vorbis_alloc(&p);
|
||||||
if (f) {
|
if (f) {
|
||||||
*f = p;
|
*f = p;
|
||||||
*data_used = f->stream - data;
|
*data_used = (int) (f->stream - data);
|
||||||
*error = 0;
|
*error = 0;
|
||||||
return f;
|
return f;
|
||||||
} else {
|
} else {
|
||||||
@ -4113,9 +4042,9 @@ unsigned int stb_vorbis_get_file_offset(stb_vorbis *f)
|
|||||||
#ifndef STB_VORBIS_NO_PUSHDATA_API
|
#ifndef STB_VORBIS_NO_PUSHDATA_API
|
||||||
if (f->push_mode) return 0;
|
if (f->push_mode) return 0;
|
||||||
#endif
|
#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
|
#ifndef STB_VORBIS_NO_STDIO
|
||||||
return ftell(f->f) - f->f_start;
|
return (unsigned int) (ftell(f->f) - f->f_start);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4611,7 +4540,7 @@ stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *er
|
|||||||
stb_vorbis *f, p;
|
stb_vorbis *f, p;
|
||||||
vorbis_init(&p, alloc);
|
vorbis_init(&p, alloc);
|
||||||
p.f = file;
|
p.f = file;
|
||||||
p.f_start = ftell(file);
|
p.f_start = (uint32) ftell(file);
|
||||||
p.stream_len = length;
|
p.stream_len = length;
|
||||||
p.close_on_free = close_on_free;
|
p.close_on_free = close_on_free;
|
||||||
if (start_decoder(&p)) {
|
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)
|
stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc)
|
||||||
{
|
{
|
||||||
unsigned int len, start;
|
unsigned int len, start;
|
||||||
start = ftell(file);
|
start = (unsigned int) ftell(file);
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
len = ftell(file) - start;
|
len = (unsigned int) (ftell(file) - start);
|
||||||
fseek(file, start, SEEK_SET);
|
fseek(file, start, SEEK_SET);
|
||||||
return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len);
|
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
|
#endif // STB_VORBIS_NO_PULLDATA_API
|
||||||
|
|
||||||
/* Version history
|
/* 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
|
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
|
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)
|
1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
|
||||||
|
@ -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/
|
// http://nothings.org/stb_vorbis/
|
||||||
//
|
//
|
||||||
// Original version written by Sean Barrett in 2007.
|
// Original version written by Sean Barrett in 2007.
|
||||||
@ -9,9 +9,9 @@
|
|||||||
//
|
//
|
||||||
// LICENSE
|
// LICENSE
|
||||||
//
|
//
|
||||||
// This software is in the public domain. Where that dedication is not
|
// This software is dual-licensed to the public domain and under the following
|
||||||
// recognized, you are granted a perpetual, irrevocable license to copy,
|
// license: you are granted a perpetual, irrevocable license to copy, modify,
|
||||||
// distribute, and modify this file as you see fit.
|
// publish, and distribute this file as you see fit.
|
||||||
//
|
//
|
||||||
// No warranty for any purpose is expressed or implied by the author (nor
|
// 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.
|
// by RAD Game Tools). Report bugs and send enhancements to the author.
|
||||||
@ -31,11 +31,14 @@
|
|||||||
// Terje Mathisen Niklas Frykholm Andy Hill
|
// Terje Mathisen Niklas Frykholm Andy Hill
|
||||||
// Casey Muratori John Bolton Gargaj
|
// Casey Muratori John Bolton Gargaj
|
||||||
// Laurent Gomila Marc LeBlanc Ronny Chevalier
|
// Laurent Gomila Marc LeBlanc Ronny Chevalier
|
||||||
// Bernhard Wodo Evan Balster "alxprd"@github
|
// Bernhard Wodo Evan Balster alxprd@github
|
||||||
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
|
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
|
||||||
// Phillip Bennefall Rohit
|
// Phillip Bennefall Rohit Thiago Goulart
|
||||||
|
// manxorist@github saga musix
|
||||||
//
|
//
|
||||||
// Partial history:
|
// 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.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)
|
// 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson)
|
||||||
// some crash fixes when out of memory or with corrupt files
|
// some crash fixes when out of memory or with corrupt files
|
||||||
@ -72,11 +75,6 @@
|
|||||||
#include "utils.h" // Android fopen function map
|
#include "utils.h" // Android fopen function map
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// RaySan: Added for Linux
|
|
||||||
#ifdef __linux
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user