⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imgdata.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        case RUNTYPE_DATATOKEN:
            // A data run takes up the amount of data in the run itself, plus
            // the length of the type and length.  Type and length are bit
            // backed together, and will take between 1 and 4 bytes to encode,
            // depending on the length.

            if (pRun->dwRunLength < (1 << 5)) {
			    dwLen += 1;

            } else if (pRun->dwRunLength < (1 << 13)) {
			    dwLen += 2;

            } else if (pRun->dwRunLength < (1 << 21)) {
			    dwLen += 3;

            } else {
			    dwLen += 4;
            }
            // Intentional Fallthrough

        case RUNTYPE_RAWDATA:
        case RUNTYPE_ZEROBLOCK:
            dwLen += pRun->dwRunLength;
            break;

        case RUNTYPE_COPYTOKEN:
            if (pRun->dwRunLength < (1 << 4)) {
			    dwLen += 4;

            } else if (pRun->dwRunLength < (1 << 12)) {
			    dwLen += 5;

            }  else if (pRun->dwRunLength < (1 << 20)) {
			    dwLen += 6;

            } else {
			    dwLen += 7;

            }

            if (m_tt.Lookup(pRun->dwOffset).iOffset != NO_COMPRESS) {
                if (m_cCompressedRegions < (1 << 8)) {
			        dwLen += 1;

                } else if (m_cCompressedRegions < (1 << 16)) {
			        dwLen += 2;

                } else {
			        dwLen += 3;

                }
            }
            break;

        case RUNTYPE_COMPRESSIONCOMMANDS:
            {
                CSectionData *pSection = (CSectionData*)pRun->dwOffset;
                dwLen += pSection->GetCountCompressionCommands() * 6 + 3;
            }
            break;

        default:
            ASSERT(0);
            break;
	}

    return dwLen;

} /* CImageData::TokenLen()
   */

////////////////////////////////////////////////////////////
// FindCompressedRegions
//   Find the regions that were compressed before
//   being packed into the image.  
////////////////////////////////////////////////////////////
HRESULT
CImageData::FindCompressedRegions()
/*---------------------------------------------------------------------------*\
 *
\*---------------------------------------------------------------------------*/
{
    HRESULT         hr      = NOERROR;
	UINT32          i;
    UINT32          j;

    m_cCompressedRegions = 0;

    //
    // Find compressed files
    //
    for (i = 0; i < m_cFiles; i++) 
    {
		FILESentry *pEntry = GetFile(i);

        CBR(pEntry);

		if ((pEntry->dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) && (pEntry->nRealFileSize > pEntry->nCompFileSize))
		{
            if (m_cCompressedRegions % NUM_COMPRESSED == 0) {
                CHR(SafeRealloc((LPVOID*)&m_pCompressedRegions, (m_cCompressedRegions + NUM_COMPRESSED) * sizeof(COMPR_RGN)));
            }
			m_pCompressedRegions[m_cCompressedRegions].iAddress = pEntry->ulLoadOffset;
			m_pCompressedRegions[m_cCompressedRegions].cBytesCompressed = pEntry->nCompFileSize;
			m_pCompressedRegions[m_cCompressedRegions].cBytesUncompressed = pEntry->nRealFileSize;
			m_cCompressedRegions++;
		}
	}

    // 
    // Find compressed sections within Modules
    //
    for(i = 0; i < m_cModules; i++) {
        o32_rom *rgO32 = GetO32List(i);
        if(rgO32) {
            e32_rom *pE32 = GetE32(i);
            CBRA(pE32);

            for(j = 0; j < pE32->e32_objcnt; j++) {
				if ((rgO32[j].o32_flags & IMAGE_SCN_COMPRESSED) &&
					(rgO32[j].o32_vsize > rgO32[j].o32_psize))
				{
                    if (m_cCompressedRegions % NUM_COMPRESSED == 0) {
                        CHR(SafeRealloc((LPVOID*)&m_pCompressedRegions, (m_cCompressedRegions + NUM_COMPRESSED) * sizeof(COMPR_RGN)));
                    }
					m_pCompressedRegions[m_cCompressedRegions].iAddress = rgO32[j].o32_dataptr;
					m_pCompressedRegions[m_cCompressedRegions].cBytesCompressed = rgO32[j].o32_psize;
					m_pCompressedRegions[m_cCompressedRegions].cBytesUncompressed = rgO32[j].o32_vsize;
					m_cCompressedRegions++;
				}
            }
        }
    }

	SortCompressedRgns(m_pCompressedRegions, m_cCompressedRegions);
	
	RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("\nCompressed regions\n")));
    for (i = 0; i < m_cCompressedRegions; ++i) {
		RETAILMSG(ZONE_PARSE_VERBOSE, (TEXT("Addr: 0x%08X, Comp: 0x%08X, Uncomp: 0x%08X\n"), 
                  m_pCompressedRegions[i].iAddress, m_pCompressedRegions[i].cBytesCompressed, m_pCompressedRegions[i].cBytesUncompressed));
    }
	
