Пример #1
0
        static int zhuffman_decode_slowpath(zbuf a, zhuffman z)
        {
            int b, s, k;

            // not resolved by fast table, so compute it the slow way
            // use jpeg approach, which requires MSbits at top
            k = bit_reverse((int)a.code_buffer, 16);
            for (s = ZFAST_BITS + 1; ; ++s)
            {
                if (k < z.maxcode[s])
                {
                    break;
                }
            }
            if (s == 16)
            {
                return(-1);         // invalid code!
            }
            // code size is s, so:
            b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s];
            Debug.Assert(z.size[b] == s);
            a.code_buffer >>= s;
            a.num_bits     -= s;
            return(z.value[b]);
        }
Пример #2
0
        static int zexpand(zbuf z, int zout, int n)  // need to make room for n bytes
        {
            byte[] q;
            int    cur, limit;

            z.pzout = zout;
            if (z.z_expandable == 0)
            {
                throw new Exception("output buffer limit,Corrupt PNG");
            }
            cur   = z.pzout - z.pzout_start;
            limit = z.pzout_end - z.pzout_start;
            while (cur + n > limit)
            {
                limit *= 2;
            }
            q = realloc(ref z.zout_start, limit);
            if (q == null)
            {
                throw new Exception("Out of memory");
            }
            z.pzout_start = 0;
            z.pzout       = cur;
            z.pzout_end   = limit;
            return(1);
        }
Пример #3
0
 static byte zget8(zbuf z)
 {
     if (z.pzbuffer >= z.pzbuffer_end)
     {
         return(0);
     }
     return(z.zbuffer[z.pzbuffer++]);
 }
Пример #4
0
 static int do_zlib(zbuf a, byte[] obuf, int olen, int exp, int parse_header)
 {
     a.zout_start   = obuf;
     a.pzout_start  = 0;
     a.pzout        = 0;
     a.pzout_end    = olen;
     a.z_expandable = exp;
     return(parse_zlib(a, parse_header));
 }
Пример #5
0
 static void fill_bits(zbuf z)
 {
     do
     {
         Debug.Assert(z.code_buffer < (1U << z.num_bits));
         z.code_buffer |= (uint)(zget8(z) << z.num_bits);
         z.num_bits    += 8;
     } while (z.num_bits <= 24);
 }
Пример #6
0
 public static int zlib_decode_buffer(byte[] obuffer, int olen, byte[] ibuffer, int ilen)
 {
     zbuf a = new zbuf();
     a.zbuffer = ibuffer;
     a.pzbuffer_end = ilen;
     if (do_zlib(a, obuffer, olen, 0, 1) != 0)
         return (int)(a.pzout - a.pzout_start);
     else
         return -1;
 }
Пример #7
0
 static int compute_huffman_codes(zbuf a)
 {
     zhuffman z_codelength = new zhuffman();
     byte[] lencodes = new byte[286 + 32 + 137];//padding for maximum single op
     byte[] codelength_sizes = new byte[19];
     int i, n;
     int hlit = (int)zreceive(a, 5) + 257;
     int hdist = (int)zreceive(a, 5) + 1;
     int hclen = (int)zreceive(a, 4) + 4;
     for (i = 0; i < hclen; ++i)
     {
         int s = (int)zreceive(a, 3);
         codelength_sizes[length_dezigzag[i]] = (byte)s;
     }
     if (zbuild_huffman(z_codelength, codelength_sizes, 19) == 0) return 0;
     n = 0;
     while (n < hlit + hdist)
     {
         int c = zhuffman_decode(a, z_codelength);
         Debug.Assert(c >= 0 && c < 19);
         if (c < 16)
             lencodes[n++] = (byte)c;
         else if (c == 16)
         {
             c = (int)zreceive(a, 2) + 3;
             {
                 byte value = lencodes[n - 1];
                 int last = n + c;
                 for (int idx = n; idx < last; idx++)
                     lencodes[idx] = value;
             }
             n += c;
         }
         else if (c == 17)
         {
             c = (int)zreceive(a, 3) + 3;
             Array.Clear(lencodes, n, c);
             n += c;
         }
         else
         {
             Debug.Assert(c == 18);
             c = (int)zreceive(a, 7) + 11;
             Array.Clear(lencodes, n, c);
             n += c;
         }
     }
     if (n != hlit + hdist) throw new Exception("bad codelengths,Corrupt PNG");
     if (zbuild_huffman(a.z_length, lencodes, hlit) == 0) return 0;
     if (zbuild_huffman(a.z_distance, lencodes, hdist, hlit) == 0) return 0;
     return 1;
 }
