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);
