Here is the code I used.
The commented-out code is code that we changed in second version. Don't 
remember the reason.
Lionscribe

Int16 zCompressLevel = 5;
UInt32 newSize;

while (zCompressLevel)
{
    newSize = 9000;
    err = myCompress(destP, &newSize, sourceP, totalSize, zCompressLevel);
    if (!err)
        break;  
    else
        zCompressLevel--;  // Try smaller compression
}
if (err)    // All levels have failed, so exit
    return err;


Err myCompress(UInt8 * dest, UInt32 * destLen, const UInt8 * source, UInt32 
sourceLen, Int16 memoryLevel)
{
    _err = 0;

    //_err = ZLibcompress2(ZLibRef, dest, destLen, source, sourceLen, 
memoryLevel);
    // Some versions of ZLib work this way, others that way. Beats me.
    //if (_err && _err != Z_MEM_ERROR)
    {
        z_stream stream;
        UInt16 level = (memoryLevel * 2) + 1;
        if (level > 9)
            level = 9;
        stream.next_in = (UInt8 *)source;
        stream.avail_in = sourceLen;
        /* Check for source > 64K on 16-bit machine: */
        if ((UInt32)stream.avail_in != sourceLen)
            return _err = Z_BUF_ERROR;

        stream.next_out = dest;
        stream.avail_out = *destLen;
        if (stream.avail_out != *destLen)
            return _err = Z_BUF_ERROR;

        stream.zalloc = (alloc_func)0;
        stream.zfree = (free_func)0;
        stream.opaque = (voidpf)0;

//      _err = deflateInit(&stream, memoryLevel);
        _err = deflateInit2(&stream, level,  Z_DEFLATED, memoryLevel + 7, 
memoryLevel,  Z_DEFAULT_STRATEGY); 
        if (_err != Z_OK)
            return _err;

        _err = deflate(&stream, Z_FINISH);
        if (_err != Z_STREAM_END)
        {
            deflateEnd(&stream);
            return _err == Z_OK ? Z_BUF_ERROR : _err;
        }
        *destLen = stream.total_out;

        _err = deflateEnd(&stream);
    }
    
    return _err;
}

As for globals, what we did (in a differrent situation), is change 'ZLibRef' 
from an UInt16 to a Macro which calls a function which returns the value from a 
feature memory, which is set when we start the library
like this. (The code was copied for use from a different library using search & 
replace, so there might be some errors.)

// UInt16 ZLibRef
#define ZLibRef getZLibRef()
#define featureNumberZLibOpenCount 0x6500


UInt16 getZLibRef()
{
    UInt32 value;
    if (errNone != FtrGet(appFileCreator, featureNumberZLibRef, &value))
        value = sysInvalidRefNum;
    return (UInt16)value;
}

static void setZLibRef(UInt16 refNum)
{
    UInt32 value = (UInt32)refNum;
    if (refNum == sysInvalidRefNum)
        FtrUnregister (appFileCreator, featureNumberZLibRef);
    else
        FtrSet(appFileCreator, featureNumberZLibRef, value);
}

static Int16 getZLibOpenCount()
{
    UInt32 value = 0;
    FtrGet(appFileCreator, featureNumberZLibOpenCount, &value);
    return (UInt16)value;
}

static Int16 incrementZLibOpenCount()
{
    UInt32 value = getZLibOpenCount();
    value++;
    FtrSet(appFileCreator, featureNumberZLibOpenCount, value);
    return value;
}

static Int16 decrementZLibOpenCount()
{
    UInt32 value = getZLibOpenCount();
    if (value > 0)
        value--;
    if (value == 0)
        FtrUnregister (appFileCreator, featureNumberZLibOpenCount);
    else
        FtrSet(appFileCreator, featureNumberZLibOpenCount, value);
    return value;
}

Err ZLibLoad()
{
    Int16 openCount = getZLibOpenCount();
    incrementZLibOpenCount();
    if (openCount == 0)
    {
        UInt16 iZLibRef = sysInvalidRefNum;

        if (errNone != SysLibFind(ZLibName, &iZLibRef))
        {
            SysLibLoad(LibType, ZLibCreator, &iZLibRef);
        }
        
        if (iZLibRef != sysInvalidRefNum)
        {
            if (mlErrNone != ZLibOpen(iZLibRef))
            {
                /* if error loading library, reset reference */
                iZLibRef = sysInvalidRefNum;
            }
        }

        setZLibRef(iZLibRef);
        if (iZLibRef == sysInvalidRefNum)
            return -1;
    }
    return 0;
}

Err ZLibUnload()
{
    decrementZLibOpenCount();
    Int16 openCount = getZLibOpenCount();

    if (openCount == 0)
    {
        UInt16 iZLibRef = getZLibRef();
        if (iZLibRef != sysInvalidRefNum)
        {
            UInt16 useCount;
            ZLibClose(iZLibRef, &useCount);
            if (useCount == 0)
            {
                SysLibRemove(iZLibRef);
            }
            iZLibRef = sysInvalidRefNum;
            setZLibRef(iZLibRef);
        }
    }
    return 0;
}




-- 
For information on using the ACCESS Developer Forums, or to unsubscribe, please 
see http://www.access-company.com/developers/forums/

Reply via email to