/******************************************************************************
*
* NSSDC/CDF Run-length encoding compression/decompression.
*
* Version 1.0, 15-May-96, Hughes STX.
*
* Modification history:
*
* V1.0 15-May-96, J Love Original version.
*
******************************************************************************/
#include "cdflib.h"
#include "cdflib64.h"
#if !SUPPORT_RLE64 && defined(BORLANDC)
#pragma warn -par
#endif
/******************************************************************************
* CompressRLE0_64.
******************************************************************************/
STATICforIDL CDFstatus CompressRLE0_64 (srcFp, srcOffset, srcSize, srcError,
destFp, destOffset, destSize, destError)
vFILE *srcFp;
OFF_T srcOffset;
OFF_T srcSize;
CDFstatus srcError;
vFILE *destFp;
OFF_T destOffset;
OFF_T *destSize;
CDFstatus destError;
{
#if SUPPORT_RLE64
CDFstatus pStatus = CDF_OK; Int32 byteN = 0, count;
uByte byte, zero = 0, max255 = (uByte) 255, zCount;
/****************************************************************************
* Seek to starting offsets.
****************************************************************************/
if (!SEEKv64(srcFp,srcOffset,vSEEK_SET)) return srcError;
if (!SEEKv64(destFp,destOffset,vSEEK_SET)) return destError;
/****************************************************************************
* Initialize destination count and begin...
****************************************************************************/
*destSize = 0;
for (;;) {
/*************************************************************************
* Return if past the last source byte.
*************************************************************************/
if (byteN == srcSize) return pStatus;
/*************************************************************************
* Read the next source byte.
*************************************************************************/
if (!READv64(&byte,1,1,srcFp)) return srcError;
byteN++;
/*************************************************************************
* If the source byte is zero, set the counter and begin...
*************************************************************************/
if (byte == 0) {
count = 1;
for (;;) {
/********************************************************************
* If past the last source byte, write a zero/count to the
* destination file and return. In this case the final `count'
* bytes of the source file are zeroes.
********************************************************************/
if (byteN == srcSize) {
if (!WRITEv64(&zero,1,1,destFp)) return destError;
(*destSize)++;
zCount = (uByte) (count - 1);
if (!WRITEv64(&zCount,1,1,destFp)) return destError;
(*destSize)++;
return pStatus;
}
/********************************************************************
* Read the next source byte.
********************************************************************/
if (!READv64(&byte,1,1,srcFp)) return srcError;
byteN++;
/********************************************************************
* If the byte is not a zero, write a zero/count and the non-zero
* byte to the destination file and break out of this loop.
********************************************************************/
if (byte != 0) {
if (!WRITEv64(&zero,1,1,destFp)) return destError;
(*destSize)++;
zCount = (Byte) (count - 1);
if (!WRITEv64(&zCount,1,1,destFp)) return destError;
(*destSize)++;
if (!WRITEv64(&byte,1,1,destFp)) return destError;
(*destSize)++;
break;
}
/********************************************************************
* Increment for another zero and check if at the limit. If so,
* write a zero/count to the destination and break out of this loop.
********************************************************************/
count++;
if (count == 256) {
if (!WRITEv64(&zero,1,1,destFp)) return destError;
(*destSize)++;
if (!WRITEv64(&max255,1,1,destFp)) return destError;
(*destSize)++;
break;
}
}
}
else {
/***********************************************************************
* A non-zero source byte - write it to the destination file.
***********************************************************************/
if (!WRITEv64(&byte,1,1,destFp)) return destError;
(*destSize)++;
}
}
#else
return UNKNOWN_COMPRESSION;
#endif
}
/******************************************************************************
* DecompressRLE0_64.
******************************************************************************/
STATICforIDL CDFstatus DecompressRLE0_64 (srcFp, srcOffset, srcSize, srcError,
destFp, destOffset, destError)
vFILE *srcFp;
OFF_T srcOffset;
OFF_T srcSize;
CDFstatus srcError;
vFILE *destFp;
OFF_T destOffset;
CDFstatus destError;
{
#if SUPPORT_RLE64
CDFstatus pStatus = CDF_OK; Int32 byteN = 0, count, i;
uByte byte, zero = 0, zCount;
/****************************************************************************
* Seek to starting offsets.
****************************************************************************/
if (!SEEKv64(srcFp,srcOffset,vSEEK_SET)) return srcError;
if (!SEEKv64(destFp,destOffset,vSEEK_SET)) return destError;
/****************************************************************************
* Begin...
****************************************************************************/
for (;;) {
/*************************************************************************
* Return if past the last source byte
*************************************************************************/
if (byteN == srcSize) return pStatus;
/*************************************************************************
* Read a source byte. If it is a zero, read the following count byte
* and write the specified number of zeroes to the destination file.
* Otherwise, just write the non-zero byte. Note that the count byte is
* one less than the number of zeroes.
*************************************************************************/
if (!READv64(&byte,1,1,srcFp)) return srcError;
byteN++;
if (byte == 0) {
if (byteN == srcSize) return DECOMPRESSION_ERROR;
if (!READv64(&zCount,1,1,srcFp)) return srcError;
byteN++;
count = ((Int32) zCount) + 1;
for (i = 0; i < count; i++) {
if (!WRITEv64(&zero,1,1,destFp)) return destError;
}
}
else
if (!WRITEv64(&byte,1,1,destFp)) return destError;
}
#else
return UNKNOWN_COMPRESSION;
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1