?? tififd.cpp
字號(hào):
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<BADRUN)
continue ;
/* Codes of 3000 and above are NEVER valid run-lengths. We use
these codes internally for special actions. See DECODE.H for
actual values. BADRUN means we've fallen out of the tree and
have to lnResync. OUREOL means we've hit an EOL code and so we
can Output our line. HORZMODE is the 2-D horizontal mode, which
forces us to drop into 1-D mode for two run-lengths. */
if (lnCode== BADRUN)
{
lnResync= 1 ;
continue ;
}
if (lnCode== OUREOL)
{
if(! ProcessLine(&device,OUREOL)) // Output our line
return NULL;
continue ;
}
if (lnCode== HORZMODE)
{
lnHorz_runs= 2;
lnCode= 0;
tree= device.color ? (NODE *)&gBTree : (NODE *)&gWTree;
continue ;
}
/* The remaining codes above 3000 are all 2-D so we start by
sorting out colours on current line and on reference line.
Then we work out lnB1 allowing for the fact that it must be a
change, and finally adjust the values of lnA0 and lnB1 if
positioned at start/end line. */
if (lnA0== (-1))
{
bRef_color= WHITE ;
}
else
{
lnA0= (m_lImgWidth/*FAXWIDTH*/-lnDots_left) ;
j= (lnA0/8) ;
bThis_bit= (0x80>>(lnA0%8)) ;
if (cpRef_line[j]&bThis_bit)
bRef_color= BLACK ;
else
bRef_color= WHITE ;
}
for (lnB1= lnA0+1;lnB1<m_lImgWidth/*FAXWIDTH*/;lnB1++)
{
j= (lnB1/8) ;
bThis_bit= (0x80>>(lnB1%8)) ;
if ((cpRef_line[j]&bThis_bit)!= (bRef_color&bThis_bit))
break ;
}
if (bRef_color!= device.color)
{
for (lnB1++;lnB1<m_lImgWidth/*FAXWIDTH*/;lnB1++)
{
j= (lnB1/8) ;
bThis_bit= (0x80>>(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<PASSMODE)
{
lnCode= ((lnB1-lnA0)+(lnCode-VTMODE0)) ;
if (!lnResync)
{
if ((lnDots_left-= lnCode)<0)
lnResync= 1 ;
}
if ((!lnResync)&&(lnCode!= 0))
if(! ProcessLine(&device, lnCode) )
return NULL;
device.color= (~device.color) ;
lnCode= 0 ;
continue ;
}
/* If the code is PASSMODE then we need to identify lnB2
before proceeding - pass mode does not flip the colour. */
for (lnB2= lnB1+1;lnB2<m_lImgWidth/*FAXWIDTH*/;lnB2++)
{
j= (lnB2/8) ;
bThis_bit= (0x80>>(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<bih.biHeight; ++row)
{
for (int col=0; col<wWidthBytes; ++col)
{
dwPos = row*wWidthBytes+col;
*(m_outImage.lpImage+dwPos) = ~(*(m_outImage.lpImage+dwPos));
}
byDelta = 8-bih.biWidth%8;
if (byDelta == 8)
continue;
byPixel = *(m_outImage.lpImage+dwPos);
byPixel >>= 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<<bih.biBitCount) * sizeof(RGBQUAD);
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER);
DWORD dwSize = dwHeaderSize + dwBitsSize + dwColorTableSize;
HANDLE hDIB = GlobalAlloc(GHND, dwSize);
if (hDIB == NULL)
return NULL;
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
memcpy(lpDIB, (LPBYTE)&bih, dwHeaderSize);
memcpy(lpDIB+dwHeaderSize, (LPBYTE)rgb, dwColorTableSize);
memcpy(FindDIBBits((LPBYTE)lpDIB), (LPBYTE)m_outImage.lpImage, dwBitsSize);
return hDIB; // OK
}
/**************************************************************************
Contents : Single function module, part of DECODE
Function name : ProcessLine
Purpose : to compose and Output decoded scan lines
Parameters passed : pointer to DEVPARMS structure (see decode.h)
integer value of run length
Value returned : integer 0 for failure, 1 for success
Variables changed : DEVPARMS structure members (flags, indices and buffers)
See DECODE.H
Functions called : VerticalScale, HorizScale, newpage, Output
Exit points : Return 0 if malloc fails to allow enough space for image
Otherwise returns 1 after any one of thirteen
successful routes to completion - sorry about the
unstructured programming, but the indentation levels
got illegible. It could be argued that this
function is too big.
COMMENTS
________
ProcessLine has five types of entry -
1. iRunlength of INIT initializes
2. iRunlength of DEINIT uninitializes
3. iRunlength of OUREOP throws pages
4. iRunlength of OUREOL outputs lines
5. all other runlengths placed scaled runs in lines
The DEVPARMS structure contains the device ID, details of the scaling
used, and the color of the current Output run. Note that there is a
substatial amount of static storage which is needed to keep track of
the run line currently being decoded.
***************************************************************************/
int CTifIFD::ProcessLine(DEVPARMS * device, int iRunlength)
{
int lnTemp;
BYTE bBit;
int lnCopyRun;
/**************************************************************************
We initialize here. We malloc storage for our Output buffer needs
(computed from the destination device width and the number of lines
it can Output at a time) and initialize that to white space. The
index to this array is set to 0, our bit counter is set to 8. In
case 2-D coding is used we set the 2-D map index to 0 and the 2-D map
bit counter to 8 also. As we keep track of the last significant byte
in each line to avoid having to Output trailing white space at the
end of lines (or complete white space for blank lines) we set m_lnLastSaveByte to
0 too. We set our m_lnRow to zero, initialize our scaling, set our color
to white and finally kick off our multibyte line counter.
**************************************************************************/
if (iRunlength==INIT)
{
m_lnFaxBytes = ((int)device->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;
}
/**************************************************************************
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -