📄 jpegvsrc.cpp
字号:
ret = m_pViewSourceResponse->SourceReady(ret, NULL); } } else { m_state = kStateReady; ret = m_pViewSourceResponse->SourceReady(status, NULL); } return ret;}/************************************************************************ * Method: * IHXFileResponse::InitDone * Purpose: * Notification interface provided by users of the IHXFileObject * interface. This method is called by the IHXFileObject when the * initialization of the file is complete. */STDMETHODIMPCJPEGViewSource::InitDone( HX_RESULT status ){ if ( m_state != kStateInitFilePending ) { return HXR_UNEXPECTED; } HX_ASSERT(m_pViewSourceResponse != NULL); m_state = kStateReady; return m_pViewSourceResponse->InitDone(status);}/************************************************************************ * Method: * IHXFileResponse::ReadDone * Purpose: * Notification interface provided by users of the IHXFileObject * interface. This method is called by the IHXFileObject when the * last read from the file is complete and a buffer is available. */STDMETHODIMPCJPEGViewSource::ReadDone(HX_RESULT status, IHXBuffer* pBuffer){ if ( m_state != kStateReadPending ) { return HXR_UNEXPECTED; } HX_RESULT result = HXR_OK; HX_ASSERT(m_pViewSourceResponse != NULL); if ( SUCCEEDED(status) ) { // Append the buffer to the fragmented buffer result = m_pFragFileBuffer->Append(pBuffer, 0, pBuffer->GetSize()); m_ulNumBytesRead += pBuffer->GetSize(); if (SUCCEEDED(result)) { // We will parse this buffer. The majority of JPEGs will have // all the info we need in the first 1k so we will end here. // There are some though that might go longer. So if our parse // fails, we will grab another 2k of the file until we are // successful // IHXBuffer* pBuf = NULL; result = m_pFragFileBuffer->QueryInterface(IID_IHXBuffer, (void**)&pBuf); if ( SUCCEEDED(result) ) { JPEGResult jret = ParseForJPEGInfo(pBuf); if ( jret == kHeaderFound ) { IHXBuffer* pReturnBuffer = NULL; result = CreateInfoBuffer(pBuf, pReturnBuffer); if ( SUCCEEDED(result) ) { m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(HXR_OK, pReturnBuffer); } else { m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(result, NULL); } HX_RELEASE(pReturnBuffer); } else if ( jret == kNotJPEG ) { // not a valid JPEG.... m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(HXR_FAIL, NULL); } else if ( jret == kNoSuccess ) { // No, we haven't reached the end of the header yet... // we need to do another read. m_state = kStateReadPending; result = m_pFileObject->Read(2048); } else { HX_ASSERT(FALSE); } } else { m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(result, NULL); } HX_RELEASE(pBuf); } else { m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(result, NULL); } } else { // We should never get here with a valid file... So we will return // an error. It means that the file must not be a jpeg. // Becase we check the entire amount read after each read, we // will have allready checked the entire file... m_state = kStateReady; result = m_pViewSourceResponse->SourceReady(status, NULL); } return result;}/************************************************************************ * Method: * IHXFileResponse::WriteDone * Purpose: * Notification interface provided by users of the IHXFileObject * interface. This method is called by the IHXFileObject when the * last write to the file is complete. */STDMETHODIMPCJPEGViewSource::WriteDone(HX_RESULT status){ // We don't ever write, so we don't expect to get this... return HXR_UNEXPECTED;}/************************************************************************ * Method: * IHXFileResponse::SeekDone * Purpose: * Notification interface provided by users of the IHXFileObject * interface. This method is called by the IHXFileObject when the * last seek in the file is complete. */STDMETHODIMPCJPEGViewSource::SeekDone(HX_RESULT status){ return HXR_UNEXPECTED;}/************************************************************************ * Method: * IHXFileResponse::CloseDone * Purpose: * Notification interface provided by users of the IHXFileObject * interface. This method is called by the IHXFileObject when the * close of the file is complete. */STDMETHODIMPCJPEGViewSource::CloseDone(HX_RESULT status){ return HXR_OK;}/************************************************************************ * Method: * CJPEGViewSource::CreateInfoBuffer */STDMETHODIMP CJPEGViewSource::CreateInfoBuffer(IHXBuffer* pFileBuf, REF(IHXBuffer*) pBuffer){ char buf[128]; /* Flawfinder: ignore */ CBigByteGrowingQueue queue(INITIAL_QUEUESIZE); queue.EnQueue(z_pOpen); sprintf(buf, z_pImage_ss, z_pJPEGGif, z_pJPEGGif); /* Flawfinder: ignore */ queue.EnQueue(buf); queue.EnQueue(z_pImageType); queue.EnQueue(" JPEG Image"); queue.EnQueue(z_pEndLine); queue.EnQueue(z_pFileName); const char* pFileName; m_pFileObject->GetFilename(pFileName); queue.EnQueue(pFileName); queue.EnQueue(z_pEndLine); QueueModificationTime(&queue, m_ulModTime); QueueFileSize(&queue, m_ulFileSize); sprintf(buf, z_pImageDimen_ii, m_ulWidth, m_ulHeight); /* Flawfinder: ignore */ queue.EnQueue(buf); queue.EnQueue(z_pEndLine); sprintf(buf, z_pJPEGComponents_i, m_ulNumComponents); /* Flawfinder: ignore */ queue.EnQueue(buf); queue.EnQueue(z_pEndLine); queue.EnQueue(z_pJPEGProgressive); if ( m_bProgressive ) { queue.EnQueue("YES"); } else { queue.EnQueue("NO"); } queue.EnQueue(z_pEndLine); IHXBuffer* pRam = NULL; IHXBuffer* pCD = NULL; if (m_pViewSourceOptions && SUCCEEDED(m_pViewSourceOptions->GetPropertyCString("RamGenURL", pRam)) && SUCCEEDED(m_pViewSourceOptions->GetPropertyCString("CurrentPath", pCD)) ) { queue.EnQueue(z_pRamLink); queue.EnQueue("<a href =\""); queue.EnQueue((const char*)pRam->GetBuffer()); const char* p = (const char*)pCD->GetBuffer(); if ( *p == '/' ) { p++; } queue.EnQueue(p); queue.EnQueue("/"); const char* pFileName; m_pFileObject->GetFilename(pFileName); queue.EnQueue(pFileName); queue.EnQueue("\">"); queue.EnQueue((const char*)pRam->GetBuffer()); queue.EnQueue(p); queue.EnQueue("/"); queue.EnQueue(pFileName); queue.EnQueue("</a>"); queue.EnQueue(z_pEndLine); } HX_RELEASE(pRam); HX_RELEASE(pCD); queue.EnQueue((void*)z_pClose, strlen(z_pClose)); HX_RELEASE(pBuffer); m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, (void**)&pBuffer); if ( !pBuffer ) { return HXR_OUTOFMEMORY; } pBuffer->SetSize(queue.GetQueuedItemCount()); unsigned char* chr = pBuffer->GetBuffer(); queue.DeQueue(chr, queue.GetQueuedItemCount()); return HXR_OK;}CJPEGViewSource::JPEGResult CJPEGViewSource::ParseForJPEGInfo(IHXBuffer* pFileBuf){ JPEGResult jret = kNoSuccess; HX_ASSERT(pFileBuf != NULL); enum {kMarkerSOF0 = 0xC0, kMarkerSOF1 = 0xC1, kMarkerSOF2 = 0xC2, kMarkerDHT = 0xC4, kMarkerRST0 = 0xD0, kMarkerRST1 = 0xD1, kMarkerRST2 = 0xD2, kMarkerRST3 = 0xD3, kMarkerRST4 = 0xD4, kMarkerRST5 = 0xD5, kMarkerRST6 = 0xD6, kMarkerRST7 = 0xD7, kMarkerSOI = 0xD8, kMarkerEOI = 0xD9, kMarkerSOS = 0xDA, kMarkerDQT = 0xDB, kMarkerDRI = 0xDD, kMarkerAPP0 = 0xE0, kMarkerTEM = 0x01}; // Now parse the file buffer BOOL bHeaderComplete = FALSE; BYTE *pCurByte = pFileBuf->GetBuffer(); BYTE *pBufLimit = pCurByte + pFileBuf->GetSize(); 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]; if (ucMarker == kMarkerAPP0) { // We look at this marker to verify this is a JFIF image file if (pCurByte[0] != 0x00 || pCurByte[1] != 0x10 || pCurByte[2] != 'J' || pCurByte[3] != 'F' || pCurByte[4] != 'I' || pCurByte[5] != 'F' || pCurByte[6] != '\0') { return kNotJPEG; } } else if (ucMarker == kMarkerSOF0 ) { m_bProgressive = FALSE; // We look at this marker to extract the width and height m_ulHeight = (pCurByte[3] << 8) | pCurByte[4]; m_ulWidth = (pCurByte[5] << 8) | pCurByte[6]; m_ulNumComponents = pCurByte[7]; } else if ( ucMarker == kMarkerSOF1 || ucMarker == kMarkerSOF2 ) { m_bProgressive = TRUE; // We look at this marker to extract the width and height m_ulHeight = (pCurByte[3] << 8) | pCurByte[4]; m_ulWidth = (pCurByte[5] << 8) | pCurByte[6]; m_ulNumComponents = pCurByte[7]; } else if (ucMarker == kMarkerSOS) { // This marker is the last marker in the header jret = kHeaderFound; bHeaderComplete = TRUE; } // Advance the pointer pCurByte += ulSegLen; } } } return jret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -