📄 pxpngff.cpp
字号:
{ // Get an IHXBuffer interface from the IHXFragmentedBuffer HX_RELEASE(m_pFileBuffer); retVal = m_pFragBuffer->QueryInterface(IID_IHXBuffer, (void**) &m_pFileBuffer); if (SUCCEEDED(retVal)) { // Now we can release the IHXFragmentedBuffer interface HX_RELEASE(m_pFragBuffer); // Set state m_ulState = kStateFileClosePending; // Close the file m_pFileObject->Close(); } } else { retVal = HXR_FAIL; } } else { // Set state m_ulState = kStateFileReadPending; // Read some more m_pFileObject->Read(kReadSize); } } if (FAILED(retVal)) { m_pFormatResponse->InitDone(retVal); } } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP PXPNGFileFormat::SeekDone(HX_RESULT status){ return HXR_UNEXPECTED;}STDMETHODIMP PXPNGFileFormat::CloseDone(HX_RESULT status){ HX_RESULT retVal = HXR_OK; if (m_ulState == kStateFileClosePending) { // Get the width and height out of the IHDR chunk if (PXPNGDecode::GetIHDRInfo(m_pFileBuffer, m_ulImageWidth, m_ulImageHeight)) { // Now we have the entire file, so first we determine the number // of packets. We do this by finding the beginning of the first // IDAT chunk. UINT32 ulOffset = 0; UINT32 ulBytes = 0; BOOL bComplete = FALSE; BOOL bPresent = PXPNGDecode::IsChunkPresent(m_pFileBuffer, 0x49444154, // IDAT chunk ulOffset, ulBytes, bComplete); if (bPresent && bComplete) { UINT32 ulFirstBufferSize = 0; if (ulOffset + kMinIDATBytes > kDefaultPacketSize) { // Since the size of the all the chunks before the IDAT is // greater than the ideal packet size, then we'll just do // the minimum here. ulFirstBufferSize = ulOffset + kMinIDATBytes; } else { // Since the size of all the chunks before the IDAT is // LESS than the ideal packet size, we'll allow some of // the IDAT chunk into the first packet. ulFirstBufferSize = kDefaultPacketSize; if (ulFirstBufferSize > m_pFileBuffer->GetSize()) { ulFirstBufferSize = m_pFileBuffer->GetSize(); } } // Add the first packet buffer m_ulNumPacketBuffers = 1; // Add all the rest of the packets past the first m_ulNumPacketBuffers += (m_pFileBuffer->GetSize() - ulFirstBufferSize + kDefaultPacketSize - 1) / kDefaultPacketSize; // So now that we know how many packets we'll have, we // can allocate the array of IHXBuffer pointers to hold // them. HX_VECTOR_DELETE(m_ppPacketBuffer); m_ppPacketBuffer = new IHXBuffer* [m_ulNumPacketBuffers]; if (m_ppPacketBuffer) { // Init the statistics m_ulMaxPacketSize = 0; m_ulAvgPacketSize = 0; // Now run through and create the buffers UINT32 ulCurOffset = 0; UINT32 ulCurSize = ulFirstBufferSize; for (UINT32 i = 0; i < m_ulNumPacketBuffers && SUCCEEDED(retVal); i++) { // Create a nested buffer CHXNestedBuffer* pNest = NULL; retVal = CHXNestedBuffer::CreateObject(&pNest); if (SUCCEEDED(retVal)) { // AddRef the object pNest->AddRef(); // Init the nested buffer retVal = pNest->Init(m_pFileBuffer, ulCurOffset, ulCurSize); if (SUCCEEDED(retVal)) { // QI for IHXBuffer IHXBuffer* pData = NULL; retVal = pNest->QueryInterface(IID_IHXBuffer, (void**) &pData); if (SUCCEEDED(retVal)) { // Update the statistics if (ulCurSize > m_ulMaxPacketSize) { m_ulMaxPacketSize = ulCurSize; } m_ulAvgPacketSize += ulCurSize; // Update the current offset and size ulCurOffset += ulCurSize; ulCurSize = kDefaultPacketSize; if (ulCurOffset + ulCurSize > m_pFileBuffer->GetSize()) { ulCurSize = m_pFileBuffer->GetSize() - ulCurOffset; } // Put it in the array m_ppPacketBuffer[i] = pData; m_ppPacketBuffer[i]->AddRef(); } HX_RELEASE(pData); } } HX_RELEASE(pNest); } // Compute the avg m_ulAvgPacketSize = (m_ulAvgPacketSize + (m_ulNumPacketBuffers >> 1)) / m_ulNumPacketBuffers; m_ulTotalBytesToSend = m_pFileBuffer->GetSize(); // Now we can release the file buffer, since all the // nested buffers have refs on it HX_RELEASE(m_pFileBuffer); // Set the state m_ulState = (SUCCEEDED(retVal) ? kStateFileFormatInitialized : kStateError); // Callback to the response interface m_pFormatResponse->InitDone(retVal); } else { retVal = HXR_OUTOFMEMORY; } } else { retVal = HXR_FAIL; } } else { retVal = HXR_FAIL; } } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP PXPNGFileFormat::WriteDone(HX_RESULT status){ // We don't ever write, so we don't expect to get this... return HXR_UNEXPECTED;}HX_RESULT STDAPICALLTYPE PXPNGFileFormat::HXCreateInstance(IUnknown** ppIUnknown){ HX_RESULT retVal = HXR_OK; if (ppIUnknown) { // Set default *ppIUnknown = NULL; // Create the object PXPNGFileFormat *pObj = new PXPNGFileFormat(); if (pObj) { // QI for IUnknown retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown); } else { retVal = HXR_OUTOFMEMORY; } if (FAILED(retVal)) { HX_DELETE(pObj); } } else { retVal = HXR_FAIL; } return HXR_OK;}void PXPNGFileFormat::Deallocate(){ for (UINT32 i = 0; i < m_ulNumPacketBuffers; i++) { HX_RELEASE(m_ppPacketBuffer[i]); } HX_RELEASE(m_pContext); HX_RELEASE(m_pFileObject); HX_RELEASE(m_pFormatResponse); HX_RELEASE(m_pCommonClassFactory); HX_RELEASE(m_pRequest); HX_RELEASE(m_pFragBuffer); HX_RELEASE(m_pFileBuffer); HX_VECTOR_DELETE(m_ppPacketBuffer); HX_RELEASE(m_pURLStr); Reset();}void PXPNGFileFormat::Reset(){ m_pContext = NULL; m_pFileObject = NULL; m_pFormatResponse = NULL; m_pCommonClassFactory = NULL; m_pRequest = NULL; m_pFragBuffer = NULL; m_ulNumBytesRead = 0; m_pFileBuffer = NULL; m_ulNumPacketBuffers = 0; m_ppPacketBuffer = NULL; m_ulState = kStateConstructed; m_ulDuration = kDefaultDuration; m_ulBitrate = kDefaultBitrate; m_ulImageWidth = 0; m_ulImageHeight = 0; m_pURLStr = NULL; m_bReliable = FALSE; m_ulTotalBytesToSend = 0; m_ulMaxPacketSize = 0; m_ulAvgPacketSize = 0; m_ulBackgroundColor = 0; m_ulNextPacketIndex = 0;}void PXPNGFileFormat::GetURLOrRequestOptions(IHXRequest* pRequest, REF(UINT32) rulDuration, REF(UINT32) rulBitrate, REF(IHXBuffer*) rpURLStr, REF(BOOL) rbReliable, REF(UINT32) rulBackgroundColor){ if (pRequest && m_pContext && m_pCommonClassFactory) { // Create an IHXValues object to hold the param name/value pairs IHXValues *pValues = NULL; m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void**) &pValues); if (pValues) { // Now add the following parameters to the IHXValues. These // parameters could have come as URL-encoded parameters or as // parameters in the request headers. These parameters will be // added as CString properties to the IHXValues. AddURLOrRequestParam(pRequest, "duration", m_pContext, pValues); AddURLOrRequestParam(pRequest, "bitrate", m_pContext, pValues); AddURLOrRequestParam(pRequest, "url", m_pContext, pValues); AddURLOrRequestParam(pRequest, "reliable", m_pContext, pValues); AddURLOrRequestParam(pRequest, "bgcolor", m_pContext, pValues); // Set the bitrate ExtractValueUINT32(pValues, "bitrate", kDefaultBitrate, rulBitrate); // Set the duration ExtractValueTime(pValues, "duration", kDefaultDuration, rulDuration); // Set the URL HX_RELEASE(rpURLStr); pValues->GetPropertyCString("url", rpURLStr); // Set the background color IHXBuffer* pTmp = NULL; pValues->GetPropertyCString("bgcolor", pTmp); if (pTmp) { HXParseColorUINT32((const char*) pTmp->GetBuffer(), rulBackgroundColor); } HX_RELEASE(pTmp); // Set the reliable flag ExtractValueBOOL(pValues, "reliable", FALSE, rbReliable); } // Release the IHXValues object HX_RELEASE(pValues); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -