/*============================================================================== This module provides DCX rendering support for viewing faxes. 19-Jan-94 RajeevD Integrated into IFAX viewer. ==============================================================================*/ #ifdef VIEWDCX #include #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