1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.internal.image;
18 public class PngHuffmanTables {
19 PngHuffmanTable literalTable;
20 PngHuffmanTable distanceTable;
22 static PngHuffmanTable FixedLiteralTable;
23 static PngHuffmanTable FixedDistanceTable;
25 static final int LiteralTableSize = 288;
26 static final int[] FixedLiteralLengths = {
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 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
31 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
32 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
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, 9, 9, 9, 9, 9, 9, 9, 9,
35 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
36 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
37 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7,
38 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
41 static final int DistanceTableSize = 32;
42 static final int[] FixedDistanceLengths = {
43 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
44 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
47 static final int LengthCodeTableSize = 19;
48 static final int[] LengthCodeOrder = {
49 16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
50 11, 4, 12, 3, 13, 2, 14, 1, 15
53 static PngHuffmanTables getDynamicTables(PngDecodingDataStream stream) throws IOException {
54 return new PngHuffmanTables(stream);
56 static PngHuffmanTables getFixedTables() {
57 return new PngHuffmanTables();
60 private PngHuffmanTable getFixedLiteralTable() {
61 if (FixedLiteralTable == null) {
62 FixedLiteralTable = new PngHuffmanTable(FixedLiteralLengths);
64 return FixedLiteralTable;
67 private PngHuffmanTable getFixedDistanceTable() {
68 if (FixedDistanceTable == null) {
69 FixedDistanceTable = new PngHuffmanTable(FixedDistanceLengths);
71 return FixedDistanceTable;
74 private PngHuffmanTables () {
75 literalTable = getFixedLiteralTable();
76 distanceTable = getFixedDistanceTable();
79 private PngHuffmanTables (PngDecodingDataStream stream) throws IOException {
80 int literals = PngLzBlockReader.FIRST_LENGTH_CODE
81 + stream.getNextIdatBits(5);
82 int distances = PngLzBlockReader.FIRST_DISTANCE_CODE
83 + stream.getNextIdatBits(5);
84 int codeLengthCodes = PngLzBlockReader.FIRST_CODE_LENGTH_CODE
85 + stream.getNextIdatBits(4);
87 if (codeLengthCodes > PngLzBlockReader.LAST_CODE_LENGTH_CODE) {
91 /* Tricky, tricky, tricky. The length codes are stored in
92 * a very odd order. (For the order, see the definition of
93 * the static field lengthCodeOrder.) Also, the data may
94 * not contain values for all the codes. It may just contain
95 * values for the first X number of codes. The table should
96 * be of size <LengthCodeTableSize> regardless of the number
97 * of values actually given in the table.
99 int[] lengthCodes = new int[LengthCodeTableSize];
100 for (int i = 0; i < codeLengthCodes; i++) {
101 lengthCodes[LengthCodeOrder[i]] = stream.getNextIdatBits(3);
103 PngHuffmanTable codeLengthsTable = new PngHuffmanTable(lengthCodes);
105 int[] literalLengths = readLengths(
106 stream, literals, codeLengthsTable, LiteralTableSize);
107 int[] distanceLengths = readLengths(
108 stream, distances, codeLengthsTable, DistanceTableSize);
110 literalTable = new PngHuffmanTable(literalLengths);
111 distanceTable = new PngHuffmanTable(distanceLengths);
114 private int [] readLengths (PngDecodingDataStream stream,
116 PngHuffmanTable lengthsTable,
117 int tableSize) throws IOException
119 int[] lengths = new int[tableSize];
121 for (int index = 0; index < numLengths;) {
122 int value = lengthsTable.getNextValue(stream);
125 lengths[index] = value;
127 } else if (value == 16) {
128 // Repeat the previous code 3-6 times.
129 int count = stream.getNextIdatBits(2) + 3;
130 for (int i = 0; i < count; i++) {
131 lengths[index] = lengths [index - 1];
134 } else if (value == 17) {
135 // Repeat 0 3-10 times.
136 int count = stream.getNextIdatBits(3) + 3;
137 for (int i = 0; i < count; i++) {
141 } else if (value == 18) {
142 // Repeat 0 11-138 times.
143 int count = stream.getNextIdatBits(7) + 11;
144 for (int i = 0; i < count; i++) {
155 int getNextLiteralValue(PngDecodingDataStream stream) throws IOException {
156 return literalTable.getNextValue(stream);
159 int getNextDistanceValue(PngDecodingDataStream stream) throws IOException {
160 return distanceTable.getNextValue(stream);