mirror of
https://github.com/emmanuel-marty/lzsa.git
synced 2024-12-27 18:30:37 +00:00
Isolate frame implementation details
This commit is contained in:
parent
31ededcdf7
commit
49b0739050
1
Makefile
1
Makefile
@ -11,6 +11,7 @@ $(OBJDIR)/%.o: src/../%.c
|
||||
APP := lzsa
|
||||
|
||||
OBJS := $(OBJDIR)/src/main.o
|
||||
OBJS += $(OBJDIR)/src/frame.o
|
||||
OBJS += $(OBJDIR)/src/shrink.o
|
||||
OBJS += $(OBJDIR)/src/expand.o
|
||||
OBJS += $(OBJDIR)/src/libdivsufsort/lib/divsufsort.o
|
||||
|
@ -179,6 +179,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\expand.h" />
|
||||
<ClInclude Include="..\src\format.h" />
|
||||
<ClInclude Include="..\src\frame.h" />
|
||||
<ClInclude Include="..\src\libdivsufsort\include\config.h" />
|
||||
<ClInclude Include="..\src\libdivsufsort\include\divsufsort.h" />
|
||||
<ClInclude Include="..\src\libdivsufsort\include\divsufsort_private.h" />
|
||||
@ -187,6 +188,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\expand.c" />
|
||||
<ClCompile Include="..\src\frame.c" />
|
||||
<ClCompile Include="..\src\libdivsufsort\lib\divsufsort.c" />
|
||||
<ClCompile Include="..\src\libdivsufsort\lib\sssort.c" />
|
||||
<ClCompile Include="..\src\libdivsufsort\lib\trsort.c" />
|
||||
|
@ -45,6 +45,9 @@
|
||||
<ClInclude Include="..\src\libdivsufsort\include\divsufsort_private.h">
|
||||
<Filter>Fichiers sources\libdivsufsort\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\frame.h">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\main.c">
|
||||
@ -68,5 +71,8 @@
|
||||
<ClCompile Include="..\src\libdivsufsort\lib\trsort.c">
|
||||
<Filter>Fichiers sources\libdivsufsort\lib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\frame.c">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
177
src/frame.c
Normal file
177
src/frame.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* frame.c - frame implementation
|
||||
*
|
||||
* Copyright (C) 2019 Emmanuel Marty
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "frame.h"
|
||||
#include "shrink.h"
|
||||
|
||||
#define LZSA_ID_0 0x7b
|
||||
#define LZSA_ID_1 0x9e
|
||||
|
||||
/**
|
||||
* Get compressed file header size
|
||||
*
|
||||
* @return file header size
|
||||
*/
|
||||
int lzsa_get_header_size(void) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get compressed frame header size
|
||||
*
|
||||
* @return frame header size
|
||||
*/
|
||||
int lzsa_get_frame_size(void) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode file header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_header(unsigned char *pFrameData, const int nMaxFrameDataSize) {
|
||||
if (nMaxFrameDataSize >= 3) {
|
||||
pFrameData[0] = LZSA_ID_0; /* Magic number */
|
||||
pFrameData[1] = LZSA_ID_1;
|
||||
pFrameData[2] = 0; /* Format version 1 */
|
||||
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode compressed block frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
* @param nBlockDataSize compressed block's data size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_compressed_block_frame(unsigned char *pFrameData, const int nMaxFrameDataSize, const int nBlockDataSize) {
|
||||
if (nMaxFrameDataSize >= 3 && nBlockDataSize <= 0x7fffff) {
|
||||
pFrameData[0] = nBlockDataSize & 0xff;
|
||||
pFrameData[1] = (nBlockDataSize >> 8) & 0xff;
|
||||
pFrameData[2] = (nBlockDataSize >> 16) & 0x7f;
|
||||
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode uncompressed block frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
* @param nBlockDataSize uncompressed block's data size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_uncompressed_block_frame(unsigned char *pFrameData, const int nMaxFrameDataSize, const int nBlockDataSize) {
|
||||
if (nMaxFrameDataSize >= 3 && nBlockDataSize <= 0x7fffff) {
|
||||
pFrameData[0] = nBlockDataSize & 0xff;
|
||||
pFrameData[1] = (nBlockDataSize >> 8) & 0xff;
|
||||
pFrameData[2] = ((nBlockDataSize >> 16) & 0x7f) | 0x80; /* Uncompressed block */
|
||||
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode terminal frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_footer_frame(unsigned char *pFrameData, const int nMaxFrameDataSize) {
|
||||
if (nMaxFrameDataSize >= 3) {
|
||||
pFrameData[0] = 0x00; /* EOD frame */
|
||||
pFrameData[1] = 0x00;
|
||||
pFrameData[2] = 0x00;
|
||||
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode file header
|
||||
*
|
||||
* @param pFrameData data bytes
|
||||
* @param nFrameDataSize number of bytes to decode
|
||||
*
|
||||
* @return 0 for success, or -1 for failure
|
||||
*/
|
||||
int lzsa_decode_header(const unsigned char *pFrameData, const int nFrameDataSize) {
|
||||
if (nFrameDataSize != 3 ||
|
||||
pFrameData[0] != LZSA_ID_0 ||
|
||||
pFrameData[1] != LZSA_ID_1 ||
|
||||
pFrameData[2] != 0) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode frame header
|
||||
*
|
||||
* @param pFrameData data bytes
|
||||
* @param nFrameDataSize number of bytes to decode
|
||||
* @param nBlockSize pointer to block size, updated if this function succeeds (set to 0 if this is the terminal frame)
|
||||
* @param nIsUncompressed pointer to compressed block flag, updated if this function succeeds
|
||||
*
|
||||
* @return 0 for success, or -1 for failure
|
||||
*/
|
||||
int lzsa_decode_frame(const unsigned char *pFrameData, const int nFrameDataSize, unsigned int *nBlockSize, int *nIsUncompressed) {
|
||||
if (nFrameDataSize == 3) {
|
||||
*nBlockSize = ((unsigned int)pFrameData[0]) |
|
||||
(((unsigned int)pFrameData[1]) << 8) |
|
||||
(((unsigned int)pFrameData[2]) << 16);
|
||||
|
||||
*nIsUncompressed = ((*nBlockSize & 0x800000) != 0) ? 1 : 0;
|
||||
*nBlockSize &= 0x7fffff;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
104
src/frame.h
Normal file
104
src/frame.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* frame.h - frame definitions
|
||||
*
|
||||
* Copyright (C) 2019 Emmanuel Marty
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _FRAME_H
|
||||
#define _FRAME_H
|
||||
|
||||
/**
|
||||
* Get compressed file header size
|
||||
*
|
||||
* @return file header size
|
||||
*/
|
||||
int lzsa_get_header_size(void);
|
||||
|
||||
/**
|
||||
* Get compressed frame header size
|
||||
*
|
||||
* @return frame header size
|
||||
*/
|
||||
int lzsa_get_frame_size(void);
|
||||
|
||||
/**
|
||||
* Encode file header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_header(unsigned char *pFrameData, const int nMaxFrameDataSize);
|
||||
|
||||
/**
|
||||
* Encode compressed block frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
* @param nBlockDataSize compressed block's data size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_compressed_block_frame(unsigned char *pFrameData, const int nMaxFrameDataSize, const int nBlockDataSize);
|
||||
|
||||
/**
|
||||
* Encode uncompressed block frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
* @param nBlockDataSize uncompressed block's data size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_uncompressed_block_frame(unsigned char *pFrameData, const int nMaxFrameDataSize, const int nBlockDataSize);
|
||||
|
||||
/**
|
||||
* Encode terminal frame header
|
||||
*
|
||||
* @param pFrameData encoding buffer
|
||||
* @param nMaxFrameDataSize max encoding buffer size, in bytes
|
||||
*
|
||||
* @return number of encoded bytes, or -1 for failure
|
||||
*/
|
||||
int lzsa_encode_footer_frame(unsigned char *pFrameData, const int nMaxFrameDataSize);
|
||||
|
||||
/**
|
||||
* Decode file header
|
||||
*
|
||||
* @param pFrameData data bytes
|
||||
* @param nFrameDataSize number of bytes to decode
|
||||
*
|
||||
* @return 0 for success, or -1 for failure
|
||||
*/
|
||||
int lzsa_decode_header(const unsigned char *pFrameData, const int nFrameDataSize);
|
||||
|
||||
/**
|
||||
* Decode frame header
|
||||
*
|
||||
* @param pFrameData data bytes
|
||||
* @param nFrameDataSize number of bytes to decode
|
||||
* @param nBlockSize pointer to block size, updated if this function succeeds (set to 0 if this is the terminal frame)
|
||||
* @param nIsUncompressed pointer to compressed block flag, updated if this function succeeds
|
||||
*
|
||||
* @return 0 for success, or -1 for failure
|
||||
*/
|
||||
int lzsa_decode_frame(const unsigned char *pFrameData, const int nFrameDataSize, unsigned int *nBlockSize, int *nIsUncompressed);
|
||||
|
||||
#endif /* _FRAME_H */
|
123
src/main.c
123
src/main.c
@ -30,6 +30,7 @@
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "format.h"
|
||||
#include "frame.h"
|
||||
#include "shrink.h"
|
||||
#include "expand.h"
|
||||
|
||||
@ -67,6 +68,7 @@ static int lzsa_compress(const char *pszInFilename, const char *pszOutFilename,
|
||||
long long nOriginalSize = 0LL, nCompressedSize = 0LL;
|
||||
int nFlags;
|
||||
int nResult;
|
||||
unsigned char cFrameData[16];
|
||||
bool bError = false;
|
||||
|
||||
f_in = fopen(pszInFilename, "rb");
|
||||
@ -163,14 +165,13 @@ static int lzsa_compress(const char *pszInFilename, const char *pszOutFilename,
|
||||
}
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cHeader[3];
|
||||
|
||||
cHeader[0] = 0x7b; /* Magic number: 0x9e7b */
|
||||
cHeader[1] = 0x9e;
|
||||
cHeader[2] = 0; /* Format version 1 */
|
||||
|
||||
bError = fwrite(cHeader, 1, 3, f_out) != 3;
|
||||
nCompressedSize += 3LL;
|
||||
int nHeaderSize = lzsa_encode_header(cFrameData, 16);
|
||||
if (nHeaderSize < 0)
|
||||
bError = true;
|
||||
else {
|
||||
bError = fwrite(cFrameData, 1, nHeaderSize, f_out) != nHeaderSize;
|
||||
nCompressedSize += (long long)nHeaderSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (nOptions & OPT_VERBOSE) {
|
||||
@ -205,15 +206,14 @@ static int lzsa_compress(const char *pszInFilename, const char *pszOutFilename,
|
||||
/* Write compressed block */
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cBlockSize[3];
|
||||
|
||||
cBlockSize[0] = nOutDataSize & 0xff;
|
||||
cBlockSize[1] = (nOutDataSize >> 8) & 0xff;
|
||||
cBlockSize[2] = (nOutDataSize >> 16) & 0xff;
|
||||
nCompressedSize += 3LL;
|
||||
|
||||
if (fwrite(cBlockSize, 1, 3, f_out) != (size_t)3) {
|
||||
int nBlockheaderSize = lzsa_encode_compressed_block_frame(cFrameData, 16, nOutDataSize);
|
||||
if (nBlockheaderSize < 0)
|
||||
bError = true;
|
||||
else {
|
||||
nCompressedSize += (long long)nBlockheaderSize;
|
||||
if (fwrite(cFrameData, 1, nBlockheaderSize, f_out) != (size_t)nBlockheaderSize) {
|
||||
bError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,22 +236,21 @@ static int lzsa_compress(const char *pszInFilename, const char *pszOutFilename,
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned char cBlockSize[3];
|
||||
|
||||
cBlockSize[0] = nInDataSize & 0xff;
|
||||
cBlockSize[1] = (nInDataSize >> 8) & 0xff;
|
||||
cBlockSize[2] = ((nInDataSize >> 16) & 0x7f) | 0x80; /* Uncompressed block */
|
||||
|
||||
if (fwrite(cBlockSize, 1, 3, f_out) != (size_t)3) {
|
||||
int nBlockheaderSize = lzsa_encode_uncompressed_block_frame(cFrameData, 16, nInDataSize);
|
||||
if (nBlockheaderSize < 0)
|
||||
bError = true;
|
||||
}
|
||||
else {
|
||||
if (fwrite(pInData + BLOCK_SIZE, 1, (size_t)nInDataSize, f_out) != (size_t)nInDataSize) {
|
||||
if (fwrite(cFrameData, 1, nBlockheaderSize, f_out) != (size_t)nBlockheaderSize) {
|
||||
bError = true;
|
||||
}
|
||||
else {
|
||||
nOriginalSize += (long long)nInDataSize;
|
||||
nCompressedSize += 3LL + (long long)nInDataSize;
|
||||
if (fwrite(pInData + BLOCK_SIZE, 1, (size_t)nInDataSize, f_out) != (size_t)nInDataSize) {
|
||||
bError = true;
|
||||
}
|
||||
else {
|
||||
nOriginalSize += (long long)nInDataSize;
|
||||
nCompressedSize += (long long)nBlockheaderSize + (long long)nInDataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,21 +264,19 @@ static int lzsa_compress(const char *pszInFilename, const char *pszOutFilename,
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char cFooter[4];
|
||||
int nFooterSize;
|
||||
|
||||
if ((nOptions & OPT_RAW) != 0) {
|
||||
nFooterSize = 0;
|
||||
}
|
||||
else {
|
||||
cFooter[0] = 0x00; /* EOD frame */
|
||||
cFooter[1] = 0x00;
|
||||
cFooter[2] = 0x00;
|
||||
nFooterSize = 3;
|
||||
nFooterSize = lzsa_encode_footer_frame(cFrameData, 16);
|
||||
if (nFooterSize < 0)
|
||||
bError = true;
|
||||
}
|
||||
|
||||
if (!bError)
|
||||
bError = fwrite(cFooter, 1, nFooterSize, f_out) != nFooterSize;
|
||||
bError = fwrite(cFrameData, 1, nFooterSize, f_out) != nFooterSize;
|
||||
nCompressedSize += (long long)nFooterSize;
|
||||
|
||||
if (!bError && (nOptions & OPT_VERBOSE)) {
|
||||
@ -322,6 +319,7 @@ static int lzsa_decompress(const char *pszInFilename, const char *pszOutFilename
|
||||
long long nStartTime = 0LL, nEndTime = 0LL;
|
||||
long long nOriginalSize = 0LL;
|
||||
unsigned int nFileSize = 0;
|
||||
unsigned char cFrameData[16];
|
||||
|
||||
FILE *pInFile = fopen(pszInFilename, "rb");
|
||||
if (!pInFile) {
|
||||
@ -330,20 +328,17 @@ static int lzsa_decompress(const char *pszInFilename, const char *pszOutFilename
|
||||
}
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cHeader[3];
|
||||
const int nHeaderSize = lzsa_get_header_size();
|
||||
|
||||
memset(cHeader, 0, 3);
|
||||
|
||||
if (fread(cHeader, 1, 3, pInFile) != 3) {
|
||||
memset(cFrameData, 0, 16);
|
||||
if (fread(cFrameData, 1, nHeaderSize, pInFile) != nHeaderSize) {
|
||||
fclose(pInFile);
|
||||
pInFile = NULL;
|
||||
fprintf(stderr, "error reading header in input file\n");
|
||||
return 100;
|
||||
}
|
||||
|
||||
if (cHeader[0] != 0x7b ||
|
||||
cHeader[1] != 0x9e ||
|
||||
cHeader[2] != 0) {
|
||||
if (lzsa_decode_header(cFrameData, nHeaderSize) < 0) {
|
||||
fclose(pInFile);
|
||||
pInFile = NULL;
|
||||
fprintf(stderr, "invalid magic number or format version in input file\n");
|
||||
@ -440,19 +435,21 @@ static int lzsa_decompress(const char *pszInFilename, const char *pszOutFilename
|
||||
|
||||
while (!feof(pInFile) && !nDecompressionError) {
|
||||
unsigned int nBlockSize = 0;
|
||||
int nIsUncompressed = 0;
|
||||
|
||||
if (nPrevDecompressedSize != 0) {
|
||||
memcpy(pOutData + BLOCK_SIZE - nPrevDecompressedSize, pOutData + BLOCK_SIZE, nPrevDecompressedSize);
|
||||
}
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cBlockSize[3];
|
||||
const int nFrameSize = lzsa_get_frame_size();
|
||||
|
||||
memset(cBlockSize, 0, 3);
|
||||
if (fread(cBlockSize, 1, 3, pInFile) == 3) {
|
||||
nBlockSize = ((unsigned int)cBlockSize[0]) |
|
||||
(((unsigned int)cBlockSize[1]) << 8) |
|
||||
(((unsigned int)cBlockSize[2]) << 16);
|
||||
memset(cFrameData, 0, 16);
|
||||
if (fread(cFrameData, 1, nFrameSize, pInFile) == nFrameSize) {
|
||||
if (lzsa_decode_frame(cFrameData, nFrameSize, &nBlockSize, &nIsUncompressed) < 0) {
|
||||
nDecompressionError = 1;
|
||||
nBlockSize = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nBlockSize = 0;
|
||||
@ -465,16 +462,14 @@ static int lzsa_decompress(const char *pszInFilename, const char *pszOutFilename
|
||||
}
|
||||
|
||||
if (nBlockSize != 0) {
|
||||
bool bIsUncompressed = (nBlockSize & 0x800000) != 0;
|
||||
int nDecompressedSize = 0;
|
||||
|
||||
nBlockSize &= 0x7fffff;
|
||||
if ((int)nBlockSize > BLOCK_SIZE) {
|
||||
fprintf(stderr, "block size %d > max size %d\n", nBlockSize, BLOCK_SIZE);
|
||||
break;
|
||||
}
|
||||
if (fread(pInBlock, 1, nBlockSize, pInFile) == nBlockSize) {
|
||||
if (bIsUncompressed) {
|
||||
if (nIsUncompressed) {
|
||||
memcpy(pOutData + BLOCK_SIZE, pInBlock, nBlockSize);
|
||||
nDecompressedSize = nBlockSize;
|
||||
}
|
||||
@ -539,6 +534,7 @@ static int lzsa_compare(const char *pszInFilename, const char *pszOutFilename, c
|
||||
long long nOriginalSize = 0LL;
|
||||
long long nKnownGoodSize = 0LL;
|
||||
unsigned int nFileSize = 0;
|
||||
unsigned char cFrameData[16];
|
||||
|
||||
FILE *pInFile = fopen(pszInFilename, "rb");
|
||||
if (!pInFile) {
|
||||
@ -547,20 +543,17 @@ static int lzsa_compare(const char *pszInFilename, const char *pszOutFilename, c
|
||||
}
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cHeader[3];
|
||||
const int nHeaderSize = lzsa_get_header_size();
|
||||
|
||||
memset(cHeader, 0, 3);
|
||||
|
||||
if (fread(cHeader, 1, 3, pInFile) != 3) {
|
||||
memset(cFrameData, 0, 16);
|
||||
if (fread(cFrameData, 1, nHeaderSize, pInFile) != nHeaderSize) {
|
||||
fclose(pInFile);
|
||||
pInFile = NULL;
|
||||
fprintf(stderr, "error reading header in compressed input file\n");
|
||||
return 100;
|
||||
}
|
||||
|
||||
if (cHeader[0] != 0x7b ||
|
||||
cHeader[1] != 0x9e ||
|
||||
cHeader[2] != 0) {
|
||||
if (lzsa_decode_header(cFrameData, nHeaderSize) < 0) {
|
||||
fclose(pInFile);
|
||||
pInFile = NULL;
|
||||
fprintf(stderr, "invalid magic number or format version in input file\n");
|
||||
@ -679,6 +672,7 @@ static int lzsa_compare(const char *pszInFilename, const char *pszOutFilename, c
|
||||
|
||||
while (!feof(pInFile) && !nDecompressionError && !bComparisonError) {
|
||||
unsigned int nBlockSize = 0;
|
||||
int nIsUncompressed = 0;
|
||||
|
||||
if (nPrevDecompressedSize != 0) {
|
||||
memcpy(pOutData + BLOCK_SIZE - nPrevDecompressedSize, pOutData + BLOCK_SIZE, nPrevDecompressedSize);
|
||||
@ -687,13 +681,14 @@ static int lzsa_compare(const char *pszInFilename, const char *pszOutFilename, c
|
||||
int nBytesToCompare = (int)fread(pCompareData, 1, BLOCK_SIZE, pOutFile);
|
||||
|
||||
if ((nOptions & OPT_RAW) == 0) {
|
||||
unsigned char cBlockSize[3];
|
||||
const int nFrameSize = lzsa_get_frame_size();
|
||||
|
||||
memset(cBlockSize, 0, 3);
|
||||
if (fread(cBlockSize, 1, 3, pInFile) == 3) {
|
||||
nBlockSize = ((unsigned int)cBlockSize[0]) |
|
||||
(((unsigned int)cBlockSize[1]) << 8) |
|
||||
(((unsigned int)cBlockSize[2]) << 16);
|
||||
memset(cFrameData, 0, 16);
|
||||
if (fread(cFrameData, 1, nFrameSize, pInFile) == nFrameSize) {
|
||||
if (lzsa_decode_frame(cFrameData, nFrameSize, &nBlockSize, &nIsUncompressed) < 0) {
|
||||
nDecompressionError = 1;
|
||||
nBlockSize = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nBlockSize = 0;
|
||||
@ -706,16 +701,14 @@ static int lzsa_compare(const char *pszInFilename, const char *pszOutFilename, c
|
||||
}
|
||||
|
||||
if (nBlockSize != 0) {
|
||||
bool bIsUncompressed = (nBlockSize & 0x800000) != 0;
|
||||
int nDecompressedSize = 0;
|
||||
|
||||
nBlockSize &= 0x7fffff;
|
||||
if ((int)nBlockSize > BLOCK_SIZE) {
|
||||
fprintf(stderr, "block size %d > max size %d\n", nBlockSize, BLOCK_SIZE);
|
||||
break;
|
||||
}
|
||||
if (fread(pInBlock, 1, nBlockSize, pInFile) == nBlockSize) {
|
||||
if (bIsUncompressed) {
|
||||
if (nIsUncompressed) {
|
||||
memcpy(pOutData + BLOCK_SIZE, pInBlock, nBlockSize);
|
||||
nDecompressedSize = nBlockSize;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user