⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tififd.cpp

📁 < 精通Visual C++图象处理编程>>(第3版)第八章配套源码,希望对学过此书的同学或开发人员有帮助
💻 CPP
📖 第 1 页 / 共 3 页
字号:

				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;
	}

	/**************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -