mirror of https://github.com/tongzx/nt5src
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.
963 lines
23 KiB
963 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
decode.c
|
|
|
|
Abstract:
|
|
|
|
This file contains functions for decoding (de-compressing)
|
|
compressed 1 bit per pel data from a TIFF data
|
|
stream. The supported compression algorithms are
|
|
as follows:
|
|
|
|
o Uncompressed (raw)
|
|
o One dimensional - MH or Modified Huffman
|
|
o Two dimensional - MR or Modified Read
|
|
|
|
Environment:
|
|
|
|
WIN32 User Mode
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 17-Feb-1996
|
|
|
|
--*/
|
|
|
|
#include "tifflibp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
BOOL
|
|
DecodeUnCompressedFaxData(
|
|
PTIFF_INSTANCE_DATA TiffInstance,
|
|
LPBYTE OutputBuffer,
|
|
BOOL SingleLineBuffer,
|
|
DWORD PadLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Decode a single page of uncompressed TIFF data.
|
|
|
|
Arguments:
|
|
|
|
TiffInstance - Pointer to the TIFF instance data
|
|
OutputBuffer - Output buffer where the uncompressed data
|
|
is written. This buffer must be allocated
|
|
by the caller and must be large enough for
|
|
a single page of data.
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
__try {
|
|
|
|
FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
TiffInstance->Lines = TiffInstance->StripDataSize / (TiffInstance->ImageWidth / 8);
|
|
CopyMemory( OutputBuffer, TiffInstance->StripData, TiffInstance->StripDataSize );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DecodeMHFaxData(
|
|
PTIFF_INSTANCE_DATA TiffInstance,
|
|
LPBYTE OutputBuffer,
|
|
BOOL SingleLineBuffer,
|
|
DWORD PadLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Decode a single page of 1 dimensionaly compressed
|
|
TIFF data.
|
|
|
|
Arguments:
|
|
|
|
TiffInstance - Pointer to the TIFF instance data
|
|
OutputBuffer - Output buffer where the uncompressed data
|
|
is written. This buffer must be allocated
|
|
by the caller and must be large enough for
|
|
a single page of data.
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
DWORD j;
|
|
BYTE octet;
|
|
PDECODE_TREE Tree;
|
|
INT code;
|
|
PBYTE plinebuf;
|
|
DWORD lineWidth;
|
|
DWORD Lines;
|
|
DWORD EolCount;
|
|
DWORD BadFaxLines;
|
|
BOOL LastLineBad;
|
|
|
|
|
|
//
|
|
// initialization
|
|
//
|
|
|
|
if (!SingleLineBuffer) {
|
|
|
|
__try {
|
|
|
|
FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Tree = WhiteDecodeTree;
|
|
code = 0;
|
|
Lines = 0;
|
|
EolCount = 1;
|
|
BadFaxLines = 0;
|
|
LastLineBad = FALSE;
|
|
TiffInstance->Color = 0;
|
|
TiffInstance->RunLength = 0;
|
|
TiffInstance->bitdata = 0;
|
|
TiffInstance->bitcnt = DWORDBITS;
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
TiffInstance->StartGood = 0;
|
|
TiffInstance->EndGood = 0;
|
|
plinebuf = TiffInstance->StripData;
|
|
lineWidth = TiffInstance->ImageWidth;
|
|
|
|
|
|
for (i=0; i<TiffInstance->StripDataSize; i++) {
|
|
if (plinebuf[i] == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// loop thru each byte in the file
|
|
//
|
|
|
|
for (; i<TiffInstance->StripDataSize; i++) {
|
|
|
|
octet = plinebuf[i];
|
|
|
|
if (i == 2147) DebugBreak();
|
|
|
|
//
|
|
// loop thru each bit in the byte
|
|
//
|
|
|
|
for (j=0; j<8; j++,octet<<=1) {
|
|
|
|
if (code == DECODEEOL) {
|
|
|
|
if (!(octet&0x80)) {
|
|
//
|
|
// here we skip all bits until we hit a 1 bit
|
|
// this happens when the first octet in a line
|
|
// is all zeroes and we detect that we are
|
|
// searching for an EOL
|
|
//
|
|
continue;
|
|
}
|
|
|
|
if (TiffInstance->RunLength && TiffInstance->RunLength != lineWidth) {
|
|
|
|
if (TiffInstance->RunLength < lineWidth) {
|
|
TiffInstance->Color = 0;
|
|
OutputCodeBits( TiffInstance, lineWidth - TiffInstance->RunLength );
|
|
}
|
|
|
|
if (LastLineBad) {
|
|
|
|
BadFaxLines += 1;
|
|
|
|
} else {
|
|
|
|
if (BadFaxLines > TiffInstance->BadFaxLines) {
|
|
TiffInstance->BadFaxLines = BadFaxLines;
|
|
}
|
|
BadFaxLines = 1;
|
|
LastLineBad = TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
LastLineBad = FALSE;
|
|
|
|
}
|
|
|
|
if (!TiffInstance->StartGood) {
|
|
TiffInstance->StartGood = i - 1;
|
|
}
|
|
|
|
//
|
|
// we hit the eol marker
|
|
//
|
|
Tree = WhiteDecodeTree;
|
|
TiffInstance->Color = 0;
|
|
code = 0;
|
|
|
|
if (SingleLineBuffer) {
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
}
|
|
|
|
if (TiffInstance->RunLength) {
|
|
|
|
FlushLine(TiffInstance,PadLength);
|
|
TiffInstance->RunLength = 0;
|
|
Lines += 1;
|
|
EolCount = 1;
|
|
|
|
} else {
|
|
|
|
//
|
|
// the eol count is maintained to that
|
|
// an rtc sequence is detected.
|
|
//
|
|
|
|
EolCount += 1;
|
|
|
|
if (EolCount == 6) {
|
|
|
|
//
|
|
// this is an rtc sequence, so any
|
|
// data that follows in the file
|
|
// is garbage.
|
|
//
|
|
|
|
goto good_exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
|
|
|
|
if (code == BADRUN) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (code < 1) {
|
|
|
|
code = (-code);
|
|
|
|
OutputCodeBits( TiffInstance, code );
|
|
|
|
if (code < 64) {
|
|
//
|
|
// terminating code
|
|
//
|
|
TiffInstance->Color = !TiffInstance->Color;
|
|
Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
|
|
}
|
|
code = 0;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
good_exit:
|
|
|
|
TiffInstance->EndGood = i;
|
|
if (BadFaxLines > TiffInstance->BadFaxLines) {
|
|
TiffInstance->BadFaxLines = BadFaxLines;
|
|
}
|
|
|
|
FlushBits( TiffInstance );
|
|
TiffInstance->Lines = Lines;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DecodeMRFaxData(
|
|
PTIFF_INSTANCE_DATA TiffInstance,
|
|
LPBYTE OutputBuffer,
|
|
BOOL SingleLineBuffer,
|
|
DWORD PadLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Decode a single page of 2 dimensionaly compressed
|
|
TIFF data.
|
|
|
|
Arguments:
|
|
|
|
TiffInstance - Pointer to the TIFF instance data
|
|
OutputBuffer - Output buffer where the uncompressed data
|
|
is written. This buffer must be allocated
|
|
by the caller and must be large enough for
|
|
a single page of data.
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
DWORD j;
|
|
BYTE octet;
|
|
PDECODE_TREE Tree;
|
|
INT code;
|
|
LPBYTE prefline;
|
|
LPBYTE pcurrline;
|
|
DWORD HorzRuns;
|
|
BOOL OneDimensional;
|
|
DWORD a0;
|
|
DWORD a1;
|
|
DWORD b1;
|
|
DWORD b2;
|
|
PBYTE plinebuf;
|
|
DWORD lineWidth;
|
|
DWORD Lines;
|
|
DWORD EolCount;
|
|
DWORD BadFaxLines;
|
|
BOOL LastLineBad;
|
|
|
|
|
|
//
|
|
// initialization
|
|
//
|
|
|
|
if (!SingleLineBuffer) {
|
|
|
|
__try {
|
|
|
|
FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Tree = WhiteDecodeTree;
|
|
code = 0;
|
|
HorzRuns = 0;
|
|
EolCount = 1;
|
|
BadFaxLines = 0;
|
|
LastLineBad = FALSE;
|
|
TiffInstance->Color = 0;
|
|
TiffInstance->RunLength = 0;
|
|
TiffInstance->bitdata = 0;
|
|
TiffInstance->bitcnt = DWORDBITS;
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
OneDimensional = TRUE;
|
|
plinebuf = TiffInstance->StripData;
|
|
lineWidth = TiffInstance->ImageWidth;
|
|
pcurrline = OutputBuffer;
|
|
prefline = OutputBuffer;
|
|
a0 = 0;
|
|
a1 = 0;
|
|
b1 = 0;
|
|
b2 = 0;
|
|
Lines = 0;
|
|
|
|
|
|
//
|
|
// loop thru each byte in the file
|
|
//
|
|
|
|
for (j=0; j<TiffInstance->StripDataSize; j++) {
|
|
|
|
|
|
octet = *plinebuf++;
|
|
|
|
//
|
|
// loop thru each bit in the byte
|
|
//
|
|
|
|
for (i=0; i<8; i++,octet<<=1) {
|
|
|
|
if (code == DECODEEOL2) {
|
|
|
|
//
|
|
// we hit the final eol marker
|
|
//
|
|
|
|
if (TiffInstance->RunLength && TiffInstance->RunLength != lineWidth) {
|
|
|
|
if (TiffInstance->RunLength < lineWidth) {
|
|
TiffInstance->Color = 0;
|
|
OutputCodeBits( TiffInstance, lineWidth - TiffInstance->RunLength );
|
|
}
|
|
|
|
if (LastLineBad) {
|
|
|
|
BadFaxLines += 1;
|
|
|
|
} else {
|
|
|
|
if (BadFaxLines > TiffInstance->BadFaxLines) {
|
|
TiffInstance->BadFaxLines = BadFaxLines;
|
|
}
|
|
BadFaxLines = 1;
|
|
LastLineBad = TRUE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
LastLineBad = FALSE;
|
|
|
|
}
|
|
|
|
if (!TiffInstance->StartGood) {
|
|
TiffInstance->StartGood = i - 1;
|
|
}
|
|
|
|
//
|
|
// set the decoding tree
|
|
//
|
|
|
|
OneDimensional = (octet & 0x80) == 0x80;
|
|
Tree = OneDimensional ? WhiteDecodeTree : TwoDecodeTree;
|
|
|
|
//
|
|
// reset the control variables
|
|
//
|
|
|
|
TiffInstance->Color = 0;
|
|
code = 0;
|
|
a0 = 0;
|
|
a1 = 0;
|
|
b1 = 0;
|
|
b2 = 0;
|
|
|
|
//
|
|
// if there is a non-zero runlength then
|
|
// spaw the reference & current line pointers
|
|
// and count this line. the runlength can be
|
|
// zero when there is just an empty eol in
|
|
// the stream.
|
|
//
|
|
|
|
if (SingleLineBuffer) {
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
}
|
|
|
|
if (TiffInstance->RunLength) {
|
|
TiffInstance->RunLength = 0;
|
|
Lines += 1;
|
|
prefline = pcurrline;
|
|
pcurrline = TiffInstance->bitbuf;
|
|
|
|
} else {
|
|
|
|
//
|
|
// the eol count is maintained to that
|
|
// an rtc sequence is detected.
|
|
//
|
|
|
|
EolCount += 1;
|
|
|
|
if (EolCount == 6) {
|
|
|
|
//
|
|
// this is an rtc sequence, so any
|
|
// data that follows in the file
|
|
// is garbage.
|
|
//
|
|
|
|
goto good_exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (code == DECODEEOL) {
|
|
|
|
if (!(octet&0x80)) {
|
|
//
|
|
// here we skip all bits until we hit a 1 bit
|
|
// this happens when the first octet in a line
|
|
// is all zeroes and we detect that we are
|
|
// searching for an EOL
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// this forces the code to pickup the next
|
|
// bit in the stream, which tells whether
|
|
// the next line is encoded in MH or MR compression
|
|
//
|
|
code = DECODEEOL2;
|
|
continue;
|
|
|
|
}
|
|
|
|
if (code == BADRUN) {
|
|
|
|
code = 0;
|
|
continue;
|
|
|
|
}
|
|
|
|
code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
|
|
|
|
b1 = NextChangingElement( prefline, a0, lineWidth, !TiffInstance->Color );
|
|
b1 = NextChangingElement( prefline, b1, lineWidth, TiffInstance->Color );
|
|
|
|
b2 = NextChangingElement( prefline, b1, lineWidth, GetBit(prefline, b1 ) );
|
|
|
|
if (OneDimensional) {
|
|
|
|
if (code < 1) {
|
|
|
|
code = (-code);
|
|
|
|
OutputCodeBits( TiffInstance, code );
|
|
|
|
//
|
|
// the affect of this is to accumulate the runlengths
|
|
// into a0, causing a0 to be placed on a2 when horizontal
|
|
// mode is completed/
|
|
//
|
|
|
|
a0 += code;
|
|
|
|
if (code < 64) {
|
|
|
|
//
|
|
// terminating code
|
|
//
|
|
TiffInstance->Color = !TiffInstance->Color;
|
|
Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
|
|
|
|
if (HorzRuns) {
|
|
|
|
HorzRuns -= 1;
|
|
|
|
if (!HorzRuns) {
|
|
|
|
Tree = TwoDecodeTree;
|
|
OneDimensional = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
code = 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (code == HORZMODE) {
|
|
|
|
//
|
|
// horizontal mode occurs when b1-a1 greater than 3
|
|
//
|
|
|
|
code= 0;
|
|
HorzRuns = 2;
|
|
OneDimensional = TRUE;
|
|
Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
|
|
|
|
} else if (code == PASSMODE) {
|
|
|
|
//
|
|
// pass mode occurs when the position of b2 lies
|
|
// to the left of a1, but a1 cannot be equal to b2.
|
|
//
|
|
|
|
code = b2 - a0;
|
|
OutputCodeBits( TiffInstance, code );
|
|
code = 0;
|
|
a0 = b2;
|
|
|
|
} else if (code >= VTMODE3N && code <= VTMODE3P) {
|
|
|
|
//
|
|
// vertical mode occurs when b1-a1 <= 3
|
|
//
|
|
|
|
a1 = b1 - (VTMODE0 - code);
|
|
code = a1 - a0;
|
|
|
|
OutputCodeBits( TiffInstance, code );
|
|
|
|
code = 0;
|
|
a0 = a1;
|
|
|
|
TiffInstance->Color = !TiffInstance->Color;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
good_exit:
|
|
|
|
TiffInstance->EndGood = i;
|
|
if (BadFaxLines > TiffInstance->BadFaxLines) {
|
|
TiffInstance->BadFaxLines = BadFaxLines;
|
|
}
|
|
|
|
FlushBits( TiffInstance );
|
|
TiffInstance->Lines = Lines;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DecodeMMRFaxData(
|
|
PTIFF_INSTANCE_DATA TiffInstance,
|
|
LPBYTE OutputBuffer,
|
|
BOOL SingleLineBuffer,
|
|
DWORD PadLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Decode a single page of 2 dimensionaly compressed
|
|
TIFF data.
|
|
|
|
Arguments:
|
|
|
|
TiffInstance - Pointer to the TIFF instance data
|
|
OutputBuffer - Output buffer where the uncompressed data
|
|
is written. This buffer must be allocated
|
|
by the caller and must be large enough for
|
|
a single page of data.
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
DWORD j;
|
|
BYTE octet;
|
|
PDECODE_TREE Tree;
|
|
INT code;
|
|
LPBYTE prefline;
|
|
LPBYTE pcurrline;
|
|
DWORD HorzRuns;
|
|
BOOL OneDimensional;
|
|
DWORD a0;
|
|
DWORD a1;
|
|
DWORD b1;
|
|
DWORD b2;
|
|
PBYTE plinebuf;
|
|
DWORD lineWidth;
|
|
DWORD Lines;
|
|
DWORD EolCount;
|
|
|
|
|
|
//
|
|
// initialization
|
|
//
|
|
|
|
if (!SingleLineBuffer) {
|
|
|
|
__try {
|
|
|
|
FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Tree = TwoDecodeTree;
|
|
code = 0;
|
|
HorzRuns = 0;
|
|
EolCount = 0;
|
|
TiffInstance->Color = 0;
|
|
TiffInstance->RunLength = 0;
|
|
TiffInstance->bitdata = 0;
|
|
TiffInstance->bitcnt = DWORDBITS;
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
OneDimensional = FALSE;
|
|
plinebuf = TiffInstance->StripData;
|
|
lineWidth = TiffInstance->ImageWidth;
|
|
pcurrline = OutputBuffer;
|
|
prefline = OutputBuffer;
|
|
a0 = 0;
|
|
a1 = 0;
|
|
b1 = 0;
|
|
b2 = 0;
|
|
Lines = 0;
|
|
|
|
|
|
//
|
|
// loop thru each byte in the file
|
|
//
|
|
|
|
for (j=0; j<TiffInstance->StripDataSize; j++) {
|
|
|
|
|
|
octet = *plinebuf++;
|
|
|
|
//
|
|
// loop thru each bit in the byte
|
|
//
|
|
|
|
for (i=0; i<8; i++,octet<<=1) {
|
|
|
|
if (Lines + 1 == TiffInstance->ImageHeight && TiffInstance->RunLength == lineWidth)
|
|
{
|
|
goto good_exit;
|
|
}
|
|
|
|
//
|
|
// if the OneDimensional flag is set and the RunLength == lineWidth
|
|
// then it means that the last run length was horizontal mode
|
|
// and it was not a terminating code. in this case we must go
|
|
// process the remaining termination code before ending the line.
|
|
//
|
|
// if the OneDimensional flag is NOT set and the RunLength == lineWidth
|
|
// then we are at the end of a line. for mmr compression there are
|
|
// no eols, so this is the pseudo eol.
|
|
//
|
|
|
|
if ((TiffInstance->RunLength == lineWidth) && (!OneDimensional)) {
|
|
//
|
|
// set the decoding tree
|
|
//
|
|
|
|
Tree = TwoDecodeTree;
|
|
|
|
//
|
|
// reset the control variables
|
|
//
|
|
|
|
TiffInstance->Color = 0;
|
|
code = 0;
|
|
a0 = 0;
|
|
a1 = 0;
|
|
b1 = 0;
|
|
b2 = 0;
|
|
Tree = TwoDecodeTree;
|
|
OneDimensional = FALSE;
|
|
|
|
//
|
|
// if there is a non-zero runlength then
|
|
// spaw the reference & current line pointers
|
|
// and count this line. the runlength can be
|
|
// zero when there is just an empty eol in
|
|
// the stream.
|
|
//
|
|
|
|
if (SingleLineBuffer) {
|
|
TiffInstance->bitbuf = OutputBuffer;
|
|
}
|
|
|
|
TiffInstance->RunLength = 0;
|
|
Lines += 1;
|
|
prefline = pcurrline;
|
|
pcurrline = TiffInstance->bitbuf;
|
|
b1 = GetBit(prefline, 0) ? 0 : NextChangingElement(prefline, 0, lineWidth, 0);
|
|
} else if (code == DECODEEOL2) {
|
|
|
|
//
|
|
// the eol count is maintained to that
|
|
// an rtc sequence is detected.
|
|
//
|
|
|
|
EolCount += 1;
|
|
|
|
if (EolCount == 2) {
|
|
|
|
//
|
|
// this is an rtc sequence, so any
|
|
// data that follows in the file
|
|
// is garbage.
|
|
//
|
|
|
|
goto good_exit;
|
|
|
|
}
|
|
|
|
continue;
|
|
} else if (code == DECODEEOL) {
|
|
|
|
if (!(octet&0x80)) {
|
|
//
|
|
// here we skip all bits until we hit a 1 bit
|
|
// this happens when the first octet in a line
|
|
// is all zeroes and we detect that we are
|
|
// searching for an EOL
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// this forces the code to pickup the next
|
|
// bit in the stream, which tells whether
|
|
// the next line is encoded in MH or MR compression
|
|
//
|
|
code = DECODEEOL2;
|
|
continue;
|
|
|
|
} else if (code == BADRUN) {
|
|
|
|
code = 0;
|
|
continue;
|
|
|
|
} else {
|
|
b1 = NextChangingElement( prefline, a0, lineWidth, !TiffInstance->Color );
|
|
b1 = NextChangingElement( prefline, b1, lineWidth, TiffInstance->Color );
|
|
}
|
|
|
|
b2 = NextChangingElement( prefline, b1, lineWidth, GetBit(prefline, b1 ) );
|
|
|
|
code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
|
|
|
|
if (OneDimensional) {
|
|
|
|
if (code < 1) {
|
|
|
|
code = (-code);
|
|
|
|
OutputCodeBits( TiffInstance, code );
|
|
|
|
//
|
|
// the affect of this is to accumulate the runlengths
|
|
// into a0, causing a0 to be placed on a2 when horizontal
|
|
// mode is completed/
|
|
//
|
|
|
|
a0 += code;
|
|
|
|
if (code < 64) {
|
|
|
|
//
|
|
// terminating code
|
|
//
|
|
TiffInstance->Color = !TiffInstance->Color;
|
|
Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
|
|
|
|
if (HorzRuns) {
|
|
|
|
HorzRuns -= 1;
|
|
|
|
if (!HorzRuns) {
|
|
|
|
Tree = TwoDecodeTree;
|
|
OneDimensional = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
code = 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (code == HORZMODE) {
|
|
|
|
//
|
|
// horizontal mode occurs when b1-a1 greater than 3
|
|
//
|
|
|
|
code= 0;
|
|
HorzRuns = 2;
|
|
OneDimensional = TRUE;
|
|
Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
|
|
|
|
} else if (code == PASSMODE) {
|
|
|
|
//
|
|
// pass mode occurs when the position of b2 lies
|
|
// to the left of a1, but a1 cannot be equal to b2.
|
|
//
|
|
|
|
code = b2 - a0;
|
|
OutputCodeBits( TiffInstance, code );
|
|
code = 0;
|
|
a0 = b2;
|
|
|
|
} else if (code >= VTMODE3N && code <= VTMODE3P) {
|
|
|
|
//
|
|
// vertical mode occurs when b1-a1 <= 3
|
|
//
|
|
|
|
a1 = b1 - (VTMODE0 - code);
|
|
code = a1 - a0;
|
|
|
|
OutputCodeBits( TiffInstance, code );
|
|
|
|
code = 0;
|
|
a0 = a1;
|
|
|
|
TiffInstance->Color = !TiffInstance->Color;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
good_exit:
|
|
FlushBits( TiffInstance );
|
|
TiffInstance->Lines = Lines;
|
|
|
|
return TRUE;
|
|
}
|