Skip to content

Instantly share code, notes, and snippets.

@bitbegin
Forked from vurtun/defl.c
Created November 17, 2019 07:10
Show Gist options
  • Save bitbegin/971a12b2012d076f4bfd632f60bb823d to your computer and use it in GitHub Desktop.
Save bitbegin/971a12b2012d076f4bfd632f60bb823d to your computer and use it in GitHub Desktop.

Revisions

  1. @vurtun vurtun revised this gist Mar 2, 2019. 1 changed file with 44 additions and 21 deletions.
    65 changes: 44 additions & 21 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -11,8 +11,9 @@
    #include <assert.h>
    #include <string.h>

    #define SDEFL_DICT_BITS 12
    #define SDEFL_DICT_BITS 10
    #define SDEFL_DICT_SIZE (1 << SDEFL_DICT_BITS)
    #define SDEFL_CACHE_SIZE 4
    #define SDEFL_MAX_OFF (1 << 15)
    #define SDEFL_MIN_MATCH 3
    #define SDEFL_MAX_MATCH 258
    @@ -51,10 +52,20 @@ sdefl_ilog2(unsigned n)
    }
    static int
    sdefl_hash(const unsigned char *s)
    {
    unsigned a = s[0], b = s[1], c = s[2];
    unsigned x = (a << 16) | (b << 8) | c;
    x ^= x >> 16; x *= 0x7feb352d;
    x ^= x >> 15; x *= 0x846ca68b;
    x ^= x >> 16;
    return x & (SDEFL_DICT_SIZE-1);
    }
    static int
    sdefl_hash2(const unsigned char *s)
    {
    unsigned a = s[0], b = s[1], c = s[2];
    unsigned v = (a << 16) | (b << 8) | c;
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_DICT_SIZE-1);
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_CACHE_SIZE-1);
    }
    static unsigned char*
    sdefl_write(unsigned char *dst, struct sdefl *s, int code, int bitcnt)
    @@ -107,37 +118,49 @@ sdefl_lit(unsigned char *dst, struct sdefl *s, int c)
    static int
    sdeflate(unsigned char *out, const unsigned char *in, int size)
    {
    struct sdefl st;
    int i = 0;
    struct sdefl st = {0};
    unsigned char *dst = out;
    const unsigned char *e = in + size;

    const unsigned char *dict[SDEFL_DICT_SIZE];
    memset(dict,0,sizeof(dict));
    memset(&st,0,sizeof(st));
    const unsigned char *dict[SDEFL_DICT_SIZE][SDEFL_CACHE_SIZE] = {{0}};

    dst = sdefl_write(dst,&st,0x01,1); /* block */
    dst = sdefl_write(dst,&st,0x01,2); /* static huffman */
    while (in < e) {
    const unsigned char *ptr = in;
    const int h = sdefl_hash(in);
    const unsigned char **ent = &dict[h & (SDEFL_DICT_SIZE-1)];
    const unsigned char *sub = *ent; *ent = in;
    if (sub && (in > sub) && ((in-sub) < SDEFL_MAX_OFF) &&
    !memcmp(in,sub,SDEFL_MIN_MATCH)) {
    /* match */
    const unsigned char *s = sub + SDEFL_MIN_MATCH;
    int len, dist = (int)(in - sub);
    in += (len = SDEFL_MIN_MATCH);
    while ((*s == *in) && (len < SDEFL_MAX_MATCH))
    len++, s++, in++;
    dst = sdefl_match(dst, &st, dist, len);
    } else dst = sdefl_lit(dst, &st, *in++);
    const unsigned char **ents = dict[h & (SDEFL_DICT_SIZE-1)];

    for (i = 0; i < SDEFL_CACHE_SIZE; ++i) {
    const unsigned char *sub = ents[i];
    if (sub && (in > sub) && ((in-sub) < SDEFL_MAX_OFF) &&
    !memcmp(in,sub,SDEFL_MIN_MATCH)) {

    /* match */
    const unsigned char *s = sub + SDEFL_MIN_MATCH;
    int len, dist = (int)(in - sub);
    in += (len = SDEFL_MIN_MATCH);
    while ((*s == *in) && (len < SDEFL_MAX_MATCH))
    len++, s++, in++;
    dst = sdefl_match(dst, &st, dist, len);
    break;
    }
    }
    if (i == SDEFL_CACHE_SIZE)
    dst = sdefl_lit(dst, &st, *in++);

    const int c = sdefl_hash2(in);
    ents[c & SDEFL_CACHE_SIZE-1] = ptr;
    }
    /* zlib partial flush */
    dst = sdefl_write(dst, &st, 0, 7);
    dst = sdefl_write(dst, &st, 2, 10);
    dst = sdefl_write(dst, &st, 2, 3);
    return (int)(dst - out);
    }
    /* ===============================================================
    * SINFL
    * ===============================================================*/
    struct sinfl {
    int bits, bitcnt;
    unsigned lits[288];
    @@ -152,7 +175,7 @@ sinfl_read(const unsigned char **src, const unsigned char *end,
    const unsigned char *in = *src;
    int v = s->bits & ((1 << n)-1);
    s->bits >>= n;
    s->bitcnt = s->bitcnt - n;
    s->bitcnt = s->bitcnt - n;
    s->bitcnt = s->bitcnt < 0 ? 0 : s->bitcnt;
    while (s->bitcnt < 16 && in < end) {
    s->bits |= (*in++) << s->bitcnt;
    @@ -236,7 +259,7 @@ sinflate(unsigned char *out, const unsigned char *in, int size)
    len = sinfl_read(&in,e,&s,16);
    nlen = sinfl_read(&in,e,&s,16);
    in -= 2; s.bitcnt = 0;

    if (len > (e-in) || !len) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
  2. @vurtun vurtun revised this gist Feb 16, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -52,8 +52,8 @@ sdefl_ilog2(unsigned n)
    static int
    sdefl_hash(const unsigned char *s)
    {
    int a = s[0], b = s[1], c = s[2];
    int v = (a << 16) | (b << 8) | c;
    unsigned a = s[0], b = s[1], c = s[2];
    unsigned v = (a << 16) | (b << 8) | c;
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_DICT_SIZE-1);
    }
    static unsigned char*
  3. @vurtun vurtun revised this gist Feb 16, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ sdefl_npow2(unsigned n)
    return ++n;
    }
    static int
    sdefl_ilog2(int n)
    sdefl_ilog2(unsigned n)
    {
    #define lt(n) n,n,n,n, n,n,n,n, n,n,n,n ,n,n,n,n
    static const char tbl[256] = {-1,0,1,1,2,2,2,2,3,3,3,3,
  4. @vurtun vurtun revised this gist Feb 16, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,7 @@ static const unsigned char sdefl_mirror[256] = {
    R6(0), R6(2), R6(1), R6(3),
    };
    static int
    sdefl_npow2(int n)
    sdefl_npow2(unsigned n)
    {
    n--;
    n |= n >> 1;
  5. @vurtun vurtun revised this gist Jan 3, 2018. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -40,8 +40,9 @@ static int
    sdefl_ilog2(int n)
    {
    #define lt(n) n,n,n,n, n,n,n,n, n,n,n,n ,n,n,n,n
    static const char tbl[256] = {-1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4),lt(5),
    lt(5),lt(6),lt(6),lt(6),lt(6),lt(7),lt(7),lt(7),lt(7),lt(7),lt(7),lt(7),lt(7)
    static const char tbl[256] = {-1,0,1,1,2,2,2,2,3,3,3,3,
    3,3,3,3,lt(4),lt(5),lt(5),lt(6),lt(6),lt(6),lt(6),
    lt(7),lt(7),lt(7),lt(7),lt(7),lt(7),lt(7),lt(7)
    }; int tt, t;
    if ((tt = (n >> 16)))
    return (t = (tt >> 8)) ? 24+tbl[t]: 16+tbl[tt];
  6. @vurtun vurtun revised this gist Jan 2, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -209,9 +209,9 @@ sinflate(unsigned char *out, const unsigned char *in, int size)
    static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
    4,4,4,5,5,5,5,0,0,0};

    const unsigned char *e = in + size, *o = out;
    enum sinfl_states {hdr,stored,fixed,dyn,blk};
    enum sinfl_states state = hdr;
    const unsigned char *e = in + size, *o = out;
    struct sinfl s;
    int last = 0;

  7. @vurtun vurtun revised this gist Dec 29, 2017. No changes.
  8. @vurtun vurtun revised this gist Dec 29, 2017. No changes.
  9. @vurtun vurtun revised this gist Dec 20, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -236,7 +236,7 @@ sinflate(unsigned char *out, const unsigned char *in, int size)
    nlen = sinfl_read(&in,e,&s,16);
    in -= 2; s.bitcnt = 0;

    if (len > (e-in)) return (int)(out-o);
    if (len > (e-in) || !len) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
    state = hdr;
  10. @vurtun vurtun revised this gist Dec 18, 2017. 1 changed file with 14 additions and 14 deletions.
    28 changes: 14 additions & 14 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@
    #define SDEFL_MIN_MATCH 3
    #define SDEFL_MAX_MATCH 258

    struct sdefl {int bits, off;};
    struct sdefl {int bits, cnt;};
    #define sinfl_rev16(n) ((sdefl_mirror[(n)&0xff] << 8) | sdefl_mirror[((n)>>8)&0xff])
    static const unsigned char sdefl_mirror[256] = {
    #define R2(n) n, n + 128, n + 64, n + 192
    @@ -58,12 +58,12 @@ sdefl_hash(const unsigned char *s)
    static unsigned char*
    sdefl_write(unsigned char *dst, struct sdefl *s, int code, int bitcnt)
    {
    s->bits |= (code << s->off);
    s->off += bitcnt;
    while (s->off >= 8) {
    s->bits |= (code << s->cnt);
    s->cnt += bitcnt;
    while (s->cnt >= 8) {
    *dst++ = (unsigned char)(s->bits & 0xFF);
    s->bits >>= 8;
    s->off -= 8;
    s->cnt -= 8;
    } return dst;
    }
    static unsigned char*
    @@ -138,7 +138,7 @@ sdeflate(unsigned char *out, const unsigned char *in, int size)
    return (int)(dst - out);
    }
    struct sinfl {
    int bits, bitoff;
    int bits, bitcnt;
    unsigned lits[288];
    unsigned dsts[32];
    unsigned lens[19];
    @@ -151,11 +151,11 @@ sinfl_read(const unsigned char **src, const unsigned char *end,
    const unsigned char *in = *src;
    int v = s->bits & ((1 << n)-1);
    s->bits >>= n;
    s->bitoff = s->bitoff - n;
    s->bitoff = s->bitoff < 0 ? 0 : s->bitoff;
    while (s->bitoff < 16 && in < end) {
    s->bits |= (*in++) << s->bitoff;
    s->bitoff += 8;
    s->bitcnt = s->bitcnt - n;
    s->bitcnt = s->bitcnt < 0 ? 0 : s->bitcnt;
    while (s->bitcnt < 16 && in < end) {
    s->bits |= (*in++) << s->bitcnt;
    s->bitcnt += 8;
    } *src = in;
    return v;
    }
    @@ -217,7 +217,7 @@ sinflate(unsigned char *out, const unsigned char *in, int size)

    memset(&s, 0, sizeof(s));
    sinfl_read(&in,e,&s,0); /* buffer input */
    while (in < e || s.bitoff) {
    while (in < e || s.bitcnt) {
    switch (state) {
    case hdr: {
    int type = 0; /* block header */
    @@ -231,10 +231,10 @@ sinflate(unsigned char *out, const unsigned char *in, int size)
    } break;
    case stored: {
    int len, nlen; /* uncompressed block */
    sinfl_read(&in,e,&s,s.bitoff & 7);
    sinfl_read(&in,e,&s,s.bitcnt & 7);
    len = sinfl_read(&in,e,&s,16);
    nlen = sinfl_read(&in,e,&s,16);
    in -= 2; s.bitoff = 0;
    in -= 2; s.bitcnt = 0;

    if (len > (e-in)) return (int)(out-o);
    memcpy(out, in, (size_t)len);
  11. @vurtun vurtun revised this gist Dec 12, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,7 @@ static const unsigned char sdefl_mirror[256] = {
    R6(0), R6(2), R6(1), R6(3),
    };
    static int
    sdefl_nxpow2i(int n)
    sdefl_npow2(int n)
    {
    n--;
    n |= n >> 1;
    @@ -89,7 +89,7 @@ sdefl_match(unsigned char *dst, struct sdefl *s, int dist, int len)

    /* distance encoding */
    {int dc = dist - 1;
    int dx = sdefl_ilog2(sdefl_nxpow2i(dist) >> 2);
    int dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
    if ((dx = (dx < 0) ? 0: dx))
    dc = ((dx + 1) << 1) + (dist > dxmax[dx]);
    dst = sdefl_write(dst, s, sdefl_mirror[dc << 3], 5);
  12. @vurtun vurtun revised this gist Dec 12, 2017. 1 changed file with 29 additions and 30 deletions.
    59 changes: 29 additions & 30 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -17,10 +17,9 @@
    #define SDEFL_MIN_MATCH 3
    #define SDEFL_MAX_MATCH 258

    typedef unsigned char uchar;
    struct sdefl {int bits, off;};
    #define sinfl_rev16(n) ((sdefl_mirror[(n)&0xff] << 8) | sdefl_mirror[((n)>>8)&0xff])
    static const uchar sdefl_mirror[256] = {
    static const unsigned char sdefl_mirror[256] = {
    #define R2(n) n, n + 128, n + 64, n + 192
    #define R4(n) R2(n), R2(n + 32), R2(n + 16), R2(n + 48)
    #define R6(n) R4(n), R4(n + 8), R4(n + 4), R4(n + 12)
    @@ -50,25 +49,25 @@ sdefl_ilog2(int n)
    #undef lt
    }
    static int
    sdefl_hash(const uchar *s)
    sdefl_hash(const unsigned char *s)
    {
    int a = s[0], b = s[1], c = s[2];
    int v = (a << 16) | (b << 8) | c;
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_DICT_SIZE-1);
    }
    static uchar*
    sdefl_write(uchar *dst, struct sdefl *s, int code, int bitcnt)
    static unsigned char*
    sdefl_write(unsigned char *dst, struct sdefl *s, int code, int bitcnt)
    {
    s->bits |= (code << s->off);
    s->off += bitcnt;
    while (s->off >= 8) {
    *dst++ = (uchar)(s->bits & 0xFF);
    *dst++ = (unsigned char)(s->bits & 0xFF);
    s->bits >>= 8;
    s->off -= 8;
    } return dst;
    }
    static uchar*
    sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    static unsigned char*
    sdefl_match(unsigned char *dst, struct sdefl *s, int dist, int len)
    {
    static const short lxmin[] = {0,11,19,35,67,131};
    static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
    @@ -97,34 +96,34 @@ sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    if (dx) dst = sdefl_write(dst, s, dist - dmin[dc], dx);}
    return dst;
    }
    static uchar*
    sdefl_lit(uchar *dst, struct sdefl *s, int c)
    static unsigned char*
    sdefl_lit(unsigned char *dst, struct sdefl *s, int c)
    {
    if (c <= 143)
    return sdefl_write(dst, s, sdefl_mirror[0x30+c], 8);
    else return sdefl_write(dst, s, 1 + 2 * sdefl_mirror[0x90 - 144 + c], 9);
    }
    static int
    sdeflate(uchar *out, const uchar *in, int size)
    sdeflate(unsigned char *out, const unsigned char *in, int size)
    {
    struct sdefl st;
    uchar *dst = out;
    const uchar *e = in + size;
    unsigned char *dst = out;
    const unsigned char *e = in + size;

    const uchar *dict[SDEFL_DICT_SIZE];
    const unsigned char *dict[SDEFL_DICT_SIZE];
    memset(dict,0,sizeof(dict));
    memset(&st,0,sizeof(st));

    dst = sdefl_write(dst,&st,0x01,1); /* block */
    dst = sdefl_write(dst,&st,0x01,2); /* static huffman */
    while (in < e) {
    const int h = sdefl_hash(in);
    const uchar **ent = &dict[h & (SDEFL_DICT_SIZE-1)];
    const uchar *sub = *ent; *ent = in;
    const unsigned char **ent = &dict[h & (SDEFL_DICT_SIZE-1)];
    const unsigned char *sub = *ent; *ent = in;
    if (sub && (in > sub) && ((in-sub) < SDEFL_MAX_OFF) &&
    !memcmp(in,sub,SDEFL_MIN_MATCH)) {
    /* match */
    const uchar *s = sub + SDEFL_MIN_MATCH;
    const unsigned char *s = sub + SDEFL_MIN_MATCH;
    int len, dist = (int)(in - sub);
    in += (len = SDEFL_MIN_MATCH);
    while ((*s == *in) && (len < SDEFL_MAX_MATCH))
    @@ -146,10 +145,10 @@ struct sinfl {
    int tlit, tdist, tlen;
    };
    static int
    sinfl_read(const uchar **src, const uchar *end,
    sinfl_read(const unsigned char **src, const unsigned char *end,
    struct sinfl *s, int n)
    {
    const uchar *in = *src;
    const unsigned char *in = *src;
    int v = s->bits & ((1 << n)-1);
    s->bits >>= n;
    s->bitoff = s->bitoff - n;
    @@ -161,7 +160,7 @@ sinfl_read(const uchar **src, const uchar *end,
    return v;
    }
    static int
    sinfl_build(unsigned *tree, uchar *lens, int symcnt)
    sinfl_build(unsigned *tree, unsigned char *lens, int symcnt)
    {
    int n, cnt[16], first[16], codes[16];
    memset(cnt, 0, sizeof(cnt));
    @@ -180,7 +179,7 @@ sinfl_build(unsigned *tree, uchar *lens, int symcnt)
    } return first[15];
    }
    static int
    sinfl_decode(const uchar **in, const uchar *end,
    sinfl_decode(const unsigned char **in, const unsigned char *end,
    struct sinfl *s, unsigned *tree, int max)
    {
    /* bsearch next prefix code */
    @@ -198,21 +197,21 @@ sinfl_decode(const uchar **in, const uchar *end,
    return (key >> 4) & 0x0fff;
    }
    static int
    sinflate(uchar *out, const uchar *in, int size)
    sinflate(unsigned char *out, const unsigned char *in, int size)
    {
    static const char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
    static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
    257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
    static const uchar dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
    static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
    10,10,11,11,12,12,13,13,0,0};
    static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,
    43,51,59,67,83,99,115,131,163,195,227,258,0,0};
    static const uchar lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
    static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
    4,4,4,5,5,5,5,0,0,0};

    enum sinfl_states {hdr,stored,fixed,dyn,blk};
    enum sinfl_states state = hdr;
    const uchar *e = in + size, *o = out;
    const unsigned char *e = in + size, *o = out;
    struct sinfl s;
    int last = 0;

    @@ -244,7 +243,7 @@ sinflate(uchar *out, const uchar *in, int size)
    } break;
    case fixed: {
    /* fixed huffman codes */
    int n; uchar lens[288+32];
    int n; unsigned char lens[288+32];
    for (n = 0; n <= 143; n++) lens[n] = 8;
    for (n = 144; n <= 255; n++) lens[n] = 9;
    for (n = 256; n <= 279; n++) lens[n] = 7;
    @@ -259,18 +258,18 @@ sinflate(uchar *out, const uchar *in, int size)
    case dyn: {
    /* dynamic huffman codes */
    int n, i, nlit, ndist, nlen;
    uchar nlens[19] = {0}, lens[288+32];
    unsigned char nlens[19] = {0}, lens[288+32];
    nlit = 257 + sinfl_read(&in,e,&s,5);
    ndist = 1 + sinfl_read(&in,e,&s,5);
    nlen = 4 + sinfl_read(&in,e,&s,4);
    for (n = 0; n < nlen; n++)
    nlens[order[n]] = (uchar)sinfl_read(&in,e,&s,3);
    nlens[order[n]] = (unsigned char)sinfl_read(&in,e,&s,3);
    s.tlen = sinfl_build(s.lens, nlens, 19);

    /* decode code lengths */
    for (n = 0; n < nlit + ndist;) {
    int sym = sinfl_decode(&in, e, &s, s.lens, s.tlen);
    switch (sym) {default: lens[n++] = (uchar)sym; break;
    switch (sym) {default: lens[n++] = (unsigned char)sym; break;
    case 16: for (i=3+sinfl_read(&in,e,&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
    case 17: for (i=3+sinfl_read(&in,e,&s,3);i;i--,n++) lens[n]=0; break;
    case 18: for (i=11+sinfl_read(&in,e,&s,7);i;i--,n++) lens[n]=0; break;}
    @@ -292,7 +291,7 @@ sinflate(uchar *out, const uchar *in, int size)
    } else if (sym == 256) {
    if (last) return (int)(out-o);
    state = hdr;
    } else *out++ = (uchar)sym;
    } else *out++ = (unsigned char)sym;
    } break;}
    } return (int)(out-o);
    }
  13. @vurtun vurtun revised this gist Nov 27, 2017. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -235,12 +235,11 @@ sinflate(uchar *out, const uchar *in, int size)
    sinfl_read(&in,e,&s,s.bitoff & 7);
    len = sinfl_read(&in,e,&s,16);
    nlen = sinfl_read(&in,e,&s,16);
    if ((unsigned)len != ~((unsigned)nlen))
    return (int)(out-o);
    in -= 2; s.bitoff = 0;

    if (len > (e-in)) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
    sinfl_read(&in,e,&s,16);
    state = hdr;
    } break;
    case fixed: {
  14. @vurtun vurtun revised this gist Nov 27, 2017. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -237,6 +237,7 @@ sinflate(uchar *out, const uchar *in, int size)
    nlen = sinfl_read(&in,e,&s,16);
    if ((unsigned)len != ~((unsigned)nlen))
    return (int)(out-o);
    if (len > (e-in)) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
    sinfl_read(&in,e,&s,16);
  15. @vurtun vurtun revised this gist Nov 27, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -237,7 +237,6 @@ sinflate(uchar *out, const uchar *in, int size)
    nlen = sinfl_read(&in,e,&s,16);
    if ((unsigned)len != ~((unsigned)nlen))
    return (int)(out-o);
    if (len >= (e-in)) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
    sinfl_read(&in,e,&s,16);
  16. @vurtun vurtun revised this gist Nov 27, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -231,9 +231,13 @@ sinflate(uchar *out, const uchar *in, int size)
    case 0x02: state = dyn; break;}
    } break;
    case stored: {
    int len; /* uncompressed block */
    int len, nlen; /* uncompressed block */
    sinfl_read(&in,e,&s,s.bitoff & 7);
    len = sinfl_read(&in,e,&s,16);
    nlen = sinfl_read(&in,e,&s,16);
    if ((unsigned)len != ~((unsigned)nlen))
    return (int)(out-o);
    if (len >= (e-in)) return (int)(out-o);
    memcpy(out, in, (size_t)len);
    in += len, out += len;
    sinfl_read(&in,e,&s,16);
  17. @vurtun vurtun revised this gist Nov 27, 2017. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -152,7 +152,8 @@ sinfl_read(const uchar **src, const uchar *end,
    const uchar *in = *src;
    int v = s->bits & ((1 << n)-1);
    s->bits >>= n;
    s->bitoff -= n;
    s->bitoff = s->bitoff - n;
    s->bitoff = s->bitoff < 0 ? 0 : s->bitoff;
    while (s->bitoff < 16 && in < end) {
    s->bits |= (*in++) << s->bitoff;
    s->bitoff += 8;
  18. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,10 @@
    https://github.com/github/putty/blob/49fb598b0e78d09d6a2a42679ee0649df482090e/sshzlib.c
    https://www.ietf.org/rfc/rfc1951.txt
    */
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>

    #define SDEFL_DICT_BITS 12
    #define SDEFL_DICT_SIZE (1 << SDEFL_DICT_BITS)
    #define SDEFL_MAX_OFF (1 << 15)
  19. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ sdefl_ilog2(int n)
    static int
    sdefl_hash(const uchar *s)
    {
    int a = s[0], b = s[1], c = [2];
    int a = s[0], b = s[1], c = s[2];
    int v = (a << 16) | (b << 8) | c;
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_DICT_SIZE-1);
    }
  20. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    /* ===============================================================
    * SDEFL
    * ===============================================================
    * public domain - no warranty implied; use at your own risk
    * References:
    https://bitbucket.org/rmitton/tigr/src/be3832bee7fb2f274fe5823e38f8ec7fa94e0ce9/src/tigr_inflate.c?at=default&fileviewer=file-view-default
    https://github.com/github/putty/blob/49fb598b0e78d09d6a2a42679ee0649df482090e/sshzlib.c
  21. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -47,7 +47,8 @@ sdefl_ilog2(int n)
    static int
    sdefl_hash(const uchar *s)
    {
    int v = (s[0] << 16) | (s[1] << 8) | s[2];
    int a = s[0], b = s[1], c = [2];
    int v = (a << 16) | (b << 8) | c;
    return ((v >> (3*8 - SDEFL_DICT_BITS)) - v) & (SDEFL_DICT_SIZE-1);
    }
    static uchar*
  22. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -89,7 +89,6 @@ sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    dc = ((dx + 1) << 1) + (dist > dxmax[dx]);
    dst = sdefl_write(dst, s, sdefl_mirror[dc << 3], 5);
    if (dx) dst = sdefl_write(dst, s, dist - dmin[dc], dx);}

    return dst;
    }
    static uchar*
  23. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 14 additions and 15 deletions.
    29 changes: 14 additions & 15 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -22,6 +22,17 @@ static const uchar sdefl_mirror[256] = {
    R6(0), R6(2), R6(1), R6(3),
    };
    static int
    sdefl_nxpow2i(int n)
    {
    n--;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    return ++n;
    }
    static int
    sdefl_ilog2(int n)
    {
    #define lt(n) n,n,n,n, n,n,n,n, n,n,n,n ,n,n,n,n
    @@ -34,17 +45,6 @@ sdefl_ilog2(int n)
    #undef lt
    }
    static int
    sdefl_nxpow2i(int n)
    {
    n--;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    return ++n;
    }
    static int
    sdefl_hash(const uchar *s)
    {
    int v = (s[0] << 16) | (s[1] << 8) | s[2];
    @@ -56,7 +56,7 @@ sdefl_write(uchar *dst, struct sdefl *s, int code, int bitcnt)
    s->bits |= (code << s->off);
    s->off += bitcnt;
    while (s->off >= 8) {
    *dst++ = s->bits & 0xFF;
    *dst++ = (uchar)(s->bits & 0xFF);
    s->bits >>= 8;
    s->off -= 8;
    } return dst;
    @@ -155,8 +155,7 @@ sinfl_read(const uchar **src, const uchar *end,
    return v;
    }
    static int
    sinfl_build(unsigned *tree,
    uchar *lens, int symcnt)
    sinfl_build(unsigned *tree, uchar *lens, int symcnt)
    {
    int n, cnt[16], first[16], codes[16];
    memset(cnt, 0, sizeof(cnt));
    @@ -171,7 +170,7 @@ sinfl_build(unsigned *tree,
    if (!len) continue;
    code = codes[len]++;
    slot = first[len]++;
    tree[slot] = (code << (32-len)) | (n << 4) | len;
    tree[slot] = (unsigned)((code << (32-len)) | (n << 4) | len);
    } return first[15];
    }
    static int
  24. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -236,7 +236,6 @@ sinflate(uchar *out, const uchar *in, int size)
    } break;
    case fixed: {
    /* fixed huffman codes */
    int i = 0;
    int n; uchar lens[288+32];
    for (n = 0; n <= 143; n++) lens[n] = 8;
    for (n = 144; n <= 255; n++) lens[n] = 9;
  25. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -21,8 +21,6 @@ static const uchar sdefl_mirror[256] = {
    #define R6(n) R4(n), R4(n + 8), R4(n + 4), R4(n + 12)
    R6(0), R6(2), R6(1), R6(3),
    };
    static int sdefl_compressed_size(int size){return size*2;}

    static int
    sdefl_ilog2(int n)
    {
  26. @vurtun vurtun revised this gist Nov 25, 2017. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@
    #define SDEFL_DICT_SIZE (1 << SDEFL_DICT_BITS)
    #define SDEFL_MAX_OFF (1 << 15)
    #define SDEFL_MIN_MATCH 3
    #define SDEFL_MAX_MATCH 285
    #define SDEFL_MAX_MATCH 258

    typedef unsigned char uchar;
    struct sdefl {int bits, off;};
    @@ -21,6 +21,8 @@ static const uchar sdefl_mirror[256] = {
    #define R6(n) R4(n), R4(n + 8), R4(n + 4), R4(n + 12)
    R6(0), R6(2), R6(1), R6(3),
    };
    static int sdefl_compressed_size(int size){return size*2;}

    static int
    sdefl_ilog2(int n)
    {
    @@ -77,7 +79,7 @@ sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    else if (len >= 258) lx = 0, lc = 285;
    else lc = ((lx-1) << 2) + 265 + ((len - lxmin[lx]) >> lx);

    if (lc < 279)
    if (lc <= 279)
    dst = sdefl_write(dst, s, sdefl_mirror[(lc - 256) << 1], 7);
    else dst = sdefl_write(dst, s, sdefl_mirror[0xc0 - 280 + lc], 8);
    if (lx) dst = sdefl_write(dst, s, len - lmin[lc - 265], lx);
    @@ -89,6 +91,7 @@ sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    dc = ((dx + 1) << 1) + (dist > dxmax[dx]);
    dst = sdefl_write(dst, s, sdefl_mirror[dc << 3], 5);
    if (dx) dst = sdefl_write(dst, s, dist - dmin[dc], dx);}

    return dst;
    }
    static uchar*
    @@ -235,6 +238,7 @@ sinflate(uchar *out, const uchar *in, int size)
    } break;
    case fixed: {
    /* fixed huffman codes */
    int i = 0;
    int n; uchar lens[288+32];
    for (n = 0; n <= 143; n++) lens[n] = 8;
    for (n = 144; n <= 255; n++) lens[n] = 9;
  27. @vurtun vurtun revised this gist Nov 24, 2017. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -192,8 +192,7 @@ sinfl_decode(const uchar **in, const uchar *end,
    return (key >> 4) & 0x0fff;
    }
    static int
    sinflate(struct profiler *p, uchar *out,
    const uchar *in, int size)
    sinflate(uchar *out, const uchar *in, int size)
    {
    static const char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
    static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
  28. @vurtun vurtun revised this gist Nov 24, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -99,7 +99,7 @@ sdefl_lit(uchar *dst, struct sdefl *s, int c)
    else return sdefl_write(dst, s, 1 + 2 * sdefl_mirror[0x90 - 144 + c], 9);
    }
    static int
    sdeflate(struct profiler *p, uchar *out, const uchar *in, int size)
    sdeflate(uchar *out, const uchar *in, int size)
    {
    struct sdefl st;
    uchar *dst = out;
  29. @vurtun vurtun revised this gist Nov 23, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion defl.c
    Original file line number Diff line number Diff line change
    @@ -89,7 +89,6 @@ sdefl_match(uchar *dst, struct sdefl *s, int dist, int len)
    dc = ((dx + 1) << 1) + (dist > dxmax[dx]);
    dst = sdefl_write(dst, s, sdefl_mirror[dc << 3], 5);
    if (dx) dst = sdefl_write(dst, s, dist - dmin[dc], dx);}

    return dst;
    }
    static uchar*
  30. @vurtun vurtun revised this gist Nov 23, 2017. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions defl.c
    Original file line number Diff line number Diff line change
    @@ -21,8 +21,6 @@ static const uchar sdefl_mirror[256] = {
    #define R6(n) R4(n), R4(n + 8), R4(n + 4), R4(n + 12)
    R6(0), R6(2), R6(1), R6(3),
    };
    static int sdefl_compressed_size(int size){return size*2;}

    static int
    sdefl_ilog2(int n)
    {