Error:
    return hr;

} /* CImageData::FindCompressedRegions()
   */

HRESULT
CImageData::GenerateDecompressedImage(CSecDiv *pSecDiv)
/*---------------------------------------------------------------------------*\
 *
\*---------------------------------------------------------------------------*/
{
    HRESULT             hr              = NOERROR;
    UCHAR*              pbBuf           = m_pbImage;
	UINT32              cLen            = m_dwImageLen;
    COMPR_CMD*          pcc             = NULL;
	UINT32				cbBufNew		= m_dwImageLen * 4;
	LPBYTE              pbBufNew        = NULL;
	LPBYTE              pbBufNewOrig;
	LPBYTE				pbBufNewEnd;
	PROMIMAGE_SECTION   pSectionHeader;
    DWORD               dwSectionCount;

typedef DWORD (*CECOMPRESS)(LPBYTE  lpbSrc, DWORD cbSrc, LPBYTE lpbDest, DWORD cbDest, WORD wStep, DWORD dwPagesize);
typedef DWORD (*CEDECOMPRESS)(LPBYTE  lpbSrc, DWORD cbSrc, LPBYTE  lpbDest, DWORD cbDest, DWORD dwSkip, WORD wStep, DWORD dwPagesize);

#define COMPRESS "compress.dll"
#define CECOMPRESSOR "CECompress"
#define CEDECOMPRESSOR "CEDecompress"

  HMODULE hcomp = LoadLibrary(COMPRESS);
  if(!hcomp){
    fprintf(stderr, "Error: LoadLibrary() failed to load '%s': %d\n", COMPRESS, GetLastError());
    CHR( hr = E_FAIL );
  }

  CEDECOMPRESS cedecompress = (CEDECOMPRESS)GetProcAddress(hcomp, CEDECOMPRESSOR);
  if(!cedecompress){
    fprintf(stderr, "Error: GetProcAddress() failed to find 'CEDecompress' in '%s': %d\n", CEDECOMPRESSOR, GetLastError());
    CHR( hr = E_FAIL );
  }

    CPR(pbBufNew = (LPBYTE)LocalAlloc(LMEM_FIXED, cbBufNew));
    pbBufNewOrig = pbBufNew;
	pbBufNewEnd  = pbBufNewOrig + cbBufNew;

	CHR(FindCompressedRegions());
	
	pSectionHeader = m_pFirstSection;
    dwSectionCount = 0;

	while (pSectionHeader->Address || (!pSectionHeader->Address && pSectionHeader->CheckSum))
	{
    	UINT32      cBytesUncompressedTotal  = 0;
		UINT32      cComprRgnsSec            = 0;
		UINT32      cComprRgnsSecMax         = 0;
		UINT32      cBytesUncompressed;
        UINT32      cBytesCompressed;
		UINT32      iRgn    = 0;
		UINT32      iOffset = 0;
		ADDRESS     addr;

        ASSERT(pcc == NULL);

		pbBuf = DataFromSection(pSectionHeader);

        CHR(m_pSectionDataList[dwSectionCount].SetUncompressedDataPtr(pbBufNew));

        if(m_cCompressedRegions > 0) 
        {
            while ((iRgn < m_cCompressedRegions - 1) && (m_pCompressedRegions[iRgn].iAddress < pSectionHeader->Address)) {
			        ++iRgn;
            }
        }

		while (iOffset < pSectionHeader->Size)
		{
            UINT32 uAddr = pSectionHeader->Address + iOffset;
  			if ((m_cCompressedRegions > 0) && uAddr == m_pCompressedRegions[iRgn].iAddress)
  			{
                addr.iAddr = iRgn;
  				addr.iOffset = 0;

  				CHR(m_tt.Insert(pbBufNew - pbBufNewOrig, addr));

  				cBytesCompressed = m_pCompressedRegions[iRgn].cBytesCompressed;
  				cBytesUncompressed = cedecompress(pbBuf + iOffset, cBytesCompressed, pbBufNew, pbBufNewEnd - pbBufNew, 0, 1, 0x1000);
  				
                  CBRA(cBytesUncompressed != CEDECOMPRESS_FAILED);

                  RETAILMSG(ZONE_DECOMPRESS, (TEXT("  %u bytes decompressed to %u\n"), cBytesCompressed, cBytesUncompressed));

  				pbBufNew += cBytesUncompressed;

  				++iRgn;
  			}
  			else
  			{
                addr.iAddr = uAddr;
                addr.iOffset = NO_COMPRESS;

  				CHR(m_tt.Insert(pbBufNew - pbBufNewOrig, addr));
  				
                if(m_cCompressedRegions > 0) 
                {
    				cBytesUncompressed = cBytesCompressed = min(pSectionHeader->Size, m_pCompressedRegions[iRgn].iAddress - pSectionHeader->Address) - iOffset;
                } else 
                {
    				cBytesUncompressed = cBytesCompressed = pSectionHeader->Size - iOffset;
                }
          
				// Check to make sure we won't go off the end of the buffer
				CBRA((pbBufNew + cBytesCompressed)<pbBufNewEnd);

  				memcpy(pbBufNew, pbBuf + iOffset, cBytesCompressed);

  				pbBufNew += cBytesCompressed;
  			}

			if (cComprRgnsSec == cComprRgnsSecMax) {
				cComprRgnsSecMax += NUM_COMPRESSED_SCN;
                CHR(SafeRealloc((LPVOID*)&pcc, cComprRgnsSecMax * sizeof(COMPR_CMD)));
			}
			pcc[cComprRgnsSec].cBytesCompressed = cBytesCompressed;
			pcc[cComprRgnsSec].cBytesUncompressed = cBytesUncompressed;
			++cComprRgnsSec;

            iOffset += cBytesCompressed;
            cBytesUncompressedTotal += cBytesUncompressed;

            if(pSecDiv) {
                CHR(pSecDiv->Add(pbBufNew));
				*pbBufNew++ = SEC_DIV_CHAR;
            }
		}

        CHR(m_pSectionDataList[dwSectionCount].SetUncompressedSize(cBytesUncompressedTotal));
        CHR(m_pSectionDataList[dwSectionCount].SetCompressionCommands(pcc, cComprRgnsSec));

        // Handed off to the SectionData List...
        pcc = NULL;

		m_cbLargestUncompressedSection = max(m_cbLargestUncompressedSection, cBytesUncompressedTotal);

		pSectionHeader = NextSection(pSectionHeader);
        dwSectionCount++;
	}

    ASSERT(dwSectionCount == m_cSections);

	m_cbUncompressedImage = pbBufNew - pbBufNewOrig;
    RETAILMSG(ZONE_VERBOSE, (TEXT("Size of uncompressed image: %u\n"), m_cbUncompressedImage));

    m_pbUncompressedImage = pbBufNewOrig;
    pbBufNewOrig = NULL;

    CHR(SafeRealloc((LPVOID*)&m_pbUncompressedImage, m_cbUncompressedImage));

Error:
    LocalFree(pcc);
    LocalFree(pbBufNewOrig);

	if (FAILED(hr))
	{
		fprintf(stderr, "Error: GenerateDecompressedImage failed : 0x%x\n", hr);
	}
	return hr;

} /* CImageData::GenerateDecompressedImage()
   */


