www.pudn.com > viewImage.rar > TifIFD.cpp
// TifIFD.cpp: implementation of the CTifIFD class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Huffman.h"
#include "TifIFD.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define DECODE_BUF_EXTEND_LEN 90000 // Old value is 6000
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTifIFD::CTifIFD()
{
//Initial class members
m_pEntry = NULL;
m_image.lpImage = NULL;
m_outImage.lpImage = NULL;
m_outImage.lnCount = 0;
m_lOldVRes = 0;
m_lOldHRes = 0;
m_lnRow = 0;
}
CTifIFD::~CTifIFD()
{
FreeMem();
}
// ---------------------------------------------------------------------------
// Load one tiff page from file
//
BOOL CTifIFD::LoadIFD(HANDLE hFile, WORD wByteOrderFlag)
{
register WORD i;
WORD wEntryCount;
DWORD dwNumOfByteRead;
WORD wLastTag;
//Initial values
WORD wIfdError=0;
short nCompression=1;
long int lnPhotometricInterpretation=-1;
long int lnHres=0;
long int lnVres=0;
long int lnRes[2];
short int nOures=1;
//free memory first.
FreeMem();
//Get EntryCount form file;
if(ReadFile(hFile,&wEntryCount,sizeof(WORD),
&dwNumOfByteRead,NULL)==0)
return FALSE;
//alloc memory for entry
m_pEntry = new TIFFMARK[wEntryCount];
if(m_pEntry == 0)
return FALSE;
wLastTag=0; // init last tag
//Initialize some value , add by zsxl
m_image.wBitOrder = 1;
m_image.wOptions = 4; // what's the meaing of 4
//end initialize
//Read and process entries.
for(i=0;i>=24 ;
else if (m_pEntry[i].wType==IFD_SHORT)
m_pEntry[i].dwValue>>=16 ;
}
}
switch (m_pEntry[i].wTag)
{
case ImageWidth_tag: // ImageWidth must be 864, there is no default
m_image.wWidth=(unsigned short int)m_pEntry[i].dwValue;
break;
case ImageLength_tag: // ImageLength must be strip size, there is no default
m_image.wLength=(unsigned short int)m_pEntry[i].dwValue;
break;
case BitsPerSample_tag: // BitsPerSample must be 1, default is ok
if ((unsigned short int)m_pEntry[i].dwValue!=1)
wIfdError=1 ;
break;
case Compression_tag: // Compression must be 3 or 4 ,the default is no good
nCompression = (short int)m_pEntry[i].dwValue;
break;
case PhotometricInterpretation_tag: /* PhotometricInterpretation must be 0 */
/* there is no default */
lnPhotometricInterpretation=(unsigned short int)m_pEntry[i].dwValue;
break;
case FillOrder_tag: // FillOrder can be 1 or 2 , take what comes
m_image.wBitOrder=(unsigned short)m_pEntry[i].dwValue;
break;
case StripOffsets_tag: /* StripOffsets we need to know */
/* there is no default */
m_image.dwOffset=m_pEntry[i].dwValue;
break;
case SamplesPerPixel_tag: /* SamplesPerPixel must be 1 */
/* default is ok */
if((unsigned short int)m_pEntry[i].dwValue!=1)
wIfdError=1 ;
break ;
case RowsPerStrip_tag: /* RowsPerStrip must be single strip */
/* default is ok */
if (m_image.wLength>7) ;
device.source_width = m_lImgWidth; // fax width & length
device.source_height = m_lImgHeight;
device.total_lines = 1;
device.dest_width = m_lImgWidth; // fax width
device.dest_height = m_lImgHeight; // fax length
if (! ProcessLine(&device,INIT))
return NULL;
// init decoding first
if(! InitDecoding())
return NULL;
/* Preliminaries for each image in the file - fseek to the start of
the image. (If we can't we give it a zero length and ignore). If a
2-D or a T.6 image, set up pointers to the reference line and the
current line. If a T.6 image (which has no initial EOL) set up our
key variables to the right initial state. If a T.4 image just set
our resync flag, which forces us to ignore everything until the next
EOL code */
cpTwolines = new char[((m_lImgWidth+7)/8)*2]; // used for some condition
if(m_image.wOptions&3)
{
memset (cpTwolines,0x00,((m_lImgWidth+7)/8)*2);
cpRef_line= &cpTwolines[0] ;
device.cur_line= &cpTwolines[(m_lImgWidth+7)/8] ;
}
else
{
device.cur_line= NULL ;
}
// will not be used again
delete cpTwolines;
if(m_image.wOptions&2)
{
bCoding_scheme= 2 ;
lnResync= 0 ;
device.color= WHITE ;
lnDots_left= m_lImgWidth;/*FAXWIDTH*/ ;
tree= (NODE *)&gTwoTree ;
lnHorz_runs= lnCode= 0 ;
lnA0= (-1) ;
}
else
{
lnResync= 1 ;
}
/* This is the main loop for processing an image - we have a double
loop, with the outer executing for each byte (octet) in the image,
and the inner executing 8 times for each octet and processing each
bit in turn. The only exits before a completed image are on
physical end of file, on error if writing Output file, or on EOFB
in a T.6 file. */
lpSrcBuf=m_image.lpImage;
dwByteCount=m_image.dwByteCount;
for (;dwByteCount;dwByteCount--)
{
if ((device.id== U_TIFF)&&(device.hFile== NULL))
break;
bOctet=*lpSrcBuf++; // get the source data
if (m_image.wBitOrder==2)
bOctet=gBackward[bOctet];
for(i=0; i<8;i++,bOctet<<= 1) // decode each bit
{
/* We have three checks for every bit in the file. First we
check for EOL in T.6 mode - there is no EOL marker, but we
should have exactly the right number of dots decoded.
There should be none left in the line. If we pass the
test we Output the line and reset our key variables */
if((m_image.wOptions&2)&&(lnHorz_runs==0)&&(lnDots_left==0))
{
if(! ProcessLine(&device, OUREOL))
return NULL;
bCoding_scheme= 2 ;
lnResync= 0 ;
device.color= WHITE ;
lnDots_left= m_lImgWidth;//FAXWIDTH ;
tree= (NODE *)&gTwoTree ;
cpTmp_line= cpRef_line ;
cpRef_line= device.cur_line ;
device.cur_line= cpTmp_line ;
memset (device.cur_line,0x00,(m_lImgWidth+7)/*FAXWIDTH*//8) ;
lnHorz_runs= lnCode= 0 ;
lnA0= (-1) ;
}
/* Next check is for an EOL code. If we have one in T.6 it
marks the end of the image (EOFB). Otherwise, we ignore
any 0 fill bits in the EOL code and carry on till the 1
which marks its end. We then reset our resync flag (set at
the start and on a decoding error and reset our key
variables to the start of the line. If we are 2-D coding, we
set a dummy OUREOL2 code to force reading of the next tag
bit. If we are 1-D coding we start the next line pointing at
the root of the white run decoding tree */
if (lnCode== OUREOL)
{
if (m_image.wOptions&2)
break;
if ((bOctet&0x80)== 0)
continue;
lnResync= 0 ;
device.color= WHITE ;
lnDots_left= m_lImgWidth;//FAXWIDTH ;
if (m_image.wOptions&1)
lnCode= OUREOL2 ;
else
{
tree= (NODE *)&gWTree ;
lnCode= 0 ;
}
continue;
}
/* Next check is for the tag bit when 2-D coding. We set our
bCoding_scheme flag appropriately and then start the next line
pointing either to the root of the white decoding tree, or else
to the two-dimensional code word coding tree, as
appropriate */
if (lnCode== OUREOL2)
{
bCoding_scheme= ((bOctet&0x80) >> 7);
if (bCoding_scheme== 1)
{
tree= (NODE *)&gWTree;
}
else
{
tree= (NODE *)&gTwoTree ;
lnHorz_runs= 0 ;
lnA0= (-1) ;
}
cpTmp_line= cpRef_line ;
cpRef_line= device.cur_line ;
device.cur_line= cpTmp_line ;
memset (device.cur_line,0x00,(m_lImgWidth+7)/*FAXWIDTH*//8) ;
lnCode= 0 ;
continue ;
}
/* Now for the main decoding algorithm. The codes are
arranged as a binary tree. We take the left fork for
a 0 bit and the right fork for a one bit, and make that
our new code word. If the code word is either zero or a
minus number we have a run length, but all positive code
words represent pointers to the next branch in the tree.
There are two types of run lengths - those below 64 are
terminating codes, which mean we flip the colour and start
the next code with the root of the other decoding tree. For
make-up codes of 64 and above we start the next code with
the root of the same tree. If we happened to be doing
1-D coding because we were in a 2-D horizontal run
(horz-run is decremented to zero) we point the next code at
the two-dimensional tree */
if(lnCode > 91)
lnCode = 0;
else
lnCode= (*tree)[lnCode][(bOctet&0x80)>>7] ;
if (lnCode<1)
{
lnCode= (-lnCode) ;
if (!lnResync)
{
if ((lnDots_left-= lnCode)<0)
lnResync= 1 ;
}
if ((!lnResync)&&(lnCode!= 0))
if(! ProcessLine(&device, lnCode))
return NULL;
if (lnCode < 64)
{
device.color= (~device.color) ;
tree= device.color ? (NODE *)&gBTree : (NODE *)&gWTree;
if (m_image.wOptions&3)
{
if ((bCoding_scheme!= 1)&&(--lnHorz_runs== 0))
{
lnA0= 0 ;
tree= (NODE *)&gTwoTree ;
}
}
}
lnCode= 0 ;
continue ;
}
if (lnCode>(lnA0%8)) ;
if (cpRef_line[j]&bThis_bit)
bRef_color= BLACK ;
else
bRef_color= WHITE ;
}
for (lnB1= lnA0+1;lnB1>(lnB1%8)) ;
if ((cpRef_line[j]&bThis_bit)!= (bRef_color&bThis_bit))
break ;
}
if (bRef_color!= device.color)
{
for (lnB1++;lnB1>(lnB1%8)) ;
if ((cpRef_line[j]&bThis_bit)==(bRef_color&bThis_bit))
break ;
}
}
if (lnB1>m_lImgWidth)//FAXWIDTH)
lnB1= m_lImgWidth;//FAXWIDTH ;
lnA0= (m_lImgWidth/*FAXWIDTH*/-lnDots_left) ;
/* If the code is below PASSMODE then it is one of the
vertical code words, which are pretty easy to decipher as
we have all the data. Vertical mode flips the colour and
then continues. */
if (lnCode>(lnB2%8)) ;
if ((cpRef_line[j]&bThis_bit)== (device.color&bThis_bit))
break ;
}
if (lnB2>m_lImgWidth/*FAXWIDTH*/) lnB2= m_lImgWidth;//FAXWIDTH ;
if (lnCode== PASSMODE)
{
lnCode= (lnB2-lnA0) ;
if (!lnResync)
{
if ((lnDots_left-= lnCode)<0)
lnResync= 1 ;
}
if ((!lnResync)&&(lnCode!= 0))
if(! ProcessLine(&device, lnCode) )
return NULL;
lnCode= 0 ;
continue ;
}
/* Finally, if we weren't pass mode, we lnResync if T4, else
abandon if T6 */
if (m_image.wOptions&2)
return NULL;
lnResync= 1 ;
continue ;
}
}
if(! ProcessLine(&device, DEINIT) )
return NULL;
// no image ????????, should never be true!!
if(m_outImage.lpImage == NULL)
return NULL;
// --- make dib image
BITMAPINFOHEADER bih;
RGBQUAD rgb[2];
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = m_outImage.wWidth;
bih.biHeight = m_outImage.wLength;
bih.biPlanes = 1;
bih.biBitCount = 1;
bih.biCompression = BI_RGB; // uncompressed format
WORD wWidthBytes = WIDTHBYTES(bih.biWidth*bih.biBitCount);
bih.biSizeImage = wWidthBytes*bih.biHeight;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
rgb[0].rgbBlue=0x00;
rgb[0].rgbGreen=0x00;
rgb[0].rgbRed=0x00;
rgb[0].rgbReserved=0;
rgb[1].rgbBlue=0xff;
rgb[1].rgbGreen=0xff;
rgb[1].rgbRed=0xff;
rgb[1].rgbReserved=0;
// flip 0, 1 in image bits
DWORD dwPos = 0;
BYTE byDelta, byPixel = 0;
for (int row=0; row>= byDelta;
byPixel <<= byDelta;
*(m_outImage.lpImage+dwPos) = byPixel;
}
// vertically flip image buffer
if (! VertFlipBuf(m_outImage.lpImage, wWidthBytes, bih.biHeight))
return FALSE;
// Allocate enough memory for the new CF_DIB, and copy bits
DWORD dwBitsSize = bih.biSizeImage;
DWORD dwColorTableSize = (1<dest_width/8)*device->total_lines;
m_lpFaxline = new BYTE[m_lnFaxBytes];
if (m_lpFaxline==NULL)
return 0;
m_lnSliceBytes = device->total_lines/8;
memset(m_lpFaxline,0x00,m_lnFaxBytes) ;
m_lnIndex=0 ;
m_lnThisbit=8 ;
m_ln2DIndex=0 ;
m_ln2DBit=8 ;
m_lnLastSaveByte=0 ;
m_lnRow = 0;
HorizScale(device,(long int)m_lnIndex) ;
VerticalScale(device,(long int)-1) ;
device->color=WHITE ;
device->this_line=device->total_lines ;
return (1) ;
}
/**************************************************************************
We deinitialize here - we just free memory and get out
**************************************************************************/
if (iRunlength==DEINIT)
{
delete m_lpFaxline;
m_lpFaxline=NULL;
return (1) ;
}
/**************************************************************************
At the end of each page we make sure any partial lines get printed
(by calling Output). We reset our m_lnLastSaveByte marker, set our Output buffer
to white space and reset vertical scaling. We do the relevant
newpage function for our device and get out.
**************************************************************************/
if (iRunlength==OUREOP)
{
if (device->total_lines>1)
{
// while (device->this_line!=device->total_lines)
// Output(device,m_lpFaxline,m_lnRow,m_lnLastSaveByte) ;
}
//else if (m_lnLastSaveByte!=0)
// Output(device,m_lpFaxline,m_lnRow,m_lnLastSaveByte) ;
m_lnLastSaveByte=0 ;
memset(m_lpFaxline,0x00,m_lnFaxBytes) ;
m_lnRow = 0 ;
//VerticalScale(device,(long int)-1) ;
//newpage(device) ;
return 1;
}
/**************************************************************************
At the end of each scan line things start to get complicated.
We always call vscale and see how many lines we have to Output.
1) If we have no lines to Output we reset our indices (leaving our
data intact for ORIng in with later lines) and return with indices,
color and horizontal scaling reset.
2) If we have multiple lines to Output, we start a loop for each
Output line. The number of lines we Output at a time (as set in the
DEVPARMS member total_lines) could be 1 (for raster devices such as
screen and HP type lasers) or a multiple of 8 (for 24-pin dot-matrix
and bubblejet printers that go in slices - note that as 9-pin dot
matrix printer have a lower resolution than a fax they never have
more than one line to Output and therefore don't get handled just
yet). We have to handle these cases in different ways.
i) For multislice printers which Output multiple lines in different
bit positions we need to cater for two further cases.
One is where we really do Output, which is only if we reach the
last line of the slice (when DEVPARMS this_line decrements to 1) ;
In this case, we call the Output function and then set the Output
buffer to white space before looping.
The other multislice case is where the slice isn't complete so we
cannot call Output just yet. What we do is to duplicate the bit
of the slice we have reached into the next bit. This involves
first finding out the bit we have reached from m_lnSliceBytes and
this_line (which is stored in the m_lnLastSaveByte of bBit) and then ORing
that back in at the next bit position (which might be in the
following byte).
For all multislice cases we then go on to the next m_lnRow and the
next bit in the slice (increment m_lnRow and decrement DEVPARMS
this_line) before carrying on with the loop.
ii) For single-slice printers or screens we simply Output, increment
m_lnRow, and loop again. 9-pin dot matric printers also come to here.
We then have a special check to see if we really printed on a 8-slice
printer (9-pin dot matrix) and if we did, we reset m_lnLastSaveByte to 0 and reset
the Output buffer to white space.
Finally, we reset indices to zero, reset bits unused to 8,
reinitialize hor scaling, reinitialize colour to white, and go back.
**************************************************************************/
if (iRunlength==OUREOL)
{
m_ln2DIndex=0 ;
m_ln2DBit=8 ;
lnTemp = 1;//VerticalScale(device,(long int)m_lnRow) ;
if (lnTemp==0)
{
m_lnIndex=0 ;
m_lnThisbit=8 ;
HorizScale(device,(long int)m_lnIndex) ;
device->color=WHITE ;
return 1;
}
for (; lnTemp>0 ; lnTemp--)
{
if (device->total_lines>8)
{
if (device->this_line==1)
{
if(!Output(device,m_lpFaxline,m_lnRow,m_lnLastSaveByte))
return 0;
m_lnRow++ ;
for (m_lnIndex=0 ; m_lnIndexthis_line/8) ;
bBit=m_lpFaxline[m_lnIndex+m_lnThisbit] ;
m_lnThisbit=device->this_line%8 ;
if (m_lnThisbit==0)
m_lnThisbit=8 ;
m_lnThisbit = 1 << (m_lnThisbit-1) ;
bBit=(bBit&m_lnThisbit) ;
if (bBit!=0)
bBit=1 ;
m_lnThisbit=(device->this_line-1)%8 ;
if (m_lnThisbit==0)
m_lnThisbit=8 ;
if (m_lnThisbit>1)
bBit <<= (m_lnThisbit-1) ;
m_lnThisbit=m_lnSliceBytes-
((device->this_line-1)/8) ;
m_lpFaxline[m_lnIndex+m_lnThisbit]=
m_lpFaxline[m_lnIndex+m_lnThisbit]|bBit ;
}
}
m_lnRow++ ;
--device->this_line ;
}
}
else
{
if(!Output(device,m_lpFaxline,m_lnRow,m_lnLastSaveByte))
return 0;
m_lnRow++ ;
}
}
if ((device->this_line==device->total_lines)
&&(device->total_lines<=8))
{
m_lnLastSaveByte=0 ;
for (m_lnIndex=0;m_lnIndexcolor=WHITE ;
return 1;
}
/**************************************************************************
Our final case is going to be normal run length. We understabably
ignore a run length of 0 (though it's a valid terminating run
length).
If we are decoding a 2-D file (we see that the cur_line current line
buffer is in use) we must preserve a copy of the current scan line
being decoded for use as the reference line when decoding the next
scan line. We keep this copy in the buffer pointed at by cur_line.
We take a copy of the run length as it gets destroyed. Then for
white runs, we just skip the correct number of bits as cur_line
buffer is always initialized to white space. For black runs, we OR a
series of 1s into the cur_line buffer until the run is exhausted -
where we can we do this in octets, but where we cannot we OR single
bits. Then we carry on as normal with the original run-length.
The run length is scaled horizontally - we ignore cases where it is
scaled down to zero.
We treat multislice printers (which Output more than one scan line at
a time with different line occupying different bit positions)
differently to raster devices like screens and lasers.
Raster devices simply require setting the same number of consecutive
bits as the run length in the Output buffer. If the run is white,
presetting the buffer to white space enables us to simply skip. If
the run is black, we OR bit in till the run is used up. We also set
the m_lnLastSaveByte marker to the final black position if it is greater than the
last m_lnLastSaveByte value.
Multislice printer require setting the identical bit in the same
number of consecutive slices as the run length in the Output buffer.
Again, if the run is white, presetting the buffer to white space
enables us to skip, but we skip slices rather than bits. If the run
is black, we first set m_lnLastSaveByte and then OR a bit in the right position
(we calculate the relative bit and slice position from this_line
knowing that we have 8 lines to a byte) till the run is used up.
**************************************************************************/
if (!iRunlength)
return 1;
if (device->cur_line!=NULL)
{
lnCopyRun=iRunlength ;
if (device->color==WHITE)
{
m_ln2DBit-=(lnCopyRun%8) ;
m_ln2DIndex+=(lnCopyRun/8) ;
if (m_ln2DBit<0)
{
m_ln2DBit+=8 ;
m_ln2DIndex++ ;
}
}
else for (;;)
{
while (m_ln2DBit>0)
{
device->cur_line[m_ln2DIndex]|=(1<<(m_ln2DBit-1)) ;
m_ln2DBit-- ;
if (!(--lnCopyRun))
break;
}
if(lnCopyRun==0)
break ;
m_ln2DIndex++;
for (; lnCopyRun>8 ; lnCopyRun-=8)
device->cur_line[m_ln2DIndex++]=(char)0xff ;
if (lnCopyRun==0)
break;
m_ln2DBit=8;
}
}
iRunlength=HorizScale(device,(long int)iRunlength) ;
if (!iRunlength)
return 1;
if (device->total_lines>1)
{
if (device->color==WHITE)
{
m_lnIndex+=(m_lnSliceBytes*iRunlength) ;
if (m_lnIndex>m_lnFaxBytes)
m_lnIndex=m_lnFaxBytes ;
return 1;
}
bBit = 1 ;
m_lnThisbit=device->this_line%8 ;
if (m_lnThisbit==0)
m_lnThisbit=8 ;
if (m_lnThisbit>1)
bBit <<= (m_lnThisbit-1) ;
m_lnThisbit=m_lnSliceBytes-(device->this_line/8) ;
for (;;)
{
if (m_lnLastSaveByte<=m_lnIndex)
m_lnLastSaveByte=(m_lnIndex+1) ;
m_lpFaxline[m_lnIndex+m_lnThisbit]|=bBit ;
if (m_lnIndexcolor==WHITE)
{
m_lnThisbit-=(iRunlength%8) ;
m_lnIndex+=(iRunlength/8) ;
if (m_lnThisbit<0)
{
m_lnThisbit+=8 ;
m_lnIndex++ ;
}
return 1;
}
for (;;)
{
if (m_lnLastSaveByte<=m_lnIndex)
m_lnLastSaveByte=(m_lnIndex+1) ;
while (m_lnThisbit>0)
{
m_lpFaxline[m_lnIndex]|=(1<<(m_lnThisbit-1)) ;
m_lnThisbit-- ;
if (!(--iRunlength))
return 1;
}
if (iRunlength==0)
return 1;
m_lnIndex++ ;
for (; iRunlength>8 ; iRunlength-=8)
m_lpFaxline[m_lnIndex++]=0xff ;
if (iRunlength==0)
return 1;
m_lnThisbit=8 ;
}
}
/**************************************************************************/
// ----------------------------------------------------------------------------
// init the decoding buffer
//
BOOL CTifIFD::InitDecoding()
{
// ALLOCATE OUTPUT MEMORY
FreeOutImageMem();
m_outImage.wWidth = (WORD)m_lImgWidth;
m_outImage.wLength = (WORD)m_lImgHeight;
long lnBufLen = ((m_outImage.wWidth+31)/32*32)/8*
((long)(m_outImage.wLength+400))+ DECODE_BUF_EXTEND_LEN;
m_outImage.lnBufLen = lnBufLen*4;
m_outImage.lpImage = (LPBYTE) new BYTE[m_outImage.lnBufLen]; // why add 6000???
if(m_outImage.lpImage == 0)
return FALSE;
memset(m_outImage.lpImage,0,m_outImage.lnBufLen);
return TRUE;
}
int CTifIFD::HorizScale(DEVPARMS * device, long int run)
{
static long int remainder ;
static char borrow ;
if (!run)
{
remainder=0 ;
borrow=0 ;
return(0) ;
}
run=(run*(long int)device->dest_width);
run=run+remainder ;
remainder=run%device->source_width ;
run=run/device->source_width ;
if ((!run)&&(!borrow))
{
run++ ;
borrow++ ;
}
if ((run>1)&&(borrow!=0))
{
run-- ;
borrow-- ;
}
return (int)(run) ;
}
int CTifIFD::VerticalScale(DEVPARMS * device, long int count)
{
static long int remainder ;
if (count<0)
{
remainder=0 ;
return(0) ;
}
count=remainder+device->dest_height ;
remainder=count%(device->source_height*device->res) ;
count=count/(device->source_height*device->res) ;
return (int)(count) ;
}
BOOL CTifIFD::Output(DEVPARMS * device, unsigned char * our_line, int our_row, int lsb)
{
DWORD newWidth = (m_lImgWidth+31)/32*32/8;
switch (device->id)
{
case DEVICE_MEMORY:
{
int nLen = ((m_outImage.wWidth+31)/32*32)/8*((long)(m_outImage.wLength+400))
+ 4000 -m_lImgWidth/8; // why add 4000
if(m_outImage.lnCount >= m_outImage.lnBufLen)
{
#if 0
return FALSE;
#endif
}
if(our_line == NULL)
{
return FALSE;
}
ASSERT((WORD)(m_outImage.lnCount + newWidth) < m_outImage.lnBufLen);
memcpy(m_outImage.lpImage+m_outImage.lnCount,
our_line,newWidth);
m_outImage.lnCount += newWidth;
break;
}
/* for uncompressed TIFF files, we simply fwrite the exact number
of bytes to the output file and increment the count of lines in
the image */
#if 0
case U_TIFF :
if ((fwrite (our_line,1,((m_lImgWidth+7)/*FAXWIDTH*//8),device->tiffile))==0)
{
fclose (device->tiffile);
device->tiffile=NULL;
}
device->ifd->ImageLength.value++;
break;
#endif
default:
break;
}
return TRUE;
}
BOOL CTifIFD::VertFlipBuf(BYTE* inbuf, UINT widthBytes, UINT height)
{
BYTE *tb1;
BYTE *tb2;
if (inbuf==NULL)
return FALSE;
UINT bufsize;
bufsize=widthBytes;
tb1= (BYTE *)new BYTE[bufsize];
if (tb1==NULL) {
return FALSE;
}
tb2= (BYTE *)new BYTE [bufsize];
if (tb1==NULL) {
return FALSE;
}
UINT row_cnt;
ULONG off1=0;
ULONG off2=0;
for (row_cnt=0;row_cnt<(height+1)/2;row_cnt++) {
off1=row_cnt*bufsize;
off2=((height-1)-row_cnt)*bufsize;
memcpy(tb1,inbuf+off1,bufsize);
memcpy(tb2,inbuf+off2,bufsize);
memcpy(inbuf+off1,tb2,bufsize);
memcpy(inbuf+off2,tb1,bufsize);
}
delete [] tb1;
delete [] tb2;
return TRUE;
}
void reverse (void *pointer,int lnCountdown)
{
int lnCountup=0 ;
BYTE bStore;
LPBYTE lpAddress = (LPBYTE)pointer ;
if (pointer==NULL) return;
if (lnCountdown%2) return;
while (lnCountup