/*============================================================================== This module provides RBA rendering support for viewing faxes. 03-Mar-94 RajeevD Created. ==============================================================================*/ #ifdef VIEWRBA #include #include "viewrend.hpp" #include "resexec.h" #define COMMON_SIZE 6 //============================================================================== RBAVIEW::RBAVIEW (DWORD nType) { _fmemset ((LPBYTE) this + sizeof(LPVOID), 0, sizeof(RBAVIEW) - sizeof(LPVOID)); nTypeOut = nType; } //============================================================================== RBAVIEW::~RBAVIEW () { if (hHRE) uiHREClose (hHRE); for (UINT iRes = 0; iRes < 256; iRes++) if (ResDir[iRes]) GlobalFreePtr (ResDir[iRes]); if (lpCodec) GlobalFreePtr (lpCodec); if (bufIn.lpbBegBuf) GlobalFreePtr (bufIn.lpbBegBuf); } //============================================================================== BOOL RBAVIEW::Init (LPVOID lpFilePath, LPVIEWINFO lpvi, LPWORD lpwBandSize) { ENDJOB EndJob; if (!Open (lpFilePath, 0)) return_error (("VIEWREND could not reopen spool file!\r\n")); if (!Read((LPBYTE) &BegJob, sizeof(BegJob))) return_error (("VIEWREND could not read spool header!\r\n")); dwOffset[0] = Tell(); DEBUGCHK (lpwBandSize); *lpwBandSize = (WORD) BegJob.xBand/8 * (WORD) BegJob.yBand + OUTBUF_SLACK; if (BegJob.cResDir) { hHRE = hHREOpen (NULL, (UINT) BegJob.xBand/8, (UINT) BegJob.cResDir); if (!hHRE) return_error (("VIEWREND could not initialize resource executor!\r\n")); } if (1) { FC_PARAM fcp; UINT cbCodec; // Query for codec size. fcp.nTypeIn = MMR_DATA; fcp.nTypeOut = LRAW_DATA; fcp.cbLine = (UINT) BegJob.xBand / 8; cbCodec = FaxCodecInit (NULL, &fcp); DEBUGCHK (cbCodec); // Allocate codec context. lpCodec = GlobalAllocPtr (0, cbCodec); if (!lpCodec) return_error (("VIEWREND could allocate codec context!\r\n")); FaxCodecInit (lpCodec, &fcp); bufIn.wLengthBuf = 2000; bufIn.lpbBegBuf = (LPBYTE) GlobalAllocPtr (0, bufIn.wLengthBuf); if (!bufIn.lpbBegBuf) return_error (("VIEWREND could not allocate input buffer!\r\n")); } // Fill VIEWINFO. lpvi->xRes = BegJob.xRes; lpvi->yRes = BegJob.yRes; if ( Seek (- (long) sizeof(ENDJOB), SEEK_END) && Read (&EndJob, sizeof(ENDJOB)) && EndJob.dwID == ID_ENDJOB ) { lpvi->cPage = EndJob.cPage; lpvi->yMax = EndJob.yMax; } else { lpvi->cPage = 0; while (SetPage (lpvi->cPage)) lpvi->cPage++; lpvi->yMax = 0; } return SetPage (0); } //============================================================================== BOOL RBAVIEW::SetPage (UINT iPage) { if (iPage < iMaxPage) { Seek (dwOffset[iPage], STREAM_SEEK_SET); // BKD: changed to STREAM_SEEK_SET return TRUE; } Seek (dwOffset[iMaxPage], STREAM_SEEK_SET); // BKD: changed to STREAM_SEEK_SET while (1) { RESHDR Header; FRAME Frame; if (!Read ((LPBYTE) &Header, sizeof(Header))) return_error (("VIEWREND could not read RBA resource header!")); switch (Header.wClass) { case ID_GLYPH: case ID_BRUSH: { UINT cbRaw; // Allocate mmeory from cache. Frame.lpData = (LPBYTE) GlobalAllocPtr (0, Header.cbRest); if (!Frame.lpData) return_error (("VIEWREND could not allocate memory!\r\n")); // Read resource from stream. if (!Read (Frame.lpData + COMMON_SIZE, Header.cbRest - COMMON_SIZE)) return_error (("VIEWREND could not read resource!\r\n")); // Trap chaingon compressed glyph sets. cbRaw = HIWORD (Header.dwID); if (cbRaw) { LPVOID lpRaw; DEBUGCHK (Header.wClass == ID_GLYPH); if (!(lpRaw = GlobalAllocPtr (0, cbRaw))) return_error (("VIEWREND could not allocate decompression buffer!\r\n")); UnpackGlyphSet (Frame.lpData, lpRaw); GlobalFreePtr (Frame.lpData); Header.cbRest = (USHORT)cbRaw; Header.dwID = LOWORD (Header.dwID); Frame.lpData = (LPBYTE) lpRaw; } // Past common header. _fmemcpy (Frame.lpData, &Header.dwID, COMMON_SIZE); Frame.wSize = Header.cbRest; // Add resource to directory. uiHREWrite (hHRE, &Frame, 1); ResDir[Header.dwID] = Frame.lpData; break; } case ID_CONTROL: if (Header.dwID == ID_ENDPAGE) { iMaxPage++; dwOffset [iMaxPage] = Tell (); if (iPage < iMaxPage) { // BKD: changed to STREAM_SEEK_SET Seek (dwOffset[iPage], STREAM_SEEK_SET); return TRUE; } } // Yes, fall through to default case! default: // Skip everything else. if (!Seek (Header.cbRest - COMMON_SIZE, SEEK_CUR)) return_error (("VIEWREND could not skip unknown RBA resource")); } // switch (Header.wClass) } // while (1) } //============================================================================== BOOL RBAVIEW::GetBand (LPBITMAP lpbmBand) { DEBUGCHK (lpbmBand && lpbmBand->bmBits); lpbmBand->bmType = 0; lpbmBand->bmWidth = (WORD) BegJob.xBand; lpbmBand->bmWidthBytes = lpbmBand->bmWidth / 8; lpbmBand->bmPlanes = 1; lpbmBand->bmBitsPixel = 1; while (1) { RESHDR Header; if (!Read ((LPBYTE) &Header, sizeof(Header))) return FALSE; switch (Header.wClass) { case ID_RPL: return ExecuteRPL (lpbmBand, &Header); case ID_BAND: return ExecuteBand (lpbmBand, &Header); case ID_CONTROL: // Trap page breaks. if (Header.dwID == ID_ENDPAGE) { Seek (-8, SEEK_CUR); lpbmBand->bmHeight = 0; return TRUE; } // Yes, fall through to default case! default: // Skip everything else. if (!Seek (Header.cbRest - COMMON_SIZE, SEEK_CUR)) return FALSE; } // switch (Header.wClass) } // while (1) } //============================================================================== BOOL RBAVIEW::ExecuteRPL (LPBITMAP lpbmBand, LPRESHDR lpHeader) { FRAME Frame; // Clear band. lpbmBand->bmHeight = (WORD) BegJob.yBand; _fmemset (lpbmBand->bmBits, 0, lpbmBand->bmHeight * lpbmBand->bmWidthBytes); // Trap blank bands. if (lpHeader->cbRest == COMMON_SIZE) return TRUE; // Allocate RPL. Frame.lpData = (LPBYTE) GlobalAllocPtr (0, lpHeader->cbRest); if (!Frame.lpData) return_error (("VIEWREND could not allocate RPL!\r\n")); // Load RPL. Frame.wSize = lpHeader->cbRest; _fmemcpy (Frame.lpData, &lpHeader->dwID, COMMON_SIZE); Read (Frame.lpData + COMMON_SIZE, Frame.wSize - COMMON_SIZE); // Execute RPL. uiHREWrite (hHRE, &Frame, 1); uiHREExecute (hHRE, lpbmBand, NULL); // Free RPL. GlobalFreePtr (Frame.lpData); return TRUE; } //============================================================================== BOOL RBAVIEW::ExecuteBand (LPBITMAP lpbmBand, LPRESHDR lpHeader) { BMPHDR bmh; UINT cbIn; FC_PARAM fcp; BUFFER bufOut; // Read bitmap header. if (!Read ((LPBYTE) &bmh, sizeof(bmh))) return FALSE; lpbmBand->bmHeight = bmh.wHeight; cbIn = lpHeader->cbRest - COMMON_SIZE - sizeof(bmh); // Trap uncompressed bands. if (!bmh.bComp) { if (!Read (lpbmBand->bmBits, cbIn)) return FALSE; if (nTypeOut == LRAW_DATA) { BUFFER bufOut2; bufOut2.lpbBegData = (LPBYTE) lpbmBand->bmBits; bufOut2.wLengthData = (USHORT)cbIn; bufOut2.dwMetaData = HRAW_DATA; BitReverseBuf (&bufOut2); } return TRUE; } // Initialize codec. fcp.nTypeIn = bmh.bComp >> 2; fcp.nTypeOut = LRAW_DATA; fcp.cbLine = (WORD) BegJob.xBand / 8; FaxCodecInit (lpCodec, &fcp); // Initialize input. bufIn.dwMetaData = fcp.nTypeIn; // Initialize output. bufOut.lpbBegBuf = (LPBYTE) lpbmBand->bmBits; bufOut.wLengthBuf = fcp.cbLine * bmh.wHeight; bufOut.lpbBegData = bufOut.lpbBegBuf; bufOut.wLengthData = 0; bufOut.dwMetaData = fcp.nTypeOut; // Convert. while (cbIn) { bufIn.lpbBegData = bufIn.lpbBegBuf; bufIn.wLengthData = min (cbIn, bufIn.wLengthBuf); if (!Read (bufIn.lpbBegData, bufIn.wLengthData)) return FALSE; cbIn -= bufIn.wLengthData; if (FaxCodecConvert (lpCodec, &bufIn, &bufOut) == FC_DECODE_ERR) return_error (("VIEWREND MMR decode error!\r\n")); } // while (cbIn) if (nTypeOut == HRAW_DATA) BitReverseBuf (&bufOut); return TRUE; } #endif // VIEWRBA