1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
diff --git a/stb_image.h b/stb_image.h
index a381630..ea438cd 100644
--- a/stb_image.h
+++ b/stb_image.h
@@ -2492,11 +2492,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
stbi__uint32 i,j,stride = x*out_n;
int k;
int img_n = s->img_n; // copy it into a local for later
+ int bpp = 8;
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
a->out = (stbi_uc *) stbi__malloc(x * y * out_n);
if (!a->out) return stbi__err("outofmem", "Out of memory");
if (s->img_x == x && s->img_y == y) {
- if (raw_len != (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
+ if (raw_len == (img_n * x / 8 + 1) * y) {
+ bpp = 1;
+ } else if (raw_len != (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
} else { // interlaced:
if (raw_len < (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
}
@@ -2521,8 +2524,13 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
}
if (img_n != out_n) cur[img_n] = 255;
raw += img_n;
+ if (bpp == 1) {
+ cur += out_n * 16;
+ } else {
cur += out_n;
+ }
prior += out_n;
+ char l;
// this is a little gross, so that we don't switch per-pixel or per-component
if (img_n == out_n) {
#define CASE(f) \
@@ -2530,7 +2538,22 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \
for (k=0; k < img_n; ++k)
switch (filter) {
- CASE(STBI__F_none) cur[k] = raw[k]; break;
+ case STBI__F_none:
+ for (i=(x - 1) * bpp / 8; i >= 1; --i) {
+ for (k = 0; k < img_n + 1; ++k) {
+ if (bpp == 1) {
+ for (l = 0; l < 8; ++l) {
+ cur[(k - 1) * 8 - l] = (raw[k - 1] >> l & 1) * 0xff;
+ }
+ } else {
+ cur[k] = raw[k];
+ }
+ }
+ raw += img_n;
+ cur += img_n * 8 / bpp;
+ prior += img_n;
+ }
+ break;
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-img_n]); 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-img_n])>>1)); break;
@@ -2744,7 +2767,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
- depth = stbi__get8(s); if (depth != 8) return stbi__err("8bit only","PNG not supported: 8-bit only");
+ depth = stbi__get8(s); if (depth != 8 && depth != 1) return stbi__err("8bit/1bit only","PNG not supported: 8-bit/1-bit only");
color = stbi__get8(s); if (color > 6) 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");
@@ -3853,6 +3876,8 @@ typedef struct
int max_x, max_y;
int cur_x, cur_y;
int line_size;
+ int loop_count;
+ int delay;
} stbi__gif;
static int stbi__gif_test_raw(stbi__context *s)
@@ -4123,19 +4148,52 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
return o;
}
- case 0x21: // Comment Extension.
+ case 0x21: // Extension Introducer
{
int len;
- if (stbi__get8(s) == 0xF9) { // Graphic Control Extension.
- len = stbi__get8(s);
+ switch (stbi__get8(s)) {
+ case 0x01: // Plain Text Extension
+ break;
+ case 0x21: // Comment Extension
+ break;
+ case 0xF9: // Graphic Control Extension
+ len = stbi__get8(s); // block size
if (len == 4) {
g->eflags = stbi__get8(s);
- stbi__get16le(s); // delay
+ g->delay = stbi__get16le(s); // delay
g->transparent = stbi__get8(s);
} else {
stbi__skip(s, len);
break;
}
+ break;
+ case 0xFF: // Application Extension
+ len = stbi__get8(s); // block size
+ if (len != 11) break;
+ if (stbi__get8(s) != 'N') break;
+ if (stbi__get8(s) != 'E') break;
+ if (stbi__get8(s) != 'T') break;
+ if (stbi__get8(s) != 'S') break;
+ if (stbi__get8(s) != 'C') break;
+ if (stbi__get8(s) != 'A') break;
+ if (stbi__get8(s) != 'P') break;
+ if (stbi__get8(s) != 'E') break;
+ if (stbi__get8(s) != '2') break;
+ if (stbi__get8(s) != '.') break;
+ if (stbi__get8(s) != '0') break;
+ if (stbi__get8(s) != 0x03) break;
+ // loop count
+ switch (stbi__get8(s)) {
+ case 0x00:
+ g->loop_count = 1;
+ break;
+ case 0x01:
+ g->loop_count = stbi__get16le(s);
+ break;
+ }
+ break;
+ default:
+ break;
}
while ((len = stbi__get8(s)) != 0)
stbi__skip(s, len);
|