changeset 960:1832ac20edb2

Clean up dmzlib and use it in stb_image.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 27 Feb 2015 04:46:13 +0200
parents 36aec8ff670a
children 70bcb294a437
files src/dmzlib.c src/dmzlib.h src/stb_image.c
diffstat 3 files changed, 89 insertions(+), 153 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmzlib.c	Fri Feb 27 04:44:48 2015 +0200
+++ b/src/dmzlib.c	Fri Feb 27 04:46:13 2015 +0200
@@ -12,7 +12,7 @@
 
 
 // @TODO: should statically initialize these for optimal thread safety
-static Uint8 stbi__zdefault_length[288], stbi__zdefault_distance[32];
+static Uint8 dm_zdefault_length[288], dm_zdefault_distance[32];
 
 
 void dmZLibInit()
@@ -21,19 +21,19 @@
 
     // use <= to match clearly with spec
     for (i = 0; i <= 143; i++)
-        stbi__zdefault_length[i] = 8;
+        dm_zdefault_length[i] = 8;
 
     for (; i <= 255; i++)
-        stbi__zdefault_length[i] = 9;
+        dm_zdefault_length[i] = 9;
 
     for (; i <= 279; i++)
-        stbi__zdefault_length[i] = 7;
+        dm_zdefault_length[i] = 7;
 
     for (; i <= 287; i++)
-        stbi__zdefault_length[i] = 8;
+        dm_zdefault_length[i] = 8;
 
     for (i = 0; i <= 31; i++)
-        stbi__zdefault_distance[i] = 5;
+        dm_zdefault_distance[i] = 5;
 }
 
 
@@ -56,7 +56,7 @@
 }
 
 
-static int stbi__zbuild_huffman(DMZHuffmanContext * ctx, const Uint8 * sizelist, const int num)
+static int dmZLibBuildHuffmanTables(DMZHuffmanContext * ctx, const Uint8 * sizelist, const int num)
 {
     int i, k = 0;
     int code, next_code[16], sizes[17];
@@ -123,7 +123,7 @@
 }
 
 
-static inline Uint8 stbi__zget8(DMZLibContext * ctx)
+static inline Uint8 dmZGet8(DMZLibContext * ctx)
 {
     if (ctx->zbuffer >= ctx->zbufferEnd)
         return 0;
@@ -137,14 +137,14 @@
     do
     {
         DMSTBI_ASSERT(ctx->codeBuffer < (1U << ctx->numBits));
-        ctx->codeBuffer |= stbi__zget8(ctx) << ctx->numBits;
+        ctx->codeBuffer |= dmZGet8(ctx) << ctx->numBits;
         ctx->numBits += 8;
     }
     while (ctx->numBits <= 24);
 }
 
 
