# HG changeset patch # User Matti Hamalainen # Date 1425005173 -7200 # Node ID 1832ac20edb22448582592fca85ee12f8bfec16a # Parent 36aec8ff670a9b34e15946bae61833487e8eb294 Clean up dmzlib and use it in stb_image. diff -r 36aec8ff670a -r 1832ac20edb2 src/dmzlib.c --- 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 diff -r 36aec8ff670a -r 1832ac20edb2 src/dmzlib.h --- 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 } diff -r 36aec8ff670a -r 1832ac20edb2 src/stb_image.c --- 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;