Пример #8
0
        static uint zreceive(zbuf z, int n)
        {
            uint k;

            if (z.num_bits < n)
            {
                fill_bits(z);
            }
            k               = z.code_buffer & (uint)((1 << n) - 1);
            z.code_buffer >>= n;
            z.num_bits     -= n;
            return(k);
        }
Пример #9
0
        public static int zlib_decode_buffer(byte[] obuffer, int olen, byte[] ibuffer, int ilen)
        {
            zbuf a = new zbuf();

            a.zbuffer      = ibuffer;
            a.pzbuffer_end = ilen;
            if (do_zlib(a, obuffer, olen, 0, 1) != 0)
            {
                return((int)(a.pzout - a.pzout_start));
            }
            else
            {
                return(-1);
            }
        }
Пример #10
0
        static int parse_uncomperssed_block(zbuf a)
        {
            byte[] header = new byte[4];
            int    len, nlen, k;

            if ((a.num_bits & 7) != 0)
            {
                zreceive(a, a.num_bits & 7); // discard
            }
            // drain the bit-packed data into header
            k = 0;
            while (a.num_bits > 0)
            {
                header[k++]     = (byte)a.code_buffer; // suppress MSVC run-time check
                a.code_buffer >>= 8;
                a.num_bits     -= 8;
            }
            Debug.Assert(a.num_bits == 0);
            // now fill header the normal way
            while (k < 4)
            {
                header[k++] = zget8(a);
            }
            len  = header[1] * 256 + header[0];
            nlen = header[3] * 256 + header[2];
            if (nlen != (len ^ 0xffff))
            {
                throw new Exception("zlib corrupt,Corrupt PNG");
            }
            if (a.pzbuffer + len > a.pzbuffer_end)
            {
                throw new Exception("read past buffer,Corrupt PNG");
            }
            if (a.pzout + len > a.pzout_end)
            {
                if (zexpand(a, a.pzout, len) == 0)
                {
                    return(0);
                }
            }
            Array.Copy(a.zbuffer, a.pzbuffer, a.zout_start, a.pzout, len);
            a.pzbuffer += len;
            a.pzout    += len;
            return(1);
        }
Пример #11
0
 public static byte[] zlib_decode(byte[] buffer, int len, int initial_size, ref int outlen, int parse_header = 1)
 {
     zbuf a = new zbuf();
     byte[] p = new byte[initial_size];
     if (p == null) return null;
     a.zbuffer = buffer;
     a.pzbuffer = 0;
     a.pzbuffer_end = len;
     if (do_zlib(a, p, initial_size, 1, parse_header) != 0)
     {
         outlen = (int)(a.pzout - a.pzout_start);
         return a.zout_start;
     }
     else
     {
         return null;
     }
 }
Пример #12
0
        static int zhuffman_decode(zbuf a, zhuffman z)
        {
            int b, s;

            if (a.num_bits < 16)
            {
                fill_bits(a);
            }
            b = z.fast[a.code_buffer & ZFAST_MASK];
            if (b != 0)
            {
                s               = b >> 9;
                a.code_buffer >>= s;
                a.num_bits     -= s;
                return(b & 511);
            }
            return(zhuffman_decode_slowpath(a, z));
        }
Пример #13
0
        public static byte[] zlib_decode(byte[] buffer, int len, int initial_size, ref int outlen, int parse_header = 1)
        {
            zbuf a = new zbuf();

            byte[] p = new byte[initial_size];
            if (p == null)
            {
                return(null);
            }
            a.zbuffer      = buffer;
            a.pzbuffer     = 0;
            a.pzbuffer_end = len;
            if (do_zlib(a, p, initial_size, 1, parse_header) != 0)
            {
                outlen = (int)(a.pzout - a.pzout_start);
                return(a.zout_start);
            }
            else
            {
                return(null);
            }
        }
Пример #14
0
        static int parse_zlib_header(zbuf a)
        {
            int cmf = zget8(a);
            int cm  = cmf & 15;
            /* int cinfo = cmf >> 4; */
            int flg = zget8(a);

            if ((cmf * 256 + flg) % 31 != 0)
            {
                throw new Exception("bad zlib header,Corrupt PNG");                             // zlib spec
            }
            if ((flg & 32) != 0)
            {
                throw new Exception("no preset dict,Corrupt PNG");                              // preset dictionary not allowed in png
            }
            if (cm != 8)
            {
                throw new Exception("bad compression,Corrupt PNG");                             // DEFLATE required for png
            }
            // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
            return(1);
        }
Пример #15
0
 // need to make room for n bytes
 static int zexpand(zbuf z, int zout, int n)
 {
     byte[] q;
     int cur, limit;
     z.pzout = zout;
     if (z.z_expandable == 0) throw new Exception("output buffer limit,Corrupt PNG");
     cur = z.pzout - z.pzout_start;
     limit = z.pzout_end - z.pzout_start;
     while (cur + n > limit)
         limit *= 2;
     q = realloc(ref z.zout_start, limit);
     if (q == null) throw new Exception("Out of memory");
     z.pzout_start = 0;
     z.pzout = cur;
     z.pzout_end = limit;
     return 1;
 }
Пример #16
0
 static int parse_zlib_header(zbuf a)
 {
     int cmf = zget8(a);
     int cm = cmf & 15;
     /* int cinfo = cmf >> 4; */
     int flg = zget8(a);
     if ((cmf * 256 + flg) % 31 != 0) throw new Exception("bad zlib header,Corrupt PNG");// zlib spec
     if ((flg & 32) != 0) throw new Exception("no preset dict,Corrupt PNG");             // preset dictionary not allowed in png
     if (cm != 8) throw new Exception("bad compression,Corrupt PNG");                    // DEFLATE required for png
     // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
     return 1;
 }
Пример #17
0
 static int parse_zlib(zbuf a, int parse_header)
 {
     int final, type;
     if (parse_header != 0)
         if (parse_zlib_header(a) == 0) return 0;
     a.num_bits = 0;
     a.code_buffer = 0;
     do
     {
         final = (int)zreceive(a, 1);
         type = (int)zreceive(a, 2);
         if (type == 0)
         {
             if (parse_uncomperssed_block(a) == 0) return 0;
         }
         else if (type == 3)
         {
             return 0;
         }
         else
         {
             if (type == 1)
             {
                 // use fixed code lengths
                 if (zdefault_distance[31] == 0) init_zdefaults();
                 if (zbuild_huffman(a.z_length, zdefault_length, 288) == 0) return 0;
                 if (zbuild_huffman(a.z_distance, zdefault_distance, 32) == 0) return 0;
             }
             else
             {
                 if (compute_huffman_codes(a) == 0) return 0;
             }
             if (parse_huffman_block(a) == 0) return 0;
         }
     } while (final == 0);
     return 1;
 }
Пример #18
0
        static int parse_huffman_block(zbuf a)
        {
            int zout = a.pzout;

            for (; ;)
            {
                int z = (int)zhuffman_decode(a, a.z_length);
                if (z < 256)
                {
                    if (z < 0)
                    {
                        throw new Exception("bad huffman code,Corrupt PNG");        // error in huffman codes
                    }
                    if (zout >= a.pzout_end)
                    {
                        if (zexpand(a, zout, 1) == 0)
                        {
                            return(0);
                        }
                        zout = a.pzout;
                    }
                    a.zout_start[zout++] = (byte)z;
                }
                else
                {
                    int p;
                    int len, dist;
                    if (z == 256)
                    {
                        a.pzout = zout;
                        return(1);
                    }
                    z  -= 257;
                    len = zlength_base[z];
                    if (zlength_extra[z] != 0)
                    {
                        len += (int)zreceive(a, zlength_extra[z]);
                    }
                    z = zhuffman_decode(a, a.z_distance);
                    if (z < 0)
                    {
                        throw new Exception("bad huffman code,Corrupt PNG");
                    }
                    dist = zdist_base[z];
                    if (zdist_extra[z] != 0)
                    {
                        dist += (int)zreceive(a, zdist_extra[z]);
                    }
                    if (zout - a.pzout_start < dist)
                    {
                        throw new Exception("bad dist,Corrupt PNG");
                    }
                    if (zout + len > a.pzout_end)
                    {
                        if (zexpand(a, zout, len) == 0)
                        {
                            return(0);
                        }
                        zout = a.pzout;
                    }
                    p = zout - dist;
                    if (dist == 1)
                    { // run of one byte; common in images.
                        do
                        {
                            a.zout_start[zout++] = a.zout_start[p];
                        } while ((--len) != 0);                                             //todo fix
                    }
                    else
                    {
                        do
                        {
                            a.zout_start[zout++] = a.zout_start[p++];
                        } while ((--len) != 0);                                              //todo fix
                    }
                }
            }
        }
Пример #19
0
 static int zhuffman_decode_slowpath(zbuf a, zhuffman z)
 {
     int b, s, k;
     // not resolved by fast table, so compute it the slow way
     // use jpeg approach, which requires MSbits at top
     k = bit_reverse((int)a.code_buffer, 16);
     for (s = ZFAST_BITS + 1; ; ++s)
         if (k < z.maxcode[s])
             break;
     if (s == 16) return -1; // invalid code!
     // code size is s, so:
     b = (k >> (16 - s)) - z.firstcode[s] + z.firstsymbol[s];
     Debug.Assert(z.size[b] == s);
     a.code_buffer >>= s;
     a.num_bits -= s;
     return z.value[b];
 }
Пример #20
0
        static int compute_huffman_codes(zbuf a)
        {
            zhuffman z_codelength = new zhuffman();

            byte[] lencodes = new byte[286 + 32 + 137];//padding for maximum single op
            byte[] codelength_sizes = new byte[19];
            int    i, n;
            int    hlit  = (int)zreceive(a, 5) + 257;
            int    hdist = (int)zreceive(a, 5) + 1;
            int    hclen = (int)zreceive(a, 4) + 4;

            for (i = 0; i < hclen; ++i)
            {
                int s = (int)zreceive(a, 3);
                codelength_sizes[length_dezigzag[i]] = (byte)s;
            }
            if (zbuild_huffman(z_codelength, codelength_sizes, 19) == 0)
            {
                return(0);
            }
            n = 0;
            while (n < hlit + hdist)
            {
                int c = zhuffman_decode(a, z_codelength);
                Debug.Assert(c >= 0 && c < 19);
                if (c < 16)
                {
                    lencodes[n++] = (byte)c;
                }
                else if (c == 16)
                {
                    c = (int)zreceive(a, 2) + 3;
                    {
                        byte value = lencodes[n - 1];
                        int  last  = n + c;
                        for (int idx = n; idx < last; idx++)
                        {
                            lencodes[idx] = value;
                        }
                    }
                    n += c;
                }
                else if (c == 17)
                {
                    c = (int)zreceive(a, 3) + 3;
                    Array.Clear(lencodes, n, c);
                    n += c;
                }
                else
                {
                    Debug.Assert(c == 18);
                    c = (int)zreceive(a, 7) + 11;
                    Array.Clear(lencodes, n, c);
                    n += c;
                }
            }
            if (n != hlit + hdist)
            {
                throw new Exception("bad codelengths,Corrupt PNG");
            }
            if (zbuild_huffman(a.z_length, lencodes, hlit) == 0)
            {
                return(0);
            }
            if (zbuild_huffman(a.z_distance, lencodes, hdist, hlit) == 0)
            {
                return(0);
            }
            return(1);
        }
Пример #21
0
 static byte zget8(zbuf z)
 {
     if (z.pzbuffer >= z.pzbuffer_end) return 0;
     return z.zbuffer[z.pzbuffer++];
 }
Пример #22
0
 static void fill_bits(zbuf z)
 {
     do
     {
         Debug.Assert(z.code_buffer < (1U << z.num_bits));
         z.code_buffer |= (uint)(zget8(z) << z.num_bits);
         z.num_bits += 8;
     } while (z.num_bits <= 24);
 }
Пример #23
0
 static int zhuffman_decode(zbuf a, zhuffman z)
 {
     int b, s;
     if (a.num_bits < 16) fill_bits(a);
     b = z.fast[a.code_buffer & ZFAST_MASK];
     if (b != 0)
     {
         s = b >> 9;
         a.code_buffer >>= s;
         a.num_bits -= s;
         return b & 511;
     }
     return zhuffman_decode_slowpath(a, z);
 }
