Added support for SQueeze compression format (both compress and expand).

Twiddled some comments in random places.
This commit is contained in:
Andy McFadden 2002-09-26 22:11:12 +00:00
parent 9d12532e6c
commit da51322d48
11 changed files with 1189 additions and 32 deletions

View File

@ -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
- pulled the sources out and started fiddling with them again
- changed hard tabs to spaces

View File

@ -30,9 +30,6 @@ Nu_CompressUncompressed(NuArchive* pArchive, NuStraw* pStraw,
*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);
BailError(err);
@ -64,25 +61,31 @@ bail:
*
* All archive-specified fields in "pThread" will be filled in, as 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:
* "targetFormat" will be used to compress the data
* the data source length will be placed into pThread->thThreadEOF
* the compressed size will be placed into pThread->thCompThreadEOF
* the CRC is computed
*
* If "sourceFormat" is compressed:
* the data will be copied without compression (targetFormat is ignored)
* the data source "otherLen" value will be placed into pThread->thThreadEOF
* 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 CRC of the uncompressed data will be placed in pThread->thThreadCRC.
* The remaining fields of "pThread", thThreadClass and thThreadKind, will
* be set based on the fields in "pDataSource".
*
* 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.)
* Data will be written to "dstFp", which must be positioned at the
* 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
Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
@ -145,6 +148,9 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
if (!srcLen) {
/* empty file! */
if (sourceFormat != kNuThreadFormatUncompressed) {
DBUG(("ODD: empty source is compressed?\n"));
}
pThread->thThreadFormat = kNuThreadFormatUncompressed;
pThread->thThreadCRC = threadCrc;
pThread->thThreadEOF = 0;
@ -155,10 +161,10 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
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)
targetFormat = kNuThreadFormatUncompressed;
@ -177,6 +183,10 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
err = Nu_CompressUncompressed(pArchive, pStraw, dstFp, srcLen,
&dstLen, &threadCrc);
break;
case kNuThreadFormatHuffmanSQ:
err = Nu_CompressHuffmanSQ(pArchive, pStraw, dstFp, srcLen,
&dstLen, &threadCrc);
break;
case kNuThreadFormatLZW1:
err = Nu_CompressLZW1(pArchive, pStraw, dstFp, srcLen, &dstLen,
&threadCrc);
@ -220,7 +230,7 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
&dstLen, &threadCrc);
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);
pThread->thThreadEOF = srcLen;
@ -284,7 +294,6 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
{
NuError err = kNuErrNone;
NuStraw* pStraw = nil;
/*uchar* buffer = nil;*/
ulong srcLen, bufferLen;
ulong count, getsize;
@ -316,8 +325,6 @@ Nu_CopyPresizedToArchive(NuArchive* pArchive, NuDataSource* pDataSource,
BailError(err);
count = srcLen;
/*buffer = Nu_Malloc(pArchive, kNuFunnelBufSize);*/
/*BailAlloc(buffer);*/
err = Nu_AllocCompressionBufferIFN(pArchive);
BailError(err);

View File

@ -4,7 +4,8 @@
* 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.
*
* 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
#include "NufxLibPriv.h"

View File

@ -162,9 +162,8 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord,
pCalcCrc);
break;
case kNuThreadFormatHuffmanSQ:
err = kNuErrBadFormat;
Nu_ReportError(NU_BLOB, kNuErrNone,
"Huffman-compressed threads not supported");
err = Nu_ExpandHuffmanSQ(pArchive, pRecord, pThread, infp, pFunnel,
pCalcCrc);
break;
case kNuThreadFormatLZW1:
case kNuThreadFormatLZW2:

View File

@ -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 (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;
goto bail;
} else {
@ -584,8 +587,6 @@ Nu_FunnelWrite(NuArchive* pArchive, NuFunnel* pFunnel, const uchar* buffer,
}
bail:
/*if (err == kNuErrNone)
err = Nu_FunnelSendProgressUpdate(pArchive, pFunnel);*/
return err;
}

View File

@ -333,15 +333,15 @@ Nu_LZWPutCode(uchar** pOutBuf, ulong prefixCode, int codeBits, int* pAtBit)
*
* This function is patterned after the LZC compress function, 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.
*
* There is a minor bug here: if a table clear is emitted when there is
* only one character left in the input, nothing will be added to the
* hash table (as there is nothing to add) but "nextFree" will be
* advanced. This mimics GSHK's behavior, and accounts for the "resetFix"
* logic in the expansion functions. Code 0x0101 is essentially lost
* in this situation.
* There is a (deliberate) minor bug here: if a table clear is emitted
* when there is only one character left in the input, nothing will be
* added to the hash table (as there is nothing to add) but "nextFree"
* will be advanced. This mimics GSHK's behavior, and accounts for the
* "resetFix" logic in the expansion functions. Code 0x0101 is essentially
* lost in this situation.
*/
static NuError
Nu_CompressLZWBlock(LZWCompressState* lzwState, const uchar* inputBuf,
@ -1393,8 +1393,7 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord,
/*printf("+++ READING %ld\n", getSize);*/
err = Nu_FRead(infp, lzwState->dataPtr + lzwState->dataInBuffer,
getSize);
if (err != kNuErrNone)
{
if (err != kNuErrNone) {
Nu_ReportError(NU_BLOB, err,
"failed reading compressed data (%ld bytes)", getSize);
goto bail;

View File

@ -28,10 +28,10 @@ CFLAGS = @BUILD_FLAGS@ -I. @DEFS@
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 \
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 \
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
SHARED_PRODUCT = libnufx.so

View File

@ -527,6 +527,7 @@ typedef enum NuProgressState {
kNuProgressPreparing, /* not started yet */
kNuProgressOpening, /* opening files */
kNuProgressAnalyzing, /* analyzing data */
kNuProgressCompressing, /* compressing data */
kNuProgressStoring, /* storing (no compression) data */
kNuProgressExpanding, /* expanding data */

View File

@ -766,6 +766,12 @@ void Nu_DataSinkFile_Close(NuDataSink* pDataSink);
NuError Nu_DataSinkPutBlock(NuDataSink* pDataSink, const uchar* buf, ulong len);
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 */
#ifdef __Thread_c__
#define THREAD_INLINE /**/

1137
nufxlib-0/Squeeze.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -12,8 +12,8 @@
/* version number; edit by hand */
static const long gNuMajorVersion = 1;
static const long gNuMinorVersion = 0;
static const long gNuBugVersion = 1;
static const long gNuMinorVersion = 1;
static const long gNuBugVersion = 0;
/* executable was build on or after this date (inserted automatically) */
static const char gNuBuildDate[] = "BUILT"; /* approximate */