1 11 package org.eclipse.swt.internal.image; 12 13 import java.io.*; 14 15 public class PngHuffmanTable { 16 CodeLengthInfo[] codeLengthInfo; 17 int[] codeValues; 18 19 static final int MAX_CODE_LENGTH = 15; 20 static final int BAD_CODE = 0xFFFFFFF; 21 static final int incs[] = {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}; 22 23 PngHuffmanTable (int[] lengths) { 24 super(); 25 initialize(lengths); 26 generateTable(lengths); 27 } 28 29 private void initialize(int[] lengths) { 30 codeValues = new int[lengths.length]; 31 for (int i = 0; i < codeValues.length; i++) { 32 codeValues[i] = i; 33 } 34 35 codeLengthInfo = new CodeLengthInfo[MAX_CODE_LENGTH]; 39 for (int i = 0; i < MAX_CODE_LENGTH; i++) { 40 codeLengthInfo[i] = new CodeLengthInfo(); 41 codeLengthInfo[i].length = i; 42 codeLengthInfo[i].baseIndex = 0; 43 codeLengthInfo[i].min = BAD_CODE; 44 codeLengthInfo[i].max = -1; 45 } 46 } 47 48 private void generateTable(int[] lengths) { 49 int codeValuesTemp; 51 for (int k = 0; k < 16; k++) { 52 for (int h = incs[k], i = h; i < lengths.length; i++) { 53 int v = lengths[i]; 54 codeValuesTemp = codeValues[i]; 55 int j = i; 56 while (j >= h && (lengths[j - h] > v || (lengths[j - h] == v && codeValues[j - h] > codeValuesTemp))) { 57 lengths[j] = lengths[j - h]; 58 codeValues[j] = codeValues[j - h]; 59 j -= h; 60 } 61 lengths[j] = v; 62 codeValues[j] = codeValuesTemp; 63 } 64 } 65 66 int[] codes = new int[lengths.length]; 70 int lastLength = 0; 71 int code = 0; 72 for (int i = 0; i < lengths.length; i++) { 73 while (lastLength != lengths[i]) { 74 lastLength++; 75 code <<= 1; 76 } 77 if (lastLength != 0) { 78 codes[i] = code; 79 code++; 80 } 81 } 82 83 int last = 0; 84 for (int i = 0; i < lengths.length; i++) { 85 if (last != lengths[i]) { 86 last = lengths[i]; 87 codeLengthInfo[last - 1].baseIndex = i; 88 codeLengthInfo[last - 1].min = codes[i]; 89 } 90 if (last != 0) codeLengthInfo[last - 1].max = codes[i]; 91 } 92 } 93 94 int getNextValue(PngDecodingDataStream stream) throws IOException { 95 int code = stream.getNextIdatBit(); 96 int codelength = 0; 97 98 while (codelength < MAX_CODE_LENGTH && code > codeLengthInfo[codelength].max) { 101 code = ((code << 1) | stream.getNextIdatBit()); 102 codelength++; 103 } 104 if (codelength >= MAX_CODE_LENGTH) stream.error(); 105 106 int offset = code - codeLengthInfo[codelength].min; 111 112 int index = codeLengthInfo[codelength].baseIndex + offset; 115 return codeValues[index]; 116 } 117 118 class CodeLengthInfo { 119 int length; 120 int max; 121 int min; 122 int baseIndex; 123 } 124 125 } 126 | Popular Tags |