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

📄 compositefile.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
字号:
#include "stdafx.h"
#include "globals.h"
#include "CompositeFile.h"
#include "ZLib/zlib.h"


#define CPC_PKFILE_MAGIC		0x04034B50
#define CPC_PKFILE_DIRMAGIC		0x02014B50
#define CPC_PKFILE_BITS_ENCRYPTED		0x1
#define CPC_PKFILE_BITS_STREAMED		0x8
//
#define CPC_PKFILE_METHOD_STORED		0x0
#define CPC_PKFILE_METHOD_DEFLATED		0x8
//
#pragma pack(push, 1)
typedef struct _CPs_PKFILE_HEADER
{
    DWORD m_dwSig;
    WORD m_wVersion;
    WORD m_wBITs;
    WORD m_wMethod;
    WORD m_wModifyTime;
    WORD m_wModifyDate;
    DWORD m_dwCRC32;
    DWORD m_dwCompressedSize;
    DWORD m_dwDecompressedSize;
    WORD m_wFilenameLen;
    WORD m_wExtraFieldLen;
} CPs_PKFILE_HEADER;
//
typedef struct _CPs_PKFILE_DESCRIPTOR
{
    DWORD m_dwCRC32;
    DWORD m_dwCompressedSize;
    DWORD m_dwDecompressedSize;

} CPs_PKFILE_DESCRIPTOR;
#pragma pack(pop)
//

typedef struct _CPs_SubFile
{
    char* m_pcName;
    DWORD m_dwCRC32;
    unsigned int m_iFileOffset;
    unsigned int m_iCompressedSize;
    unsigned int m_iUncompressedSize;
    WORD m_wMethod;

    void* m_pNext;

} CPs_SubFile;
//
typedef struct _CPs_CompositeContext
{
    HANDLE m_hFileMapping;
    BYTE* m_pFileBase;
    DWORD m_dwFileSize;
    BOOL m_bMemMappedFile;

    CPs_SubFile* m_pFirstSubFile;

} CPs_CompositeContext;

//
#define CPM_GET_BYTE(offset) (*(BYTE*)(pContext->m_pFileBase + (offset++) ))
#define CPM_GET_WORD(offset) (*(WORD*)(pContext->m_pFileBase + (offset+=2) - 2))
#define CPM_GET_DWORD(offset) (*(DWORD*)(pContext->m_pFileBase + (offset+=4) - 4))

BOOL CP_BuildDirectory(CP_COMPOSITEFILE hComposite);
const CPs_SubFile* CP_FindFile(CP_COMPOSITEFILE hComposite, const char* pcFilename);

