You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.9 KiB
129 lines
3.9 KiB
/*++
|
|
|
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
|
|
#define TIFF_MIN_RUN 4 /* Minimum repeats before use RLE */
|
|
#define TIFF_MAX_RUN 128 /* Maximum repeats */
|
|
#define TIFF_MAX_LITERAL 128 /* Maximum consecutive literal data */
|
|
|
|
int
|
|
iCompTIFF( pbOBuf, cbO, pbIBuf, cb )
|
|
BYTE *pbOBuf; /* Output buffer, PRESUMED BIG ENOUGH: see above */
|
|
int cbO; /* Output buffer size */
|
|
BYTE *pbIBuf; /* Raster data to send */
|
|
int cb; /* Number of bytes in the above */
|
|
{
|
|
BYTE *pbOut; /* Output byte location */
|
|
BYTE *pbStart; /* Start of current input stream */
|
|
BYTE *pb; /* Miscellaneous usage */
|
|
BYTE *pbEnd; /* The last byte of input */
|
|
BYTE jLast; /* Last byte, for match purposes */
|
|
BYTE *pbOEnd; /* The last byte of Output buffer */
|
|
|
|
int cSize; /* Bytes in the current length */
|
|
int cSend; /* Number to send in this command */
|
|
|
|
|
|
pbOut = pbOBuf;
|
|
pbStart = pbIBuf;
|
|
|
|
pbEnd = pbIBuf + cb; /* The last byte */
|
|
pbOEnd = pbOBuf + cbO; /* The last byte of Output buffer */
|
|
|
|
jLast = *pbIBuf++;
|
|
|
|
while( pbIBuf < pbEnd )
|
|
{
|
|
if( jLast == *pbIBuf )
|
|
{
|
|
/* Find out how long this run is. Then decide on using it */
|
|
|
|
for( pb = pbIBuf; pb < pbEnd && *pb == jLast; ++pb )
|
|
;
|
|
|
|
/*
|
|
* Note that pbIBuf points at the SECOND byte of the pattern!
|
|
* AND also that pb points at the first byte AFTER the run.
|
|
*/
|
|
|
|
if( (pb - pbIBuf) >= (TIFF_MIN_RUN - 1) )
|
|
{
|
|
/*
|
|
* Worth recording as a run, so first set the literal
|
|
* data which may have already been scanned before recording
|
|
* this run.
|
|
*/
|
|
|
|
if( (cSize = (int)(pbIBuf - pbStart - 1)) > 0 )
|
|
{
|
|
/* There is literal data, so record it now */
|
|
while( (cSend = min( cSize, TIFF_MAX_LITERAL )) > 0 )
|
|
{
|
|
// Buffer over run check
|
|
if ( (pbOut+cSend)<=pbOEnd ) {
|
|
*pbOut++ = cSend - 1;
|
|
CopyMemory( pbOut, pbStart, cSend );
|
|
pbOut += cSend;
|
|
pbStart += cSend;
|
|
cSize -= cSend;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Now for the repeat pattern. Same logic, but only
|
|
* one byte is needed per entry.
|
|
*/
|
|
|
|
cSize = (int)(pb - pbIBuf + 1);
|
|
|
|
while( (cSend = min( cSize, TIFF_MAX_RUN )) > 0 )
|
|
{
|
|
// Buffer over run check
|
|
if ( (pbOut+2)<=pbOEnd ) {
|
|
*pbOut++ = 1 - cSend; /* -ve indicates repeat */
|
|
*pbOut++ = jLast;
|
|
cSize -= cSend;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
pbStart = pb; /* Ready for the next one! */
|
|
}
|
|
pbIBuf = pb; /* Start from this position! */
|
|
}
|
|
else
|
|
jLast = *pbIBuf++; /* Onto the next byte */
|
|
|
|
}
|
|
|
|
if( pbStart < pbIBuf )
|
|
{
|
|
/* Left some dangling. This can only be literal data. */
|
|
|
|
cSize = (int)(pbIBuf - pbStart);
|
|
|
|
while( (cSend = min( cSize, TIFF_MAX_LITERAL )) > 0 )
|
|
{
|
|
// Buffer over run check
|
|
if ( (pbOut+cSend)<=pbOEnd ) {
|
|
*pbOut++ = cSend - 1;
|
|
CopyMemory( pbOut, pbStart, cSend );
|
|
pbOut += cSend;
|
|
pbStart += cSend;
|
|
cSize -= cSend;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (int)(pbOut - pbOBuf);
|
|
}
|