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.
193 lines
4.6 KiB
193 lines
4.6 KiB
/*==============================================================================
|
|
This module provides DCX rendering support for viewing faxes.
|
|
|
|
19-Jan-94 RajeevD Integrated into IFAX viewer.
|
|
==============================================================================*/
|
|
#ifdef VIEWDCX
|
|
|
|
#include <memory.h>
|
|
#include "viewrend.hpp"
|
|
#include "dcxcodec.h"
|
|
|
|
//==============================================================================
|
|
DCXVIEW::DCXVIEW (DWORD nType)
|
|
{
|
|
nTypeOut = nType;
|
|
lpCodec = NULL;
|
|
bufIn.wLengthBuf = 8000;
|
|
bufIn.lpbBegBuf = (LPBYTE) GlobalAllocPtr (0, bufIn.wLengthBuf);
|
|
}
|
|
|
|
//==============================================================================
|
|
DCXVIEW::~DCXVIEW ()
|
|
{
|
|
if (lpCodec)
|
|
GlobalFreePtr (lpCodec);
|
|
if (bufIn.lpbBegBuf)
|
|
GlobalFreePtr (bufIn.lpbBegBuf);
|
|
}
|
|
|
|
//==============================================================================
|
|
BOOL DCXVIEW::Init (LPVOID lpFilePath, LPVIEWINFO lpvi, LPWORD lpwBandSize)
|
|
{
|
|
DWORD dwOffset;
|
|
PCX_HDR pcx;
|
|
UINT cbCodec;
|
|
|
|
if (!this || !bufIn.lpbBegBuf)
|
|
return_error (("VIEWREND could not allocate context!\r\n"));
|
|
|
|
if (!Open (lpFilePath, 0))
|
|
return_error (("VIEWREND could not open spool file!\r\n"));
|
|
|
|
if (!Seek (sizeof(DWORD), SEEK_BEG))
|
|
return_error (("VIEWREND could not seek to first page offset!\r\n"));
|
|
|
|
if (!Read (&dwOffset, sizeof(dwOffset)))
|
|
return_error (("VIEWREND could not read first page offset\r\n"));
|
|
|
|
if (!Seek (dwOffset, SEEK_BEG))
|
|
return_error (("VIEWREND could not seek to first page!\r\n"));
|
|
|
|
if (!Read (&pcx, sizeof(pcx)))
|
|
return_error (("VIEWREND could read header of first page!\r\n"));
|
|
|
|
|
|
// Fill VIEWINFO.
|
|
lpvi->cPage = 0;
|
|
while (SetPage(lpvi->cPage))
|
|
lpvi->cPage++;
|
|
switch (pcx.xRes)
|
|
{
|
|
case 640:
|
|
// Assume square aspect ratio
|
|
lpvi->xRes = 200;
|
|
lpvi->yRes = 200;
|
|
break;
|
|
|
|
default:
|
|
lpvi->xRes = pcx.xRes;
|
|
lpvi->yRes = pcx.yRes;
|
|
break;
|
|
}
|
|
lpvi->yMax = pcx.yMax - pcx.yMin;
|
|
|
|
// Set up codec.
|
|
fcp.nTypeIn = DCX_DATA;
|
|
fcp.nTypeOut = HRAW_DATA;
|
|
fcp.cbLine = (pcx.xMax - pcx.xMin + 1) / 8;
|
|
|
|
// Query codec.
|
|
cbCodec = DcxCodecInit (NULL, &fcp);
|
|
if (!cbCodec)
|
|
return_error (("VIEWREND could not init codec!\r\n"));
|
|
|
|
// Initialize codec.
|
|
lpCodec = GlobalAllocPtr (0, cbCodec);
|
|
if (!lpCodec)
|
|
return_error (("VIEWREND could not allocate codec!\r\n"));
|
|
|
|
cbBand = *lpwBandSize;
|
|
return SetPage (0);
|
|
}
|
|
|
|
//==============================================================================
|
|
BOOL DCXVIEW::SetPage (UINT iPage)
|
|
{
|
|
DWORD dwOffset[2];
|
|
DEBUGCHK (iPage < 1024);
|
|
|
|
// Get offset of current and next page.
|
|
Seek (sizeof(DWORD) * (iPage + 1), SEEK_BEG);
|
|
Read (dwOffset, sizeof(dwOffset));
|
|
if (!dwOffset[0])
|
|
return FALSE;
|
|
if (!dwOffset[1])
|
|
{
|
|
Seek (0, SEEK_END);
|
|
dwOffset[1] = Tell();
|
|
}
|
|
|
|
// Seek to page.
|
|
dwOffset[0] += sizeof(PCX_HDR);
|
|
if (!Seek (dwOffset[0], SEEK_BEG))
|
|
return_error (("VIEWREND could not seek to page %d!",iPage));
|
|
cbPage = dwOffset[1] - dwOffset[0];
|
|
|
|
// Initialize codec.
|
|
DcxCodecInit (lpCodec, &fcp);
|
|
bufIn.Reset();
|
|
|
|
fEndPage = FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
//==============================================================================
|
|
BOOL DCXVIEW::GetBand (LPBITMAP lpbmBand)
|
|
{
|
|
FC_STATUS fcs;
|
|
BUFFER bufOut;
|
|
|
|
DEBUGCHK (lpbmBand && lpbmBand->bmBits);
|
|
|
|
// Fill descriptor.
|
|
lpbmBand->bmType = 0;
|
|
lpbmBand->bmWidth = 8 * fcp.cbLine;
|
|
lpbmBand->bmWidthBytes = fcp.cbLine;
|
|
lpbmBand->bmPlanes = 1;
|
|
lpbmBand->bmBitsPixel = 1;
|
|
|
|
// Trap end of page.
|
|
if (fEndPage)
|
|
{
|
|
lpbmBand->bmHeight = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
// Set up output buffer.
|
|
bufOut.lpbBegBuf = (LPBYTE) lpbmBand->bmBits;
|
|
bufOut.wLengthBuf = cbBand;
|
|
bufOut.Reset();
|
|
bufOut.dwMetaData = LRAW_DATA;
|
|
|
|
do
|
|
{
|
|
// Fetch input buffer?
|
|
if (!bufIn.wLengthData)
|
|
{
|
|
// Reset buffer.
|
|
bufIn.lpbBegData = bufIn.lpbBegBuf;
|
|
if ((DWORD) bufIn.wLengthBuf < cbPage)
|
|
bufIn.wLengthData = bufIn.wLengthBuf;
|
|
else
|
|
bufIn.wLengthData = (WORD) cbPage;
|
|
|
|
// Read DCX data.
|
|
if (!Read (bufIn.lpbBegData, bufIn.wLengthData))
|
|
return_error (("VIEWREND could not read DCX buffer!\r\n"));
|
|
cbPage -= bufIn.wLengthData;
|
|
}
|
|
|
|
// Decode the DCX data.
|
|
fcs = DcxCodecConvert (lpCodec, &bufIn, &bufOut);
|
|
|
|
// Check for end of page.
|
|
if (!cbPage)
|
|
{
|
|
fEndPage = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
while (fcs == FC_INPUT_EMPTY);
|
|
|
|
// Bit reverse if needed.
|
|
if (nTypeOut == LRAW_DATA)
|
|
BitReverseBuf (&bufOut);
|
|
|
|
// Calculate output height.
|
|
lpbmBand->bmHeight = bufOut.wLengthData / fcp.cbLine;
|
|
return TRUE;
|
|
}
|
|
|
|
#endif // VIEWDCX
|
|
|