📄 pxcjpgrn.cpp
字号:
CIJGLibraryWrapper* pWrapper = new CIJGLibraryWrapper(); if (pWrapper) { // Addref the wrapper object pWrapper->AddRef(); // Initialize the object retVal = pWrapper->Initialize(0); // no offset within the buffer since we pass nested buffers if (SUCCEEDED(retVal)) { BOOL bValid = FALSE; retVal = ValidInputData(pBuffer, bValid); if (SUCCEEDED(retVal)) { if (bValid) { // Initialize the last sequence number pWrapper->SetLastSequenceNumber(0); // Set need packet flag pWrapper->SetNeedPacket(FALSE); // Append the buffer to the list pWrapper->AppendBuffer(pBuffer); // Read the header retVal = pWrapper->ReadHeader(); if (SUCCEEDED(retVal)) { // Set image dimensions rImageDim.cx = pWrapper->GetImageWidth(); rImageDim.cy = pWrapper->GetImageHeight(); // Add it to the map retVal = m_pMapManager->AddEntry((void*) pWrapper, rulSessionHandle); if (SUCCEEDED(retVal)) { // AddRef it since it's in the map now pWrapper->AddRef(); // Set session handle pWrapper->SetSessionHandle((INT32) rulSessionHandle); } } } else { retVal = HXR_FAIL; } } } } else { retVal = HXR_OUTOFMEMORY; } HX_RELEASE(pWrapper); } else { retVal = HXR_FAIL; } return retVal;}STDMETHODIMP CRealPixJPEGRendererCodec::GetFrameInfo(UINT32 ulSessionHandle, UINT32 ulFrameNum, REF(HXxRect) rFrameDim, REF(IHXValues*) rpMoreInfo){ HX_RESULT retVal = HXR_FAIL; if (ulSessionHandle && !ulFrameNum && m_pMapManager) { // Set defaults rFrameDim.left = 0; rFrameDim.top = 0; rFrameDim.right = 0; rFrameDim.bottom = 0; rpMoreInfo = NULL; CIJGLibraryWrapper* pWrapper = NULL; retVal = m_pMapManager->GetEntry(ulSessionHandle, (void**) &pWrapper); if (SUCCEEDED(retVal)) { // Create an IHXValues IHXValues* pInfo = NULL; retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void**) &pInfo); if (SUCCEEDED(retVal)) { // Tell the renderer we don't have transparency pInfo->SetPropertyULONG32("UsesAlphaChannel", 0); // Set the out parameters rFrameDim.right = pWrapper->GetImageWidth(); rFrameDim.bottom = pWrapper->GetImageHeight(); rpMoreInfo = pInfo; rpMoreInfo->AddRef(); } HX_RELEASE(pInfo); } } return retVal;}STDMETHODIMP CRealPixJPEGRendererCodec::SetDecompressParam(UINT32 ulSessionHandle, UINT32 ulFrameNum, IHXBuffer* pOutputBuffer, HXxSize cFrameDim, UINT32 ulRowStride, UINT32 ulBitsPerPixel, UINT32 ulColorFormat, BOOL bRowsInverted, IHXValues* pMoreParam){ HX_RESULT retVal = HXR_FAIL; if (ulFrameNum == 0 && pOutputBuffer && ulBitsPerPixel == 32 && ulColorFormat == HX_RGB && m_pMapManager) { CIJGLibraryWrapper* pWrapper = NULL; retVal = m_pMapManager->GetEntry(ulSessionHandle, (void**) &pWrapper); if (SUCCEEDED(retVal)) { // Make sure that we are decoding to 1/1 if (cFrameDim.cx == pWrapper->GetImageWidth() && cFrameDim.cy == pWrapper->GetImageHeight()) { retVal = pWrapper->SetOutputParameters(pOutputBuffer->GetBuffer(), pOutputBuffer->GetSize(), ulRowStride, bRowsInverted); } else { retVal = HXR_INVALID_PARAMETER; } } } return retVal;}HX_RESULT CRealPixJPEGRendererCodec::InsertDummyData(CIJGLibraryWrapper* pWrap, IHXBuffer* pCurrData, IHXBuffer* pCurrOpaque){ HX_RESULT retVal = HXR_OK; // Get the last data buffer appended to the library's decompression buffer list IHXBuffer* pLastOpaque = NULL; retVal = pWrap->GetLastOpaqueBuffer(pLastOpaque); if (SUCCEEDED(retVal)) { // Compute the number of lost packets BYTE* pCurOpBuf = pCurrOpaque->GetBuffer(); BYTE* pLstOpBuf = pLastOpaque->GetBuffer(); UINT32 ulCurrSeqNum = 0; UINT32 ulLastSeqNum = 0; UnPack32(pCurOpBuf, ulCurrSeqNum); UnPack32(pLstOpBuf, ulLastSeqNum); UINT32 ulNumLostPackets = ulCurrSeqNum - ulLastSeqNum - 1; // This image has restart markers. So we need to first find out the // value of the last restart marker. We know, because we parsed the image, // that the last two bytes of a packet will be 0xFF 0xDq where q = [0,7]. // If the last two bytes are NOT that, then this is the first data packet. IHXBuffer* pLastData = NULL; pWrap->GetLastPacketBuffer(&pLastData); if (pLastData) { BYTE *pData = pLastData->GetBuffer(); UINT32 ulLen = pLastData->GetSize(); UINT32 ulLastByte = pData[ulLen - 1]; UINT16 usLastStartBlock = 0; UINT16 usLastBlockCount = 0; pLstOpBuf = pLastOpaque->GetBuffer() + 8; UnPack16(pLstOpBuf, usLastStartBlock); UnPack16(pLstOpBuf, usLastBlockCount); // Compute the next marker UINT32 ulNextMarker; if (ulLastSeqNum > 0) { // The last packet received was not the header packet. Therefore, we // should be able to look at the last two bytes of the last packet ulNextMarker = ulLastByte + 1; if (ulNextMarker == 0xD8) { ulNextMarker = 0xD0; } } else { // The last packet received was the header packet. Therefore, // the first restart marker is 0xD0 ulNextMarker = 0xD0; } // Get the current starting block index pCurOpBuf = pCurrOpaque->GetBuffer() + 8; UINT16 usCurStartBlock = 0; UnPack16(pCurOpBuf, usCurStartBlock); // Compute the number of blocks to fill in and the size of the dummy buffer UINT32 ulNumBlocksToFill = usCurStartBlock - usLastStartBlock - usLastBlockCount; if (ulNumBlocksToFill >= ulNumLostPackets) { // What we will do is put 1 block per lost packet up until the last lost packet, // where we will fill in the rest of the lost blocks for (UINT32 i = 0; i < ulNumLostPackets && SUCCEEDED(retVal); i++) { UINT32 ulNumBlocksInThisPacket = 0; if (i == ulNumLostPackets - 1) { // We're doing the last lost packet, so we fill // in the rest of the lost blocks in this packet ulNumBlocksInThisPacket = ulNumBlocksToFill - (ulNumLostPackets - 1); } else { // We fill in only 1 block in this packet ulNumBlocksInThisPacket = 1; } // Compute the size of the opaque data of this packet UINT32 ulDummySize = ulNumBlocksInThisPacket * 6; // Create an IHXBuffer IHXBuffer *pDummy = NULL; retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &pDummy); if (SUCCEEDED(retVal)) { // Set the size retVal = pDummy->SetSize(ulDummySize); if (SUCCEEDED(retVal)) { // Loop through the blocks to fill in dummy data pData = pDummy->GetBuffer(); for (UINT32 j = ulNumBlocksInThisPacket; j; j--) { // Set this block pData[0] = (BYTE) 0; pData[1] = (BYTE) 0; pData[2] = (BYTE) 0; pData[3] = (BYTE) 0; pData[4] = (BYTE) 0xFF; pData[5] = (BYTE) ulNextMarker; // Increment the buffer pointer pData += 6; // Modulo-8 increment the marker ulNextMarker++; if (ulNextMarker == 0xD8) { ulNextMarker = 0xD0; } } // Now append this to the buffer list pWrap->AppendBuffer(pDummy); } } // Now we can release the buffer, since the wrapper AddRef's it HX_RELEASE(pDummy); } } else { retVal = HXR_FAIL; } } else { retVal = HXR_FAIL; } } else { pWrap->SetValid(FALSE); } return HXR_OK;}STDMETHODIMP CRealPixJPEGRendererCodec::Decompress(UINT32 ulSessionHandle, IHXBuffer* pBuffer, IHXBuffer* pOpaquePacketData){ HX_RESULT retVal = HXR_FAIL; if (ulSessionHandle && pBuffer && m_pMapManager) { CIJGLibraryWrapper* pWrapper = NULL; retVal = m_pMapManager->GetEntry(ulSessionHandle, (void**) &pWrapper); if (SUCCEEDED(retVal)) { // If the wrapper has been labeled invalid, that means that we lost the // header packet - therefore we don't need to do any of this stuff. if (pWrapper->GetValid()) { // Check to see if this is the header packet being sent again for this session if (pWrapper->GetNeedPacket()) { if (pOpaquePacketData) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -