OpenCores
URL https://opencores.org/ocsvn/mb-jpeg/mb-jpeg/trunk

Subversion Repositories mb-jpeg

[/] [mb-jpeg/] [tags/] [arelease/] [decoder/] [tree_vld.c] - Blame information for rev 66

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 quickwayne
/*-----------------------------------------*/
2
/* File : tree_vld.c, utilities for jfif view */
3
/* Author : Pierre Guerrier, march 1998    */
4
/*-----------------------------------------*/
5
 
6
#include <stdlib.h>
7
#include <stdio.h>
8
 
9
 
10
/*--------------------------------------*/
11
/* private huffman.c defines and macros */
12
/*--------------------------------------*/
13
 
14
/* Number of HTable words sacrificed to bookkeeping: */
15
#define GLOB_SIZE               32
16
 
17
/* Memory size of HTables: */
18
#define MAX_SIZE(hclass)                ((hclass)?384:64)
19
 
20
/* Available cells, top of storage: */
21
#define MAX_CELLS(hclass)       (MAX_SIZE(hclass) - GLOB_SIZE)
22
 
23
/* for Huffman tree descent */
24
/* lower 8 bits are for value/left son */
25
 
26
#define GOOD_NODE_FLAG          0x100
27
#define GOOD_LEAF_FLAG          0x200
28
#define BAD_LEAF_FLAG           0x300
29
#define SPECIAL_FLAG            0x000
30
#define HUFF_FLAG_MSK           0x300
31
 
32
#define HUFF_FLAG(c)            ((c) & HUFF_FLAG_MSK)
33
#define HUFF_VALUE(c)           ((unsigned char)( (c) & (~HUFF_FLAG_MSK) ))
34
 
35
 
36
/*--------------------------------------*/
37
/* some static structures for storage   */
38
/*--------------------------------------*/
39
 
40
static unsigned int     DC_Table0[MAX_SIZE(DC_CLASS)],
41
                        DC_Table1[MAX_SIZE(DC_CLASS)];
42
 
43
static unsigned int     AC_Table0[MAX_SIZE(AC_CLASS)],
44
                        AC_Table1[MAX_SIZE(AC_CLASS)];
45
 
46
static unsigned int    *HTable[4] = {
47
                                      &DC_Table0[0], &DC_Table1[0],
48
                                      &AC_Table0[0], &AC_Table1[0]
49
                                    };
50
 
51
 
52
/*----------------------------------------------------------*/
53
/* Loading of Huffman table, with leaves drop ability       */
54
/*----------------------------------------------------------*/
55
 