Пример #24
0
 static int parse_huffman_block(zbuf a)
 {
     int zout = a.pzout;
     for (; ; )
     {
         int z = (int)zhuffman_decode(a, a.z_length);
         if (z < 256)
         {
             if (z < 0) throw new Exception("bad huffman code,Corrupt PNG"); // error in huffman codes
             if (zout >= a.pzout_end)
             {
                 if (zexpand(a, zout, 1) == 0) return 0;
                 zout = a.pzout;
             }
             a.zout_start[zout++] = (byte)z;
         }
         else
         {
             int p;
             int len, dist;
             if (z == 256)
             {
                 a.pzout = zout;
                 return 1;
             }
             z -= 257;
             len = zlength_base[z];
             if (zlength_extra[z] != 0) len += (int)zreceive(a, zlength_extra[z]);
             z = zhuffman_decode(a, a.z_distance);
             if (z < 0) throw new Exception("bad huffman code,Corrupt PNG");
             dist = zdist_base[z];
             if (zdist_extra[z] != 0) dist += (int)zreceive(a, zdist_extra[z]);
             if (zout - a.pzout_start < dist) throw new Exception("bad dist,Corrupt PNG");
             if (zout + len > a.pzout_end)
             {
                 if (zexpand(a, zout, len) == 0) return 0;
                 zout = a.pzout;
             }
             p = zout - dist;
             if (dist == 1)
             { // run of one byte; common in images.
                 do a.zout_start[zout++] = a.zout_start[p]; while ((--len) != 0);    //todo fix
             }
             else
             {
                 do a.zout_start[zout++] = a.zout_start[p++]; while ((--len) != 0);   //todo fix
             }
         }
     }
 }
Пример #25
0
 static uint zreceive(zbuf z, int n)
 {
     uint k;
     if (z.num_bits < n) fill_bits(z);
     k = z.code_buffer & (uint)((1 << n) - 1);
     z.code_buffer >>= n;
     z.num_bits -= n;
     return k;
 }
Пример #26
0
 static int parse_uncomperssed_block(zbuf a)
 {
     byte[] header = new byte[4];
     int len, nlen, k;
     if ((a.num_bits & 7) != 0)
         zreceive(a, a.num_bits & 7); // discard
     // drain the bit-packed data into header
     k = 0;
     while (a.num_bits > 0)
     {
         header[k++] = (byte)a.code_buffer; // suppress MSVC run-time check
         a.code_buffer >>= 8;
         a.num_bits -= 8;
     }
     Debug.Assert(a.num_bits == 0);
     // now fill header the normal way
     while (k < 4)
         header[k++] = zget8(a);
     len = header[1] * 256 + header[0];
     nlen = header[3] * 256 + header[2];
     if (nlen != (len ^ 0xffff)) throw new Exception("zlib corrupt,Corrupt PNG");
     if (a.pzbuffer + len > a.pzbuffer_end) throw new Exception("read past buffer,Corrupt PNG");
     if (a.pzout + len > a.pzout_end)
         if (zexpand(a, a.pzout, len) == 0) return 0;
     Array.Copy(a.zbuffer, a.pzbuffer, a.zout_start, a.pzout, len);
     a.pzbuffer += len;
     a.pzout += len;
     return 1;
 }
Пример #27
0
 static int do_zlib(zbuf a, byte[] obuf, int olen, int exp, int parse_header)
 {
     a.zout_start = obuf;
     a.pzout_start = 0;
     a.pzout = 0;
     a.pzout_end = olen;
     a.z_expandable = exp;
     return parse_zlib(a, parse_header);
 }
Пример #28
0
        static int parse_zlib(zbuf a, int parse_header)
        {
            int final, type;

            if (parse_header != 0)
            {
                if (parse_zlib_header(a) == 0)
                {
                    return(0);
                }
            }
            a.num_bits    = 0;
            a.code_buffer = 0;
            do
            {
                final = (int)zreceive(a, 1);
                type  = (int)zreceive(a, 2);
                if (type == 0)
                {
                    if (parse_uncomperssed_block(a) == 0)
                    {
                        return(0);
                    }
                }
                else if (type == 3)
                {
                    return(0);
                }
                else
                {
                    if (type == 1)
                    {
                        // use fixed code lengths
                        if (zdefault_distance[31] == 0)
                        {
                            init_zdefaults();
                        }
                        if (zbuild_huffman(a.z_length, zdefault_length, 288) == 0)
                        {
                            return(0);
                        }
                        if (zbuild_huffman(a.z_distance, zdefault_distance, 32) == 0)
                        {
                            return(0);
                        }
                    }
                    else
                    {
                        if (compute_huffman_codes(a) == 0)
                        {
                            return(0);
                        }
                    }
                    if (parse_huffman_block(a) == 0)
                    {
                        return(0);
                    }
                }
            } while (final == 0);
            return(1);
        }