00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <j2k/Fred/Standard.hpp>
00019 #include <ctype.h>
00020
00021 #include <j2k/DataType/HuffMan/LettFreq.hpp>
00022 typedef LettFreq* Belem;
00023
00024 #include <j2k/DataType/BinTree.hpp>
00025 #include <j2k/DataType/HuffMan/HuffTree.hpp>
00026
00027 typedef HuffTree* Elem;
00028
00029
00030 #include <j2k/DataType/Link/SLink.hpp>
00031 #include <j2k/DataType/Link/SList.hpp>
00032
00033
00034 #include <j2k/DataType/Link/SLink.cpp>
00035 #include <j2k/DataType/Link/SList.cpp>
00036
00037 #define CODELEN 20 // Max length of a huffman code
00038
00039
00040 void print(List& in)
00041 {
00042 if (in.isEmpty())
00043 {
00044 cout << "()\n";
00045 }
00046 else
00047 {
00048 in.setFirst();
00049 cout << "( " << in.currValue();
00050 in.next();
00051
00052 while (in.isInList())
00053 {
00054 cout << ", " << in.currValue();
00055 in.next();
00056 }
00057
00058 cout << " )\n";
00059 }
00060 }
00061
00062 double total = 0;
00063
00064
00065 ostream& operator << (ostream& s, LettFreq* z)
00066 {
00067 cout << "In lettfreq << operator\n";
00068 if (z->letter() != '\0')
00069 {
00070 return(s << z->letter() << "/" << z->weight());
00071 }
00072 else
00073 {
00074 return(s << "NULL/" << z->weight());
00075 }
00076 }
00077
00078
00079 ostream& operator << (ostream& s, HuffTree* z)
00080 {
00081 return(s << z->root()->value());
00082 }
00083
00084
00085 struct CodeTableEntry
00086 {
00087 LettFreq* entrydata;
00088 char code[CODELEN];
00089
00090 } CodeTable[100];
00091
00092 int CodeCount = 0;
00093 FILE *fp;
00094
00095 List templist;
00096
00097
00098
00099 void read_freqs(List& hufflist)
00100 {
00101 char buff[100];
00102 char buff2[100];
00103 char *ptr;
00104 char *ptr2;
00105 int freq;
00106 HuffTree* temptree;
00107
00108 while (TRUE)
00109 {
00110 if (!fgets(buff, 99, fp))
00111 {
00112 cout << "No more codes to read -- where is end?\n";
00113 assert(FALSE);
00114 }
00115
00116
00117 for(ptr=buff; *ptr==' '; ptr++);
00118 {
00119 if (!strncmp(ptr, "end", 3))
00120 {
00121 cout<< "Print out the tree:\n";
00122 print(hufflist);
00123 return;
00124 }
00125 }
00126
00127 if (*ptr != '"')
00128 {
00129 cout << "First char was not a quote mark.\n";
00130 assert(FALSE);
00131 }
00132
00133 for (ptr2=buff2,ptr++; *ptr!='"'; ptr++)
00134 {
00135 *ptr2++ = *ptr;
00136 }
00137
00138 *ptr2 = '\0';
00139
00140 for (ptr++; *ptr==' '; ptr++);
00141
00142 if (!isdigit(*ptr)) assert(FALSE);
00143
00144 freq = atoi(ptr);
00145
00146 CodeTable[CodeCount].entrydata = new LettFreq(freq, buff2[0]);
00147
00148 temptree = new HuffTree(CodeTable[CodeCount++].entrydata);
00149
00150
00151
00152
00153 for (hufflist.setFirst(); hufflist.isInList(); hufflist.next())
00154 {
00155 if (temptree->weight() <= hufflist.currValue()->weight())
00156 {
00157 hufflist.insert(temptree);
00158 break;
00159 }
00160 }
00161
00162 if (!hufflist.isInList())
00163 {
00164 hufflist.append(temptree);
00165 }
00166
00167 }
00168 }
00169
00170 #include <j2k/DataType/HuffMan/HuffBld.hpp>
00171
00172
00173 int getindex(char codeword)
00174 {
00175 register int i;
00176
00177 for ( i = 0; i < CodeCount; i++ )
00178 {
00179 if ( codeword == CodeTable[i].entrydata->letter() )
00180 {
00181 return i;
00182 }
00183 }
00184
00185 return -1;
00186 }
00187
00188
00189
00190 void output_tree( BinNode* node, char* prefix, int level )
00191 {
00192 int index;
00193 assert( node != NULL );
00194 if ( node->isLeaf() )
00195 {
00196 cout << node->value()->letter() << "\t" << prefix << "\n";
00197 index = getindex( node->value()->letter() );
00198 strcpy( CodeTable[index].code, prefix );
00199 total += level * node->value()->weight();
00200 }
00201 else
00202 {
00203 prefix[ level ] = '0';
00204 prefix[ level + 1 ] = '\0';
00205 output_tree( node->leftchild(), prefix, level+1 );
00206
00207 prefix[ level ] = '1';
00208 prefix[ level + 1 ] = '\0';
00209 output_tree( node->rightchild(), prefix, level+1 );
00210
00211 prefix[ level ] = '\0';
00212 }
00213 }
00214
00215
00216 void do_commands( HuffTree* tree )
00217 {
00218 BinNode* temp;
00219 char* currchar;
00220 char buff[80];
00221 int index;
00222
00223 while( fgets(buff, 99, fp) )
00224 {
00225 if( !strncmp(buff, "decode", 6) )
00226 {
00227 for( currchar = buff; *currchar != '"'; currchar++ );
00228
00229 cout << "Decode " << currchar++;
00230 temp = tree->root();
00231
00232 while (*currchar != '"')
00233 {
00234 if ( *currchar == '0' )
00235 {
00236 temp = temp->leftchild();
00237 }
00238 else if ( *currchar == '1' )
00239 {
00240 temp = temp->rightchild();
00241 }
00242 else
00243 {
00244 cout << "Bad input! " << *currchar << "\n";
00245 abort();
00246 }
00247
00248 if ( temp->isLeaf() )
00249 {
00250 cout << temp->value()->letter();
00251 temp = tree->root();
00252 }
00253
00254 currchar++;
00255
00256 }
00257
00258 }
00259 else if( !strncmp(buff, "encode", 6) )
00260 {
00261
00262 for ( currchar = buff; *currchar != '"'; currchar++);
00263
00264 cout << "Encode " << currchar++;
00265
00266
00267 while( *currchar != '"' )
00268 {
00269 if (*currchar == ' ')
00270 {
00271 cout << ' ';
00272 }
00273 else
00274 {
00275 index = getindex( *currchar );
00276 assert( index < CodeCount );
00277 cout << CodeTable[index].code;
00278 }
00279
00280 currchar++;
00281 }
00282 }
00283 cout << "\n";
00284
00285 }
00286 }
00287
00288
00289 int main( int argc, char** argv )
00290 {
00291 HuffTree* codes;
00292 char prefix[30];
00293
00294 if (argc == 1)
00295 {
00296 fp = stdin;
00297 }
00298 else
00299 {
00300 fp = fopen(argv[1], "rt");
00301 cout << "Read frequencies\n";
00302 read_freqs(templist);
00303 cout << "Build the tree\n";
00304 codes = build_tree(templist);
00305 cout << "Output the tree\n";
00306 output_tree(codes->root(), prefix, 0);
00307 cout << "Average code length is ";
00308 cout << total/(double)codes->weight() << "\n";
00309 do_commands(codes);
00310 return(FALSE);
00311 }
00312 }