56
int load_huff_tables(FILE *fi)
57
{
58
  char aux;
59
  int size, hclass, id;
60
  int LeavesN, NodesN, CellsN;
61
  int MaxDepth, i, k, done;
62
  int NextCellPt;       /* where shall we put next cell */
63
  int NextLevelPt;      /* where shall node point to */
64
  unsigned int flag;
65
 
66
  size = get_size(fi); /* this is the tables' size */
67
 
68
  size -= 2;
69
 
70
  while (size>0) {
71
 
72
    aux = fgetc(fi);
73
    hclass = first_quad(aux);   /* AC or DC */
74
    id = second_quad(aux);      /* table no */
75
    if (id>1) {
76
      fprintf(stderr, "\tERROR:\tBad HTable identity %d!\n",id);
77
      return -1;
78
    }
79
    id = HUFF_ID(hclass, id);
80
    if (verbose)
81
      fprintf(stderr, "\tINFO:\tLoading Table %d\n", id);
82
    size--;
83
    CellsN = NodesN = 1;      /* the root one */
84
    LeavesN = 0;
85
 
86
    for (i=0; i<MAX_CELLS(hclass); i++)
87
      HTable[id][i] = SPECIAL_FLAG;     /* secure memory with crash value */
88
 
89
    /* first load the sizes of code elements */
90
    /* and compute contents of each tree level */
91
    /* Adress   Content         */
92
    /* Top              Leaves 0        */
93
    /* Top-1    Nodes  0        */
94
    /* ......   .......         */
95
    /* Top-2k   Leaves k        */
96
    /* Top-2k-1 Nodes  k        */
97
 
98
    MaxDepth = 0;
99
    for (i=0; i<16; i++) {
100
      LeavesN = HTable[id][MAX_SIZE(hclass)-2*i-1] = fgetc(fi);
101
      CellsN = 2*NodesN; /* nodes is old */
102
      NodesN = HTable[id][MAX_SIZE(hclass)-2*i-2] = CellsN-LeavesN;
103
      if (LeavesN) MaxDepth = i;
104
    }
105
    size-=16;
106
 
107
    /* build root at address 0, then deeper levels at */
108
    /* increasing addresses until MAX_CELLS reached */
109
 
110
    HTable[id][0] = 1 | GOOD_NODE_FLAG;          /* points to cell _2_ ! */
111
    /* we give up address one to keep left brothers on even adresses */
112
    NextCellPt = 2;
113
    i = 0;               /* this is actually length 1 */
114
 
115
    done = 0;
116
 
117
    while (i<= MaxDepth) {
118
 
119
      /* then load leaves for other levels */
120
      LeavesN = HTable[id][MAX_SIZE(hclass)-2*i-1];
121
      for (k = 0; k<LeavesN; k++)
122
        if (!done) {
123
          HTable[id][NextCellPt++] = fgetc(fi) | GOOD_LEAF_FLAG;
124
          if (NextCellPt >= MAX_CELLS(hclass)) {
125
            done = 1;
126
            fprintf(stderr, "\tWARNING:\tTruncating Table at depth %d\n", i+1);
127
          }
128
        }
129
        else fgetc(fi); /* throw it away, just to keep file sync */
130
      size -= LeavesN;
131
 
132
      if (done || (i == MaxDepth)) { i++; continue; }
133
      /* skip useless node building */
134
 
135
      /* then build nodes at that level */
136
      NodesN = HTable[id][MAX_SIZE(hclass)-2*i-2];
137
 
138
      NextLevelPt = NextCellPt+NodesN;
139
      for (k = 0; k<NodesN; k++) {
140
        if (NextCellPt >= MAX_CELLS(hclass)) { done = 1; break; }
141
 
142
        flag = ((NextLevelPt|1) >=
143
                MAX_CELLS(hclass)) ? BAD_LEAF_FLAG : GOOD_NODE_FLAG;
144
        /* we OR by 1 to check even right brother within range */
145
        HTable[id][NextCellPt++] = (NextLevelPt/2) | flag;
146
        NextLevelPt += 2;
147
      }
148
 
149
      i++;      /* now for next level */
150
    }   /* nothing left to read from file after maxdepth */
151
 
152
    if (verbose)
153
      fprintf(stderr, "\tINFO:\tUsing %d words of table memory\n", NextCellPt);
154
 
155
    /*
156
      -- this is useful for displaying the uploaded tree --
157
      for(i=0; i<NextCellPt; i++) {
158
      switch (HUFF_FLAG(HTable[id][i])) {
159
      case GOOD_NODE_FLAG:
160
      fprintf(stderr, "Cell %X: Node to %X and %X\n", i,
161
      HUFF_VALUE(HTable[id][i])*2,
162
      HUFF_VALUE(HTable[id][i])*2 +1);
163
      break;
164
      case GOOD_LEAF_FLAG:
165
      fprintf(stderr, "Cell %X: Leaf with value %X\n", i,
166
      HUFF_VALUE(HTable[id][i]) );
167
      break;
168
      case SPECIAL_FLAG:
169
      fprintf(stderr, "Cell %X: Special flag\n", i);
170
      break;
171
      case BAD_LEAF_FLAG:
172
      fprintf(stderr, "Cell %X: Bad leaf\n", i);
173
      break;
174
      }
175
      }
176
      */
177
 
178
  }     /* loop on tables */
179
  return 0;
180
}
181
 
182
/*-----------------------------------*/
183
/* extract a single symbol from file */
184
/* using specified huffman table ... */
185
/*-----------------------------------*/
186
 
187
unsigned char
188
get_symbol(FILE *fi, int select)
189
{
190
  int cellPt;
191
 
192
  cellPt = 0; /* this is the root cell */
193
 
194
  while (HUFF_FLAG(HTable[select][cellPt]) == GOOD_NODE_FLAG)
195
    cellPt = get_one_bit(fi) | (HUFF_VALUE(HTable[select][cellPt])<<1);
196
 
197
  switch (HUFF_FLAG(HTable[select][cellPt])) {
198
  case SPECIAL_FLAG:
199
    fprintf(stderr, "%ld:\tERROR:\tFound forbidden Huffman symbol !\n",
200
            ftell(fi));
201
    aborted_stream(fi, fo);
202
    break;
203
 
204
  case GOOD_LEAF_FLAG:
205
    return HUFF_VALUE(HTable[select][cellPt]);
206
    break;
207
 
208
  case BAD_LEAF_FLAG:
209
    /* how do we fall back in case of truncated tree ? */
210
    /* suggest we send an EOB and warn */
211
    fprintf(stderr, "%ld:\tWARNING:\tFalling out of truncated tree !\n",
212
            ftell(fi));
213
    return 0;
214
    break;
215
 
216
  default:
217
    break;
218
  }
219
  return 0;
220
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.