Java Byte Array Decompress decompress(byte src[], int src_off, int src_len, byte dst[], int dst_off, int dst_len)

Here you can find the source of decompress(byte src[], int src_off, int src_len, byte dst[], int dst_off, int dst_len)

Description

decompress

License

Open Source License

Declaration

public static int decompress(byte src[], int src_off, int src_len, byte dst[], int dst_off, int dst_len)
            throws Exception 

Method Source Code

//package com.java2s;
/*//  w  w  w . j  a  v  a2s .  c o  m
 * Copyright 2002 Stewart Allen <stewart@neuron.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Artistic License.
 */

public class Main {
    public static int decompress(byte src[], int src_off, int src_len, byte dst[], int dst_off, int dst_len)
            throws Exception {
        int len;
        int bptr;
        int iptr = src_off;
        int optr = dst_off;

        len = unsign(src[iptr++]);
        // if any bits set from [11110000]
        // COPY from SRC->DST where t=(0 to 238)
        // if the next byte is < 16 then an error has occurred
        if (len > 17) {
            len = len - 17;
            do {
                dst[optr++] = src[iptr++];
            } while (--len > 0);
            len = unsign(src[iptr++]);
            if (len < 16) {
                throw new Exception("Decompression Error");
            }
        }

        start:

        for (;; len = unsign(src[iptr++])) {
            // if only bits set from [00001111]
            if (len < 16) {
                // series of 0's (equal to 255) + 15 + first non-0 value
                if (len == 0) {
                    while (src[iptr] == 0) {
                        len = len + 255;
                        iptr++;
                    }
                    len = len + unsign(src[iptr++]) + 15;
                }
                len = len + 3;
                // COPY from SRC->DST where t=(3-xxxx)
                do {
                    dst[optr++] = src[iptr++];
                } while (--len > 0);
                len = unsign(src[iptr++]);
                // if only bits set from [00001111]
                if (len < 16) {
                    // len bits use [00001100]>>2 [00111111]<<2
                    // output ptr - 2049 - (t >> 2) - (next char << 2)
                    bptr = optr - 0x801 - (len >> 2) - (unsign(src[iptr++]) << 2);
                    if (bptr < dst_off) {
                        // look back preceeds dst output ptr
                        throw new Exception("Lookback overrun");
                    }
                    len = 3;
                    // COPY from DST->DST where pos=(-2049 to -2304) and t=(3)
                    do {
                        dst[optr++] = dst[bptr++];
                    } while (--len > 0);
                    // len bits use [00000011]
                    len = src[iptr - 2] & 3;
                    if (len == 0) {
                        continue;
                    }
                    // COPY from SRC->DST where t=(0-3)
                    do {
                        dst[optr++] = src[iptr++];
                    } while (--len > 0);
                    len = unsign(src[iptr++]);
                }
            }
            // more copying from dst to dst
            for (;; len = unsign(src[iptr++])) {
                // if any bits set from [11000000]
                // pos bits use [00011100]>>2 [00011111]<<3
                // len bits use [11100000]>>5
                // COPY from DST->DST where pos=(-1 to -256) and t=(2-8)
                if (len >= 64) {
                    // outpos - 1 - (0-255)
                    bptr = optr - ((len >> 2) & 7) - (unsign(src[iptr++]) << 3) - 1;
                    len = (len >> 5) - 1;
                }
                // if any bits set from [11100000]
                // pos bits use [--------] [11111100]>>2 [00111111]<<2
                // COPY from DST->DST where pos=(-1 to -256) and t=(2-xxxx)
                else if (len >= 32) {
                    // if all bits [00011111] empty, use 0 seq to add 255's
                    len = len & 31;
                    if (len == 0) {
                        while (src[iptr] == 0) {
                            len = len + 255;
                            iptr++;
                        }
                        len = len + unsign(src[iptr++]) + 31;
                    }
                    bptr = optr - (unsign(src[iptr++]) >> 2) - (unsign(src[iptr++]) << 6) - 1;
                }
                // if any bits set from [11110000]
                // pos bits use [00001000]<<11 [11111100]>>2 [00111111]<<2
                // len bits use [00000111]
                // COPY from DST->DST where pos=(-16384 to -16639)||(-1 to -256) and t=(2-xxxx)
                else if (len >= 16) {
                    bptr = optr - ((len & 8) << 11);
                    len = len & 7;
                    if (len == 0) {
                        while (src[iptr] == 0) {
                            len = len + 255;
                            iptr++;
                        }
                        len = len + 7 + unsign(src[iptr++]);
                    }
                    bptr = bptr - (unsign(src[iptr++]) >> 2) - (unsign(src[iptr++]) << 6);
                    if (bptr == optr) {
                        break start;
                    }
                    bptr = bptr - 0x4000;
                }
                // pos bits use [11111100]>>2 [00111111]<<2
                // COPY from DST->DST where pos=(-1 to -256) and t=(2)
                else {
                    bptr = optr - (len >> 2) - (unsign(src[iptr++]) << 2) - 1;
                    len = 0;
                }
                if (bptr < dst_off) {
                    throw new Exception("Lookback overrun");
                }
                len = len + 2;
                // do DST->DST copy
                do {
                    dst[optr++] = dst[bptr++];
                } while (--len > 0);
                len = src[iptr - 2] & 3;
                if (len == 0) {
                    break;
                }
                // COPY from SRC->DST where t=(0-3)
                do {
                    dst[optr++] = src[iptr++];
                } while (--len > 0);
            }
        }

        optr = optr - dst_off;
        iptr = iptr - src_off;

        if (len != 1) {
            throw new Exception("Decompression Error");
        }
        if (iptr > src_len) {
            throw new Exception("Input too short");
        }
        if (iptr < src_len) {
            throw new Exception("Input not exhausted");
        }

        return optr;
    }

    public static int unsign(byte b) {
        return b & 0xff;
    }
}

Related

  1. decompress(byte[] compressed, int sequenceLen)
  2. decompress(byte[] in, int len)
  3. decompress_action(byte[] source)
  4. decompressHuffman(byte[] message, int length)