mirror of
https://github.com/fadden/nulib2.git
synced 2024-05-28 23:41:29 +00:00
Added support for SQueeze compression format (both compress and expand).
Twiddled some comments in random places.
This commit is contained in:
parent
9d12532e6c
commit
da51322d48
|
@ -1,3 +1,9 @@
|
||||||
|
2002/09/26 fadden
|
||||||
|
- added support for SQueezed files (both compress and expand)
|
||||||
|
|
||||||
|
2002/09/23 fadden
|
||||||
|
- ran the code through valgrind; found and fixed some minor bugs
|
||||||
|
|
||||||
2002/09/20 fadden
|
2002/09/20 fadden
|
||||||
- pulled the sources out and started fiddling with them again
|
- pulled the sources out and started fiddling with them again
|
||||||
- changed hard tabs to spaces
|
- changed hard tabs to spaces
|
||||||
|
|
|
@ -30,9 +30,6 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
|
||||||
|
|
||||||
*pDstLen = srcLen; /* get this over with */
|
*pDstLen = srcLen; /* get this over with */
|
||||||
|
|
||||||
/* doesn't have to be same size as funnel, but it's not a bad idea */
|
|
||||||
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
|
|
||||||
/*BailAlloc(buffer);*/
|
|
||||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
|
||||||
|
@ -64,25 +61,31 @@ bail:
|
||||||
*
|
*
|
||||||
* All archive-specified fields in "pThread" will be filled in, as will
|
* All archive-specified fields in "pThread" will be filled in, as will
|
||||||
* "actualThreadEOF". The "nuThreadIdx" and "fileOffset" fields will
|
* "actualThreadEOF". The "nuThreadIdx" and "fileOffset" fields will
|
||||||
* not be modified.
|
* not be modified, and must be specified before calling here.
|
||||||
*
|
*
|
||||||
* If "sourceFormat" is uncompressed:
|
* If "sourceFormat" is uncompressed:
|
||||||
* "targetFormat" will be used to compress the data
|
* "targetFormat" will be used to compress the data
|
||||||
* the data source length will be placed into pThread->thThreadEOF
|
* the data source length will be placed into pThread->thThreadEOF
|
||||||
* the compressed size will be placed into pThread->thCompThreadEOF
|
* the compressed size will be placed into pThread->thCompThreadEOF
|
||||||
|
* the CRC is computed
|
||||||
*
|
*
|
||||||
* If "sourceFormat" is compressed:
|
* If "sourceFormat" is compressed:
|
||||||
* the data will be copied without compression (targetFormat is ignored)
|
* the data will be copied without compression (targetFormat is ignored)
|
||||||
* the data source "otherLen" value will be placed into pThread->thThreadEOF
|
* the data source "otherLen" value will be placed into pThread->thThreadEOF
|
||||||
* the data source length will be placed into pThread->thCompThreadEOF
|
* the data source length will be placed into pThread->thCompThreadEOF
|
||||||
|
* the CRC is retrieved from Nu_DataSourceGetRawCrc
|
||||||
*
|
*
|
||||||
* The actual format used will be placed in pThread->thThreadFormat, and
|
* The actual format used will be placed in pThread->thThreadFormat, and
|
||||||
* the CRC of the uncompressed data will be placed in pThread->thThreadCRC.
|
* the CRC of the uncompressed data will be placed in pThread->thThreadCRC.
|
||||||
* The remaining fields of "pThread", thThreadClass and thThreadKind, will
|
* The remaining fields of "pThread", thThreadClass and thThreadKind, will
|
||||||
* be set based on the fields in "pDataSource".
|
* be set based on the fields in "pDataSource".
|
||||||
*
|
*
|
||||||
* The output file will be positioned after the last byte of the output.
|
* Data will be written to "dstFp", which must be positioned at the
|
||||||
* (For a pre-sized buffer, this may not be the desired result.)
|
* correct point in the output. The position is expected to match
|
||||||
|
* pThread->fileOffset.
|
||||||
|
*
|
||||||
|
* On exit, the output file will be positioned after the last byte of the
|
||||||
|
* output. (For a pre-sized buffer, this may not be the desired result.)
|
||||||
*/
|
*/
|
||||||
NuError
|
NuError
|
||||||
Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
|
@ -145,6 +148,9 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
|
|
||||||
if (!srcLen) {
|
if (!srcLen) {
|
||||||
/* empty file! */
|
/* empty file! */
|
||||||
|
if (sourceFormat != kNuThreadFormatUncompressed) {
|
||||||
|
DBUG(("ODD: empty source is compressed?\n"));
|
||||||
|
}
|
||||||
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
pThread->thThreadFormat = kNuThreadFormatUncompressed;
|
||||||
pThread->thThreadCRC = threadCrc;
|
pThread->thThreadCRC = threadCrc;
|
||||||
pThread->thThreadEOF = 0;
|
pThread->thThreadEOF = 0;
|
||||||
|
@ -155,10 +161,10 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
|
|
||||||
if (sourceFormat == kNuThreadFormatUncompressed) {
|
if (sourceFormat == kNuThreadFormatUncompressed) {
|
||||||
/*
|
/*
|
||||||
* Compress the input.
|
* Compress the input to the requested target format.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* GSHK doesn't compress anything under 512 bytes */
|
/* for some reason, GSHK doesn't compress anything under 512 bytes */
|
||||||
if (pArchive->valMimicSHK && srcLen < kNuSHKLZWThreshold)
|
if (pArchive->valMimicSHK && srcLen < kNuSHKLZWThreshold)
|
||||||
targetFormat = kNuThreadFormatUncompressed;
|
targetFormat = kNuThreadFormatUncompressed;
|
||||||
|
|
||||||
|
@ -177,6 +183,10 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
err = Nu_CompressUncompressed(pArchive, pStraw, dstFp, srcLen,
|
err = Nu_CompressUncompressed(pArchive, pStraw, dstFp, srcLen,
|
||||||
&dstLen, &threadCrc);
|
&dstLen, &threadCrc);
|
||||||
break;
|
break;
|
||||||
|
case kNuThreadFormatHuffmanSQ:
|
||||||
|
err = Nu_CompressHuffmanSQ(pArchive, pStraw, dstFp, srcLen,
|
||||||
|
&dstLen, &threadCrc);
|
||||||
|
break;
|
||||||
case kNuThreadFormatLZW1:
|
case kNuThreadFormatLZW1:
|
||||||
err = Nu_CompressLZW1(pArchive, pStraw, dstFp, srcLen, &dstLen,
|
err = Nu_CompressLZW1(pArchive, pStraw, dstFp, srcLen, &dstLen,
|
||||||
&threadCrc);
|
&threadCrc);
|
||||||
|
@ -220,7 +230,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
&dstLen, &threadCrc);
|
&dstLen, &threadCrc);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
|
||||||
/* [didn't need to recompute CRC, but I was being paranoid] */
|
/* [can set "&threadCrc" above to nil to speed things up] */
|
||||||
Assert(threadCrc == pThread->thThreadCRC);
|
Assert(threadCrc == pThread->thThreadCRC);
|
||||||
|
|
||||||
pThread->thThreadEOF = srcLen;
|
pThread->thThreadEOF = srcLen;
|
||||||
|
@ -284,7 +294,6 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
{
|
{
|
||||||
NuError err = kNuErrNone;
|
NuError err = kNuErrNone;
|
||||||
NuStraw* pStraw = nil;
|
NuStraw* pStraw = nil;
|
||||||
/*uchar* buffer = nil;*/
|
|
||||||
ulong srcLen, bufferLen;
|
ulong srcLen, bufferLen;
|
||||||
ulong count, getsize;
|
ulong count, getsize;
|
||||||
|
|
||||||
|
@ -316,8 +325,6 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
|
||||||
count = srcLen;
|
count = srcLen;
|
||||||
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
|
|
||||||
/*BailAlloc(buffer);*/
|
|
||||||
err = Nu_AllocCompressionBufferIFN(pArchive);
|
err = Nu_AllocCompressionBufferIFN(pArchive);
|
||||||
BailError(err);
|
BailError(err);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* This is free software; you can redistribute it and/or modify it under the
|
* This is free software; you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Library General Public License, see the file COPYING.LIB.
|
* terms of the GNU Library General Public License, see the file COPYING.LIB.
|
||||||
*
|
*
|
||||||
* Compute 16-bit CRCs.
|
* Compute 16-bit CRCs. Depending on the hardware, the table version
|
||||||
|
* might be slower than the loop computation.
|
||||||
*/
|
*/
|
||||||
#define __Crc16_c__ 1
|
#define __Crc16_c__ 1
|
||||||
#include "NufxLibPriv.h"
|
#include "NufxLibPriv.h"
|
||||||
|
|
|
@ -162,9 +162,8 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
|
||||||
pCalcCrc);
|
pCalcCrc);
|
||||||
break;
|
break;
|
||||||
case kNuThreadFormatHuffmanSQ:
|
case kNuThreadFormatHuffmanSQ:
|
||||||
err = kNuErrBadFormat;
|
err = Nu_ExpandHuffmanSQ(pArchive, pRecord, pThread, infp, pFunnel,
|
||||||
Nu_ReportError(NU_BLOB, kNuErrNone,
|
pCalcCrc);
|
||||||
"Huffman-compressed threads not supported");
|
|
||||||
break;
|
break;
|
||||||
case kNuThreadFormatLZW1:
|
case kNuThreadFormatLZW1:
|
||||||
case kNuThreadFormatLZW2:
|
case kNuThreadFormatLZW2:
|
||||||
|
|
|
@ -560,7 +560,10 @@ Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel, const uchar* buffer,
|
||||||
* If it will fit into the buffer, just copy it in.
|
* If it will fit into the buffer, just copy it in.
|
||||||
*/
|
*/
|
||||||
if (pFunnel->bufCount + count < kNuFunnelBufSize) {
|
if (pFunnel->bufCount + count < kNuFunnelBufSize) {
|
||||||
memcpy(pFunnel->buffer + pFunnel->bufCount, buffer, count);
|
if (count == 1) /* minor optimization */
|
||||||
|
*(pFunnel->buffer + pFunnel->bufCount) = *buffer;
|
||||||
|
else
|
||||||
|
memcpy(pFunnel->buffer + pFunnel->bufCount, buffer, count);
|
||||||
pFunnel->bufCount += count;
|
pFunnel->bufCount += count;
|
||||||
goto bail;
|
goto bail;
|
||||||
} else {
|
} else {
|
||||||
|
@ -584,8 +587,6 @@ Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel, const uchar* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
/*if (err == kNuErrNone)
|
|
||||||
err = Nu_FunnelSendProgressUpdate(pArchive, pFunnel);*/
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,15 +333,15 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
|
||||||
*
|
*
|
||||||
* This function is patterned after the LZC compress function, rather
|
* This function is patterned after the LZC compress function, rather
|
||||||
* than the NuLib LZW code, because the NuLib code was abysmal (a rather
|
* than the NuLib LZW code, because the NuLib code was abysmal (a rather
|
||||||
* straight translation from assembly). This function differs from LZC
|
* straight translation from 6502 assembly). This function differs from LZC
|
||||||
* in a few areas in order to make the output match GS/ShrinkIt.
|
* in a few areas in order to make the output match GS/ShrinkIt.
|
||||||
*
|
*
|
||||||
* There is a minor bug here: if a table clear is emitted when there is
|
* There is a (deliberate) minor bug here: if a table clear is emitted
|
||||||
* only one character left in the input, nothing will be added to the
|
* when there is only one character left in the input, nothing will be
|
||||||
* hash table (as there is nothing to add) but "nextFree" will be
|
* added to the hash table (as there is nothing to add) but "nextFree"
|
||||||
* advanced. This mimics GSHK's behavior, and accounts for the "resetFix"
|
* will be advanced. This mimics GSHK's behavior, and accounts for the
|
||||||
* logic in the expansion functions. Code 0x0101 is essentially lost
|
* "resetFix" logic in the expansion functions. Code 0x0101 is essentially
|
||||||
* in this situation.
|
* lost in this situation.
|
||||||
*/
|
*/
|
||||||
static NuError
|
static NuError
|
||||||
Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
|
Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
|
||||||
|
@ -1393,8 +1393,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
|
||||||
/*printf("+++ READING %ld\n", getSize);*/
|
/*printf("+++ READING %ld\n", getSize);*/
|
||||||
err = Nu_FRead(infp, lzwState->dataPtr + lzwState->dataInBuffer,
|
err = Nu_FRead(infp, lzwState->dataPtr + lzwState->dataInBuffer,
|
||||||
getSize);
|
getSize);
|
||||||
if (err != kNuErrNone)
|
if (err != kNuErrNone) {
|
||||||
{
|
|
||||||
Nu_ReportError(NU_BLOB, err,
|
Nu_ReportError(NU_BLOB, err,
|
||||||
"failed reading compressed data (%ld bytes)", getSize);
|
"failed reading compressed data (%ld bytes)", getSize);
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
|
@ -28,10 +28,10 @@ CFLAGS = @BUILD_FLAGS@ -I. @DEFS@
|
||||||
|
|
||||||
SRCS = Archive.c ArchiveIO.c Compress.c Crc16.c Debug.c Deferred.c \
|
SRCS = Archive.c ArchiveIO.c Compress.c Crc16.c Debug.c Deferred.c \
|
||||||
Entry.c Expand.c FileIO.c Funnel.c Lzw.c MiscStuff.c MiscUtils.c \
|
Entry.c Expand.c FileIO.c Funnel.c Lzw.c MiscStuff.c MiscUtils.c \
|
||||||
Record.c SourceSink.c Thread.c Value.c Version.c
|
Record.c SourceSink.c Squeeze.c Thread.c Value.c Version.c
|
||||||
OBJS = Archive.o ArchiveIO.o Compress.o Crc16.o Debug.o Deferred.o \
|
OBJS = Archive.o ArchiveIO.o Compress.o Crc16.o Debug.o Deferred.o \
|
||||||
Entry.o Expand.o FileIO.o Funnel.o Lzw.o MiscStuff.o MiscUtils.o \
|
Entry.o Expand.o FileIO.o Funnel.o Lzw.o MiscStuff.o MiscUtils.o \
|
||||||
Record.o SourceSink.o Thread.o Value.o Version.o
|
Record.o SourceSink.o Squeeze.o Thread.o Value.o Version.o
|
||||||
|
|
||||||
STATIC_PRODUCT = libnufx.a
|
STATIC_PRODUCT = libnufx.a
|
||||||
SHARED_PRODUCT = libnufx.so
|
SHARED_PRODUCT = libnufx.so
|
||||||
|
|
|
@ -527,6 +527,7 @@ typedef enum NuProgressState {
|
||||||
kNuProgressPreparing, /* not started yet */
|
kNuProgressPreparing, /* not started yet */
|
||||||
kNuProgressOpening, /* opening files */
|
kNuProgressOpening, /* opening files */
|
||||||
|
|
||||||
|
kNuProgressAnalyzing, /* analyzing data */
|
||||||
kNuProgressCompressing, /* compressing data */
|
kNuProgressCompressing, /* compressing data */
|
||||||
kNuProgressStoring, /* storing (no compression) data */
|
kNuProgressStoring, /* storing (no compression) data */
|
||||||
kNuProgressExpanding, /* expanding data */
|
kNuProgressExpanding, /* expanding data */
|
||||||
|
|
|
@ -766,6 +766,12 @@ void Nu_DataSinkFile_Close(NuDataSink* pDataSink);
|
||||||
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len);
|
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len);
|
||||||
NuError Nu_DataSinkGetError(NuDataSink* pDataSink);
|
NuError Nu_DataSinkGetError(NuDataSink* pDataSink);
|
||||||
|
|
||||||
|
/* Squeeze.c */
|
||||||
|
NuError Nu_CompressHuffmanSQ(NuArchive* pArchive, NuStraw* pStraw, FILE* fp,
|
||||||
|
ulong srcLen, ulong* pDstLen, ushort* pCrc);
|
||||||
|
NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord,
|
||||||
|
const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc);
|
||||||
|
|
||||||
/* Thread.c */
|
/* Thread.c */
|
||||||
#ifdef __Thread_c__
|
#ifdef __Thread_c__
|
||||||
#define THREAD_INLINE /**/
|
#define THREAD_INLINE /**/
|
||||||
|
|
1137
nufxlib-0/Squeeze.c
Normal file
1137
nufxlib-0/Squeeze.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
/* version number; edit by hand */
|
/* version number; edit by hand */
|
||||||
static const long gNuMajorVersion = 1;
|
static const long gNuMajorVersion = 1;
|
||||||
static const long gNuMinorVersion = 0;
|
static const long gNuMinorVersion = 1;
|
||||||
static const long gNuBugVersion = 1;
|
static const long gNuBugVersion = 0;
|
||||||
|
|
||||||
/* executable was build on or after this date (inserted automatically) */
|
/* executable was build on or after this date (inserted automatically) */
|
||||||
static const char gNuBuildDate[] = "BUILT"; /* approximate */
|
static const char gNuBuildDate[] = "BUILT"; /* approximate */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user