com.ning.compress.lzf.LZFChunk Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compress-lzf Show documentation
Show all versions of compress-lzf Show documentation
Compression codec for LZF encoding for particularly encoding/decoding, with reasonable compression.
Compressor is basic Lempel-Ziv codec, without Huffman (deflate/gzip) or statistical post-encoding.
See "http://oldhome.schmorp.de/marc/liblzf.html" for more on original LZF package.
/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.ning.compress.lzf;
import java.io.*;
/**
* Helper class used to store LZF encoded segments (compressed and non-compressed)
* that can be sequenced to produce LZF files/streams.
*
* @author Tatu Saloranta
*/
public class LZFChunk
{
/**
* Maximum length of literal run for LZF encoding.
*/
public static final int MAX_LITERAL = 1 << 5; // 32
/**
* Chunk length is limited by 2-byte length indicator, to 64k
*/
public static final int MAX_CHUNK_LEN = 0xFFFF;
/**
* Header can be either 7 bytes (compressed) or 5 bytes (uncompressed)
* long
*/
public static final int MAX_HEADER_LEN = 7;
public static final int HEADER_LEN_COMPRESSED = 7;
public static final int HEADER_LEN_NOT_COMPRESSED = 5;
public final static byte BYTE_Z = 'Z';
public final static byte BYTE_V = 'V';
public final static int BLOCK_TYPE_NON_COMPRESSED = 0;
public final static int BLOCK_TYPE_COMPRESSED = 1;
protected final byte[] _data;
protected LZFChunk _next;
private LZFChunk(byte[] data) { _data = data; }
/**
* Factory method for constructing compressed chunk
*/
public static LZFChunk createCompressed(int origLen, byte[] encData, int encPtr, int encLen)
{
byte[] result = new byte[encLen + HEADER_LEN_COMPRESSED];
result[0] = BYTE_Z;
result[1] = BYTE_V;
result[2] = BLOCK_TYPE_COMPRESSED;
result[3] = (byte) (encLen >> 8);
result[4] = (byte) encLen;
result[5] = (byte) (origLen >> 8);
result[6] = (byte) origLen;
System.arraycopy(encData, encPtr, result, HEADER_LEN_COMPRESSED, encLen);
return new LZFChunk(result);
}
public static int appendCompressedHeader(int origLen, int encLen, byte[] headerBuffer, int offset)
{
headerBuffer[offset++] = BYTE_Z;
headerBuffer[offset++] = BYTE_V;
headerBuffer[offset++] = BLOCK_TYPE_COMPRESSED;
headerBuffer[offset++] = (byte) (encLen >> 8);
headerBuffer[offset++] = (byte) encLen;
headerBuffer[offset++] = (byte) (origLen >> 8);
headerBuffer[offset++] = (byte) origLen;
return offset;
}
public static void writeCompressedHeader(int origLen, int encLen, OutputStream out, byte[] headerBuffer)
throws IOException
{
headerBuffer[0] = BYTE_Z;
headerBuffer[1] = BYTE_V;
headerBuffer[2] = BLOCK_TYPE_COMPRESSED;
headerBuffer[3] = (byte) (encLen >> 8);
headerBuffer[4] = (byte) encLen;
headerBuffer[5] = (byte) (origLen >> 8);
headerBuffer[6] = (byte) origLen;
out.write(headerBuffer, 0, HEADER_LEN_COMPRESSED);
}
/**
* Factory method for constructing compressed chunk
*/
public static LZFChunk createNonCompressed(byte[] plainData, int ptr, int len)
{
byte[] result = new byte[len + HEADER_LEN_NOT_COMPRESSED];
result[0] = BYTE_Z;
result[1] = BYTE_V;
result[2] = BLOCK_TYPE_NON_COMPRESSED;
result[3] = (byte) (len >> 8);
result[4] = (byte) len;
System.arraycopy(plainData, ptr, result, HEADER_LEN_NOT_COMPRESSED, len);
return new LZFChunk(result);
}
/**
* Method for appending specific content as non-compressed chunk, in
* given buffer.
*/
public static int appendNonCompressed(byte[] plainData, int ptr, int len,
byte[] outputBuffer, int outputPtr)
{
outputBuffer[outputPtr++] = BYTE_Z;
outputBuffer[outputPtr++] = BYTE_V;
outputBuffer[outputPtr++] = BLOCK_TYPE_NON_COMPRESSED;
outputBuffer[outputPtr++] = (byte) (len >> 8);
outputBuffer[outputPtr++] = (byte) len;
System.arraycopy(plainData, ptr, outputBuffer, outputPtr, len);
return outputPtr + len;
}
public static int appendNonCompressedHeader(int len, byte[] headerBuffer, int offset)
{
headerBuffer[offset++] = BYTE_Z;
headerBuffer[offset++] = BYTE_V;
headerBuffer[offset++] = BLOCK_TYPE_NON_COMPRESSED;
headerBuffer[offset++] = (byte) (len >> 8);
headerBuffer[offset++] = (byte) len;
return offset;
}
public static void writeNonCompressedHeader(int len, OutputStream out, byte[] headerBuffer)
throws IOException
{
headerBuffer[0] = BYTE_Z;
headerBuffer[1] = BYTE_V;
headerBuffer[2] = BLOCK_TYPE_NON_COMPRESSED;
headerBuffer[3] = (byte) (len >> 8);
headerBuffer[4] = (byte) len;
out.write(headerBuffer, 0, HEADER_LEN_NOT_COMPRESSED);
}
public void setNext(LZFChunk next) { _next = next; }
public LZFChunk next() { return _next; }
public int length() { return _data.length; }
public byte[] getData() { return _data; }
public int copyTo(byte[] dst, int ptr) {
int len = _data.length;
System.arraycopy(_data, 0, dst, ptr, len);
return ptr+len;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy