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

📄 ppmd.cpp

📁 PPMd压缩方式的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    "\t\t-r1 - cut off model (slow)\n"
    "\t\t-r2 - freeze model (dangerous)\n"
};
template <class T>
inline T CLAMP(const T& X,const T& LoX,const T& HiX) { return (X >= LoX)?((X <= HiX)?(X):(HiX)):(LoX); }
template <class T>
inline void SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }

void _STDCALL PrintInfo(_PPMD_FILE* DecodedFile,_PPMD_FILE* EncodedFile)
{
    char WrkStr[320];
    UINT NDec=ftell(DecodedFile);
    NDec += (NDec == 0);
    UINT NEnc=ftell(EncodedFile)-StartFilePosition;
    UINT n1=(8U*NEnc)/NDec;
    UINT n2=(100U*(8U*NEnc-NDec*n1)+NDec/2U)/NDec;
    if (n2 == 100) { n1++;                  n2=0; }
    int RunTime=((clock()-StartClock) << 10)/int(CLK_TCK);
    UINT Speed=NDec/(RunTime+(RunTime == 0));
    UINT UsedMemory=GetUsedMemory() >> 10;
    UINT m1=UsedMemory >> 10;
    UINT m2=(10U*(UsedMemory-(m1 << 10))+(1 << 9)) >> 10;
    if (m2 == 10) { m1++;                   m2=0; }
    if ( !EncodeFlag )                      SWAP(NDec,NEnc);
    sprintf(WrkStr,"%14s:%7d >%7d, %1d.%02d bpb, used:%3d.%1dMB, speed: %d KB/sec",
            pFName,NDec,NEnc,n1,n2,m1,m2,Speed);
    printf("%-79.79s\r",WrkStr);
}
static char* _STDCALL ChangeExtRare(const char* In,char* Out,const char* Ext)
{
    char* RetVal=Out;
    const char* p=strrchr(In,'.');
    if (!p || strrchr(In,BACKSLASH) > p)    p=In+strlen(In);
    do { *Out++ = *In++; } while (In != p);
    *Out++='.';
    while((*Out++ = *Ext++) != 0)           ;
    return RetVal;
}
inline BOOL RemoveFile(const char* FName)
{
    EnvSetNormAttr(FName);                  return (remove(FName) == 0);
}
static BOOL _STDCALL TestAccessRare(const char* FName)
{
static BOOL YesToAll=FALSE;
    FILE* fp=fopen(FName,"rb");
    if ( !fp )                              return TRUE;
    fclose(fp);
    if ( YesToAll )                         return RemoveFile(FName);
    printf("%s already exists, overwrite?: <Y>es, <N>o, <A>ll, <Q>uit?",FName);
    for ( ; ; )
        switch ( toupper(EnvGetCh()) ) {
            case 'A':                       YesToAll=TRUE;
            case '\r': case 'Y':            return RemoveFile(FName);
            case 0x1B: case 'Q':            printf(MTxt[3]); exit(-1);
            case 'N':                       return FALSE;
        }
}
inline FILE* FOpen(const char* FName,const char* mode)
{
    FILE* fp=fopen(FName,mode);
    if ( !fp ) { printf(MTxt[0],FName);     exit(-1); }
    setvbuf(fp,NULL,_IOFBF,64*1024);        return fp;
}
inline void PrepareCoding(int SASize,FILE* fp)
{
    if ( !StartSubAllocator(SASize) ) {
        printf(MTxt[2]);                    exit(-1);
    }
    StartClock=clock();                     StartFilePosition=ftell(fp);
}
inline void EncodeFile(const ENV_FIND_RESULT& efr,int MaxOrder,int SASize,MR_METHOD MRMethod,const char* ArcName)
{
    char WrkStr[260];
    strcpy(WrkStr,ArcName);
    if (!WrkStr[0] && !TestAccessRare(ChangeExtRare(efr.getFName(),WrkStr,"pmd")))
                return;
    FILE* fpIn = FOpen(efr.getFName(),"rb"), * fpOut = FOpen(WrkStr,"a+b");
    pFName=strrchr(efr.getFName(),BACKSLASH);
    pFName=( pFName )?(pFName+1):(efr.getFName());
    efr.copyDateTimeAttr();
    ai.signature=PPMdSignature;             ai.FNLen=strlen(pFName)+(MRMethod << 14);
    ai.info=(MaxOrder-1) | ((SASize-1) << 4) | ((Variant-'A') << 12);
    fwrite(&ai,sizeof(ai),1,fpOut);         fwrite(pFName,ai.FNLen & 0x1FF,1,fpOut);
    PrepareCoding(SASize,fpOut);            EncodeFile(fpOut,fpIn,MaxOrder,MRMethod);
    putchar('\n');
    if (ferror(fpOut) || ferror(fpIn)) {
        printf(MTxt[1],efr.getFName(),WrkStr);
        exit(-1);
    }
    fclose(fpIn);                           fclose(fpOut);
}
inline BOOL DecodeOneFile(FILE* fpIn)
{
    char WrkStr[260];
    int MaxOrder, SASize;
    MR_METHOD MRMethod;
    if ( !fread(&ai,sizeof(ai),1,fpIn) )    return FALSE;
    MRMethod=MR_METHOD(ai.FNLen >> 14);
    ai.FNLen=CLAMP(int(ai.FNLen & 0x1FF),1,260-1);
    fread(WrkStr,ai.FNLen,1,fpIn);          WrkStr[ai.FNLen]=0;
    if ( !TestAccessRare(WrkStr) )          return FALSE;
    FILE* fpOut = FOpen(pFName=WrkStr,"wb");
    MaxOrder=(ai.info & 0x0F)+1;            SASize=((ai.info >> 4) & 0xFF)+1;
    DWORD Variant=(ai.info >> 12)+'A';
    if (ai.signature != PPMdSignature || Variant != ::Variant) {
        printf(MTxt[0],WrkStr);             exit(-1);
    }
    PrepareCoding(SASize,fpIn);             DecodeFile(fpOut,fpIn,MaxOrder,MRMethod);
    putchar('\n');
    if (ferror(fpOut) || ferror(fpIn) || feof(fpIn)) {
        printf(MTxt[1],WrkStr,WrkStr);      exit(-1);
    }
    fclose(fpOut);                          EnvSetDateTimeAttr(WrkStr);
    return TRUE;
}
inline void DecodeFile(const ENV_FIND_RESULT& efr)
{
    FILE* fpIn=FOpen(efr.getFName(),"rb");
    while ( DecodeOneFile(fpIn) )           ;
    fclose(fpIn);
}
inline void TestArchive(char* ArcName,const char* Pattern)
{
    if ( !Pattern[0] ) {
        char CurDir[260];
        EnvGetCWD(CurDir);
        const char* p=strrchr(CurDir,BACKSLASH);
        p = (p && strlen(p+1))?(p+1):("PPMdFile");
        ChangeExtRare(p,ArcName,"pmd");
    } else                                  strcpy(ArcName,Pattern);
    FILE* fp = fopen(ArcName,"rb");
    if ( fp ) {
        if (!fread(&ai,sizeof(ai),1,fp) || ai.signature != PPMdSignature ||
                                            (ai.info >> 12)+'A' != ::Variant) {
            printf(MTxt[0],ArcName);        exit(-1);
        }
        fclose(fp);
    }
}
struct FILE_LIST_NODE {
    FILE_LIST_NODE* next;
    ENV_FIND_RESULT efr;
    FILE_LIST_NODE(const ENV_FIND_RESULT& Data,FILE_LIST_NODE** PrevNode) {
        efr=Data;                           next=*PrevNode;
        *PrevNode=this;
    }
    void destroy(FILE_LIST_NODE** PrevNode) {
        *PrevNode=next;                     delete this;
    }
};
int main(int argc, char *argv[])
{
    char ArcName[260];
    BOOL DeleteFile=FALSE;
    int i, MaxOrder=4, SASize=10;
    MR_METHOD MRMethod=MRM_RESTART;
    printf("Fast PPMII compressor for textual data, variant %c, "__DATE__"\n",char(Variant));
    if (argc < 3) { printf(MTxt[6],SASize,MAX_O,MaxOrder);      return -1; }
    switch ( toupper(argv[1][0]) ) {
        case 'E': EncodeFlag=TRUE;                              break;
        case 'D': EncodeFlag=FALSE;                             break;
        default : printf(MTxt[4],argv[1]);                      return -1;
    }
    for (ArcName[0]=0,i=2;i < argc && (argv[i][0] == '-' || argv[i][0] == '/');i++)
        switch ( toupper(argv[i][1]) ) {
            case 'D': DeleteFile=TRUE;                          break;
            case 'F': TestArchive(ArcName,argv[i]+2);           break;
            case 'M': SASize=CLAMP(atoi(argv[i]+2),1,256);      break;
            case 'O': MaxOrder=CLAMP(atoi(argv[i]+2),2,MAX_O);  break;
            case 'R': MRMethod=MR_METHOD(CLAMP(atoi(argv[i]+2),0,2));
                        break;
            default : printf(MTxt[5],argv[i]);   				return -1;
        }
    FILE_LIST_NODE* pNode, * pFirstNode=NULL, ** ppNode=&pFirstNode;
    for (ENV_FILE_FINDER eff;i < argc;i++) {
        if ( eff.findFirst(argv[i]) )
            do {
                if ( eff.isFileValid() ) {
                    pNode = new FILE_LIST_NODE(eff.getResult(),ppNode);
                    if ( !pNode ) {
                        printf(MTxt[2]);    return -1;
                    }
                    ppNode=&(pNode->next);
                }
            } while ( eff.findNext() );
        eff.findStop();
    }
    while ((pNode=pFirstNode) != NULL) {
        ENV_FIND_RESULT& efr=pNode->efr;
        if ( EncodeFlag )                   EncodeFile(efr,MaxOrder,SASize,MRMethod,ArcName);
        else                                DecodeFile(efr);
        if ( DeleteFile )                   remove(efr.getFName());
        pNode->destroy(&pFirstNode);
    }
    StopSubAllocator();
    return 0;
}

⌨️ 快捷键说明

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