mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-03 03:19:16 +00:00
feat(kernel): ⬆️ update stb headers
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
|
||||||
no warranty implied; use at your own risk
|
no warranty implied; use at your own risk
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
@ -48,6 +48,8 @@ LICENSE
|
|||||||
|
|
||||||
RECENT REVISION HISTORY:
|
RECENT REVISION HISTORY:
|
||||||
|
|
||||||
|
2.30 (2024-05-31) avoid erroneous gcc warning
|
||||||
|
2.29 (2023-05-xx) optimizations
|
||||||
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
|
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
|
||||||
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
|
||||||
2.26 (2020-07-13) many minor fixes
|
2.26 (2020-07-13) many minor fixes
|
||||||
@ -127,10 +129,6 @@ RECENT REVISION HISTORY:
|
|||||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||||
#define STBI_INCLUDE_STB_IMAGE_H
|
#define STBI_INCLUDE_STB_IMAGE_H
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
||||||
|
|
||||||
// DOCUMENTATION
|
// DOCUMENTATION
|
||||||
//
|
//
|
||||||
// Limitations:
|
// Limitations:
|
||||||
@ -1076,8 +1074,8 @@ static int stbi__addints_valid(int a, int b)
|
|||||||
return a <= INT_MAX - b;
|
return a <= INT_MAX - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 1 if the product of two signed shorts is valid, 0 on overflow.
|
// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
|
||||||
static int stbi__mul2shorts_valid(short a, short b)
|
static int stbi__mul2shorts_valid(int a, int b)
|
||||||
{
|
{
|
||||||
if (b == 0 || b == -1)
|
if (b == 0 || b == -1)
|
||||||
return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
|
return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
|
||||||
@ -3825,14 +3823,14 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
|
||||||
{
|
{
|
||||||
// some JPEGs have junk at end, skip over it but if we find what looks
|
// some JPEGs have junk at end, skip over it but if we find what looks
|
||||||
// like a valid marker, resume there
|
// like a valid marker, resume there
|
||||||
while (!stbi__at_eof(j->s))
|
while (!stbi__at_eof(j->s))
|
||||||
{
|
{
|
||||||
int x = stbi__get8(j->s);
|
stbi_uc x = stbi__get8(j->s);
|
||||||
while (x == 255)
|
while (x == 0xff)
|
||||||
{ // might be a marker
|
{ // might be a marker
|
||||||
if (stbi__at_eof(j->s))
|
if (stbi__at_eof(j->s))
|
||||||
return STBI__MARKER_none;
|
return STBI__MARKER_none;
|
||||||
@ -4041,9 +4039,9 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
|
|||||||
|
|
||||||
// interleave even and odd pixels, then undo scaling.
|
// interleave even and odd pixels, then undo scaling.
|
||||||
__m128i int0 = _mm_unpacklo_epi16(even, odd);
|
__m128i int0 = _mm_unpacklo_epi16(even, odd);
|
||||||
__m128i int1_ = _mm_unpackhi_epi16(even, odd);
|
__m128i int1 = _mm_unpackhi_epi16(even, odd);
|
||||||
__m128i de0 = _mm_srli_epi16(int0, 4);
|
__m128i de0 = _mm_srli_epi16(int0, 4);
|
||||||
__m128i de1 = _mm_srli_epi16(int1_, 4);
|
__m128i de1 = _mm_srli_epi16(int1, 4);
|
||||||
|
|
||||||
// pack and write output
|
// pack and write output
|
||||||
__m128i outv = _mm_packus_epi16(de0, de1);
|
__m128i outv = _mm_packus_epi16(de0, de1);
|
||||||
@ -4761,6 +4759,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
stbi_uc *zbuffer, *zbuffer_end;
|
stbi_uc *zbuffer, *zbuffer_end;
|
||||||
int num_bits;
|
int num_bits;
|
||||||
|
int hit_zeof_once;
|
||||||
stbi__uint32 code_buffer;
|
stbi__uint32 code_buffer;
|
||||||
|
|
||||||
char *zout;
|
char *zout;
|
||||||
@ -4835,10 +4834,26 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
|
|||||||
{
|
{
|
||||||
if (stbi__zeof(a))
|
if (stbi__zeof(a))
|
||||||
{
|
{
|
||||||
return -1; /* report error for unexpected end of data. */
|
if (!a->hit_zeof_once)
|
||||||
|
{
|
||||||
|
// This is the first time we hit eof, insert 16 extra padding btis
|
||||||
|
// to allow us to keep going; if we actually consume any of them
|
||||||
|
// though, that is invalid data. This is caught later.
|
||||||
|
a->hit_zeof_once = 1;
|
||||||
|
a->num_bits += 16; // add 16 implicit zero bits
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We already inserted our extra 16 padding bits and are again
|
||||||
|
// out, this stream is actually prematurely terminated.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
stbi__fill_bits(a);
|
stbi__fill_bits(a);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
|
||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
@ -4916,6 +4931,14 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|||||||
if (z == 256)
|
if (z == 256)
|
||||||
{
|
{
|
||||||
a->zout = zout;
|
a->zout = zout;
|
||||||
|
if (a->hit_zeof_once && a->num_bits < 16)
|
||||||
|
{
|
||||||
|
// The first time we hit zeof, we inserted 16 extra zero bits into our bit
|
||||||
|
// buffer so the decoder can just do its speculative decoding. But if we
|
||||||
|
// actually consumed any of those bits (which is the case when num_bits < 16),
|
||||||
|
// the stream actually read past the end so it is malformed.
|
||||||
|
return stbi__err("unexpected end", "Corrupt PNG");
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (z >= 286)
|
if (z >= 286)
|
||||||
@ -4932,7 +4955,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
|||||||
dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
dist += stbi__zreceive(a, stbi__zdist_extra[z]);
|
||||||
if (zout - a->zout_start < dist)
|
if (zout - a->zout_start < dist)
|
||||||
return stbi__err("bad dist", "Corrupt PNG");
|
return stbi__err("bad dist", "Corrupt PNG");
|
||||||
if (zout + len > a->zout_end)
|
if (len > a->zout_end - zout)
|
||||||
{
|
{
|
||||||
if (!stbi__zexpand(a, zout, len))
|
if (!stbi__zexpand(a, zout, len))
|
||||||
return 0;
|
return 0;
|
||||||
@ -5116,6 +5139,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
|
|||||||
return 0;
|
return 0;
|
||||||
a->num_bits = 0;
|
a->num_bits = 0;
|
||||||
a->code_buffer = 0;
|
a->code_buffer = 0;
|
||||||
|
a->hit_zeof_once = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
final = stbi__zreceive(a, 1);
|
final = stbi__zreceive(a, 1);
|
||||||
@ -5301,9 +5325,8 @@ enum
|
|||||||
STBI__F_up = 2,
|
STBI__F_up = 2,
|
||||||
STBI__F_avg = 3,
|
STBI__F_avg = 3,
|
||||||
STBI__F_paeth = 4,
|
STBI__F_paeth = 4,
|
||||||
// synthetic filters used for first scanline to avoid needing a dummy row of 0s
|
// synthetic filter used for first scanline to avoid needing a dummy row of 0s
|
||||||
STBI__F_avg_first,
|
STBI__F_avg_first
|
||||||
STBI__F_paeth_first
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static stbi_uc first_row_filter[5] =
|
static stbi_uc first_row_filter[5] =
|
||||||
@ -5312,23 +5335,52 @@ static stbi_uc first_row_filter[5] =
|
|||||||
STBI__F_sub,
|
STBI__F_sub,
|
||||||
STBI__F_none,
|
STBI__F_none,
|
||||||
STBI__F_avg_first,
|
STBI__F_avg_first,
|
||||||
STBI__F_paeth_first};
|
STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
|
||||||
|
};
|
||||||
|
|
||||||
static int stbi__paeth(int a, int b, int c)
|
static int stbi__paeth(int a, int b, int c)
|
||||||
{
|
{
|
||||||
int p = a + b - c;
|
// This formulation looks very different from the reference in the PNG spec, but is
|
||||||
int pa = abs(p - a);
|
// actually equivalent and has favorable data dependencies and admits straightforward
|
||||||
int pb = abs(p - b);
|
// generation of branch-free code, which helps performance significantly.
|
||||||
int pc = abs(p - c);
|
int thresh = c * 3 - (a + b);
|
||||||
if (pa <= pb && pa <= pc)
|
int lo = a < b ? a : b;
|
||||||
return a;
|
int hi = a < b ? b : a;
|
||||||
if (pb <= pc)
|
int t0 = (hi <= thresh) ? lo : c;
|
||||||
return b;
|
int t1 = (thresh <= lo) ? hi : t0;
|
||||||
return c;
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const stbi_uc stbi__depth_scale_table[9] = {0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01};
|
static const stbi_uc stbi__depth_scale_table[9] = {0, 0xff, 0x55, 0, 0x11, 0, 0, 0, 0x01};
|
||||||
|
|
||||||
|
// adds an extra all-255 alpha channel
|
||||||
|
// dest == src is legal
|
||||||
|
// img_n must be 1 or 3
|
||||||
|
static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// must process data backwards since we allow dest==src
|
||||||
|
if (img_n == 1)
|
||||||
|
{
|
||||||
|
for (i = x - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
dest[i * 2 + 1] = 255;
|
||||||
|
dest[i * 2 + 0] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STBI_ASSERT(img_n == 3);
|
||||||
|
for (i = x - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
dest[i * 4 + 3] = 255;
|
||||||
|
dest[i * 4 + 2] = src[i * 3 + 2];
|
||||||
|
dest[i * 4 + 1] = src[i * 3 + 1];
|
||||||
|
dest[i * 4 + 0] = src[i * 3 + 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
@ -5336,6 +5388,8 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
stbi__context *s = a->s;
|
stbi__context *s = a->s;
|
||||||
stbi__uint32 i, j, stride = x * out_n * bytes;
|
stbi__uint32 i, j, stride = x * out_n * bytes;
|
||||||
stbi__uint32 img_len, img_width_bytes;
|
stbi__uint32 img_len, img_width_bytes;
|
||||||
|
stbi_uc *filter_buf;
|
||||||
|
int all_ok = 1;
|
||||||
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
|
||||||
|
|
||||||
@ -5348,9 +5402,13 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
if (!a->out)
|
if (!a->out)
|
||||||
return stbi__err("outofmem", "Out of memory");
|
return stbi__err("outofmem", "Out of memory");
|
||||||
|
|
||||||
|
// note: error exits here don't need to clean up a->out individually,
|
||||||
|
// stbi__do_png always does on error.
|
||||||
if (!stbi__mad3sizes_valid(img_n, x, depth, 7))
|
if (!stbi__mad3sizes_valid(img_n, x, depth, 7))
|
||||||
return stbi__err("too large", "Corrupt PNG");
|
return stbi__err("too large", "Corrupt PNG");
|
||||||
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
|
||||||
|
if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes))
|
||||||
|
return stbi__err("too large", "Corrupt PNG");
|
||||||
img_len = (img_width_bytes + 1) * y;
|
img_len = (img_width_bytes + 1) * y;
|
||||||
|
|
||||||
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
|
||||||
@ -5359,266 +5417,167 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
|||||||
if (raw_len < img_len)
|
if (raw_len < img_len)
|
||||||
return stbi__err("not enough pixels", "Corrupt PNG");
|
return stbi__err("not enough pixels", "Corrupt PNG");
|
||||||
|
|
||||||
for (j = 0; j < y; ++j)
|
// Allocate two scan lines worth of filter workspace buffer.
|
||||||
{
|
filter_buf = (stbi_uc *)stbi__malloc_mad2(img_width_bytes, 2, 0);
|
||||||
stbi_uc *cur = a->out + stride * j;
|
if (!filter_buf)
|
||||||
stbi_uc *prior;
|
return stbi__err("outofmem", "Out of memory");
|
||||||
int filter = *raw++;
|
|
||||||
|
|
||||||
if (filter > 4)
|
|
||||||
return stbi__err("invalid filter", "Corrupt PNG");
|
|
||||||
|
|
||||||
|
// Filtering for low-bit-depth images
|
||||||
if (depth < 8)
|
if (depth < 8)
|
||||||
{
|
{
|
||||||
if (img_width_bytes > x)
|
|
||||||
return stbi__err("invalid width", "Corrupt PNG");
|
|
||||||
cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
|
|
||||||
filter_bytes = 1;
|
filter_bytes = 1;
|
||||||
width = img_width_bytes;
|
width = img_width_bytes;
|
||||||
}
|
}
|
||||||
prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
|
|
||||||
|
for (j = 0; j < y; ++j)
|
||||||
|
{
|
||||||
|
// cur/prior filter buffers alternate
|
||||||
|
stbi_uc *cur = filter_buf + (j & 1) * img_width_bytes;
|
||||||
|
stbi_uc *prior = filter_buf + (~j & 1) * img_width_bytes;
|
||||||
|
stbi_uc *dest = a->out + stride * j;
|
||||||
|
int nk = width * filter_bytes;
|
||||||
|
int filter = *raw++;
|
||||||
|
|
||||||
|
// check filter type
|
||||||
|
if (filter > 4)
|
||||||
|
{
|
||||||
|
all_ok = stbi__err("invalid filter", "Corrupt PNG");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if first row, use special filter that doesn't sample previous row
|
// if first row, use special filter that doesn't sample previous row
|
||||||
if (j == 0)
|
if (j == 0)
|
||||||
filter = first_row_filter[filter];
|
filter = first_row_filter[filter];
|
||||||
|
|
||||||
// handle first byte explicitly
|
// perform actual filtering
|
||||||
for (k = 0; k < filter_bytes; ++k)
|
|
||||||
{
|
|
||||||
switch (filter)
|
switch (filter)
|
||||||
{
|
{
|
||||||
case STBI__F_none:
|
|
||||||
cur[k] = raw[k];
|
|
||||||
break;
|
|
||||||
case STBI__F_sub:
|
|
||||||
cur[k] = raw[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] >> 1));
|
|
||||||
break;
|
|
||||||
case STBI__F_paeth:
|
|
||||||
cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0));
|
|
||||||
break;
|
|
||||||
case STBI__F_avg_first:
|
|
||||||
cur[k] = raw[k];
|
|
||||||
break;
|
|
||||||
case STBI__F_paeth_first:
|
|
||||||
cur[k] = raw[k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depth == 8)
|
|
||||||
{
|
|
||||||
if (img_n != out_n)
|
|
||||||
cur[img_n] = 255; // first pixel
|
|
||||||
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;
|
|
||||||
prior += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) * filter_bytes;
|
|
||||||
#define STBI__CASE(f) \
|
|
||||||
case f: \
|
|
||||||
for (k = 0; k < nk; ++k)
|
|
||||||
switch (filter)
|
|
||||||
{
|
|
||||||
// "none" filter turns into a memcpy here; make that explicit.
|
|
||||||
case STBI__F_none:
|
case STBI__F_none:
|
||||||
memcpy(cur, raw, nk);
|
memcpy(cur, raw, nk);
|
||||||
break;
|
break;
|
||||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); }
|
case STBI__F_sub:
|
||||||
|
memcpy(cur, raw, filter_bytes);
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]);
|
||||||
break;
|
break;
|
||||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); }
|
case STBI__F_up:
|
||||||
|
for (k = 0; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
|
||||||
break;
|
break;
|
||||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); }
|
case STBI__F_avg:
|
||||||
|
for (k = 0; k < filter_bytes; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1));
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1));
|
||||||
break;
|
break;
|
||||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); }
|
case STBI__F_paeth:
|
||||||
|
for (k = 0; k < filter_bytes; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
|
||||||
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes]));
|
||||||
break;
|
break;
|
||||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); }
|
case STBI__F_avg_first:
|
||||||
break;
|
memcpy(cur, raw, filter_bytes);
|
||||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); }
|
for (k = filter_bytes; k < nk; ++k)
|
||||||
|
cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#undef STBI__CASE
|
|
||||||
raw += nk;
|
raw += nk;
|
||||||
|
|
||||||
|
// expand decoded bits in cur to dest, also adding an extra alpha channel if desired
|
||||||
|
if (depth < 8)
|
||||||
|
{
|
||||||
|
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
||||||
|
stbi_uc *in = cur;
|
||||||
|
stbi_uc *out = dest;
|
||||||
|
stbi_uc inb = 0;
|
||||||
|
stbi__uint32 nsmp = x * img_n;
|
||||||
|
|
||||||
|
// expand bits to bytes first
|
||||||
|
if (depth == 4)
|
||||||
|
{
|
||||||
|
for (i = 0; i < nsmp; ++i)
|
||||||
|
{
|
||||||
|
if ((i & 1) == 0)
|
||||||
|
inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 4);
|
||||||
|
inb <<= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (depth == 2)
|
||||||
|
{
|
||||||
|
for (i = 0; i < nsmp; ++i)
|
||||||
|
{
|
||||||
|
if ((i & 3) == 0)
|
||||||
|
inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 6);
|
||||||
|
inb <<= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STBI_ASSERT(depth == 1);
|
||||||
|
for (i = 0; i < nsmp; ++i)
|
||||||
|
{
|
||||||
|
if ((i & 7) == 0)
|
||||||
|
inb = *in++;
|
||||||
|
*out++ = scale * (inb >> 7);
|
||||||
|
inb <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert alpha=255 values if desired
|
||||||
|
if (img_n != out_n)
|
||||||
|
stbi__create_png_alpha_expand8(dest, dest, x, img_n);
|
||||||
|
}
|
||||||
|
else if (depth == 8)
|
||||||
|
{
|
||||||
|
if (img_n == out_n)
|
||||||
|
memcpy(dest, cur, x * img_n);
|
||||||
|
else
|
||||||
|
stbi__create_png_alpha_expand8(dest, cur, x, img_n);
|
||||||
|
}
|
||||||
|
else if (depth == 16)
|
||||||
|
{
|
||||||
|
// convert the image data from big-endian to platform-native
|
||||||
|
stbi__uint16 *dest16 = (stbi__uint16 *)dest;
|
||||||
|
stbi__uint32 nsmp = x * img_n;
|
||||||
|
|
||||||
|
if (img_n == out_n)
|
||||||
|
{
|
||||||
|
for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
|
||||||
|
*dest16 = (cur[0] << 8) | cur[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STBI_ASSERT(img_n + 1 == out_n);
|
STBI_ASSERT(img_n + 1 == out_n);
|
||||||
#define STBI__CASE(f) \
|
|
||||||
case f: \
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
STBI__CASE(STBI__F_none) { cur[k] = raw[k]; }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); }
|
|
||||||
break;
|
|
||||||
STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#undef STBI__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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we make a separate pass to expand bits to pixels; for performance,
|
|
||||||
// this could run two scanlines behind the above code, so it won't
|
|
||||||
// intefere with filtering but will still be in the cache.
|
|
||||||
if (depth < 8)
|
|
||||||
{
|
|
||||||
for (j = 0; j < y; ++j)
|
|
||||||
{
|
|
||||||
stbi_uc *cur = a->out + stride * j;
|
|
||||||
stbi_uc *in_ = a->out + stride * j + x * out_n - img_width_bytes;
|
|
||||||
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
|
|
||||||
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
|
|
||||||
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
|
|
||||||
|
|
||||||
// note that the final byte might overshoot and write more data than desired.
|
|
||||||
// we can allocate enough data that this never writes out of memory, but it
|
|
||||||
// could also overwrite the next scanline. can it overwrite non-empty data
|
|
||||||
// on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
|
|
||||||
// so we need to explicitly clamp the final ones
|
|
||||||
|
|
||||||
if (depth == 4)
|
|
||||||
{
|
|
||||||
for (k = x * img_n; k >= 2; k -= 2, ++in_)
|
|
||||||
{
|
|
||||||
*cur++ = scale * ((*in_ >> 4));
|
|
||||||
*cur++ = scale * ((*in_) & 0x0f);
|
|
||||||
}
|
|
||||||
if (k > 0)
|
|
||||||
*cur++ = scale * ((*in_ >> 4));
|
|
||||||
}
|
|
||||||
else if (depth == 2)
|
|
||||||
{
|
|
||||||
for (k = x * img_n; k >= 4; k -= 4, ++in_)
|
|
||||||
{
|
|
||||||
*cur++ = scale * ((*in_ >> 6));
|
|
||||||
*cur++ = scale * ((*in_ >> 4) & 0x03);
|
|
||||||
*cur++ = scale * ((*in_ >> 2) & 0x03);
|
|
||||||
*cur++ = scale * ((*in_) & 0x03);
|
|
||||||
}
|
|
||||||
if (k > 0)
|
|
||||||
*cur++ = scale * ((*in_ >> 6));
|
|
||||||
if (k > 1)
|
|
||||||
*cur++ = scale * ((*in_ >> 4) & 0x03);
|
|
||||||
if (k > 2)
|
|
||||||
*cur++ = scale * ((*in_ >> 2) & 0x03);
|
|
||||||
}
|
|
||||||
else if (depth == 1)
|
|
||||||
{
|
|
||||||
for (k = x * img_n; k >= 8; k -= 8, ++in_)
|
|
||||||
{
|
|
||||||
*cur++ = scale * ((*in_ >> 7));
|
|
||||||
*cur++ = scale * ((*in_ >> 6) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_ >> 5) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_ >> 4) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_ >> 3) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_ >> 2) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_ >> 1) & 0x01);
|
|
||||||
*cur++ = scale * ((*in_) & 0x01);
|
|
||||||
}
|
|
||||||
if (k > 0)
|
|
||||||
*cur++ = scale * ((*in_ >> 7));
|
|
||||||
if (k > 1)
|
|
||||||
*cur++ = scale * ((*in_ >> 6) & 0x01);
|
|
||||||
if (k > 2)
|
|
||||||
*cur++ = scale * ((*in_ >> 5) & 0x01);
|
|
||||||
if (k > 3)
|
|
||||||
*cur++ = scale * ((*in_ >> 4) & 0x01);
|
|
||||||
if (k > 4)
|
|
||||||
*cur++ = scale * ((*in_ >> 3) & 0x01);
|
|
||||||
if (k > 5)
|
|
||||||
*cur++ = scale * ((*in_ >> 2) & 0x01);
|
|
||||||
if (k > 6)
|
|
||||||
*cur++ = scale * ((*in_ >> 1) & 0x01);
|
|
||||||
}
|
|
||||||
if (img_n != out_n)
|
|
||||||
{
|
|
||||||
int q;
|
|
||||||
// insert alpha = 255
|
|
||||||
cur = a->out + stride * j;
|
|
||||||
if (img_n == 1)
|
if (img_n == 1)
|
||||||
{
|
{
|
||||||
for (q = x - 1; q >= 0; --q)
|
for (i = 0; i < x; ++i, dest16 += 2, cur += 2)
|
||||||
{
|
{
|
||||||
cur[q * 2 + 1] = 255;
|
dest16[0] = (cur[0] << 8) | cur[1];
|
||||||
cur[q * 2 + 0] = cur[q];
|
dest16[1] = 0xffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STBI_ASSERT(img_n == 3);
|
STBI_ASSERT(img_n == 3);
|
||||||
for (q = x - 1; q >= 0; --q)
|
for (i = 0; i < x; ++i, dest16 += 4, cur += 6)
|
||||||
{
|
{
|
||||||
cur[q * 4 + 3] = 255;
|
dest16[0] = (cur[0] << 8) | cur[1];
|
||||||
cur[q * 4 + 2] = cur[q * 3 + 2];
|
dest16[1] = (cur[2] << 8) | cur[3];
|
||||||
cur[q * 4 + 1] = cur[q * 3 + 1];
|
dest16[2] = (cur[4] << 8) | cur[5];
|
||||||
cur[q * 4 + 0] = cur[q * 3 + 0];
|
dest16[3] = 0xffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
STBI_FREE(filter_buf);
|
||||||
{
|
if (!all_ok)
|
||||||
*cur16 = (cur[0] << 8) | cur[1];
|
return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -6012,12 +5971,12 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
|||||||
}
|
}
|
||||||
if (z->depth == 16)
|
if (z->depth == 16)
|
||||||
{
|
{
|
||||||
for (k = 0; k < s->img_n; ++k)
|
for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning
|
||||||
tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (k = 0; k < s->img_n; ++k)
|
for (k = 0; k < s->img_n && k < 3; ++k)
|
||||||
tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9146,8 +9105,6 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
|
|||||||
return stbi__is_16_main(&s);
|
return stbi__is_16_main(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
#endif // STB_IMAGE_IMPLEMENTATION
|
#endif // STB_IMAGE_IMPLEMENTATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user