[FFmpeg-devel] zlib decoder

Michael Niedermayer michaelni
Tue Jul 3 23:27:03 CEST 2007


Hi

On Mon, Jul 02, 2007 at 10:30:16PM +0100, M?ns Rullg?rd wrote:
> Here, at long last, is my highly anticipated zlib decoder.
> 
> It decompresses a random choice of gzip files I've tried it on
> correctly.  I'm sure there still are corner cases I haven't covered,
> though.  Any help finding, and better yet fixing, these is
> appreciated.
> 
> Speedwise it's on par with gunzip, with large buffer sizes even a bit
> faster.
[...]
> static const unsigned int len_tab[29][2] = {
>     { 0, 3 },
>     { 0, 4 },
>     { 0, 5 },
>     { 0, 6 },
>     { 0, 7 },
>     { 0, 8 },
>     { 0, 9 },
>     { 0, 10 },
>     { 1, 11 },
>     { 1, 13 },
>     { 1, 15 },
>     { 1, 17 },
>     { 2, 19 },
>     { 2, 23 },
>     { 2, 27 },
>     { 2, 31 },
>     { 3, 35 },
>     { 3, 43 },
>     { 3, 51 },
>     { 3, 59 },
>     { 4, 67 },
>     { 4, 83 },
>     { 4, 99 },
>     { 4, 115 },
>     { 5, 131 },
>     { 5, 163 },
>     { 5, 195 },
>     { 5, 227 },
>     { 0, 258 },
> };
> 
> static const unsigned int dist_tab[32][2] = {
>     { 0, 1 },
>     { 0, 2 },
>     { 0, 3 },
>     { 0, 4 },
>     { 1, 5 },
>     { 1, 7 },
>     { 2, 9 },
>     { 2, 13 },
>     { 3, 17 },
>     { 3, 25 },
>     { 4, 33 },
>     { 4, 49 },
>     { 5, 65 },
>     { 5, 97 },
>     { 6, 129 },
>     { 6, 193 },
>     { 7, 257 },
>     { 7, 385 },
>     { 8, 513 },
>     { 8, 769 },
>     { 9, 1025 },
>     { 9, 1537 },
>     { 10, 2049 },
>     { 10, 3073 },
>     { 11, 4097 },
>     { 11, 6145 },
>     { 12, 8193 },
>     { 12, 12289 },
>     { 13, 16385 },
>     { 13, 24577 },
> };

this fit in short

