Source for gnu.javax.imageio.jpeg.HuffmanTable

   1: /* HuffmanTable.java --
   2:    Copyright (C)  2006  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.javax.imageio.jpeg;
  39: 
  40: import java.io.IOException;
  41: 
  42: import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
  43: 
  44: 
  45: /**
  46:  * This Object construct a JPEGHuffmanTable which can be used to encode/decode
  47:  * a scan from a JPEG codec stream. The table must be initalized with either a
  48:  * BITS byte amount and a Huffman Table Value for decoding or a Huffman Size
  49:  * and Huffman Code table for encoding.
  50:  */
  51: public class HuffmanTable
  52: {
  53:   public final static int HUFFMAN_MAX_TABLES = 4;
  54: 
  55:   private short[]  huffcode = new short[256];
  56:   private short[]  huffsize = new short[256];
  57:   private short[]  EHUFCO;
  58:   private short[]  EHUFSI;
  59:   private short[]  valptr = new short[16];
  60:   private short[]  mincode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  61:                             -1,-1,-1};
  62:   private short[]  maxcode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  63:                             -1, -1, -1};
  64:   private short[] huffval;
  65:   private short[] bits;
  66: 
  67:   static byte JPEG_DC_TABLE = 0;
  68:   static byte JPEG_AC_TABLE = 1;
  69: 
  70:   private short lastk = 0;
  71: 
  72:   public HuffmanTable(JPEGHuffmanTable table)
  73:   {
  74:     huffcode = table.getValues();
  75:     bits = table.getLengths();
  76:   }
  77: 
  78:   /**
  79:    * Generated from FIGURE C.1 - Generation of table of Huffman code sizes on
  80:    * ISO DIS 10918-1. Requirements and Guidelines
  81:    */
  82:   private void generateSizeTable()
  83:   {
  84:     short index=0;
  85:     for(short i=0; i < bits.length ; i++)
  86:       {
  87:         for(short j=0; j < bits[i] ; j++)
  88:           {
  89:             huffsize[index] = (short) (i+1);
  90:             index++;
  91:           }
  92:       }
  93:     lastk = index;
  94:   }
  95: 
  96:   /**
  97:    * Generated from FIGURE C.2 - Generation of table of Huffman codes on
  98:    * ISO DIS 10918-1. Requirements and Guidelines
  99:    */
 100:   private void generateCodeTable()
 101:   {
 102:     short k=0;
 103:     short si = huffsize[0];
 104:     short code = 0;
 105:     for(short i=0; i < huffsize.length ; i++)
 106:       {
 107:         while(huffsize[k]==si)
 108:           {
 109:             huffcode[k] = code;
 110:             code++;
 111:             k++;
 112:           }
 113:         code <<= 1;
 114:         si++;
 115:       }
 116:   }
 117: 
 118:   /**
 119:    * Generated from FIGURE F.15 - Generation of decode table generation on
 120:    * ISO DIS 10918-1. Requirements and Guidelines
 121:    */
 122:   private void generateDecoderTables()
 123:   {
 124:     short bitcount = 0;
 125:     for(int i=0; i < 16 ; i++)
 126:       {
 127:         if(bits[i]!=0)
 128:           valptr[i] = bitcount;
 129:         for(int j=0 ; j < bits[i] ; j++)
 130:           {
 131:             if(huffcode[j+bitcount] < mincode[i] || mincode[i] == -1)
 132:               mincode[i] = huffcode[j+bitcount];
 133: 
 134:             if(huffcode[j+bitcount] > maxcode[i])
 135:               maxcode[i] = huffcode[j+bitcount];
 136:           }
 137:         if(mincode[i]!=-1)
 138:           valptr[i] = (short) (valptr[i] - mincode[i]);
 139:         bitcount += bits[i];
 140:       }
 141:   }
 142: 
 143:   /**
 144:    * Generated from FIGURE C.3 - Generation of Order Codes and tables EHUFCO
 145:    * and EHUFSI from the ISO DIS 10918-1. Requirements and Guidelines
 146:    */
 147:   public void orderCodes(boolean isDC)
 148:   {
 149:     EHUFCO = new short[isDC ? 15 : 255];
 150:     EHUFSI = new short[isDC ? 15 : 255];
 151: 
 152:     for (int p=0; p < lastk ; p++)
 153:       {
 154:         int i = huffval[p];
 155:         if(i < 0 || i > EHUFCO.length || EHUFSI[i]!=0)
 156:           System.err.println("Error, bad huffman table.");
 157:         EHUFCO[i] = huffcode[p];
 158:         EHUFSI[i] = huffsize[p];
 159:       }
 160:   }
 161: 
 162:   /**
 163:    * Generated from FIGURE F.12 - Extending the sign bit of a decoded value in on
 164:    * ISO DIS 10918-1. Requirements and Guidelines<p>
 165:    *
 166:    * @param diff TODO
 167:    * @param t TODO
 168:    * @return TODO
 169:    */
 170:   public static int extend(int diff, int t)
 171:   {
 172:     int Vt = (int)Math.pow(2,(t-1));
 173:     if(diff<Vt)
 174:       {
 175:         Vt=(-1 << t)+1;
 176:         diff=diff+Vt;
 177:       }
 178:     return diff;
 179:   }
 180: 
 181:   /**
 182:    * Generated from FIGURE F.16 - Procedure for DECODE on
 183:    * ISO DIS 10918-1. Requirements and Guidelines<p>
 184:    *
 185:    * This function takes in a dynamic amount of bits and using the Huffman
 186:    * table returns information on how many bits must be read in to a byte in
 187:    * order to reconstruct said byte.
 188:    *
 189:    * @param JPEGStream the bits of the data stream.
 190:    */
 191:   public int decode(JPEGImageInputStream JPEGStream)
 192:     throws IOException, JPEGException
 193:   {
 194:     int i=0;
 195:     short code = (short) JPEGStream.readBits(1);
 196:     while(code > maxcode[i])
 197:       {
 198:         i++;
 199:         code <<= 1;
 200:         code |= JPEGStream.readBits(1);
 201:       }
 202:     int val = huffval[code+(valptr[i])];
 203:     if(val < 0)
 204:       val = 256 + val;
 205:     return val;
 206:   }
 207: }