Frames | No Frames |
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: }