-static inline unsigned int stbi__zreceive(DMZLibContext * ctx, int n)
+static inline unsigned int dmZReceive(DMZLibContext * ctx, int n)
 {
     unsigned int val;
 
@@ -162,6 +162,7 @@
 static int stbi__zhuffman_decode_slowpath(DMZLibContext * ctx, DMZHuffmanContext * huff, int *val)
 {
     int b, s, k;
+    *val = 0;
 
     // not resolved by fast table, so compute it the slow way
     // use jpeg approach, which requires MSbits at top
@@ -270,7 +271,7 @@
 };
 
 
-static int stbi__parse_huffman_block(DMZLibContext * a)
+static int dmZLibParseHuffmanBlock(DMZLibContext * a)
 {
     Uint8 *zout = a->zout;
     for (;;)
@@ -303,14 +304,14 @@
 
             len = stbi__zlength_base[z];
             if (stbi__zlength_extra[z])
-                len += stbi__zreceive(a, stbi__zlength_extra[z]);
+                len += dmZReceive(a, stbi__zlength_extra[z]);
 
             if ((ret = stbi__zhuffman_decode(a, &a->zdistance, &z)) != DMERR_OK)
                 return ret;
 
             dist = stbi__zdist_base[z];
             if (stbi__zdist_extra[z])
-                dist += stbi__zreceive(a, stbi__zdist_extra[z]);
+                dist += dmZReceive(a, stbi__zdist_extra[z]);
 
             if (zout - a->zoutStart < dist)
             {
@@ -347,26 +348,26 @@
 };
 
 
-static int stbi__compute_huffman_codes(DMZLibContext * a)
+static int dmZLibComputeHuffmanCodes(DMZLibContext * a)
 {
     DMZHuffmanContext z_codelength;
-    Uint8 lencodes[286 + 32 + 137];     //padding for maximum single op
-    Uint8 codelength_sizes[19];
+    Uint8 codeLengths[286 + 32 + 137];     //padding for maximum single op
+    Uint8 codeLengthSizes[19];
     int i, n, ret;
 
-    int hlit  = stbi__zreceive(a, 5) + 257;
-    int hdist = stbi__zreceive(a, 5) + 1;
-    int hclen = stbi__zreceive(a, 4) + 4;
+    int hlit  = dmZReceive(a, 5) + 257;
+    int hdist = dmZReceive(a, 5) + 1;
+    int hclen = dmZReceive(a, 4) + 4;
 
-    memset(codelength_sizes, 0, sizeof(codelength_sizes));
+    memset(codeLengthSizes, 0, sizeof(codeLengthSizes));
 
     for (i = 0; i < hclen; i++)
     {
-        int s = stbi__zreceive(a, 3);
-        codelength_sizes[length_dezigzag[i]] = (Uint8) s;
+        int s = dmZReceive(a, 3);
+        codeLengthSizes[length_dezigzag[i]] = (Uint8) s;
     }
 
-    if ((ret = stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) != DMERR_OK)
+    if ((ret = dmZLibBuildHuffmanTables(&z_codelength, codeLengthSizes, 19)) != DMERR_OK)
         return ret;
 
     n = 0;
@@ -379,25 +380,25 @@
         DMSTBI_ASSERT(c >= 0 && c < 19);
 
         if (c < 16)
-            lencodes[n++] = (Uint8) c;
+            codeLengths[n++] = (Uint8) c;
         else
         if (c == 16)
         {
-            c = stbi__zreceive(a, 2) + 3;
-            memset(lencodes + n, lencodes[n - 1], c);
+            c = dmZReceive(a, 2) + 3;
+            memset(codeLengths + n, codeLengths[n - 1], c);
             n += c;
         }
         else
         if (c == 17)
         {
-            c = stbi__zreceive(a, 3) + 3;
-            memset(lencodes + n, 0, c);
+            c = dmZReceive(a, 3) + 3;
+            memset(codeLengths + n, 0, c);
             n += c;
         }
         else
         {
-            c = stbi__zreceive(a, 7) + 11;
-            memset(lencodes + n, 0, c);
+            c = dmZReceive(a, 7) + 11;
+            memset(codeLengths + n, 0, c);
             n += c;
         }
     }
@@ -408,23 +409,23 @@
             "Bad huffman codelengths.\n");
     }
 
-    if ((ret = stbi__zbuild_huffman(&a->zlength, lencodes, hlit)) != DMERR_OK)
+    if ((ret = dmZLibBuildHuffmanTables(&a->zlength, codeLengths, hlit)) != DMERR_OK)
         return ret;
 
-    if ((ret = stbi__zbuild_huffman(&a->zdistance, lencodes + hlit, hdist)) != DMERR_OK)
+    if ((ret = dmZLibBuildHuffmanTables(&a->zdistance, codeLengths + hlit, hdist)) != DMERR_OK)
         return ret;
 
     return DMERR_OK;
 }
 
 
