feat(kernel): ⬆️ update stb headers

This commit is contained in:
2025-05-18 19:42:50 +00:00
parent 4929b76c7c
commit 8103caa52c
2 changed files with 17270 additions and 9226 deletions

View File

@ -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