[...]
> #define check_bits(label, gb, n)                                        \
>     case AV_INFLATE_ ## label:                                          \
>         ctx->state = AV_INFLATE_ ## label;                              \
>         if ((n) > (gb)->size_in_bits - get_bits_count(gb) && insize) {  \
>             needbits = n;                                               \
>             goto outbits;                                               \
>         }
> 
> #define check_tail(gb)                                          \
>     do {                                                        \
>         if (tailbits) {                                         \
>             unsigned int rb = get_bits_count(gb);               \
>             if (rb >= tailbits) {                               \
>                 dprintf(NULL, "tailbits=%d rb=%d\n",            \
>                         tailbits, rb);                          \
>                 init_get_bits(gb, inbuf, insize * 8);           \
>                 skip_bits_long(gb, rb - tailbits);              \
>                 tailbits = 0;                                   \
>             }                                                   \
>         }                                                       \
>     } while(0)
> 
> #define rs_bits(what, label, dst, gb, n)                        \
>     do {                                                        \
>         check_bits(label, gb, n);                               \
>         (dst) = what##_bits((gb), (n));                         \
>         dprintf(NULL, "%-9s %-9s %4x %4x\n",                    \
>                 #what, #label, n, dst);                         \
>         check_tail(gb);                                         \
>     } while(0)
> 
> #define read_bits(label, dst, gb, n) rs_bits(get, label, dst, gb, n)
> #define show_bits(label, dst, gb, n) rs_bits(show, label, dst, gb, n)
> 
> #define read_vlc(label, dst, gb, tab)                           \
>     do {                                                        \
>         check_bits(label, gb, 16);                              \
>         (dst) = get_vlc2(gb, ctx->tab.table, ctx->tab.bits, 2); \
>         dprintf(NULL, "read_vlc  %-9s %4x %c\n", #label,        \
>                 dst, (dst)<127 && (dst)>32? (dst): '.');        \
>         check_tail(gb);                                         \
>     } while(0)
> 
> #define decode_code_lens()                                              \
> do {                                                                    \
>     ctx->i = 0;                                                         \
>     while (ctx->i < ctx->hlit + 257 + ctx->hdist + 1) {                 \
>         read_vlc(CLV, ctx->clv, &ctx->gb, cl_vlc);                      \
>                                                                         \
>         if (ctx->clv < 16) {                                            \
>             ctx->ll_len[ctx->i++] = ctx->clv;                           \
>         } else if (ctx->clv < 19) {                                     \
>             ctx->clr = 0;                                               \
>                                                                         \
>             if (ctx->clv == 16) {                                       \
>                 read_bits(CLR1, ctx->clr, &ctx->gb, 2);                 \
>                 ctx->clr += 3;                                          \
>                 ctx->clv = ctx->ll_len[ctx->i-1];                       \
>             } else if (ctx->clv == 17) {                                \
>                 read_bits(CLR2, ctx->clr, &ctx->gb, 3);                 \
>                 ctx->clr += 3;                                          \
>                 ctx->clv = 0;                                           \
>             } else if (ctx->clv == 18) {                                \
>                 read_bits(CLR3, ctx->clr, &ctx->gb, 7);                 \
>                 ctx->clr += 11;                                         \
>                 ctx->clv = 0;                                           \
>             }                                                           \
>                                                                         \
>             while (ctx->clr--) {                                        \
>                 ctx->ll_len[ctx->i++] = ctx->clv;                       \
>             }                                                           \
>         } else {                                                        \
>             av_log(NULL, AV_LOG_ERROR,                                  \
>                    "decode_code_lens: invalid code %d\n", ctx->clv);    \
>             return -1;                                                  \
>         }                                                               \
>     }                                                                   \
> } while(0)
> 
> #define vlc_dynamic_decl                                                \
>     unsigned int ll_codes[288];                                         \
>     unsigned int dist_codes[32];                                        \
>     unsigned int cl_codes[19];                                          \
>     unsigned int nll, ndist;                                            \
>     unsigned int ncl;                                                   \
>     uint8_t *dist_len
> 
> #define build_vlc_dynamic()                                             \
> do {                                                                    \
>     read_bits(HLIT, ctx->hlit, &ctx->gb, 5);                            \
>     read_bits(HDIST, ctx->hdist, &ctx->gb, 5);                          \
>     read_bits(HCLEN, ctx->hclen, &ctx->gb, 4);                          \
>                                                                         \
>     dprintf(NULL, "hlit=%d hdist=%d hclen=%d\n",                        \
>             ctx->hlit, ctx->hdist, ctx->hclen);                         \
>                                                                         \
>     for (ctx->i = 0; ctx->i < ctx->hclen + 4; ctx->i++) {               \
>         read_bits(CLLEN, ctx->cl_len[cl_perm[ctx->i]], &ctx->gb, 3);    \
>     }                                                                   \
>     for (; ctx->i < 19; ctx->i++) {                                     \
>         ctx->cl_len[cl_perm[ctx->i]] = 0;                               \
>     }                                                                   \
>                                                                         \
>     ncl = build_codes(19, ctx->cl_len, cl_codes);                       \
>                                                                         \
>     if(init_vlc(&ctx->cl_vlc, 7, ncl,                                   \
>                 ctx->cl_len, sizeof(ctx->cl_len[0]), sizeof(ctx->cl_len[0]), \
>                 cl_codes, sizeof(cl_codes[0]), sizeof(cl_codes[0]),     \
>                 INIT_VLC_LE))                                           \
>         return -1;                                                      \
>                                                                         \
>     decode_code_lens();                                                 \
>                                                                         \
>     free_vlc(&ctx->cl_vlc);                                             \
>                                                                         \
>     dist_len = ctx->ll_len + ctx->hlit + 257;                           \
>                                                                         \
>     nll = build_codes(ctx->hlit + 257, ctx->ll_len, ll_codes);          \
>     ndist = build_codes(ctx->hdist + 1, dist_len, dist_codes);          \
>                                                                         \
>     if(init_vlc(&ctx->ll_vlc, 9, nll,                                   \
>                 ctx->ll_len, sizeof(ctx->ll_len[0]), sizeof(ctx->ll_len[0]), \
>                 ll_codes, sizeof(ll_codes[0]), sizeof(ll_codes[0]),     \
>                 INIT_VLC_LE))                                           \
>         return -1;                                                      \
>                                                                         \
>     if(init_vlc(&ctx->dist_vlc, 9, ndist,                               \
>                 dist_len, sizeof(dist_len[0]), sizeof(dist_len[0]),     \
>                 dist_codes, sizeof(dist_codes[0]), sizeof(dist_codes[0]), \
>                 INIT_VLC_LE))                                           \
>         return -1;                                                      \
> } while(0)

are all thouse macros really needed?
cant this be implemented in a more readable way?

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070703/03822b39/attachment.pgp>



More information about the ffmpeg-devel mailing list