-static int stbi__parse_uncompressed_block(DMZLibContext * a)
+static int dmZLibParseUncompresedBlock(DMZLibContext * a)
 {
     Uint8 header[4];
     int len, nlen, k;
 
     if (a->numBits & 7)
-        stbi__zreceive(a, a->numBits & 7);     // discard
+        dmZReceive(a, a->numBits & 7);     // discard
 
     // drain the bit-packed data into header
     k = 0;
@@ -438,7 +439,7 @@
 
     // now fill header the normal way
     while (k < 4)
-        header[k++] = stbi__zget8(a);
+        header[k++] = dmZGet8(a);
 
     len  = (header[1] << 8) | header[0];
     nlen = (header[3] << 8) | header[2];
@@ -471,8 +472,8 @@
 
 int dmZLibParseHeader(DMZLibContext * ctx, BOOL checkPNG)
 {
-    int cmf = stbi__zget8(ctx);
-    int flags = stbi__zget8(ctx);
+    int cmf = dmZGet8(ctx);
+    int flags = dmZGet8(ctx);
     int cm = cmf & 15;
     // int cinfo = cmf >> 4;
 
@@ -508,11 +509,11 @@
     ctx->codeBuffer = 0;
     do
     {
-        final = stbi__zreceive(ctx, 1);
-        type = stbi__zreceive(ctx, 2);
+        final = dmZReceive(ctx, 1);
+        type  = dmZReceive(ctx, 2);
         if (type == 0)
         {
-            if ((ret = stbi__parse_uncompressed_block(ctx)) != DMERR_OK)
+            if ((ret = dmZLibParseUncompresedBlock(ctx)) != DMERR_OK)
                 return ret;
         }
         else
@@ -523,17 +524,17 @@
             if (type == 1)
             {
                 // use fixed code lengths
-                if ((ret = stbi__zbuild_huffman(&ctx->zlength, stbi__zdefault_length, 288)) != DMERR_OK)
+                if ((ret = dmZLibBuildHuffmanTables(&ctx->zlength, dm_zdefault_length, 288)) != DMERR_OK)
                     return ret;
 
-                if ((ret = stbi__zbuild_huffman(&ctx->zdistance, stbi__zdefault_distance, 32)) != DMERR_OK)
+                if ((ret = dmZLibBuildHuffmanTables(&ctx->zdistance, dm_zdefault_distance, 32)) != DMERR_OK)
                     return ret;
             }
             else
-            if ((ret = stbi__compute_huffman_codes(ctx)) != DMERR_OK)
+            if ((ret = dmZLibComputeHuffmanCodes(ctx)) != DMERR_OK)
                 return ret;
 
-            if ((ret = stbi__parse_huffman_block(ctx)) != DMERR_OK)
+            if ((ret = dmZLibParseHuffmanBlock(ctx)) != DMERR_OK)
                 return ret;
         }
     }
@@ -541,109 +542,3 @@
 
     return DMERR_OK;
 }
-
-
-Uint8 *stbi_zlib_decode_malloc_guesssize_headerflag(
-    const Uint8 *buffer, const size_t len,
-    const size_t initialSize, size_t *outLen,
-    BOOL parseHeader)
-{
-    DMZLibContext ctx;
-    Uint8 *outBuf;
-    int ret;
-
-    if ((outBuf = dmMalloc(initialSize)) == NULL)
-        return NULL;
-
-    ctx.zbuffer    = (Uint8 *) buffer;
-    ctx.zbufferEnd = (Uint8 *) buffer + len;
-    ctx.zout       = outBuf;
-    ctx.zoutStart  = outBuf;
-    ctx.zoutEnd    = outBuf + initialSize;
-    ctx.expandable = TRUE;
-
-    if (parseHeader && (ret = dmZLibParseHeader(&ctx, TRUE)) != DMERR_OK)
-    {
-        return dmError(ret,
-            "Failed to parse zlib header data.\n");
-    }
-
-    if ((ret = dmZLibDecode(&ctx)) != DMERR_OK)
-    {
-        if (outLen)
-            *outLen = ctx.zout - ctx.zoutStart;
-
-        return ctx.zoutStart;
-    }
-    else
-    {
-        dmFree(ctx.zoutStart);
-        return NULL;
-    }
-}
-
-
-#if 0
-
-Uint8 *stbi_zlib_decode_malloc(Uint8 const *buffer, int len, int *outlen)
-{
-    return stbi_zlib_decode_malloc_guesssize(buffer, len, DM_ZLIB_TMPBUF_SIZE, outlen);
-}
-
-
-int stbi_zlib_decode_buffer(Uint8 *obuffer, size_t olen, Uint8 const *ibuffer, size_t ilen, size_t *res)
-{
-    DMZLibContext ctx;
-    int ret;
-
-    ctx.zbuffer = (Uint8 *) ibuffer;
-    ctx.zbufferEnd = (Uint8 *) ibuffer + ilen;
-
-    if ((ret = stbi__do_zlib(&a, obuffer, olen, 0, 1)) != DMERR_OK)
-    {
-        *res = a.zout - a.zoutStart;
-        return DMERR_OK;
-    }
-    else
-        return ret;
-}
-
-
-Uint8 *stbi_zlib_decode_noheader_malloc(Uint8 const *buffer, int len, size_t *outlen)
-{
-    DMZLibContext ctx;
-    Uint8 *p = (Uint8 *) dmMalloc(DM_ZLIB_TMPBUF_SIZE);
-    if (p == NULL)
-        return NULL;
-
-    ctx.zbuffer = (Uint8 *) buffer;
-    ctx.zbufferEnd = (Uint8 *) buffer + len;
-
-    if (stbi__do_zlib(&ctx, p, DM_ZLIB_TMPBUF_SIZE, 1, 0))
-    {
-        if (outlen != NULL)
-            *outlen = (int) (ctx.zout - a.zoutStart);
-        return a.zoutStart;
-    }
-    else
-    {
-        dmFree(a.zoutStart);
-        return NULL;
-    }
-}
-
-
-int stbi_zlib_decode_noheader_buffer(Uint8 *obuffer, int olen, const Uint8 *ibuffer, int ilen)
-{
-    DMZLibContext a;
-
-    a.zbuffer = (Uint8 *) ibuffer;
-    a.zbufferEnd = (Uint8 *) ibuffer + ilen;
-
-    if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
-        return (int) (a.zout - a.zoutStart);
-    else
-        return -1;
-}
-
-#endif
--- a/src/dmzlib.h	Fri Feb 27 04:44:48 2015 +0200
+++ b/src/dmzlib.h	Fri Feb 27 04:46:13 2015 +0200
@@ -48,7 +48,6 @@
 int  dmZLibDecode(DMZLibContext * ctx);
 int  dmZLibParseHeader(DMZLibContext * ctx, BOOL checkPNG);
 
