📄 wbmpff.cpp
字号:
if (m_ulDesiredFileOffset == m_ulFileOffset) { // Compute the number of bytes to read UINT32 ulBytesToRead = m_ulBytesPerRow * m_ulRowsPerPacket; // Set the state for a read m_ulState = kStateGetPacketReadDonePending; // Read that many bytes m_pFileObject->Read(ulBytesToRead); } else { // We need to seek, so set the state m_ulState = kStateGetPacketSeekDonePending; // Seek to the desired offset m_pFileObject->Seek(m_ulDesiredFileOffset, FALSE); } } else { // We're done, so send a stream done m_pFormatResponse->StreamDone(0); } } else { retVal = HXR_INVALID_PARAMETER; } } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::Seek(UINT32 ulOffset){ HX_RESULT retVal = HXR_OK; if (m_pFormatResponse) { // Whenever we get a Seek(), we resend all // the packets m_ulNextRow = 0; // Reset the state m_ulState = kStateReady; // Tell the format response we're ready m_pFormatResponse->SeekDone(HXR_OK); } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::Close(){ HX_RESULT retVal = HXR_OK; // Close the file if (m_pFileObject) { m_pFileObject->Close(); } HX_RELEASE(m_pContext); HX_RELEASE(m_pFileObject); HX_RELEASE(m_pFormatResponse); HX_RELEASE(m_pCommonClassFactory); HX_RELEASE(m_pFileHeader); m_ulState = kStateReady; m_ulImageWidth = 0; m_ulImageHeight = 0; m_ulHeaderSize = 0; m_ulDesiredFileOffset = 0; m_ulFileOffset = 0; m_ulBytesPerRow = 0; m_ulRowsPerPacket = 0; m_ulNextRow = 0; return retVal;}STDMETHODIMP CWBMPFileFormat::InitDone(HX_RESULT status){ HX_RESULT retVal = HXR_OK; if (m_ulState == kStateFileInitDonePending) { // Set the state m_ulState = kStateReady; // Call back to the response interface m_pFormatResponse->InitDone(status); } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::ReadDone(HX_RESULT status, IHXBuffer* pBuffer){ HX_RESULT retVal = HXR_OK; if (m_ulState == kStateFileHeaderReadDonePending) { retVal = status; if (SUCCEEDED(retVal)) { // Save the header to be send as opaque // data in the stream header HX_RELEASE(m_pFileHeader); m_pFileHeader = pBuffer; m_pFileHeader->AddRef(); // Set the file offset m_ulFileOffset = pBuffer->GetSize(); // Parse the buffer to determine type, width, height // For now, we assume that the type will be Type 0, // since that's the only one the standard currently defines. retVal = ParseWBMPHeader(pBuffer->GetBuffer(), pBuffer->GetSize(), m_ulImageWidth, m_ulImageHeight, m_ulHeaderSize); if (SUCCEEDED(retVal)) { // We assume type 0, which is 8 bits per pixel monochrome // where white = 1 and black = 0. If the width is not // a multiple of 8, then rows are padded up to a multiple // of 8. So compute how many bytes in a row. m_ulBytesPerRow = (m_ulImageWidth + 7) >> 3; // Each packet will hold an integral number of rows. // Determine how many rows per packet m_ulRowsPerPacket = kIdealPacketSize / m_ulBytesPerRow; // Create an IHXValues IHXValues* pFileHeader = NULL; retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void**) &pFileHeader); if (SUCCEEDED(retVal)) { // Set the stream count pFileHeader->SetPropertyULONG32("StreamCount", 1); // Set the state m_ulState = kStateReady; // Send the file header m_pFormatResponse->FileHeaderReady(HXR_OK, pFileHeader); } HX_RELEASE(pFileHeader); } } if (FAILED(retVal)) { // Set the state m_ulState = kStateFileHeaderCloseDonePending; // Close the file m_pFileObject->Close(); } } else if (m_ulState == kStateGetPacketReadDonePending) { retVal = status; if (SUCCEEDED(retVal)) { // Compute the number of rows in this buffer UINT32 ulNumRows = pBuffer->GetSize() / m_ulBytesPerRow; // Update the file offset m_ulFileOffset += pBuffer->GetSize(); // Create a packet buffer IHXBuffer* pPacketBuffer = NULL; retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pPacketBuffer); if (SUCCEEDED(retVal)) { // Set the size retVal = pPacketBuffer->SetSize(pBuffer->GetSize() + 4); if (SUCCEEDED(retVal)) { // Set the starting row number in the buffer // in big endian format BYTE* pBuf = pPacketBuffer->GetBuffer(); pBuf[0] = (BYTE) ((m_ulNextRow & 0xFF000000) >> 24); pBuf[1] = (BYTE) ((m_ulNextRow & 0x00FF0000) >> 16); pBuf[2] = (BYTE) ((m_ulNextRow & 0x0000FF00) >> 8); pBuf[3] = (BYTE) (m_ulNextRow & 0x000000FF); // Copy the data memcpy(pBuf + 4, pBuffer->GetBuffer(), ulNumRows * m_ulBytesPerRow); // Create a packet IHXPacket* pPacket = NULL; retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**) &pPacket); if (SUCCEEDED(retVal)) { retVal = pPacket->Set(pPacketBuffer, // opaque data 0, // time stamp 0, // stream 0 HX_ASM_SWITCH_ON, // ASM flag 0); // ASM rule if (SUCCEEDED(retVal)) { // Update the next row m_ulNextRow += ulNumRows; // Set the state m_ulState = kStateReady; // Send the packet m_pFormatResponse->PacketReady(retVal, pPacket); } } HX_RELEASE(pPacket); } } HX_RELEASE(pPacketBuffer); } if (FAILED(retVal)) { // Issue a StreamDone m_pFormatResponse->StreamDone(0); // Set the state m_ulState = kStateGetPacketCloseDonePending; // Close the file m_pFileObject->Close(); } } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::SeekDone(HX_RESULT status){ HX_RESULT retVal = HXR_OK; if (m_ulState == kStateFileHeaderSeekDonePending) { if (SUCCEEDED(status)) { // Set the state m_ulState = kStateFileHeaderReadDonePending; // Read some header bytes m_pFileObject->Read(kHeaderReadSize); } else { // Set the state m_ulState = kStateFileHeaderCloseDonePending; // Close the file m_pFileObject->Close(); } } else if (m_ulState == kStateGetPacketSeekDonePending) { if (SUCCEEDED(status)) { // Set the file offset m_ulFileOffset = m_ulDesiredFileOffset; // Compute the number of bytes to read UINT32 ulBytesToRead = m_ulBytesPerRow * m_ulRowsPerPacket; // Set the state for a read m_ulState = kStateGetPacketReadDonePending; // Read that many bytes m_pFileObject->Read(ulBytesToRead); } else { // We failed, so issue a StreamDone() m_pFormatResponse->StreamDone(0); // Set the state m_ulState = kStateGetPacketCloseDonePending; // Close the file m_pFileObject->Close(); } } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::CloseDone(HX_RESULT status){ HX_RESULT retVal = HXR_OK; if (m_ulState == kStateFileHeaderCloseDonePending) { // We can release the file object HX_RELEASE(m_pFileObject); // Set the state m_ulState = kStateReady; // The only reason we would have gotten here during // reading the file header is if we failed, so // respond that we failed m_pFormatResponse->FileHeaderReady(HXR_FAIL, NULL); } else if (m_ulState == kStateGetPacketCloseDonePending) { // We can release the file object HX_RELEASE(m_pFileObject); // Reset the state m_ulState = kStateReady; // Don't really have to do anything else, since // we have already issued a StreamDone() if we // ever encountered an error during GetPacket(). } else { retVal = HXR_UNEXPECTED; } return retVal;}STDMETHODIMP CWBMPFileFormat::WriteDone(HX_RESULT status){ // We don't ever write, so we don't expect to get this... return HXR_UNEXPECTED;}HX_RESULT STDAPICALLTYPE CWBMPFileFormat::HXCreateInstance(IUnknown** ppIUnknown){ HX_RESULT retVal = HXR_OK; if (ppIUnknown) { // Set default *ppIUnknown = NULL; // Create the object CWBMPFileFormat *pObj = new CWBMPFileFormat(); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -