1 11 package org.eclipse.swt.internal.image; 12 13 import java.io.*; 14 15 public class PngHuffmanTables { 16 PngHuffmanTable literalTable; 17 PngHuffmanTable distanceTable; 18 19 static PngHuffmanTable FixedLiteralTable; 20 static PngHuffmanTable FixedDistanceTable; 21 22 static final int LiteralTableSize = 288; 23 static final int[] FixedLiteralLengths = { 24 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 25 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 27 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 28 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 29 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 30 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 31 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 32 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 33 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 34 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 35 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 36 }; 37 38 static final int DistanceTableSize = 32; 39 static final int[] FixedDistanceLengths = { 40 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 41 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 42 }; 43 44 static final int LengthCodeTableSize = 19; 45 static final int[] LengthCodeOrder = { 46 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 47 11, 4, 12, 3, 13, 2, 14, 1, 15 48 }; 49 50 static PngHuffmanTables getDynamicTables(PngDecodingDataStream stream) throws IOException { 51 return new PngHuffmanTables(stream); 52 } 53 static PngHuffmanTables getFixedTables() { 54 return new PngHuffmanTables(); 55 } 56 57 private PngHuffmanTable getFixedLiteralTable() { 58 if (FixedLiteralTable == null) { 59 FixedLiteralTable = new PngHuffmanTable(FixedLiteralLengths); 60 } 61 return FixedLiteralTable; 62 } 63 64 private PngHuffmanTable getFixedDistanceTable() { 65 if (FixedDistanceTable == null) { 66 FixedDistanceTable = new PngHuffmanTable(FixedDistanceLengths); 67 } 68 return FixedDistanceTable; 69 } 70 71 private PngHuffmanTables () { 72 literalTable = getFixedLiteralTable(); 73 distanceTable = getFixedDistanceTable(); 74 } 75 76 private PngHuffmanTables (PngDecodingDataStream stream) throws IOException { 77 int literals = PngLzBlockReader.FIRST_LENGTH_CODE 78 + stream.getNextIdatBits(5); 79 int distances = PngLzBlockReader.FIRST_DISTANCE_CODE 80 + stream.getNextIdatBits(5); 81 int codeLengthCodes = PngLzBlockReader.FIRST_CODE_LENGTH_CODE 82 + stream.getNextIdatBits(4); 83 84 if (codeLengthCodes > PngLzBlockReader.LAST_CODE_LENGTH_CODE) { 85 stream.error(); 86 } 87 88 96 int[] lengthCodes = new int[LengthCodeTableSize]; 97 for (int i = 0; i < codeLengthCodes; i++) { 98 lengthCodes[LengthCodeOrder[i]] = stream.getNextIdatBits(3); 99 } 100 PngHuffmanTable codeLengthsTable = new PngHuffmanTable(lengthCodes); 101 102 int[] literalLengths = readLengths( 103 stream, literals, codeLengthsTable, LiteralTableSize); 104 int[] distanceLengths = readLengths( 105 stream, distances, codeLengthsTable, DistanceTableSize); 106 107 literalTable = new PngHuffmanTable(literalLengths); 108 distanceTable = new PngHuffmanTable(distanceLengths); 109 } 110 111 private int [] readLengths (PngDecodingDataStream stream, 112 int numLengths, 113 PngHuffmanTable lengthsTable, 114 int tableSize) throws IOException 115 { 116 int[] lengths = new int[tableSize]; 117 118 for (int index = 0; index < numLengths;) { 119 int value = lengthsTable.getNextValue(stream); 120 if (value < 16) { 121 lengths[index] = value; 123 index++; 124 } else if (value == 16) { 125 int count = stream.getNextIdatBits(2) + 3; 127 for (int i = 0; i < count; i++) { 128 lengths[index] = lengths [index - 1]; 129 index++; 130 } 131 } else if (value == 17) { 132 int count = stream.getNextIdatBits(3) + 3; 134 for (int i = 0; i < count; i++) { 135 lengths[index] = 0; 136 index++; 137 } 138 } else if (value == 18) { 139 int count = stream.getNextIdatBits(7) + 11; 141 for (int i = 0; i < count; i++) { 142 lengths[index] = 0; 143 index++; 144 } 145 } else { 146 stream.error(); 147 } 148 } 149 return lengths; 150 } 151 152 int getNextLiteralValue(PngDecodingDataStream stream) throws IOException { 153 return literalTable.getNextValue(stream); 154 } 155 156 int getNextDistanceValue(PngDecodingDataStream stream) throws IOException { 157 return distanceTable.getNextValue(stream); 158 } 159 160 } 161 | Popular Tags |