diff --git a/nufxlib-0/ChangeLog.txt b/nufxlib-0/ChangeLog.txt index de33d19..98fad1c 100644 --- a/nufxlib-0/ChangeLog.txt +++ b/nufxlib-0/ChangeLog.txt @@ -1,3 +1,6 @@ +2002/09/30 fadden + - added support for "deflate" compression via zlib + 2002/09/27 fadden - added support for 12-bit and 16-bit LZC (UNIX compress) diff --git a/nufxlib-0/Compress.c b/nufxlib-0/Compress.c index 3228a2b..b23779b 100644 --- a/nufxlib-0/Compress.c +++ b/nufxlib-0/Compress.c @@ -203,6 +203,12 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource, err = Nu_CompressLZC16(pArchive, pStraw, dstFp, srcLen, &dstLen, &threadCrc); break; + #ifdef HAVE_LIBZ + case kNuThreadFormatDeflate: + err = Nu_CompressDeflate(pArchive, pStraw, dstFp, srcLen, &dstLen, + &threadCrc); + break; + #endif default: /* should've been blocked in Value.c */ Assert(0); @@ -239,7 +245,14 @@ Nu_CompressToArchive(NuArchive* pArchive, NuDataSource* pDataSource, &dstLen, &threadCrc); BailError(err); - /* [can set "&threadCrc" above to nil to speed things up] */ + /* + * This holds so long as the previous attempt at compressing + * computed a CRC on the entire file (i.e. didn't stop early + * when it noticed the output was larger than the input). If + * this is always the case, then we can change "&threadCrc" + * a few lines back to "nil" and avoid re-computing the CRC. + * If this is not always the case, remove this assert. + */ Assert(threadCrc == pThread->thThreadCRC); pThread->thThreadEOF = srcLen; diff --git a/nufxlib-0/Debug.c b/nufxlib-0/Debug.c index df4d57f..7ca9a99 100644 --- a/nufxlib-0/Debug.c +++ b/nufxlib-0/Debug.c @@ -32,6 +32,7 @@ static const char* gThreadFormatNames[] = { "dynamic LZW/2", "12-bit LZC", "16-bit LZC", + "deflate" }; /* days of the week */ diff --git a/nufxlib-0/Deflate.c b/nufxlib-0/Deflate.c new file mode 100644 index 0000000..9c11743 --- /dev/null +++ b/nufxlib-0/Deflate.c @@ -0,0 +1,300 @@ +/* + * NuFX archive manipulation library + * Copyright (C) 2000 by Andy McFadden, All Rights Reserved. + * 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. + * + * Support for the "deflate" algorithm, via the "zlib" library. + * + * This compression format is totally unsupported on the Apple II. This + * is provided primarily for the benefit of Apple II emulators that want + * a better storage format for disk images than SHK+LZW or a ZIP. + */ +#include "NufxLibPriv.h" + +/* + * Because of the lack of Apple II support, I'm making this feature optional + * at compile time. The configure scripts will only define HAVE_LIBZ + * if both the library and the header file can be found. + */ +#ifdef HAVE_LIBZ +#include "zlib.h" + +#define kNuDeflateLevel 9 /* use maximum compression */ + + +/* + * Alloc and free functions provided to zlib. + */ +static voidpf +Nu_zalloc(voidpf opaque, uInt items, uInt size) +{ + return Nu_Malloc(opaque, items * size); +} +void +Nu_zfree(voidpf opaque, voidpf address) +{ + return Nu_Free(opaque, address); +} + + +/* + * =========================================================================== + * Compression + * =========================================================================== + */ + +/* + * Compress "srcLen" bytes from "pStraw" to "fp". + */ +NuError +Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp, + ulong srcLen, ulong* pDstLen, ushort* pCrc) +{ + NuError err = kNuErrNone; + z_stream zstream; + int zerr; + Bytef* outbuf = nil; + + Assert(pArchive != nil); + Assert(pStraw != nil); + Assert(fp != nil); + Assert(srcLen > 0); + Assert(pDstLen != nil); + Assert(pCrc != nil); + + err = Nu_AllocCompressionBufferIFN(pArchive); + if (err != kNuErrNone) + return err; + + /* allocate a similarly-sized buffer for the output */ + outbuf = Nu_Malloc(pArchive, kNuGenCompBufSize); + BailAlloc(outbuf); + + /* + * Initialize the zlib stream. + */ + zstream.zalloc = Nu_zalloc; + zstream.zfree = Nu_zfree; + zstream.opaque = pArchive; + zstream.next_in = nil; + zstream.avail_in = 0; + zstream.next_out = outbuf; + zstream.avail_out = kNuGenCompBufSize; + zstream.data_type = Z_UNKNOWN; + + zerr = deflateInit(&zstream, kNuDeflateLevel); + if (zerr != Z_OK) { + err = kNuErrInternal; + if (zerr == Z_VERSION_ERROR) { + Nu_ReportError(NU_BLOB, err, + "installed zlib is not compatible with linked version (%s)", + ZLIB_VERSION); + } else { + Nu_ReportError(NU_BLOB, err, + "call to deflateInit failed (zerr=%d)", zerr); + } + goto bail; + } + + /* + * Loop while we have data. + */ + do { + ulong getSize; + int flush; + + /* should be able to read a full buffer every time */ + if (zstream.avail_in == 0 && srcLen) { + getSize = (srcLen > kNuGenCompBufSize) ? kNuGenCompBufSize : srcLen; + DBUG(("+++ reading %ld bytes\n", getSize)); + + err = Nu_StrawRead(pArchive, pStraw, pArchive->compBuf, getSize); + if (err != kNuErrNone) { + Nu_ReportError(NU_BLOB, err, "deflate read failed"); + goto z_bail; + } + + srcLen -= getSize; + + *pCrc = Nu_CalcCRC16(*pCrc, pArchive->compBuf, getSize); + + zstream.next_in = pArchive->compBuf; + zstream.avail_in = getSize; + } + + if (srcLen == 0) + flush = Z_FINISH; /* tell zlib that we're done */ + else + flush = Z_NO_FLUSH; /* more to come! */ + + zerr = deflate(&zstream, flush); + if (zerr != Z_OK && zerr != Z_STREAM_END) { + err = kNuErrInternal; + Nu_ReportError(NU_BLOB, err, "zlib deflate call failed (zerr=%d)", + zerr); + goto z_bail; + } + + /* write when we're full or when we're done */ + if (zstream.avail_out == 0 || + (zerr == Z_STREAM_END && zstream.avail_out != kNuGenCompBufSize)) + { + DBUG(("+++ writing %d bytes\n", zstream.next_out - outbuf)); + err = Nu_FWrite(fp, outbuf, zstream.next_out - outbuf); + if (err != kNuErrNone) { + Nu_ReportError(NU_BLOB, err, "fwrite failed in deflate"); + goto z_bail; + } + + zstream.next_out = outbuf; + zstream.avail_out = kNuGenCompBufSize; + } + } while (zerr == Z_OK); + + Assert(zerr == Z_STREAM_END); /* other errors should've been caught */ + + *pDstLen = zstream.total_out; + +z_bail: + deflateEnd(&zstream); /* free up any allocated structures */ + +bail: + if (outbuf != nil) + free(outbuf); + return err; +} + + +/* + * =========================================================================== + * Expansion + * =========================================================================== + */ + +/* + * Expand from "infp" to "pFunnel". + */ +NuError +Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord, + const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc) +{ + NuError err = kNuErrNone; + z_stream zstream; + int zerr; + ulong compRemaining; + Bytef* outbuf; + + Assert(pArchive != nil); + Assert(pThread != nil); + Assert(infp != nil); + Assert(pFunnel != nil); + + err = Nu_AllocCompressionBufferIFN(pArchive); + if (err != kNuErrNone) + return err; + + /* allocate a similarly-sized buffer for the output */ + outbuf = Nu_Malloc(pArchive, kNuGenCompBufSize); + BailAlloc(outbuf); + + compRemaining = pThread->thCompThreadEOF; + + /* + * Initialize the zlib stream. + */ + zstream.zalloc = Nu_zalloc; + zstream.zfree = Nu_zfree; + zstream.opaque = pArchive; + zstream.next_in = nil; + zstream.avail_in = 0; + zstream.next_out = outbuf; + zstream.avail_out = kNuGenCompBufSize; + zstream.data_type = Z_UNKNOWN; + + zerr = inflateInit(&zstream); + if (zerr != Z_OK) { + err = kNuErrInternal; + if (zerr == Z_VERSION_ERROR) { + Nu_ReportError(NU_BLOB, err, + "installed zlib is not compatible with linked version (%s)", + ZLIB_VERSION); + } else { + Nu_ReportError(NU_BLOB, err, + "call to inflateInit failed (zerr=%d)", zerr); + } + goto bail; + } + + /* + * Loop while we have data. + */ + do { + ulong getSize; + + /* read as much as we can */ + if (zstream.avail_in == 0) { + getSize = (compRemaining > kNuGenCompBufSize) ? + kNuGenCompBufSize : compRemaining; + DBUG(("+++ reading %ld bytes (%ld left)\n", getSize, + compRemaining)); + + err = Nu_FRead(infp, pArchive->compBuf, getSize); + if (err != kNuErrNone) { + Nu_ReportError(NU_BLOB, err, "inflate read failed"); + goto z_bail; + } + + compRemaining -= getSize; + + zstream.next_in = pArchive->compBuf; + zstream.avail_in = getSize; + } + + /* uncompress the data */ + zerr = inflate(&zstream, Z_NO_FLUSH); + if (zerr != Z_OK && zerr != Z_STREAM_END) { + err = kNuErrInternal; + Nu_ReportError(NU_BLOB, err, "zlib inflate call failed (zerr=%d)", + zerr); + goto z_bail; + } + + /* write every time (buffer will usually be full) */ + if (zstream.avail_out != kNuGenCompBufSize) { + DBUG(("+++ writing %d bytes\n", zstream.next_out - outbuf)); + err = Nu_FunnelWrite(pArchive, pFunnel, outbuf, + zstream.next_out - outbuf); + if (err != kNuErrNone) { + Nu_ReportError(NU_BLOB, err, "write failed in inflate"); + goto z_bail; + } + + if (pCrc != nil) + *pCrc = Nu_CalcCRC16(*pCrc, outbuf, zstream.next_out - outbuf); + + zstream.next_out = outbuf; + zstream.avail_out = kNuGenCompBufSize; + } + } while (zerr == Z_OK); + + Assert(zerr == Z_STREAM_END); /* other errors should've been caught */ + + if (zstream.total_out != pThread->actualThreadEOF) { + err = kNuErrBadData; + Nu_ReportError(NU_BLOB, err, + "size mismatch on inflated file (%ld vs %ld)", + zstream.total_out, pThread->actualThreadEOF); + goto z_bail; + } + +z_bail: + inflateEnd(&zstream); /* free up any allocated structures */ + +bail: + if (outbuf != nil) + free(outbuf); + return err; +} + +#endif /*HAVE_LIBZ*/ diff --git a/nufxlib-0/Expand.c b/nufxlib-0/Expand.c index 011743e..f561e39 100644 --- a/nufxlib-0/Expand.c +++ b/nufxlib-0/Expand.c @@ -173,13 +173,25 @@ Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord, case kNuThreadFormatLZC16: err = Nu_ExpandLZC(pArchive, pRecord, pThread, infp, pFunnel, pCalcCrc); break; + case kNuThreadFormatDeflate: + #ifdef HAVE_LIBZ + err = Nu_ExpandDeflate(pArchive, pRecord, pThread, infp, pFunnel, + pCalcCrc); + #else + err = kNuErrBadFormat; + Nu_ReportError(NU_BLOB, kNuErrNone, + "deflate compression not supported"); + #endif + break; default: err = kNuErrBadFormat; Nu_ReportError(NU_BLOB, err, "format %u unknown", pThread->thThreadFormat); break; } + BailError(err); + err = Nu_FunnelFlush(pArchive, pFunnel); BailError(err); /* diff --git a/nufxlib-0/Lzc.c b/nufxlib-0/Lzc.c index bbcbb66..2f88f80 100644 --- a/nufxlib-0/Lzc.c +++ b/nufxlib-0/Lzc.c @@ -5,7 +5,9 @@ * terms of the GNU Library General Public License, see the file COPYING.LIB. * * This is the LZW implementation found in the UNIX "compress" command, - * sometimes referred to as "LZC". + * sometimes referred to as "LZC". GS/ShrinkIt v1.1 can unpack threads + * in LZC format, P8 ShrinkIt cannot. The only other application that + * is known to create LZC threads is the original NuLib. * * There's a lot of junk in here for the sake of smaller systems (e.g. MSDOS) * and pre-ANSI compilers. For the most part it has been left unchanged. @@ -1055,7 +1057,7 @@ Nu_LZC_decompress(LZCState* pLzcState, ulong compressedLen) */ NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord, - const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc) + const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc) { NuError err = kNuErrNone; LZCState lzcState; @@ -1065,20 +1067,17 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord, lzcState.infp = infp; lzcState.pFunnel = pFunnel; - if (pThreadCrc == nil) { + if (pCrc == nil) { lzcState.doCalcCRC = false; } else { lzcState.doCalcCRC = true; - lzcState.crc = *pThreadCrc; + lzcState.crc = *pCrc; } Nu_LZC_decompress(&lzcState, pThread->thCompThreadEOF); err = lzcState.exit_stat; DBUG(("+++ LZC_decompress returned with %d\n", err)); - if (err == kNuErrNone) - err = Nu_FunnelFlush(pArchive, pFunnel); - #if (SPLIT_HT) free_array(CODE,lzcState.ht[1], 0); free_array(CODE,lzcState.ht[0], 0); @@ -1094,8 +1093,8 @@ Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord, #endif free_array(char,lzcState.sfx, 256); - if (pThreadCrc != nil) - *pThreadCrc = lzcState.crc; + if (pCrc != nil) + *pCrc = lzcState.crc; return err; } diff --git a/nufxlib-0/Lzw.c b/nufxlib-0/Lzw.c index 615f497..c5fa306 100644 --- a/nufxlib-0/Lzw.c +++ b/nufxlib-0/Lzw.c @@ -135,6 +135,10 @@ typedef struct LZWCompressState { /* * Allocate some "reusable" state for LZW compression. + * + * The only thing that really needs to be retained across calls is + * the hash function. This way we don't have to re-create it for + * every file, or store it statically in the binary. */ static NuError Nu_AllocLZWCompressState(NuArchive* pArchive) @@ -1596,9 +1600,6 @@ Nu_ExpandLZW(NuArchive* pArchive, const NuRecord* pRecord, } bail: - if (err == kNuErrNone) - err = Nu_FunnelFlush(pArchive, pFunnel); - return err; } diff --git a/nufxlib-0/Makefile.in b/nufxlib-0/Makefile.in index b85086a..2633890 100644 --- a/nufxlib-0/Makefile.in +++ b/nufxlib-0/Makefile.in @@ -27,13 +27,13 @@ GCC_FLAGS = -Wall -Wwrite-strings -Wstrict-prototypes -Wpointer-arith -Wshadow 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 Lzc.c Lzw.c MiscStuff.c \ - MiscUtils.c Record.c SourceSink.c Squeeze.c Thread.c Value.c \ - Version.c + Deflate.c Entry.c Expand.c FileIO.c Funnel.c Lzc.c Lzw.c \ + MiscStuff.c MiscUtils.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 Lzc.o Lzw.o MiscStuff.o \ - MiscUtils.o Record.o SourceSink.o Squeeze.o Thread.o Value.o \ - Version.o + Deflate.o Entry.o Expand.o FileIO.o Funnel.o Lzc.o Lzw.o \ + MiscStuff.o MiscUtils.o Record.o SourceSink.o Squeeze.o \ + Thread.o Value.o Version.o STATIC_PRODUCT = libnufx.a SHARED_PRODUCT = libnufx.so @@ -68,13 +68,13 @@ shared:: PRODUCT="$(SHARED_PRODUCT)" $(MAKE) -e $(STATIC_PRODUCT): $(OBJS) - -rm -f $(SHARED_PRODUCT) + -rm -f $(STATIC_PRODUCT) $(SHARED_PRODUCT) $(AR) $@ $(OBJS) @RANLIB@ $@ $(SHARED_PRODUCT): $(OBJS) - -rm -f $(STATIC_PRODUCT) - $(CC) @SHARE_FLAGS@ -o $@ $(OBJS) + -rm -f $(STATIC_PRODUCT) $(SHARED_PRODUCT) + $(CC) @SHARE_FLAGS@ -o $@ $(OBJS) @LIBS@ # the build date is approximate, the build flags are accurate Version.c: Version.c.in Makefile diff --git a/nufxlib-0/MiscStuff.h b/nufxlib-0/MiscStuff.h index cabbf35..142c8e1 100644 --- a/nufxlib-0/MiscStuff.h +++ b/nufxlib-0/MiscStuff.h @@ -9,7 +9,7 @@ #ifndef __MiscStuff__ #define __MiscStuff__ -#define VALGRIND /* assume we're using it */ +#define VALGRIND /* let's just assume we're using it */ #include "SysDefs.h" diff --git a/nufxlib-0/NufxLib.h b/nufxlib-0/NufxLib.h index c0c6a8d..5d3f4c2 100644 --- a/nufxlib-0/NufxLib.h +++ b/nufxlib-0/NufxLib.h @@ -164,7 +164,8 @@ typedef enum NuThreadFormat { kNuThreadFormatLZW1 = 0x0002, kNuThreadFormatLZW2 = 0x0003, kNuThreadFormatLZC12 = 0x0004, - kNuThreadFormatLZC16 = 0x0005 + kNuThreadFormatLZC16 = 0x0005, + kNuThreadFormatDeflate = 0x0006, /* NOTE: not in NuFX standard */ } NuThreadFormat; @@ -254,6 +255,7 @@ enum NuValueValue { kNuCompressLZW2 = 13, kNuCompressLZC12 = 14, kNuCompressLZC16 = 15, + kNuCompressDeflate = 16, /* for kNuValueEOL */ kNuEOLUnknown = 50, diff --git a/nufxlib-0/NufxLibPriv.h b/nufxlib-0/NufxLibPriv.h index 77ba660..6342962 100644 --- a/nufxlib-0/NufxLibPriv.h +++ b/nufxlib-0/NufxLibPriv.h @@ -571,6 +571,12 @@ NuThreadMod* Nu_ThreadMod_FindByThreadIdx(const NuRecord* pRecord, NuThreadIdx threadIdx); NuError Nu_Flush(NuArchive* pArchive, long* pStatusFlags); +/* Deflate.c */ +NuError Nu_CompressDeflate(NuArchive* pArchive, NuStraw* pStraw, FILE* fp, + ulong srcLen, ulong* pDstLen, ushort* pCrc); +NuError Nu_ExpandDeflate(NuArchive* pArchive, const NuRecord* pRecord, + const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc); + /* Expand.c */ NuError Nu_ExpandStream(NuArchive* pArchive, const NuRecord* pRecord, const NuThread* pThread, FILE* infp, NuFunnel* pFunnel); @@ -637,7 +643,7 @@ NuError Nu_CompressLZC12(NuArchive* pArchive, NuStraw* pStraw, FILE* fp, NuError Nu_CompressLZC16(NuArchive* pArchive, NuStraw* pStraw, FILE* fp, ulong srcLen, ulong* pDstLen, ushort* pCrc); NuError Nu_ExpandLZC(NuArchive* pArchive, const NuRecord* pRecord, - const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc); + const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc); /* Lzw.c */ NuError Nu_CompressLZW1(NuArchive* pArchive, NuStraw* pStraw, FILE* fp, diff --git a/nufxlib-0/Squeeze.c b/nufxlib-0/Squeeze.c index 597600e..a20337b 100644 --- a/nufxlib-0/Squeeze.c +++ b/nufxlib-0/Squeeze.c @@ -532,10 +532,8 @@ Nu_SQComputeHuffTree(SQState* pSqState) int* pWeight; err = Nu_SQGetcRLE(pSqState, &sym); - if (err != kNuErrNone) { - NuArchive* pArchive = pSqState->pArchive; - BailError(err); - } + if (err != kNuErrNone) + goto bail; Assert(sym >= 0 && sym <= kNuSQEOFToken); pWeight = &pSqState->node[(unsigned)sym].weight; @@ -682,7 +680,7 @@ bail: } /* - * Compress in "SQ" format, from "pStraw" to "fp". + * Compress "srcLen" bytes into SQ format, from "pStraw" to "fp". * * This requires two passes through the input. */ @@ -897,7 +895,7 @@ Nu_USQReadShort(USQState* pUsqState, short* pShort) */ NuError Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord, - const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pThreadCrc) + const NuThread* pThread, FILE* infp, NuFunnel* pFunnel, ushort* pCrc) { NuError err = kNuErrNone; USQState usqState; @@ -1071,8 +1069,8 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord, val = 2; } while (--val) { - if (pThreadCrc != nil) - *pThreadCrc = Nu_CalcCRC16(*pThreadCrc, &lastc, 1); + if (pCrc != nil) + *pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1); err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1); #ifdef FULL_SQ_HEADER checksum += lastc; @@ -1086,8 +1084,8 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord, inrep = true; } else { lastc = val; - if (pThreadCrc != nil) - *pThreadCrc = Nu_CalcCRC16(*pThreadCrc, &lastc, 1); + if (pCrc != nil) + *pCrc = Nu_CalcCRC16(*pCrc, &lastc, 1); err = Nu_FunnelWrite(pArchive, pFunnel, &lastc, 1); #ifdef FULL_SQ_HEADER checksum += lastc; @@ -1131,9 +1129,6 @@ Nu_ExpandHuffmanSQ(NuArchive* pArchive, const NuRecord* pRecord, } bail: - if (err == kNuErrNone) - err = Nu_FunnelFlush(pArchive, pFunnel); - return err; } diff --git a/nufxlib-0/Value.c b/nufxlib-0/Value.c index 9b06688..a94dcaf 100644 --- a/nufxlib-0/Value.c +++ b/nufxlib-0/Value.c @@ -88,7 +88,7 @@ Nu_SetValue(NuArchive* pArchive, NuValueID ident, NuValue value) pArchive->valConvertExtractedEOL = value; break; case kNuValueDataCompression: - if (value < kNuCompressNone || value > kNuCompressLZC16) { + if (value < kNuCompressNone || value > kNuCompressDeflate) { Nu_ReportError(NU_BLOB, err, "Invalid kNuValueDataCompression value %ld\n", value); goto bail; @@ -210,6 +210,12 @@ Nu_ConvertCompressValToFormat(NuArchive* pArchive, NuValue compValue) case kNuCompressSQ: threadFormat = kNuThreadFormatHuffmanSQ; break; case kNuCompressLZC12: threadFormat = kNuThreadFormatLZC12; break; case kNuCompressLZC16: threadFormat = kNuThreadFormatLZC16; break; + #ifdef HAVE_LIBZ + case kNuCompressDeflate: threadFormat = kNuThreadFormatDeflate; break; + #else + case kNuCompressDeflate: threadFormat = kNuThreadFormatDeflate; + unsup = true; break; + #endif default: Assert(false); Nu_ReportError(NU_BLOB, kNuErrInvalidArg, diff --git a/nufxlib-0/config.h.in b/nufxlib-0/config.h.in index dac1c9d..1035df2 100644 --- a/nufxlib-0/config.h.in +++ b/nufxlib-0/config.h.in @@ -120,6 +120,9 @@ /* Define if VSNPRINTF is declared in stdio.h. */ #undef VSNPRINTF_DECLARED +/* Define if you have libz.a or libz.so */ +#undef HAVE_LIBZ + /* Define if we want to use the dmalloc library (--enable-dmalloc). */ #undef USE_DMALLOC diff --git a/nufxlib-0/configure b/nufxlib-0/configure index 67f2902..53579ca 100755 --- a/nufxlib-0/configure +++ b/nufxlib-0/configure @@ -915,9 +915,8 @@ else fi - echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:921: checking how to run the C preprocessor" >&5 +echo "configure:920: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -932,13 +931,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:942: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:941: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -949,13 +948,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:959: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:958: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -966,13 +965,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:976: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1001,17 +1000,17 @@ for ac_hdr in fcntl.h malloc.h stdlib.h sys/stat.h sys/time.h sys/types.h \ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1005: checking for $ac_hdr" >&5 +echo "configure:1004: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1015: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1014: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1038,13 +1037,90 @@ fi done +LIBS="" +echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 +echo "configure:1043: checking for deflate in -lz" >&5 +ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lz $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_safe=`echo "zlib.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for zlib.h""... $ac_c" 1>&6 +echo "configure:1079: checking for zlib.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1089: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LIBZ 1 +EOF + LIBS="$LIBS -lz" +else + echo "$ac_t""no" 1>&6 +fi + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:1043: checking for working const" >&5 +echo "configure:1119: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1114,21 +1190,21 @@ EOF fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:1118: checking for inline" >&5 +echo "configure:1194: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1208: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -1154,12 +1230,12 @@ EOF esac echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1158: checking for ANSI C header files" >&5 +echo "configure:1234: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1167,7 +1243,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1171: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1247: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1184,7 +1260,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1202,7 +1278,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1223,7 +1299,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1234,7 +1310,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1314: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1258,12 +1334,12 @@ EOF fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:1262: checking for mode_t" >&5 +echo "configure:1338: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1291,12 +1367,12 @@ EOF fi echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:1295: checking for off_t" >&5 +echo "configure:1371: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1324,12 +1400,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:1328: checking for size_t" >&5 +echo "configure:1404: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1357,12 +1433,12 @@ EOF fi echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 -echo "configure:1361: checking whether struct tm is in sys/time.h or time.h" >&5 +echo "configure:1437: checking whether struct tm is in sys/time.h or time.h" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1370,7 +1446,7 @@ int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF -if { (eval echo configure:1374: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else @@ -1391,12 +1467,12 @@ EOF fi echo $ac_n "checking for uchar""... $ac_c" 1>&6 -echo "configure:1395: checking for uchar" >&5 +echo "configure:1471: checking for uchar" >&5 if eval "test \"`echo '$''{'ac_cv_type_uchar'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1424,12 +1500,12 @@ EOF fi echo $ac_n "checking for ushort""... $ac_c" 1>&6 -echo "configure:1428: checking for ushort" >&5 +echo "configure:1504: checking for ushort" >&5 if eval "test \"`echo '$''{'ac_cv_type_ushort'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1457,12 +1533,12 @@ EOF fi echo $ac_n "checking for uint""... $ac_c" 1>&6 -echo "configure:1461: checking for uint" >&5 +echo "configure:1537: checking for uint" >&5 if eval "test \"`echo '$''{'ac_cv_type_uint'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1490,12 +1566,12 @@ EOF fi echo $ac_n "checking for ulong""... $ac_c" 1>&6 -echo "configure:1494: checking for ulong" >&5 +echo "configure:1570: checking for ulong" >&5 if eval "test \"`echo '$''{'ac_cv_type_ulong'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1527,12 +1603,12 @@ for ac_func in fdopen ftruncate memmove mkdir mkstemp mktime timelocal \ localtime_r snprintf strcasecmp strncasecmp strtoul strerror vsnprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1531: checking for $ac_func" >&5 +echo "configure:1607: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1581,13 +1657,13 @@ done echo $ac_n "checking if snprintf is declared""... $ac_c" 1>&6 -echo "configure:1585: checking if snprintf is declared" >&5 +echo "configure:1661: checking if snprintf is declared" >&5 if eval "test \"`echo '$''{'nufxlib_cv_snprintf_in_header'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -1613,13 +1689,13 @@ fi echo "$ac_t""$nufxlib_cv_snprintf_in_header" 1>&6 echo $ac_n "checking if vsnprintf is declared""... $ac_c" 1>&6 -echo "configure:1617: checking if vsnprintf is declared" >&5 +echo "configure:1693: checking if vsnprintf is declared" >&5 if eval "test \"`echo '$''{'nufxlib_cv_vsnprintf_in_header'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -1687,7 +1763,7 @@ if test "$host_os" = "beos"; then fi echo $ac_n "checking if sprintf returns int""... $ac_c" 1>&6 -echo "configure:1691: checking if sprintf returns int" >&5 +echo "configure:1767: checking if sprintf returns int" >&5 if eval "test \"`echo '$''{'nufxlib_cv_sprintf_returns_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1696,7 +1772,7 @@ else nufxlib_cv_sprintf_returns_int=no else cat > conftest.$ac_ext < @@ -1709,7 +1785,7 @@ else } EOF -if { (eval echo configure:1713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then nufxlib_cv_sprintf_returns_int=yes else @@ -1738,7 +1814,7 @@ if test "${enable_dmalloc+set}" = set; then enableval="$enable_dmalloc" \ echo "--- enabling dmalloc"; \ - DMALLOC="-L/usr/local/lib -ldmalloc"; cat >> confdefs.h <<\EOF + LIBS="$LIBS -L/usr/local/lib -ldmalloc"; cat >> confdefs.h <<\EOF #define USE_DMALLOC 1 EOF diff --git a/nufxlib-0/configure.in b/nufxlib-0/configure.in index 308b2ea..aedec87 100644 --- a/nufxlib-0/configure.in +++ b/nufxlib-0/configure.in @@ -10,12 +10,15 @@ AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_RANLIB -dnl Checks for libraries. - dnl Checks for header files. AC_CHECK_HEADERS(fcntl.h malloc.h stdlib.h sys/stat.h sys/time.h sys/types.h \ sys/utime.h unistd.h utime.h) +dnl Check for zlib. Make sure it comes with zlib.h. +LIBS="" +AC_CHECK_LIB(z, deflate, + AC_CHECK_HEADER(zlib.h, AC_DEFINE(HAVE_LIBZ) LIBS="$LIBS -lz")) + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE @@ -130,7 +133,7 @@ AC_MSG_RESULT($nufxlib_cv_sprintf_returns_int) DMALLOC= AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc: do dmalloc stuff], \ [ echo "--- enabling dmalloc"; \ - DMALLOC="-L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ]) + LIBS="$LIBS -L/usr/local/lib -ldmalloc"; AC_DEFINE(USE_DMALLOC) ]) AC_SUBST(DMALLOC) AC_OUTPUT(Makefile samples/Makefile) diff --git a/nufxlib-0/samples/Makefile.in b/nufxlib-0/samples/Makefile.in index a5f7ef9..06472f4 100644 --- a/nufxlib-0/samples/Makefile.in +++ b/nufxlib-0/samples/Makefile.in @@ -22,7 +22,7 @@ CFLAGS = @BUILD_FLAGS@ -I. -I.. @DEFS@ ALL_SRCS = Exerciser.c Launder.c ImgConv.c TestBasic.c TestExtract.c \ TestSimple.c -NUFXLIB = -L.. -lnufx @DMALLOC@ +NUFXLIB = -L.. -lnufx PRODUCTS = exerciser imgconv launder test-basic test-extract test-simple @@ -47,22 +47,22 @@ all: $(PRODUCTS) # @$(MAKE) PURIFY_BUILD=1 exerciser: Exerciser.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ Exerciser.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ Exerciser.o $(NUFXLIB) @LIBS@ imgconv: ImgConv.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ ImgConv.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ ImgConv.o $(NUFXLIB) @LIBS@ launder: Launder.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ Launder.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ Launder.o $(NUFXLIB) @LIBS@ test-basic: TestBasic.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestBasic.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestBasic.o $(NUFXLIB) @LIBS@ test-simple: TestSimple.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestSimple.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestSimple.o $(NUFXLIB) @LIBS@ test-extract: TestExtract.o $(LIB_PRODUCT) - $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestExtract.o $(NUFXLIB) + $(PURIFY) $(QUANTIFY) $(CC) -o $@ TestExtract.o $(NUFXLIB) @LIBS@ tags:: ctags --totals -R ../*