USGS

Isis 3.0 Application Source Code Reference

Home

getdecode.cpp

Go to the documentation of this file.
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 }