-Uint8 *stbi_zlib_decode_malloc_guesssize(const Uint8 *buffer, const size_t len, const size_t initialSize, size_t *outLen);
 
 #ifdef __cplusplus
 }
--- a/src/stb_image.c	Fri Feb 27 04:44:48 2015 +0200
+++ b/src/stb_image.c	Fri Feb 27 04:46:13 2015 +0200
@@ -4151,6 +4151,44 @@
    }
 }
 
+
+int stbi_zlib_decode_malloc_guesssize_headerflag(
+    Uint8 *inBuf, size_t inLen,
+    Uint8 **outBuf, size_t *outLen,
+    size_t initialSize,
+    BOOL parseHeader)
+{
+    DMZLibContext ctx;
+    int ret;
+
+    if ((*outBuf = dmMalloc(initialSize)) == NULL)
+        return 0;
+
+    ctx.zbuffer    = (Uint8 *) inBuf;
+    ctx.zbufferEnd = (Uint8 *) inBuf + inLen;
+    ctx.zout       = *outBuf;
+    ctx.zoutStart  = *outBuf;
+    ctx.zoutEnd    = *outBuf + initialSize;
+    ctx.expandable = TRUE;
+
+    if (parseHeader && (ret = dmZLibParseHeader(&ctx, TRUE)) != DMERR_OK)
+    {
+        return dmError(ret,
+            "Failed to parse zlib header data.\n");
+    }
+
+    if ((ret = dmZLibDecode(&ctx)) != DMERR_OK)
+    {
+        dmFree(*outBuf);
+        return ret;
+    }
+    
+    *outLen = ctx.zout - ctx.zoutStart;
+    return DMERR_OK;
+}
+
+
+
 #define STBI__PNG_TYPE(a,b,c,d)  (((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
 
 static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
@@ -4256,7 +4294,7 @@
          }
 
          case STBI__PNG_TYPE('I','E','N','D'): {
-            Uint32 raw_len, bpl;
+            size_t raw_len, bpl;
             if (first) return stbi__err("first not IHDR", "Corrupt PNG");
             if (scan != STBI__SCAN_load) return 1;
             if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
@@ -4264,7 +4302,11 @@
             bpl = (s->img_x * 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 */;
 
-            z->expanded = (Uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
+            if (stbi_zlib_decode_malloc_guesssize_headerflag(
+                z->idata, ioff,
+                &z->expanded, &raw_len,
+                raw_len, !is_iphone) != DMERR_OK)
+                return 0;
 
             if (z->expanded == NULL) return 0; // zlib should set error
             STBI_FREE(z->idata); z->idata = NULL;