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

📄 huffc.c

📁 很好的JPEG图象解码器,基于VC环境开发。
💻 C
📖 第 1 页 / 共 3 页
字号:
    numCOL=cPtr->imageWidth;    numROW=cPtr->imageHeight;    compsInScan=cPtr->compsInScan;    Pr=cPtr->dataPrecision;    Pt=cPtr->Pt;    prevRowBuf=NULL;    curRowBuf=mcuTable;    for (row=0; row<numROW; row++) {        for (col=0; col<numCOL; col++) {            for (curComp = 0; curComp < compsInScan; curComp++) {                ci = cPtr->MCUmembership[curComp];                compptr = cPtr->curCompInfo[ci];                tblNo=compptr->dcTblNo;                for (i=0;i<numSelValue;i++) {                    Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,                        psvSet[i],&predictor);                    r = curRowBuf[col][curComp]-predictor;                     curCountTblNo=psvSet[i]-1;                    CountOneDiff(r,freqCountPtrs[curCountTblNo][tblNo]);                }            }        }        prevRowBuf=curRowBuf;        curRowBuf+=numCOL;    }}/* *-------------------------------------------------------------- * * FreqCountAllSelValue -- * *      Count the times each category symbol occurs in this *      image for all seven PSV. *      To do this all together is even faster than to use *      a loop to go through 4 only PSVs.  * * Results: *      None. * * Side effects: *      The freqCountPtrs[i] has counted all category symbols *      appeared in the image, where i goes from 0 to 6.  * *-------------------------------------------------------------- */voidFreqCountAllSelValue(cPtr)    CompressInfo *cPtr;{    register short curComp, ci;    register int col,row;    register JpegComponentInfo *compptr;    register int r;    int numCOL,numROW,compsInScan;    int Pr,Pt,Ss,j;    int predictor;    MCU *prevRowBuf,*curRowBuf;    numCOL=cPtr->imageWidth;    numROW=cPtr->imageHeight;    compsInScan=cPtr->compsInScan;    Pr=cPtr->dataPrecision;    Pt=cPtr->Pt;    Ss=cPtr->Ss;    prevRowBuf=NULL;    curRowBuf=mcuTable;    /*     * Do some specical case checking such that we can reduce the     * computations in the main loop.     */     /*     * For the very first mcu in the scan, predictor is 1<<(Pr-Pt-1).      */    for (curComp = 0; curComp < compsInScan; curComp++) {        ci = cPtr->MCUmembership[curComp];        compptr = cPtr->curCompInfo[ci];        r = curRowBuf[0][curComp] - (1<<(Pr-Pt-1));        AllPredCountOneDiff(r,compptr->dcTblNo);    }    /*     * In rest of the first row, left neighboring pixel is the predictor.      */    for (col=1; col<numCOL; col++) {        for (curComp = 0; curComp < compsInScan; curComp++) {            ci = cPtr->MCUmembership[curComp];            compptr = cPtr->curCompInfo[ci];            r = curRowBuf[col][curComp]-curRowBuf[col-1][curComp];            AllPredCountOneDiff(r,compptr->dcTblNo);        }    }    prevRowBuf=curRowBuf;    curRowBuf+=numCOL;    for (row=1; row<numROW; row++) {        /*         * For the first column, upper neighbor is the predictor.          */        for (curComp = 0; curComp < compsInScan; curComp++) {            ci = cPtr->MCUmembership[curComp];            compptr = cPtr->curCompInfo[ci];            r = curRowBuf[0][curComp]-prevRowBuf[0][curComp];            AllPredCountOneDiff(r,compptr->dcTblNo);        }         /*         * Call AllPredCountOneComp to count the rest samples on this row.           */        for (col=1; col<numCOL; col++) {            for (curComp = 0; curComp < compsInScan; curComp++) {                ci = cPtr->MCUmembership[curComp];                compptr = cPtr->curCompInfo[ci];                AllPredCountOneComp(col,curComp,compptr->dcTblNo,                                    curRowBuf,prevRowBuf);            }        }        prevRowBuf=curRowBuf;        curRowBuf+=numCOL;    }}/* *-------------------------------------------------------------- * * FreqCountInit -- * *	Allocate and zero the count tables. * * Results: *      None. * * Side effects: *      Seven tables pointed by freqCountPtrs[][] have been  *	allocated and initiallized.   * *-------------------------------------------------------------- */voidFreqCountInit(cPtr)    CompressInfo *cPtr;{    int i,j,tbl;    for (i = 0; i < NUM_HUFF_TBLS; i++) {        for (j=0;j<7;j++)            freqCountPtrs[j][i] = NULL;    }    /*     * Create seven count tables for each Huffman table.     * Initialize the table entries to zero.     * Note that GenHuffCoding expects 257 entries in each table,      * although I think 17 will be enough.     */    for (i = 0; i < cPtr->compsInScan; i++) {        tbl = cPtr->curCompInfo[i]->dcTblNo;        for (j=0;j<7;j++) {            if (freqCountPtrs[j][tbl] == NULL) {               freqCountPtrs[j][tbl] = (long *) malloc (257 *sizeof(long));               MEMSET((void *)(freqCountPtrs[j][tbl]), 0, 257*sizeof(long));            }        }    }}/* *-------------------------------------------------------------- * * EmitBitsSum -- * *	Find the number of bits emiting for a PSV (curCountTblNo+1). *	It includes the total bits of category symbols and additional *	bits. * * Results: *      Total "category symbol" and "additional bits" output bits *	for this PSV. * * Side effects: *	If in vervose mode, totalHuffSym and totalAddBits for *	this PSV is stored. These data are later output as statistics *	data. * *-------------------------------------------------------------- */longEmitBitsSum(curCountTblNo, htblPtr)    int curCountTblNo;    HuffmanTable *htblPtr[4];{    int i,tbl;    long addBitSum,symLenSum,totalBits;           addBitSum=0;    symLenSum=0;    /*      * Count additional bits and Huffman symbol size.     */    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        if (freqCountPtrs[curCountTblNo][tbl] != NULL) {           for (i=1;i<17;i++) {               addBitSum+=freqCountPtrs[curCountTblNo][tbl][i]*i;           }           for (i=0;i<17;i++) {               symLenSum+=freqCountPtrs[curCountTblNo][tbl][i]*                          htblPtr[tbl]->ehufsi[i];           }        }    }    totalBits=symLenSum+addBitSum;    if (verbose) {       totalHuffSym[curCountTblNo]=symLenSum;        totalAddBits[curCountTblNo]=addBitSum;     }    return (totalBits);}/* *-------------------------------------------------------------- * * HuffOptimize -- * *	Find the best coding parameters for a Huffman-coded scan. *	When called, the scan data has already been converted to *	a sequence of MCU groups of source image samples, which *	are stored in a "big" array, mcuTable. * *	It counts the times each category symbol occurs. Based on *	this counting, optimal Huffman tables are built. Then it *	uses this optimal Huffman table and counting table to find *	the best PSV.  * * Results: *	Optimal Huffman tables are retured in cPtr->dcHuffTblPtrs[tbl]. *	Best PSV is retured in cPtr->Ss. * * Side effects: *	None. * *-------------------------------------------------------------- */voidHuffOptimize (cPtr)    CompressInfo *cPtr;{    int tbl,i;    HuffmanTable *curHtblPtr[4];    long curTotalBits,bestTotalBits;    long curFreqCount[257];    int curCountTblNo;      FreqCountInit(cPtr);    /*     * Collect the frequency count in freqCountPtrs for each PSV.     * Experiment data shows that when numSelValue > 4,      * FreqCountAllSelValue does a better job than FreqCountSelValueSet.     */    if (numSelValue>3) {        FreqCountAllSelValue(cPtr);       }    else {       FreqCountSelValueSet(cPtr);    }     /*      * Generate optimal Huffman tables and find the best PSV.     * Loop through each PSV is the psvSet. Whenever a better PSV     * is found, its Huffman table is stored in cPtr->dcHuffTblPtrs;     * and itself is stored in cPtr->Ss.     */    /*     * Set curCountTblNo to the first PSV. Allocate memory,     * and point bestHtblPtr to cPtr->dcHuffTblPtrs,     */    curCountTblNo=psvSet[0]-1;    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        curHtblPtr[tbl]=NULL;        if (freqCountPtrs[curCountTblNo][tbl] != NULL) {           curHtblPtr[tbl]=(HuffmanTable *) malloc (sizeof(HuffmanTable));           if (cPtr->dcHuffTblPtrs[tbl] == NULL) {              cPtr->dcHuffTblPtrs[tbl]=(HuffmanTable *)                                         malloc (sizeof(HuffmanTable));           }        }    }      /*     * Generate the Huffman tables for the first PSV and count the     * total output bits of category symbols and additional bits.     */    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        if (freqCountPtrs[curCountTblNo][tbl] != NULL) {           /*            * Make an extra copy of the freqency tables since            * GenHuffCoding destroys it. We need these tables             * to count output bits next.            */           MEMCPY(curFreqCount,freqCountPtrs[curCountTblNo][tbl],                  257*sizeof(long));           GenHuffCoding(cPtr->dcHuffTblPtrs[tbl], curFreqCount);           FixHuffTbl(cPtr->dcHuffTblPtrs[tbl]);        }    }     bestTotalBits=EmitBitsSum(curCountTblNo,cPtr->dcHuffTblPtrs);    cPtr->Ss=psvSet[0];    /*     * Generate the Huffman tables and count the output bits for the     * remaining PSVs. Store the best one in cPtr pionted structure.     */    for (i=1; i<numSelValue; i++) {        curCountTblNo=psvSet[i]-1;        for (tbl=0; tbl<NUM_HUFF_TBLS; tbl++) {            if (freqCountPtrs[curCountTblNo][tbl] != NULL) {               MEMCPY(curFreqCount,freqCountPtrs[curCountTblNo][tbl],                      257*sizeof(long));               GenHuffCoding(curHtblPtr[tbl],curFreqCount);               FixHuffTbl(curHtblPtr[tbl]);            }        }           curTotalBits=EmitBitsSum(curCountTblNo,curHtblPtr);        if (curTotalBits<bestTotalBits) {           for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {               if (curHtblPtr[tbl] != NULL) {                  swap(HuffmanTable *,cPtr->dcHuffTblPtrs[tbl],curHtblPtr[tbl]);               }           }           bestTotalBits=curTotalBits;           cPtr->Ss=psvSet[i];        }    }    /*      * Set sent_table FALSE so updated table will be     * written to JPEG file.     */    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        if (cPtr->dcHuffTblPtrs[tbl] != NULL) {           cPtr->dcHuffTblPtrs[tbl]->sentTable = 0;        }    }                 /*     * Release the freqency Count tables, and temporary Huffman tables.     */    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        for (i=0;i<7;i++) {            if (freqCountPtrs[i][tbl] != NULL) {               free(freqCountPtrs[i][tbl]);            }        }        if (curHtblPtr[tbl] != NULL) {           free(curHtblPtr[tbl]);        }    }}/* *-------------------------------------------------------------- * * StdPickSelValue -- * *	Select the best PSV from the psvSet. Default Huffman *	tables and frequency counting tables are used in the *	selection procedure. * * Results: *	Chosen selection value is stored in cPtr->Ss * * Side effects: *	None. * *-------------------------------------------------------------- */voidStdPickSelValue(cPtr)    CompressInfo *cPtr;{    int tbl,i;    long curTotalBits,bestTotalBits;    long curFreqCount[257];    int curCountTblNo;     FreqCountInit(cPtr);    /*     * Collect the frequency count in freqCountPtrs for each PSV.     * Experiment data shows that when numSelValue > 4,     * FreqCountAllSelValue does a better job than FreqCountSelValueSet.     */    if (numSelValue>3) {        FreqCountAllSelValue(cPtr);       }    else {       FreqCountSelValueSet(cPtr);    }    /*      * Loop through each PSV in the psvSet, and store the PSV     * which generates the least output bits in cPtr->Ss.     */    curCountTblNo=psvSet[0]-1;    bestTotalBits=EmitBitsSum(curCountTblNo,cPtr->dcHuffTblPtrs);    cPtr->Ss=psvSet[0];    for (i=1; i<numSelValue; i++) {        curCountTblNo=psvSet[i]-1;        curTotalBits=EmitBitsSum(curCountTblNo,cPtr->dcHuffTblPtrs);        if (curTotalBits<bestTotalBits) {           bestTotalBits=curTotalBits;           cPtr->Ss=psvSet[i];        }    }    /*     * Release frequency counting tables.     */    for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {        for (i=0;i<7;i++) {            if (freqCountPtrs[i][tbl] != NULL) {               free(freqCountPtrs[i][tbl]);            }        }    }}/* *-------------------------------------------------------------- * * AddHuffTable -- * *	Huffman table setup routines. Copy bits and val tables  *	into a Huffman table. * * Results: *	bits and val are copied into htblprt. *	(*htblptr)->sentTable is set to 0. * * Side effects: *      None. * *-------------------------------------------------------------- */voidAddHuffTable (htblptr, bits, val)    HuffmanTable **htblptr;    Uchar *bits, *val;{    if (*htblptr == NULL)       *htblptr = (HuffmanTable *) (malloc (sizeof(HuffmanTable)));    MEMCPY((*htblptr)->bits, bits, sizeof((*htblptr)->bits));    MEMCPY((*htblptr)->huffval, val, sizeof((*htblptr)->huffval));    /*     * Initialize sent_table FALSE so table will be written to JPEG file.     * In an application where we are writing non-interchange JPEG files,     * it might be desirable to save space by leaving default Huffman tables     * out of the file.  To do that, just initialize sent_table = TRUE...     */    (*htblptr)->sentTable = 0;}/* *-------------------------------------------------------------- * * LoadStdHuffTables -- * *	Load the standard Huffman tables (cf. JPEG standard *	section K.3) into compression data structure pointed *	by cPtr. *	IMPORTANT: these are only valid for 8-bit data precision! * * Results: *      Standard Huffman table, bits and val, are copied into *	cPtr->dcHuffTblPtrs. * * Side effects: *      None. * *-------------------------------------------------------------- */voidLoadStdHuffTables (cPtr)    CompressInfo *cPtr;{    static Uchar dcLuminanceBits[17] =      { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };    static Uchar dcLuminanceVal[] =      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };     static Uchar dcChrominanceBits[17] =      { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };    static Uchar dcChrominanceVal[] =      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };     AddHuffTable(&(cPtr->dcHuffTblPtrs[0]),dcLuminanceBits,dcLuminanceVal);    AddHuffTable(&(cPtr->dcHuffTblPtrs[1]),dcChrominanceBits,dcChrominanceVal);}

⌨️ 快捷键说明

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