|
Isis 3.0 Application Source Code Reference |
Home |
00001 /* 00002 NOTICE 00003 00004 The software accompanying this notice (the "Software") is provided to you 00005 free of charge to facilitate your use of the data collected by the Mars 00006 Orbiter Camera (the "MOC Data"). Malin Space Science Systems ("MSSS") 00007 grants to you (either as an individual or entity) a personal, 00008 non-transferable, and non-exclusive right (i) to use and reproduce the 00009 Software solely for the purpose of accessing the MOC Data; (ii) to modify 00010 the source code of the Software as necessary to maintain or adapt the 00011 Software to run on alternate computer platforms; and (iii) to compile, use 00012 and reproduce the modified versions of the Software solely for the purpose 00013 of accessing the MOC Data. In addition, you may distribute the Software, 00014 including any modifications thereof, solely for use with the MOC Data, 00015 provided that (i) you must include this notice with all copies of the 00016 Software to be distributed; (ii) you may not remove or alter any 00017 proprietary notices contained in the Software; (iii) you may not charge any 00018 third party for the Software; and (iv) you will not export the Software 00019 without the appropriate United States and foreign government licenses. 00020 00021 You acknowledge that no title to the intellectual property in the Software 00022 is transferred to you. You further acknowledge that title and full 00023 ownership rights to the Software will remain the exclusive property of MSSS 00024 or its suppliers, and you will not acquire any rights to the Software 00025 except as expressly set forth above. The Software is provided to you AS 00026 IS. MSSS MAKES NO WARRANTY, EXPRESS OR IMPLIED, WITH RESPECT TO THE 00027 SOFTWARE, AND SPECIFICALLY DISCLAIMS THE IMPLIED WARRANTIES OF 00028 NON-INFRINGEMENT OF THIRD PARTY RIGHTS, MERCHANTABILITY AND FITNESS FOR A 00029 PARTICULAR PURPOSE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR 00030 LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO SUCH LIMITATIONS OR 00031 EXCLUSIONS MAY NOT APPLY TO YOU. 00032 00033 Your use or reproduction of the Software constitutes your agreement to the 00034 terms of this Notice. If you do not agree with the terms of this notice, 00035 promptly return or destroy all copies of the Software in your possession. 00036 00037 Copyright (C) 1999 Malin Space Science Systems. All Rights Reserved. 00038 */ 00039 //static char *sccsid = "@(#)getdecode.c 1.1 10/04/99"; 00040 00041 /* 00042 Huffman code tree module 00043 Mike Caplinger, MOC GDS Design Scientist 00044 SCCS @(#)getdecode.c 1.1 11/19/91 00045 00046 This module manages the Ligocki-style Huffman decoding trees for 00047 the predictive decompressor. It is a little roundabout in that 00048 it builds a Huffman code tree in node form from the flight software 00049 encoding tables and then "tablefies" it; that way, separate decoding 00050 tables don't have to be maintained. One can also just load an 00051 existing decode file in (for testing.) 00052 00053 This will probably all go away if the clean canonical decompressor 00054 is ever written. 00055 */ 00056 00057 #include <stdlib.h> 00058 #include <stdio.h> 00059 00060 #include "fs.h" 00061 00062 #define DEFINE_CODE_TABLES 00063 #include "fs.h" 00064 #include "predcode.h" 00065 00066 typedef struct ht_node { 00067 int value; 00068 struct ht_node *zero, *one; 00069 } Huffman_node; 00070 00071 /* in TJL terminology, left is 0 and right is 1. */ 00072 extern uint8 code[], left[], right[]; 00073 00074 void decodeLoad(char *decodefile) 00075 { 00076 unsigned int decodeSize; 00077 FILE *fd; 00078 00079 if((fd = fopen(decodefile, "r")) == NULL) { 00080 (void)fprintf(stderr, "Unable to open '%s' for reading\n", 00081 decodefile); 00082 exit(1); 00083 } 00084 00085 if(fread((char *)(&decodeSize), sizeof(decodeSize), 1, fd) != 1) { 00086 fprintf(stderr, "Unable to read decode file, '%s'\n", decodefile); 00087 exit(1); 00088 } 00089 00090 if(fread(code, sizeof(code[0]), decodeSize, fd) != decodeSize) { 00091 fprintf(stderr, "Unable to read decode file, '%s'\n", decodefile); 00092 exit(1); 00093 } 00094 00095 if(fread(left, sizeof(left[0]), decodeSize, fd) != decodeSize) { 00096 fprintf(stderr, "Unable to read decode file, '%s'\n", decodefile); 00097 exit(1); 00098 } 00099 00100 if(fread(right, sizeof(right[0]), decodeSize, fd) != decodeSize) { 00101 fprintf(stderr, "Unable to read decode file, '%s'\n", decodefile); 00102 exit(1); 00103 } 00104 00105 (void)fclose(fd); 00106 } 00107 00108 Huffman_node *ht_insert(Huffman_node *root, int value, int code, int len) 00109 { 00110 int bit; 00111 Huffman_node **branch; 00112 00113 if(!root) { 00114 root = (Huffman_node *) malloc(sizeof(Huffman_node)); 00115 root->value = 0; 00116 root->zero = root->one = NULL; 00117 } 00118 00119 if(len == 0) { 00120 root->value = value; 00121 } 00122 else { 00123 bit = code & 0x1; 00124 if(bit == 0) branch = &root->zero; 00125 else branch = &root->one; 00126 00127 if(*branch == 0) { 00128 *branch = (Huffman_node *) malloc(sizeof(Huffman_node)); 00129 (*branch)->value = 0; 00130 (*branch)->zero = 0; 00131 (*branch)->one = 0; 00132 } 00133 ht_insert(*branch, value, code >> 1, len - 1); 00134 } 00135 return root; 00136 } 00137 00138 int ht_lookup(Huffman_node *root, int code, int len) 00139 { 00140 int bit; 00141 00142 if(root->zero == 0 && root->one == 0) return root->value; 00143 bit = code & 1; 00144 if(bit == 0) return ht_lookup(root->zero, code >> 1, len - 1); 00145 else return ht_lookup(root->one, code >> 1, len - 1); 00146 } 00147 00148 void ht_dump(Huffman_node *root, int code, int len) 00149 { 00150 if(root->zero == 0 && root->one == 0) { 00151 printf("%d %x(%d)\n", root->value, code, len); 00152 } 00153 else { 00154 if(root->zero) { 00155 ht_dump(root->zero, code, len + 1); 00156 } 00157 if(root->one) { 00158 ht_dump(root->one, code | (1 << len), len + 1); 00159 } 00160 } 00161 } 00162 00163 #define ZERO (1<<0) 00164 #define ONE (1<<1) 00165 00166 /* 00167 Convert a Huffman tree to TJL table form. Call initially 00168 with index = 0. 00169 */ 00170 int ht_tablefy(Huffman_node *root, unsigned char *flags, unsigned char *zero, unsigned char *one, unsigned char *index) 00171 { 00172 int local_index = (int)(long)(index); 00173 00174 if(root->zero) { 00175 if(root->zero->zero == 0 && root->zero->one == 0) { 00176 flags[(int)(long)index] &= ~ZERO; 00177 zero[(int)(long)index] = root->zero->value; 00178 } 00179 else { 00180 flags[local_index] |= ZERO; 00181 index += 1; 00182 zero[local_index] = (char)(long)index; 00183 index = (unsigned char*)(long)ht_tablefy(root->zero, flags, zero, one, index); 00184 } 00185 } 00186 if(root->one) { 00187 if(root->one->zero == 0 && root->one->one == 0) { 00188 flags[local_index] &= ~ONE; 00189 one[local_index] = root->one->value; 00190 } 00191 else { 00192 flags[local_index] |= ONE; 00193 index += 1; 00194 one[local_index] = (char)(long)index; 00195 index = (unsigned char*)(long)ht_tablefy(root->one, flags, zero, one, index); 00196 } 00197 } 00198 return (int)(long)index; 00199 } 00200 00201 Huffman_node *ht_tree_gen(int i) 00202 { 00203 Huffman_node *tree = 0; 00204 uint16 *code; 00205 uint8 *len; 00206 uint8 *requant; 00207 00208 code = CodeBitsVec[i]; 00209 len = CodeLenVec[i]; 00210 requant = CodeRequantVec[i]; 00211 00212 tree = ht_insert(tree, requant[0], code[0], len[0]); 00213 00214 for(i = 1; i < 128; i++) { 00215 if(requant[i] != requant[i-1]) 00216 tree = ht_insert(tree, requant[i], code[i], len[i]); 00217 } 00218 00219 tree = ht_insert(tree, requant[255], code[255], len[255]); 00220 00221 for(i = 254; i >= 128; i--) { 00222 if(requant[i] != requant[i+1]) 00223 tree = ht_insert(tree, requant[i], code[i], len[i]); 00224 } 00225 return tree; 00226 } 00227 00228 void ht_free(Huffman_node *root) 00229 { 00230 if(root->zero) ht_free(root->zero); 00231 if(root->one) ht_free(root->one); 00232 free(root); 00233 } 00234 00235 void decodeInit(int n) { 00236 Huffman_node *tree = 0; 00237 // uint8 flags[256], zero[256], one[256]; 00238 00239 tree = ht_tree_gen(n); 00240 /* i is the # of slots actually used... */ 00241 ht_tablefy(tree, code, left, right, 0); 00242 ht_free(tree); 00243 }