📄 pxjpgff.cpp
字号:
{ LISTPOSITION pos = m_pPacketInfoList->GetHeadPosition(); while (pos) { PacketInfo* pInfo = (PacketInfo*) m_pPacketInfoList->GetNext(pos); HX_DELETE(pInfo); } m_pPacketInfoList->RemoveAll(); }}HX_RESULT CJPEGFileFormat::ParseImageBuffer(BYTE *pFileBuffer, UINT32 ulFileSize){ // Clear the packet info list ClearPacketInfoList(); // Make reasonably sure this is a JPEG image. Most .jpg images should // be JFIF-compliant. However, a lot of images coming off digital cameras // are non-compliant: they don't have an APP0 marker, they have non-JFIF // APP0 markers, multiple APP0 markers, etc. Therefore, we will only // check the beginning of the file for the SOI marker if (pFileBuffer[0] != 0xFF || pFileBuffer[1] != kMarkerSOI) { return HXR_FAIL; } // Set defaults m_ulRestartInterval = 0; // Now parse the file buffer BOOL bHeaderComplete = FALSE; BYTE *pCurByte = pFileBuffer; BYTE *pBufLimit = pFileBuffer + ulFileSize; UINT32 ulSequenceNumber = 0; while (bHeaderComplete == FALSE && pCurByte < pBufLimit) { // Look for a 0xFF, which would signify a marker if (*pCurByte++ == 0xFF) { // Now take different actions depending on what kind of // marker this is - some markers have data associated with // them (such as DRI) and others don't (such as SOI and EOI) BYTE ucMarker = *pCurByte++; if (!(ucMarker == kMarkerSOI || ucMarker == kMarkerEOI || ucMarker == kMarkerTEM || (ucMarker >= kMarkerRST0 && ucMarker <= kMarkerRST7))) { UINT32 ulSegLen = (pCurByte[0] << 8) | pCurByte[1]; // Add SOF1 and SOF2 to support progressive if (ucMarker == kMarkerSOF0 || ucMarker == kMarkerSOF1 || ucMarker == kMarkerSOF2) { // We look at this marker to extract the width and height m_ulImageHeight = (pCurByte[3] << 8) | pCurByte[4]; m_ulImageWidth = (pCurByte[5] << 8) | pCurByte[6]; } else if (ucMarker == kMarkerDRI) { // We look at this marker to extract the restart interval m_ulRestartInterval = (pCurByte[2] << 8) | pCurByte[3]; } else if (ucMarker == kMarkerSOS) { // This marker is the last marker in the header bHeaderComplete = TRUE; } // Advance the pointer pCurByte += ulSegLen; } } } // Did we get a valid header? if (!bHeaderComplete) { return HXR_FAILED; } // Now we've reached the end of the header, make append // the first packet info struct PacketInfo *pInfo = new PacketInfo; if (!pInfo) { return HXR_OUTOFMEMORY; } pInfo->m_pBuffer = pFileBuffer; pInfo->m_ulSize = pCurByte - pFileBuffer; pInfo->m_ulSequenceNumber = ulSequenceNumber++; pInfo->m_ulStartingBlock = 0; pInfo->m_ulNumBlocks = 0; if (!m_pPacketInfoList) { m_pPacketInfoList = new CHXSimpleList(); } if (m_pPacketInfoList) { m_pPacketInfoList->AddTail((void*) pInfo); } // If the restart interval is non-zero, then we need to look for // restart markers. This gives us some measure of loss tolerance. if (m_ulRestartInterval > 0) { BOOL bImageComplete = FALSE; UINT32 ulCurBlock = 0; while (pCurByte < pBufLimit && bImageComplete == FALSE) { BOOL bPacketComplete = FALSE; UINT32 ulNumRSTMarkers = 0; BYTE *pCurStart = pCurByte; while (bPacketComplete == FALSE && pCurByte < pBufLimit) { if (*pCurByte++ == 0xFF) { BYTE ucMarker = *pCurByte++; if (ucMarker >= kMarkerRST0 && ucMarker <= kMarkerRST7) { ulNumRSTMarkers++; if (pCurByte - pCurStart >= kDefaultPacketSize) { bPacketComplete = TRUE; } } else if (ucMarker == kMarkerEOI) { bPacketComplete = TRUE; bImageComplete = TRUE; } } } // Did we get a valid packet? if (bPacketComplete == FALSE) { return HXR_FAILED; } // Make a new packet info entry PacketInfo *pInfo = new PacketInfo; if (!pInfo) { return HXR_OUTOFMEMORY; } pInfo->m_pBuffer = pCurStart; // We check how many bytes we have left after this UINT32 ulNumBytesLeft = pBufLimit - pCurByte; if (ulNumBytesLeft < kMinimumPacketSize) { pCurByte = pBufLimit; bImageComplete = TRUE; } pInfo->m_ulSize = pCurByte - pCurStart; pInfo->m_ulSequenceNumber = ulSequenceNumber++; pInfo->m_ulStartingBlock = ulCurBlock; pInfo->m_ulNumBlocks = ulNumRSTMarkers; if (!m_pPacketInfoList) { m_pPacketInfoList = new CHXSimpleList(); } if (m_pPacketInfoList) { m_pPacketInfoList->AddTail((void*) pInfo); } // Increment the current block ulCurBlock += ulNumRSTMarkers; } // Did we finish the image OK? if (bImageComplete == FALSE) { return HXR_FAILED; } } else { while (pCurByte < pBufLimit) { BYTE *pCurStart = pCurByte; pCurByte += kDefaultPacketSize; if (pCurByte > pBufLimit) { pCurByte = pBufLimit; } // Make a new packet info entry PacketInfo *pInfo = new PacketInfo; if (!pInfo) { return HXR_OUTOFMEMORY; } pInfo->m_pBuffer = pCurStart; pInfo->m_ulSize = pCurByte - pCurStart; pInfo->m_ulSequenceNumber = ulSequenceNumber++; pInfo->m_ulStartingBlock = 0; pInfo->m_ulNumBlocks = 0; if (!m_pPacketInfoList) { m_pPacketInfoList = new CHXSimpleList(); } if (m_pPacketInfoList) { m_pPacketInfoList->AddTail((void*) pInfo); } } } // Compute some statistics on the packets UINT32 ulMin = 0xFFFFFFFF; UINT32 ulMax = 0; UINT32 ulSum = 0; if (m_pPacketInfoList) { LISTPOSITION pos = m_pPacketInfoList->GetHeadPosition(); while (pos) { PacketInfo* pLInfo = (PacketInfo*) m_pPacketInfoList->GetNext(pos); if (pLInfo) { UINT32 ulSize = pLInfo->m_ulSize + kJPEGPacketOverhead; if (ulSize > ulMax) { ulMax = ulSize; } if (ulSize < ulMin) { ulMin = ulSize; } ulSum += ulSize; } } } // Set min and max packet size m_ulMinPacketSize = ulMin; m_ulMaxPacketSize = ulMax; // Set average packet size UINT32 ulNumPackets = 0; if (m_pPacketInfoList) { ulNumPackets = m_pPacketInfoList->GetCount(); } if (!ulNumPackets) { return HXR_FAILED; } m_ulAvgPacketSize = (ulSum + (ulNumPackets >> 1)) / ulNumPackets; // Set total bytes to send// m_ulTotalBytesToSend = m_ulFileSize + ulNumPackets * (kIRMAPacketOverhead + kJPEGPacketOverhead); m_ulTotalBytesToSend = m_ulFileSize + ulNumPackets * kJPEGPacketOverhead; // Changed since this screwed predata calculations // Initialize the iterator if (m_pPacketInfoList) { m_pPacketInfoListItr = m_pPacketInfoList->GetHeadPosition(); } return HXR_OK;}void CJPEGFileFormat::ReportError(UINT32 ulErrorID){ // Try to get the string from the resource manager CHXString cErrStr; HX_RESULT retVal = GetResourceErrorString(ulErrorID, cErrStr); if (retVal != HXR_OK) { switch (ulErrorID) { case IDS_ERR_JPG_BADBITRATE: cErrStr = ERRSTR_JPG_BADBITRATE; break; case IDS_ERR_JPG_BADPREROLL: cErrStr = ERRSTR_JPG_BADPREROLL; break; case IDS_ERR_JPG_BADDURATION: cErrStr = ERRSTR_JPG_BADDURATION; break; case IDS_ERR_JPG_BADDISPLAYTIME: cErrStr = ERRSTR_JPG_BADDISPLAYTIME; break; case IDS_ERR_JPG_BADURL: cErrStr = ERRSTR_JPG_BADURL; break; case IDS_ERR_JPG_BADTARGET: cErrStr = ERRSTR_JPG_BADTARGET; break; case IDS_ERR_JPG_BADRELFLAG: cErrStr = ERRSTR_JPG_BADRELFLAG; break; case IDS_ERR_JPG_BITRATEZERO: cErrStr = ERRSTR_JPG_BITRATEZERO; break; case IDS_ERR_JPG_DURATIONZERO: cErrStr = ERRSTR_JPG_DURATIONZERO; break; case IDS_ERR_JPG_DISPTIMETOOBIG: cErrStr = ERRSTR_JPG_DISPTIMETOOBIG; break; case IDS_ERR_JPG_ILLEGALTARGET: cErrStr = ERRSTR_JPG_ILLEGALTARGET; break; case IDS_ERR_JPG_BADSEEKTIME: cErrStr = ERRSTR_JPG_BADSEEKTIME; break; case IDS_ERR_JPG_UNKPLAYERCOMMAND: cErrStr = ERRSTR_JPG_UNKPLAYERCOMMAND; break; case IDS_ERR_JPG_NOTARGETBROWSER: cErrStr = ERRSTR_JPG_NOTARGETBROWSER; break; case IDS_ERR_JPG_NOPROGRESSIVE: cErrStr = ERRSTR_JPG_NOPROGRESSIVE; break; default: cErrStr = ERRSTR_JPG_GENERALERROR; break; } } if (m_pError) { m_pError->Report(HXLOG_CRIT, HXR_FAIL, 0, (const char*) cErrStr, NULL); }}HX_RESULT CJPEGFileFormat::GetResourceErrorString(UINT32 ulErrorID, CHXString& rErrorStr){ IHXExternalResourceManager* pResMgr = NULL; HX_RESULT retVal = m_pContext->QueryInterface(IID_IHXExternalResourceManager, (void**) &pResMgr); if (retVal != HXR_OK) { return retVal; } IHXExternalResourceReader* pResRdr = NULL; retVal = pResMgr->CreateExternalResourceReader(CORE_RESOURCE_SHORT_NAME, pResRdr); if (retVal != HXR_OK) { HX_RELEASE(pResMgr); return retVal; }#ifdef _WINDOWS char szDLLPath[1024]; /* Flawfinder: ignore */ GetModuleFileName((HMODULE)g_hInstance, szDLLPath, sizeof(szDLLPath)); pResRdr->SetDefaultResourceFile(szDLLPath);#endif IHXXResource* pRes = pResRdr->GetResource(HX_RT_STRING, ulErrorID); if(!pRes) { HX_RELEASE(pResRdr); HX_RELEASE(pResMgr); return HXR_FAIL; } // Assign the error string to the out parameter rErrorStr = (const char*) pRes->ResourceData(); // Release all references HX_RELEASE(pRes); HX_RELEASE(pResRdr); HX_RELEASE(pResMgr); return HXR_OK;}STDMETHODIMP_(UINT32) CJPEGFileFormat::IsThreadSafe(){ return HX_THREADSAFE_METHOD_FF_GETPACKET | HX_THREADSAFE_METHOD_FSR_READDONE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -