mirror of
https://github.com/emmanuel-marty/lzsa.git
synced 2024-11-22 05:33:58 +00:00
Support backward decompression
This commit is contained in:
parent
0c4dbf2b72
commit
4835e4c26c
@ -7,6 +7,18 @@
|
||||
;
|
||||
; out:
|
||||
; * LZSA_DST_LO and LZSA_DST_HI contain the last decompressed byte address, +1
|
||||
;
|
||||
; -----------------------------------------------------------------------------
|
||||
; Backward decompression is also supported, use lzsa -r -b <original_file> <compressed_file>
|
||||
; To use it, also define BACKWARD_DECOMPRESS=1 before including this code!
|
||||
;
|
||||
; in:
|
||||
; * LZSA_SRC_LO/LZSA_SRC_HI must contain the address of the last byte of compressed data
|
||||
; * LZSA_DST_LO/LZSA_DST_HI must contain the address of the last byte of the destination buffer
|
||||
;
|
||||
; out:
|
||||
; * LZSA_DST_LO/LZSA_DST_HI contain the last decompressed byte address, -1
|
||||
;
|
||||
; -----------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (C) 2019 Emmanuel Marty
|
||||
@ -96,11 +108,29 @@ PREPARE_COPY_MATCH_Y
|
||||
|
||||
COPY_MATCH_LOOP
|
||||
LDA $AAAA ; get one byte of backreference
|
||||
JSR PUTDST ; copy to destination
|
||||
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression -- put backreference bytes backward
|
||||
|
||||
LDA COPY_MATCH_LOOP+1
|
||||
BNE GETMATCH_DONE
|
||||
DEC COPY_MATCH_LOOP+2
|
||||
GETMATCH_DONE
|
||||
DEC COPY_MATCH_LOOP+1
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression -- put backreference bytes forward
|
||||
|
||||
INC COPY_MATCH_LOOP+1
|
||||
BNE GETMATCH_DONE
|
||||
INC COPY_MATCH_LOOP+2
|
||||
GETMATCH_DONE
|
||||
JSR PUTDST ; copy to destination
|
||||
|
||||
endif
|
||||
|
||||
DEX
|
||||
BNE COPY_MATCH_LOOP
|
||||
DEY
|
||||
@ -111,6 +141,29 @@ GET_LONG_OFFSET ; handle 16 bit offset:
|
||||
JSR GETLARGESRC ; grab low 8 bits in X, high 8 bits in A
|
||||
|
||||
GOT_OFFSET
|
||||
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression - substract match offset
|
||||
|
||||
STA OFFSHI ; store high 8 bits of offset
|
||||
STX OFFSLO
|
||||
|
||||
SEC ; substract dest - match offset
|
||||
LDA PUTDST+1
|
||||
OFFSLO = *+1
|
||||
SBC #$AA ; low 8 bits
|
||||
STA COPY_MATCH_LOOP+1 ; store back reference address
|
||||
LDA PUTDST+2
|
||||
OFFSHI = *+1
|
||||
SBC #$AA ; high 8 bits
|
||||
STA COPY_MATCH_LOOP+2 ; store high 8 bits of address
|
||||
SEC
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression - add match offset
|
||||
|
||||
STA OFFSHI ; store high 8 bits of offset
|
||||
TXA
|
||||
|
||||
@ -123,6 +176,8 @@ OFFSHI = *+1
|
||||
ADC PUTDST+2
|
||||
STA COPY_MATCH_LOOP+2 ; store high 8 bits of address
|
||||
|
||||
endif
|
||||
|
||||
PLA ; retrieve token from stack again
|
||||
AND #$0F ; isolate match len (MMMM)
|
||||
ADC #$02 ; plus carry which is always set by the high ADC
|
||||
@ -145,6 +200,45 @@ OFFSHI = *+1
|
||||
DECOMPRESSION_DONE
|
||||
RTS
|
||||
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression -- get and put bytes backward
|
||||
|
||||
GETPUT
|
||||
JSR GETSRC
|
||||
PUTDST
|
||||
LZSA_DST_LO = *+1
|
||||
LZSA_DST_HI = *+2
|
||||
STA $AAAA
|
||||
LDA PUTDST+1
|
||||
BNE PUTDST_DONE
|
||||
DEC PUTDST+2
|
||||
PUTDST_DONE
|
||||
DEC PUTDST+1
|
||||
RTS
|
||||
|
||||
GETLARGESRC
|
||||
JSR GETSRC ; grab low 8 bits
|
||||
TAX ; move to X
|
||||
; fall through grab high 8 bits
|
||||
|
||||
GETSRC
|
||||
LZSA_SRC_LO = *+1
|
||||
LZSA_SRC_HI = *+2
|
||||
LDA $AAAA
|
||||
PHA
|
||||
LDA GETSRC+1
|
||||
BNE GETSRC_DONE
|
||||
DEC GETSRC+2
|
||||
GETSRC_DONE
|
||||
DEC GETSRC+1
|
||||
PLA
|
||||
RTS
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression -- get and put bytes forward
|
||||
|
||||
GETPUT
|
||||
JSR GETSRC
|
||||
PUTDST
|
||||
@ -171,3 +265,5 @@ LZSA_SRC_HI = *+2
|
||||
INC GETSRC+2
|
||||
GETSRC_DONE
|
||||
RTS
|
||||
|
||||
endif
|
||||
|
@ -8,6 +8,18 @@
|
||||
;
|
||||
; out:
|
||||
; * LZSA_DST_LO and LZSA_DST_HI contain the last decompressed byte address, +1
|
||||
;
|
||||
; -----------------------------------------------------------------------------
|
||||
; Backward decompression is also supported, use lzsa -r -b -f2 <original_file> <compressed_file>
|
||||
; To use it, also define BACKWARD_DECOMPRESS=1 before including this code!
|
||||
;
|
||||
; in:
|
||||
; * LZSA_SRC_LO/LZSA_SRC_HI must contain the address of the last byte of compressed data
|
||||
; * LZSA_DST_LO/LZSA_DST_HI must contain the address of the last byte of the destination buffer
|
||||
;
|
||||
; out:
|
||||
; * LZSA_DST_LO/LZSA_DST_HI contain the last decompressed byte address, -1
|
||||
;
|
||||
; -----------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (C) 2019 Emmanuel Marty
|
||||
@ -130,6 +142,25 @@ GOT_OFFSET_LO
|
||||
STX OFFSHI ; store high byte of match offset
|
||||
|
||||
REP_MATCH
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression - substract match offset
|
||||
|
||||
SEC ; add dest + match offset
|
||||
LDA PUTDST+1 ; low 8 bits
|
||||
OFFSLO = *+1
|
||||
SBC #$AA
|
||||
STA COPY_MATCH_LOOP+1 ; store back reference address
|
||||
LDA PUTDST+2
|
||||
OFFSHI = *+1
|
||||
SBC #$AA ; high 8 bits
|
||||
STA COPY_MATCH_LOOP+2 ; store high 8 bits of address
|
||||
SEC
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression - add match offset
|
||||
|
||||
CLC ; add dest + match offset
|
||||
LDA PUTDST+1 ; low 8 bits
|
||||
OFFSLO = *+1
|
||||
@ -140,6 +171,8 @@ OFFSHI = *+1
|
||||
ADC PUTDST+2
|
||||
STA COPY_MATCH_LOOP+2 ; store high 8 bits of address
|
||||
|
||||
endif
|
||||
|
||||
PLA ; retrieve token from stack again
|
||||
AND #$07 ; isolate match len (MMM)
|
||||
ADC #$01 ; add MIN_MATCH_SIZE_V2 and carry
|
||||
@ -173,11 +206,29 @@ PREPARE_COPY_MATCH_Y
|
||||
|
||||
COPY_MATCH_LOOP
|
||||
LDA $AAAA ; get one byte of backreference
|
||||
JSR PUTDST ; copy to destination
|
||||
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression -- put backreference bytes backward
|
||||
|
||||
LDA COPY_MATCH_LOOP+1
|
||||
BNE GETMATCH_DONE
|
||||
DEC COPY_MATCH_LOOP+2
|
||||
GETMATCH_DONE
|
||||
DEC COPY_MATCH_LOOP+1
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression -- put backreference bytes forward
|
||||
|
||||
INC COPY_MATCH_LOOP+1
|
||||
BNE GETMATCH_DONE
|
||||
INC COPY_MATCH_LOOP+2
|
||||
GETMATCH_DONE
|
||||
JSR PUTDST ; copy to destination
|
||||
|
||||
endif
|
||||
|
||||
DEX
|
||||
BNE COPY_MATCH_LOOP
|
||||
DEY
|
||||
@ -215,6 +266,45 @@ HAS_NIBBLES
|
||||
AND #$0F ; isolate low 4 bits of nibble
|
||||
RTS
|
||||
|
||||
ifdef BACKWARD_DECOMPRESS
|
||||
|
||||
; Backward decompression -- get and put bytes backward
|
||||
|
||||
GETPUT
|
||||
JSR GETSRC
|
||||
PUTDST
|
||||
LZSA_DST_LO = *+1
|
||||
LZSA_DST_HI = *+2
|
||||
STA $AAAA
|
||||
LDA PUTDST+1
|
||||
BNE PUTDST_DONE
|
||||
DEC PUTDST+2
|
||||
PUTDST_DONE
|
||||
DEC PUTDST+1
|
||||
RTS
|
||||
|
||||
GETLARGESRC
|
||||
JSR GETSRC ; grab low 8 bits
|
||||
TAX ; move to X
|
||||
; fall through grab high 8 bits
|
||||
|
||||
GETSRC
|
||||
LZSA_SRC_LO = *+1
|
||||
LZSA_SRC_HI = *+2
|
||||
LDA $AAAA
|
||||
PHA
|
||||
LDA GETSRC+1
|
||||
BNE GETSRC_DONE
|
||||
DEC GETSRC+2
|
||||
GETSRC_DONE
|
||||
DEC GETSRC+1
|
||||
PLA
|
||||
RTS
|
||||
|
||||
else
|
||||
|
||||
; Forward decompression -- get and put bytes forward
|
||||
|
||||
GETPUT
|
||||
JSR GETSRC
|
||||
PUTDST
|
||||
@ -241,3 +331,5 @@ LZSA_SRC_HI = *+2
|
||||
INC GETSRC+2
|
||||
GETSRC_DONE
|
||||
RTS
|
||||
|
||||
endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "expand_context.h"
|
||||
#include "expand_block_v1.h"
|
||||
#include "expand_block_v2.h"
|
||||
#include "lib.h"
|
||||
|
||||
/**
|
||||
* Decompress one data block
|
||||
@ -45,14 +46,31 @@
|
||||
* @param nOutDataOffset starting index of where to store decompressed bytes in output buffer (and size of previously decompressed bytes)
|
||||
* @param nBlockMaxSize total size of output decompression buffer, in bytes
|
||||
* @param nFormatVersion version of format to use (1-2)
|
||||
* @param nFlags compression flags (LZSA_FLAG_xxx)
|
||||
*
|
||||
* @return size of decompressed data in bytes, or -1 for error
|
||||
*/
|
||||
int lzsa_decompressor_expand_block(const unsigned char *pInBlock, int nBlockSize, unsigned char *pOutData, int nOutDataOffset, int nBlockMaxSize, const int nFormatVersion) {
|
||||
int lzsa_decompressor_expand_block(unsigned char *pInBlock, int nBlockSize, unsigned char *pOutData, int nOutDataOffset, int nBlockMaxSize, const int nFormatVersion, const int nFlags) {
|
||||
int nDecompressedSize;
|
||||
|
||||
if (nFlags & LZSA_FLAG_RAW_BACKWARD) {
|
||||
lzsa_reverse_buffer(pInBlock, nBlockSize);
|
||||
}
|
||||
|
||||
if (nFormatVersion == 1)
|
||||
return lzsa_decompressor_expand_block_v1(pInBlock, nBlockSize, pOutData, nOutDataOffset, nBlockMaxSize);
|
||||
nDecompressedSize = lzsa_decompressor_expand_block_v1(pInBlock, nBlockSize, pOutData, nOutDataOffset, nBlockMaxSize);
|
||||
else if (nFormatVersion == 2)
|
||||
return lzsa_decompressor_expand_block_v2(pInBlock, nBlockSize, pOutData, nOutDataOffset, nBlockMaxSize);
|
||||
nDecompressedSize = lzsa_decompressor_expand_block_v2(pInBlock, nBlockSize, pOutData, nOutDataOffset, nBlockMaxSize);
|
||||
else
|
||||
return -1;
|
||||
nDecompressedSize = -1;
|
||||
|
||||
if (nDecompressedSize != -1 && (nFlags & LZSA_FLAG_RAW_BACKWARD)) {
|
||||
lzsa_reverse_buffer(pOutData + nOutDataOffset, nDecompressedSize);
|
||||
}
|
||||
|
||||
if (nFlags & LZSA_FLAG_RAW_BACKWARD) {
|
||||
lzsa_reverse_buffer(pInBlock, nBlockSize);
|
||||
}
|
||||
|
||||
return nDecompressedSize;
|
||||
}
|
||||
|
@ -48,10 +48,11 @@ extern "C" {
|
||||
* @param nOutDataOffset starting index of where to store decompressed bytes in output buffer (and size of previously decompressed bytes)
|
||||
* @param nBlockMaxSize total size of output decompression buffer, in bytes
|
||||
* @param nFormatVersion version of format to use (1-2)
|
||||
* @param nFlags compression flags (LZSA_FLAG_xxx)
|
||||
*
|
||||
* @return size of decompressed data in bytes, or -1 for error
|
||||
*/
|
||||
int lzsa_decompressor_expand_block(const unsigned char *pInBlock, int nBlockSize, unsigned char *pOutData, int nOutDataOffset, int nBlockMaxSize, const int nFormatVersion);
|
||||
int lzsa_decompressor_expand_block(unsigned char *pInBlock, int nBlockSize, unsigned char *pOutData, int nOutDataOffset, int nBlockMaxSize, const int nFormatVersion, const int nFlags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ size_t lzsa_get_max_decompressed_size_inmem(const unsigned char *pFileData, size
|
||||
*
|
||||
* @return actual decompressed size, or -1 for error
|
||||
*/
|
||||
size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion) {
|
||||
const unsigned char *pCurFileData = pFileData;
|
||||
size_t lzsa_decompress_inmem(unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion) {
|
||||
unsigned char *pCurFileData = pFileData;
|
||||
const unsigned char *pEndFileData = pCurFileData + nFileSize;
|
||||
unsigned char *pCurOutBuffer = pOutBuffer;
|
||||
const unsigned char *pEndOutBuffer = pCurOutBuffer + nMaxOutBufferSize;
|
||||
@ -107,7 +107,7 @@ size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOut
|
||||
const int nHeaderSize = lzsa_get_header_size();
|
||||
|
||||
if (nFlags & LZSA_FLAG_RAW_BLOCK) {
|
||||
return (size_t)lzsa_decompressor_expand_block(pFileData, (int)nFileSize, pOutBuffer, 0, (int)nMaxOutBufferSize, *pFormatVersion);
|
||||
return (size_t)lzsa_decompressor_expand_block(pFileData, (int)nFileSize, pOutBuffer, 0, (int)nMaxOutBufferSize, *pFormatVersion, nFlags);
|
||||
}
|
||||
|
||||
/* Check header */
|
||||
@ -139,7 +139,7 @@ size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOut
|
||||
if ((pCurFileData + nBlockDataSize) > pEndFileData)
|
||||
return -1;
|
||||
|
||||
nDecompressedSize = lzsa_decompressor_expand_block(pCurFileData, nBlockDataSize, pCurOutBuffer - nPreviousBlockSize, nPreviousBlockSize, (int)(pEndOutBuffer - pCurOutBuffer + nPreviousBlockSize), *pFormatVersion);
|
||||
nDecompressedSize = lzsa_decompressor_expand_block(pCurFileData, nBlockDataSize, pCurOutBuffer - nPreviousBlockSize, nPreviousBlockSize, (int)(pEndOutBuffer - pCurOutBuffer + nPreviousBlockSize), *pFormatVersion, nFlags);
|
||||
if (nDecompressedSize < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -61,7 +61,7 @@ size_t lzsa_get_max_decompressed_size_inmem(const unsigned char *pFileData, size
|
||||
*
|
||||
* @return actual decompressed size, or -1 for error
|
||||
*/
|
||||
size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion);
|
||||
size_t lzsa_decompress_inmem(unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ lzsa_status_t lzsa_decompress_stream(lzsa_stream_t *pInStream, lzsa_stream_t *pO
|
||||
nDecompressedSize = nBlockSize;
|
||||
}
|
||||
else {
|
||||
nDecompressedSize = lzsa_decompressor_expand_block(pInBlock, nBlockSize, pOutData, BLOCK_SIZE, BLOCK_SIZE, nFormatVersion);
|
||||
nDecompressedSize = lzsa_decompressor_expand_block(pInBlock, nBlockSize, pOutData, BLOCK_SIZE, BLOCK_SIZE, nFormatVersion, nFlags);
|
||||
if (nDecompressedSize < 0) {
|
||||
nDecompressionError = LZSA_ERROR_DECOMPRESSION;
|
||||
break;
|
||||
|
18
src/lib.h
18
src/lib.h
@ -69,6 +69,24 @@ typedef enum _lzsa_status_t {
|
||||
/* Compression flags */
|
||||
#define LZSA_FLAG_FAVOR_RATIO (1<<0) /**< 1 to compress with the best ratio, 0 to trade some compression ratio for extra decompression speed */
|
||||
#define LZSA_FLAG_RAW_BLOCK (1<<1) /**< 1 to emit raw block */
|
||||
#define LZSA_FLAG_RAW_BACKWARD (1<<2) /**< 1 to compress or decompress raw block backward */
|
||||
|
||||
/**
|
||||
* Reverse bytes in the specified buffer
|
||||
*
|
||||
* @param pBuffer pointer to buffer whose contents are to be reversed
|
||||
* @param nBufferSize size of buffer in bytes
|
||||
*/
|
||||
static inline void lzsa_reverse_buffer(unsigned char *pBuffer, const int nBufferSize) {
|
||||
int nMidPoint = nBufferSize / 2;
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = nBufferSize - 1; i < nMidPoint; i++, j--) {
|
||||
unsigned char c = pBuffer[i];
|
||||
pBuffer[i] = pBuffer[j];
|
||||
pBuffer[j] = c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
34
src/lzsa.c
34
src/lzsa.c
@ -42,11 +42,12 @@
|
||||
#endif
|
||||
#include "lib.h"
|
||||
|
||||
#define OPT_VERBOSE 1
|
||||
#define OPT_RAW 2
|
||||
#define OPT_FAVOR_RATIO 4
|
||||
#define OPT_VERBOSE 1
|
||||
#define OPT_RAW 2
|
||||
#define OPT_FAVOR_RATIO 4
|
||||
#define OPT_RAW_BACKWARD 8
|
||||
|
||||
#define TOOL_VERSION "1.0.4"
|
||||
#define TOOL_VERSION "1.0.5"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -109,6 +110,8 @@ static int do_compress(const char *pszInFilename, const char *pszOutFilename, co
|
||||
nFlags |= LZSA_FLAG_FAVOR_RATIO;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
if (nOptions & OPT_VERBOSE) {
|
||||
nStartTime = do_get_time();
|
||||
@ -160,6 +163,8 @@ static int do_decompress(const char *pszInFilename, const char *pszOutFilename,
|
||||
nFlags = 0;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
if (nOptions & OPT_VERBOSE) {
|
||||
nStartTime = do_get_time();
|
||||
@ -308,6 +313,8 @@ static int do_compare(const char *pszInFilename, const char *pszOutFilename, con
|
||||
nFlags = 0;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
if (nOptions & OPT_VERBOSE) {
|
||||
nStartTime = do_get_time();
|
||||
@ -419,6 +426,8 @@ static int do_self_test(const unsigned int nOptions, const int nMinMatchSize, in
|
||||
nFlags |= LZSA_FLAG_FAVOR_RATIO;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
pGeneratedData = (unsigned char*)malloc(4 * BLOCK_SIZE);
|
||||
if (!pGeneratedData) {
|
||||
@ -590,6 +599,8 @@ static int do_compr_benchmark(const char *pszInFilename, const char *pszOutFilen
|
||||
nFlags |= LZSA_FLAG_FAVOR_RATIO;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
if (pszDictionaryFilename) {
|
||||
fprintf(stderr, "in-memory benchmarking does not support dictionaries\n");
|
||||
@ -720,6 +731,8 @@ static int do_dec_benchmark(const char *pszInFilename, const char *pszOutFilenam
|
||||
nFlags = 0;
|
||||
if (nOptions & OPT_RAW)
|
||||
nFlags |= LZSA_FLAG_RAW_BLOCK;
|
||||
if (nOptions & OPT_RAW_BACKWARD)
|
||||
nFlags |= LZSA_FLAG_RAW_BACKWARD;
|
||||
|
||||
if (pszDictionaryFilename) {
|
||||
fprintf(stderr, "in-memory benchmarking does not support dictionaries\n");
|
||||
@ -987,6 +1000,13 @@ int main(int argc, char **argv) {
|
||||
else
|
||||
bArgsError = true;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-b")) {
|
||||
if ((nOptions & OPT_RAW_BACKWARD) == 0) {
|
||||
nOptions |= OPT_RAW_BACKWARD;
|
||||
}
|
||||
else
|
||||
bArgsError = true;
|
||||
}
|
||||
else {
|
||||
if (!pszInFilename)
|
||||
pszInFilename = argv[i];
|
||||
@ -999,6 +1019,11 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!bArgsError && (nOptions & OPT_RAW_BACKWARD) && !(nOptions & OPT_RAW)) {
|
||||
fprintf(stderr, "error: -b (compress backwards) requires -r (raw block format)\n");
|
||||
return 100;
|
||||
}
|
||||
|
||||
if (!bArgsError && cCommand == 't') {
|
||||
return do_self_test(nOptions, nMinMatchSize, nFormatVersion);
|
||||
}
|
||||
@ -1014,6 +1039,7 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr, " -v: be verbose\n");
|
||||
fprintf(stderr, " -f <value>: LZSA compression format (1-2)\n");
|
||||
fprintf(stderr, " -r: raw block format (max. 64 Kb files)\n");
|
||||
fprintf(stderr, " -b: compress backward (requires -r and a backward decompressor)\n");
|
||||
fprintf(stderr, " -D <filename>: use dictionary file\n");
|
||||
fprintf(stderr, " -m <value>: minimum match size (3-5) (default: 3)\n");
|
||||
fprintf(stderr, " --prefer-ratio: favor compression ratio (default)\n");
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "shrink_block_v2.h"
|
||||
#include "format.h"
|
||||
#include "matchfinder.h"
|
||||
#include "lib.h"
|
||||
|
||||
/**
|
||||
* Initialize compression context
|
||||
@ -188,23 +189,43 @@ void lzsa_compressor_destroy(lzsa_compressor *pCompressor) {
|
||||
*
|
||||
* @return size of compressed data in output buffer, or -1 if the data is uncompressible
|
||||
*/
|
||||
int lzsa_compressor_shrink_block(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize) {
|
||||
if (lzsa_build_suffix_array(pCompressor, pInWindow, nPreviousBlockSize + nInDataSize))
|
||||
return -1;
|
||||
if (nPreviousBlockSize) {
|
||||
lzsa_skip_matches(pCompressor, 0, nPreviousBlockSize);
|
||||
}
|
||||
lzsa_find_all_matches(pCompressor, nPreviousBlockSize, nPreviousBlockSize + nInDataSize);
|
||||
int lzsa_compressor_shrink_block(lzsa_compressor *pCompressor, unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize) {
|
||||
int nCompressedSize;
|
||||
|
||||
if (pCompressor->format_version == 1) {
|
||||
return lzsa_optimize_and_write_block_v1(pCompressor, pInWindow, nPreviousBlockSize, nInDataSize, pOutData, nMaxOutDataSize);
|
||||
}
|
||||
else if (pCompressor->format_version == 2) {
|
||||
return lzsa_optimize_and_write_block_v2(pCompressor, pInWindow, nPreviousBlockSize, nInDataSize, pOutData, nMaxOutDataSize);
|
||||
if (pCompressor->flags & LZSA_FLAG_RAW_BACKWARD) {
|
||||
lzsa_reverse_buffer(pInWindow + nPreviousBlockSize, nInDataSize);
|
||||
}
|
||||
|
||||
if (lzsa_build_suffix_array(pCompressor, pInWindow, nPreviousBlockSize + nInDataSize))
|
||||
nCompressedSize = -1;
|
||||
else {
|
||||
return -1;
|
||||
if (nPreviousBlockSize) {
|
||||
lzsa_skip_matches(pCompressor, 0, nPreviousBlockSize);
|
||||
}
|
||||
lzsa_find_all_matches(pCompressor, nPreviousBlockSize, nPreviousBlockSize + nInDataSize);
|
||||
|
||||
if (pCompressor->format_version == 1) {
|
||||
nCompressedSize = lzsa_optimize_and_write_block_v1(pCompressor, pInWindow, nPreviousBlockSize, nInDataSize, pOutData, nMaxOutDataSize);
|
||||
if (nCompressedSize != -1 && (pCompressor->flags & LZSA_FLAG_RAW_BACKWARD)) {
|
||||
lzsa_reverse_buffer(pOutData, nCompressedSize);
|
||||
}
|
||||
}
|
||||
else if (pCompressor->format_version == 2) {
|
||||
nCompressedSize = lzsa_optimize_and_write_block_v2(pCompressor, pInWindow, nPreviousBlockSize, nInDataSize, pOutData, nMaxOutDataSize);
|
||||
if (nCompressedSize != -1 && (pCompressor->flags & LZSA_FLAG_RAW_BACKWARD)) {
|
||||
lzsa_reverse_buffer(pOutData, nCompressedSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nCompressedSize = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCompressor->flags & LZSA_FLAG_RAW_BACKWARD) {
|
||||
lzsa_reverse_buffer(pInWindow + nPreviousBlockSize, nInDataSize);
|
||||
}
|
||||
|
||||
return nCompressedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +123,7 @@ void lzsa_compressor_destroy(lzsa_compressor *pCompressor);
|
||||
*
|
||||
* @return size of compressed data in output buffer, or -1 if the data is uncompressible
|
||||
*/
|
||||
int lzsa_compressor_shrink_block(lzsa_compressor *pCompressor, const unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize);
|
||||
int lzsa_compressor_shrink_block(lzsa_compressor *pCompressor, unsigned char *pInWindow, const int nPreviousBlockSize, const int nInDataSize, unsigned char *pOutData, const int nMaxOutDataSize);
|
||||
|
||||
/**
|
||||
* Get the number of compression commands issued in compressed data blocks
|
||||
|
@ -62,7 +62,7 @@ size_t lzsa_get_max_compressed_size_inmem(size_t nInputSize) {
|
||||
*
|
||||
* @return actual compressed size, or -1 for error
|
||||
*/
|
||||
size_t lzsa_compress_inmem(const unsigned char *pInputData, unsigned char *pOutBuffer, size_t nInputSize, size_t nMaxOutBufferSize,
|
||||
size_t lzsa_compress_inmem(unsigned char *pInputData, unsigned char *pOutBuffer, size_t nInputSize, size_t nMaxOutBufferSize,
|
||||
const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion) {
|
||||
lzsa_compressor compressor;
|
||||
size_t nOriginalSize = 0;
|
||||
|
@ -61,7 +61,7 @@ size_t lzsa_get_max_compressed_size_inmem(size_t nInputSize);
|
||||
*
|
||||
* @return actual compressed size, or -1 for error
|
||||
*/
|
||||
size_t lzsa_compress_inmem(const unsigned char *pInputData, unsigned char *pOutBuffer, size_t nInputSize, size_t nMaxOutBufferSize,
|
||||
size_t lzsa_compress_inmem(unsigned char *pInputData, unsigned char *pOutBuffer, size_t nInputSize, size_t nMaxOutBufferSize,
|
||||
const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user