/* @see Codec#decompress(RandomAccessInputStream, CodecOptions) */ public byte[] decompress(RandomAccessInputStream in, CodecOptions options) throws FormatException, IOException { if (in == null) throw new IllegalArgumentException("No data to decompress."); // Adapted from LZO for Java, available at // http://www.oberhumer.com/opensource/lzo/ ByteVector dst = new ByteVector(); int t = in.read() & 0xff; int mPos; if (t > 17) { t -= 17; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; // if (t < 16) return; if (t < 16) { return dst.toByteArray(); } } loop: for (; ; t = in.read() & 0xff) { if (t < 16) { if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 15 + (f & 0xff); } t += 3; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; if (t < 16) { mPos = dst.size() - 0x801 - (t >> 2) - ((in.read() & 0xff) << 2); if (mPos < 0) { t = LZO_OVERRUN; break loop; } t = 3; do { dst.add(dst.get(mPos++)); } while (--t > 0); // do dst[op++] = dst[mPos++]; while (--t > 0); in.seek(in.getFilePointer() - 2); t = in.read() & 3; in.skipBytes(1); if (t == 0) continue; // do dst[op++] = src[ip++]; while (--t > 0); b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; } } for (; ; t = in.read() & 0xff) { if (t >= 64) { mPos = dst.size() - 1 - ((t >> 2) & 7) - ((in.read() & 0xff) << 3); t = (t >> 5) - 1; } else if (t >= 32) { t &= 31; if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 31 + (f & 0xff); } mPos = dst.size() - 1 - ((in.read() & 0xff) >> 2); mPos -= ((in.read() & 0xff) << 6); } else if (t >= 16) { mPos = dst.size() - ((t & 8) << 11); t &= 7; if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 7 + (f & 0xff); } mPos -= ((in.read() & 0xff) >> 2); mPos -= ((in.read() & 0xff) << 6); if (mPos == dst.size()) break loop; mPos -= 0x4000; } else { mPos = dst.size() - 1 - (t >> 2) - ((in.read() & 0xff) << 2); t = 0; } if (mPos < 0) { t = LZO_OVERRUN; break loop; } t += 2; // do dst[op++] = dst[mPos++]; while (--t > 0); do { dst.add(dst.get(mPos++)); } while (--t > 0); in.seek(in.getFilePointer() - 2); t = in.read() & 3; in.skipBytes(1); if (t == 0) break; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = 0; } } return dst.toByteArray(); }