tree_vld.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 225 行
C
225 行
/*-----------------------------------------*//* File : tree_vld.c, utilities for jfif view *//* Author : Pierre Guerrier, march 1998 *//*-----------------------------------------*/#include <stdlib.h>#include <stdio.h>#include "jpeg.h"/*--------------------------------------*//* private huffman.c defines and macros *//*--------------------------------------*//* Number of HTable words sacrificed to bookkeeping: */#define GLOB_SIZE 32/* Memory size of HTables: */#define MAX_SIZE(hclass) ((hclass)?384:64)/* Available cells, top of storage: */#define MAX_CELLS(hclass) (MAX_SIZE(hclass) - GLOB_SIZE)/* for Huffman tree descent *//* lower 8 bits are for value/left son */#define GOOD_NODE_FLAG 0x100#define GOOD_LEAF_FLAG 0x200#define BAD_LEAF_FLAG 0x300#define SPECIAL_FLAG 0x000#define HUFF_FLAG_MSK 0x300#define HUFF_FLAG(c) ((c) & HUFF_FLAG_MSK)#define HUFF_VALUE(c) ((unsigned char)( (c) & (~HUFF_FLAG_MSK) ))/*--------------------------------------*//* some static structures for storage *//*--------------------------------------*/static unsigned int DC_Table0[MAX_SIZE(DC_CLASS)], DC_Table1[MAX_SIZE(DC_CLASS)];static unsigned int AC_Table0[MAX_SIZE(AC_CLASS)], AC_Table1[MAX_SIZE(AC_CLASS)];static unsigned int *HTable[4] = { &DC_Table0[0], &DC_Table1[0], &AC_Table0[0], &AC_Table1[0] };/*----------------------------------------------------------*//* Loading of Huffman table, with leaves drop ability *//*----------------------------------------------------------*/int load_huff_tables(FILE *fi){ char aux; int size, hclass, id; int LeavesN, NodesN, CellsN; int MaxDepth, i, k, done; int NextCellPt; /* where shall we put next cell */ int NextLevelPt; /* where shall node point to */ unsigned int flag; size = get_size(fi); /* this is the tables' size */ size -= 2; while (size>0) { aux = fgetc(fi); hclass = first_quad(aux); /* AC or DC */ id = second_quad(aux); /* table no */ if (id>1) { fprintf(stderr, "\tERROR:\tBad HTable identity %d!\n",id); return -1; } id = HUFF_ID(hclass, id); if (verbose) fprintf(stderr, "\tINFO:\tLoading Table %d\n", id); size--; CellsN = NodesN = 1; /* the root one */ LeavesN = 0; for (i=0; i<MAX_CELLS(hclass); i++) HTable[id][i] = SPECIAL_FLAG; /* secure memory with crash value */ /* first load the sizes of code elements */ /* and compute contents of each tree level */ /* Adress Content */ /* Top Leaves 0 */ /* Top-1 Nodes 0 */ /* ...... ....... */ /* Top-2k Leaves k */ /* Top-2k-1 Nodes k */ MaxDepth = 0; for (i=0; i<16; i++) { LeavesN = HTable[id][MAX_SIZE(hclass)-2*i-1] = fgetc(fi); CellsN = 2*NodesN; /* nodes is old */ NodesN = HTable[id][MAX_SIZE(hclass)-2*i-2] = CellsN-LeavesN; if (LeavesN) MaxDepth = i; } size-=16; /* build root at address 0, then deeper levels at */ /* increasing addresses until MAX_CELLS reached */ HTable[id][0] = 1 | GOOD_NODE_FLAG; /* points to cell _2_ ! */ /* we give up address one to keep left brothers on even adresses */ NextCellPt = 2; i = 0; /* this is actually length 1 */ done = 0; while (i<= MaxDepth) { /* then load leaves for other levels */ LeavesN = HTable[id][MAX_SIZE(hclass)-2*i-1]; for (k = 0; k<LeavesN; k++) if (!done) { HTable[id][NextCellPt++] = fgetc(fi) | GOOD_LEAF_FLAG; if (NextCellPt >= MAX_CELLS(hclass)) { done = 1; fprintf(stderr, "\tWARNING:\tTruncating Table at depth %d\n", i+1); } } else fgetc(fi); /* throw it away, just to keep file sync */ size -= LeavesN; if (done || (i == MaxDepth)) { i++; continue; } /* skip useless node building */ /* then build nodes at that level */ NodesN = HTable[id][MAX_SIZE(hclass)-2*i-2]; NextLevelPt = NextCellPt+NodesN; for (k = 0; k<NodesN; k++) { if (NextCellPt >= MAX_CELLS(hclass)) { done = 1; break; } flag = ((NextLevelPt|1) >= MAX_CELLS(hclass)) ? BAD_LEAF_FLAG : GOOD_NODE_FLAG; /* we OR by 1 to check even right brother within range */ HTable[id][NextCellPt++] = (NextLevelPt/2) | flag; NextLevelPt += 2; } i++; /* now for next level */ } /* nothing left to read from file after maxdepth */ if (verbose) fprintf(stderr, "\tINFO:\tUsing %d words of table memory\n", NextCellPt); /* -- this is useful for displaying the uploaded tree -- for(i=0; i<NextCellPt; i++) { switch (HUFF_FLAG(HTable[id][i])) { case GOOD_NODE_FLAG: fprintf(stderr, "Cell %X: Node to %X and %X\n", i, HUFF_VALUE(HTable[id][i])*2, HUFF_VALUE(HTable[id][i])*2 +1); break; case GOOD_LEAF_FLAG: fprintf(stderr, "Cell %X: Leaf with value %X\n", i, HUFF_VALUE(HTable[id][i]) ); break; case SPECIAL_FLAG: fprintf(stderr, "Cell %X: Special flag\n", i); break; case BAD_LEAF_FLAG: fprintf(stderr, "Cell %X: Bad leaf\n", i); break; } } */ } /* loop on tables */ return 0;}/*-----------------------------------*//* extract a single symbol from file *//* using specified huffman table ... *//*-----------------------------------*/unsigned charget_symbol(FILE *fi, int select){ int cellPt; cellPt = 0; /* this is the root cell */ while (HUFF_FLAG(HTable[select][cellPt]) == GOOD_NODE_FLAG) cellPt = get_one_bit(fi) | (HUFF_VALUE(HTable[select][cellPt])<<1); switch (HUFF_FLAG(HTable[select][cellPt])) { case SPECIAL_FLAG: fprintf(stderr, "%ld:\tERROR:\tFound forbidden Huffman symbol !\n", ftell(fi)); aborted_stream(fi, fo); break; case GOOD_LEAF_FLAG: return HUFF_VALUE(HTable[select][cellPt]); break; case BAD_LEAF_FLAG: /* how do we fall back in case of truncated tree ? */ /* suggest we send an EOB and warn */ fprintf(stderr, "%ld:\tWARNING:\tFalling out of truncated tree !\n", ftell(fi)); return 0; break; default: break; } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?