CP_COMPOSITEFILE CF_Create_FromFile(const char* pcPath)
{
    CPs_CompositeContext* pContext;
    HANDLE hFile;
    DWORD dwFileSize;

    hFile = CreateFile(pcPath,
                       GENERIC_READ,
                       FILE_SHARE_READ,
                       NULL,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
    if(hFile == INVALID_HANDLE_VALUE)
        return NULL;

    dwFileSize = GetFileSize(hFile, NULL);
    if(dwFileSize > 0x00800000 )
    {
        CloseHandle(hFile);
        return NULL;
    }

    pContext = (CPs_CompositeContext*)malloc(sizeof(CPs_CompositeContext));
    pContext->m_dwFileSize = dwFileSize;
    pContext->m_hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    CloseHandle(hFile);
    if(pContext->m_hFileMapping == INVALID_HANDLE_VALUE)
    {
        free(pContext);
        return NULL;
    }
    pContext->m_pFileBase = (BYTE*)MapViewOfFile(pContext->m_hFileMapping, FILE_MAP_READ, 0, 0, 0);
    if(!pContext->m_pFileBase)
    {
        CloseHandle(pContext->m_hFileMapping);
        free(pContext);
        return NULL;
    }

    if(CP_BuildDirectory(pContext) == FALSE)
    {
        CF_Destroy(pContext);
        return NULL;
    }

    return pContext;
}
//

CP_COMPOSITEFILE CF_Create_FromResource(HMODULE hModule, UINT uiResourceID, const char* pcResourceType)
{
    CPs_CompositeContext* pContext;
    HRSRC hResource;
    HGLOBAL hResourceData;

    hResource = FindResource(hModule, MAKEINTRESOURCE(uiResourceID), pcResourceType);
    CP_ASSERT(hResource);
    hResourceData = LoadResource(hModule, hResource);
    CP_ASSERT(hResourceData);

    pContext = (CPs_CompositeContext*)malloc(sizeof(CPs_CompositeContext));
    pContext->m_dwFileSize = SizeofResource(hModule, hResource);
    pContext->m_hFileMapping = NULL;
    pContext->m_pFileBase = LockResource(hResourceData);

    if(CP_BuildDirectory(pContext) == FALSE)
    {
        CF_Destroy(pContext);
        return NULL;
    }

    // Success
    return pContext;
}
//

void CF_Destroy(CP_COMPOSITEFILE hComposite)
{
    CPs_CompositeContext* pContext = (CPs_CompositeContext*)hComposite;
    CPs_SubFile* pSubFile_Cursor;
    CPs_SubFile* pSubFile_Next;
    CP_CHECKOBJECT(pContext);

    if(pContext->m_hFileMapping)
    {
        UnmapViewOfFile(pContext->m_pFileBase);
        CloseHandle(pContext->m_hFileMapping);
    }

    for(pSubFile_Cursor = pContext->m_pFirstSubFile; pSubFile_Cursor; pSubFile_Cursor = pSubFile_Next)
    {
        pSubFile_Next = (CPs_SubFile*)pSubFile_Cursor->m_pNext;
        free(pSubFile_Cursor->m_pcName);
        free(pSubFile_Cursor);
    }

    free(pContext);
}
//

BOOL CF_GetSubFile(CP_COMPOSITEFILE hComposite, const char* pcSubfilename, void** ppSubFile_Uncompressed, unsigned int* piSubFile_Length)
{
    CPs_CompositeContext* pContext = (CPs_CompositeContext*)hComposite;
    const CPs_SubFile* pSubFile;
    DWORD dwCRC32;
    CP_CHECKOBJECT(pContext);

    pSubFile = CP_FindFile(hComposite, pcSubfilename);
    if(!pSubFile)
    {
        *ppSubFile_Uncompressed = NULL;
        *piSubFile_Length = 0;
        return FALSE;
    }

    *ppSubFile_Uncompressed = malloc(pSubFile->m_iUncompressedSize);
    *piSubFile_Length = pSubFile->m_iUncompressedSize;

    if(pSubFile->m_wMethod == CPC_PKFILE_METHOD_STORED)
    {
        memcpy(*ppSubFile_Uncompressed, pContext->m_pFileBase + pSubFile->m_iFileOffset, *piSubFile_Length);
    }
    else if(pSubFile->m_wMethod == CPC_PKFILE_METHOD_DEFLATED)
    {
        z_stream zStream;

        zStream.zalloc = Z_NULL;
        zStream.zfree = Z_NULL;
        zStream.opaque = Z_NULL;
        zStream.data_type = Z_BINARY;
        inflateInit2(&zStream, -15);	

        zStream.next_out = (BYTE*)*ppSubFile_Uncompressed;
        zStream.avail_out = *piSubFile_Length;
        zStream.next_in = pContext->m_pFileBase + pSubFile->m_iFileOffset;
        zStream.avail_in = pSubFile->m_iCompressedSize;
        inflate(&zStream, Z_FINISH);

        inflateEnd(&zStream);
    }

    dwCRC32 = crc32(0, *ppSubFile_Uncompressed, *piSubFile_Length);
    if(dwCRC32 != pSubFile->m_dwCRC32)
    {
        free(*ppSubFile_Uncompressed);
        *ppSubFile_Uncompressed = NULL;
        *piSubFile_Length = 0;
        return FALSE;
    }

    return TRUE;
}

BOOL CP_BuildDirectory(CP_COMPOSITEFILE hComposite)
{
    CPs_CompositeContext* pContext = (CPs_CompositeContext*)hComposite;
    unsigned int iOffset;
    CP_CHECKOBJECT(pContext);

    pContext->m_pFirstSubFile = NULL;

    iOffset = 0;
    while( ((iOffset + sizeof(CPs_PKFILE_HEADER)) < pContext->m_dwFileSize)
            && *(DWORD*)(pContext->m_pFileBase + iOffset) != CPC_PKFILE_DIRMAGIC)
    {
        CPs_PKFILE_HEADER* pHeader = (CPs_PKFILE_HEADER*)(pContext->m_pFileBase + iOffset);
        CPs_SubFile* pNewSubFile;

        if(pHeader->m_dwSig != CPC_PKFILE_MAGIC
                || (pHeader->m_wBITs & CPC_PKFILE_BITS_ENCRYPTED)
                || (pHeader->m_wBITs & CPC_PKFILE_BITS_STREAMED)
                || (pHeader->m_wMethod != CPC_PKFILE_METHOD_STORED && pHeader->m_wMethod != CPC_PKFILE_METHOD_DEFLATED) )
        {
            CP_TRACE0("ZIP format not understood");
            return FALSE;
        }

        pNewSubFile = (CPs_SubFile*)malloc(sizeof(*pNewSubFile));
        pNewSubFile->m_pNext = pContext->m_pFirstSubFile;
        pContext->m_pFirstSubFile = pNewSubFile;

        pNewSubFile->m_pcName = (char*)malloc(pHeader->m_wFilenameLen + 1);
        memcpy(pNewSubFile->m_pcName, pContext->m_pFileBase + iOffset + sizeof(*pHeader), pHeader->m_wFilenameLen);
        pNewSubFile->m_pcName[pHeader->m_wFilenameLen] = '\0';
        pNewSubFile->m_wMethod = pHeader->m_wMethod;
        pNewSubFile->m_dwCRC32 = pHeader->m_dwCRC32;
        pNewSubFile->m_iCompressedSize = pHeader->m_dwCompressedSize;
        pNewSubFile->m_iUncompressedSize = pHeader->m_dwDecompressedSize;
        pNewSubFile->m_iFileOffset = iOffset + sizeof(*pHeader) + pHeader->m_wFilenameLen + pHeader->m_wExtraFieldLen;
        CP_TRACE1("SubFile:\"%s\"", pNewSubFile->m_pcName);

        iOffset += sizeof(*pHeader)
                   + pHeader->m_dwCompressedSize
                   + pHeader->m_wFilenameLen
                   + pHeader->m_wExtraFieldLen;
    }


    return TRUE;
}

const CPs_SubFile* CP_FindFile(CP_COMPOSITEFILE hComposite, const char* pcFilename)
{
    CPs_CompositeContext* pContext = (CPs_CompositeContext*)hComposite;
    const CPs_SubFile* pSubFile_Cursor;
    CP_CHECKOBJECT(pContext);

    for(pSubFile_Cursor = pContext->m_pFirstSubFile; pSubFile_Cursor; pSubFile_Cursor = (const CPs_SubFile*)pSubFile_Cursor->m_pNext)
    {
        if(stricmp(pSubFile_Cursor->m_pcName, pcFilename) == 0)
            return pSubFile_Cursor;
    }

    return NULL;
}

⌨️ 快捷键说明

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