HRESULT
CImageData::FindDataPtr(DWORD dwVirtualAddr, DWORD dwLen, 
                        CSectionData **ppSection, LPBYTE *ppbData)
/*---------------------------------------------------------------------------*\
 * Find some data within the image...
 *      dwVirtualAddr       - Virtual address that we're looking for.  This is 
 *                            a real address in flash, which means that it's 
 *                            a "compressed" address.  This is an address that
 *                            you could actually go read from flash.  
 *                            If you need the address of some uncompressed data
 *                            You have to call this function with the base 
 *                            address of the compression block and offset into
 *                            it the appropriate amount.
 *      dwLen               - Length of the data section.  Note that the entire
 *                            data section must be either compressed or 
 *                            uncompressed and can not cross a section boundary.
 *                            If the data is compressed, this is the COMPRESSED
 *                            length of the data.
 *      ppbData             - return pointer for the address in memory.
\*---------------------------------------------------------------------------*/
{
    HRESULT         hr          = NOERROR;
    int             i, j;  
    DWORD           dwAddr;
    LPBYTE          pb;

    ASSERT(ppSection);
    ASSERT(ppbData);

    for(i = 0; i < m_cSections; i++) {
        CSectionData *pSection = GetSection(i);
        ROMIMAGE_SECTION *pSectionHdr = pSection->GetSectionHeader();
        
        if( dwVirtualAddr >= pSectionHdr->Address && 
            dwVirtualAddr + dwLen <= pSectionHdr->Address + pSectionHdr->Size)
        {
            // It's in here somewhere... Now we have to see if it was compressed...
            dwAddr = pSectionHdr->Address;
            pb = pSection->GetUncompressedDataPtr();

            if(pSection->GetCountCompressionCommands()) {
                for(j = 0; j < pSection->GetCountCompressionCommands(); j++) {
                    COMPR_CMD *pCmd = pSection->GetCompressionCommand(j);

                    if(dwVirtualAddr >= dwAddr && dwVirtualAddr + dwLen <= dwAddr + pCmd->cBytesCompressed) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -