/* */ package com.sun.j3d.utils.compression;
/* */
/* */ import java.io.PrintStream;
/* */ import java.util.Collection;
/* */ import java.util.Collections;
/* */ import java.util.Comparator;
/* */ import java.util.Iterator;
/* */ import java.util.LinkedList;
/* */ import java.util.ListIterator;
/* */
/* */ class HuffmanTable
/* */ {
/* */ private static final int MAX_TAG_LENGTH = 6;
/* */ private HuffmanNode[] positions;
/* */ private HuffmanNode[] normals;
/* */ private HuffmanNode[] colors;
/* */
/* */ HuffmanTable()
/* */ {
/* 75 */ this.colors = new HuffmanNode[544];
/* 76 */ this.positions = new HuffmanNode[544];
/* */
/* 84 */ this.normals = new HuffmanNode[112];
/* */ }
/* */
/* */ private final int getPositionIndex(int len, int shift, boolean absolute) {
/* 88 */ return (absolute ? 1 : 0) * 272 + len * 16 + shift;
/* */ }
/* */
/* */ private final int getNormalIndex(int length, int shift, boolean absolute) {
/* 92 */ return (absolute ? 1 : 0) * 56 + length * 7 + shift;
/* */ }
/* */
/* */ private final int getColorIndex(int length, int shift, boolean absolute) {
/* 96 */ return getPositionIndex(length, shift, absolute);
/* */ }
/* */
/* */ void addPositionEntry(int length, int shift, boolean absolute)
/* */ {
/* 110 */ addEntry(this.positions, getPositionIndex(length, shift, absolute), length, shift, absolute);
/* */ }
/* */
/* */ HuffmanNode getPositionEntry(int length, int shift, boolean absolute)
/* */ {
/* 128 */ return getEntry(this.positions, getPositionIndex(length, shift, absolute));
/* */ }
/* */
/* */ void addColorEntry(int length, int shift, boolean absolute)
/* */ {
/* 141 */ addEntry(this.colors, getColorIndex(length, shift, absolute), length, shift, absolute);
/* */ }
/* */
/* */ HuffmanNode getColorEntry(int length, int shift, boolean absolute)
/* */ {
/* 159 */ return getEntry(this.colors, getColorIndex(length, shift, absolute));
/* */ }
/* */
/* */ void addNormalEntry(int length, int shift, boolean absolute)
/* */ {
/* 172 */ addEntry(this.normals, getNormalIndex(length, shift, absolute), length, shift, absolute);
/* */ }
/* */
/* */ HuffmanNode getNormalEntry(int length, int shift, boolean absolute)
/* */ {
/* 190 */ return getEntry(this.normals, getNormalIndex(length, shift, absolute));
/* */ }
/* */
/* */ private void addEntry(HuffmanNode[] table, int index, int length, int shift, boolean absolute)
/* */ {
/* 197 */ if (table[index] == null) {
/* 198 */ table[index] = new HuffmanNode(length, shift, absolute);
/* */ }
/* 200 */ else if (table[index].cleared()) {
/* 201 */ table[index].set(length, shift, absolute);
/* */ }
/* 203 */ table[index].addCount();
/* */ }
/* */
/* */ private HuffmanNode getEntry(HuffmanNode[] table, int index) {
/* 207 */ HuffmanNode t = table[index];
/* */
/* 209 */ while (t.merged()) {
/* 210 */ t = t.getMergeNode();
/* */ }
/* 212 */ return t;
/* */ }
/* */
/* */ private void getEntries(HuffmanNode[] table, Collection c) {
/* 216 */ for (int i = 0; i < table.length; i++)
/* 217 */ if ((table[i] != null) && (!table[i].cleared()) && (table[i].hasCount()) && (!table[i].merged()))
/* */ {
/* 219 */ c.add(table[i]);
/* */ }
/* */ }
/* */
/* */ void clear()
/* */ {
/* 227 */ for (int i = 0; i < this.positions.length; i++) {
/* 228 */ if (this.positions[i] != null)
/* 229 */ this.positions[i].clear();
/* */ }
/* 231 */ for (int i = 0; i < this.colors.length; i++) {
/* 232 */ if (this.colors[i] != null)
/* 233 */ this.colors[i].clear();
/* */ }
/* 235 */ for (int i = 0; i < this.normals.length; i++)
/* 236 */ if (this.normals[i] != null)
/* 237 */ this.normals[i].clear();
/* */ }
/* */
/* */ void computeTags()
/* */ {
/* 244 */ LinkedList nodeList = new LinkedList();
/* 245 */ getEntries(this.positions, nodeList);
/* 246 */ computeTags(nodeList, 3);
/* */
/* 248 */ nodeList.clear();
/* 249 */ getEntries(this.colors, nodeList);
/* 250 */ computeTags(nodeList, 3);
/* */
/* 252 */ nodeList.clear();
/* 253 */ getEntries(this.normals, nodeList);
/* 254 */ computeTags(nodeList, 2);
/* */ }
/* */
/* */ private void computeTags(LinkedList nodes, int minComponentCount)
/* */ {
/* 264 */ if (nodes.isEmpty()) {
/* */ return;
/* */ }
/* */ while (true)
/* */ {
/* 269 */ Collections.sort(nodes, HuffmanNode.frequencyComparator);
/* */
/* 273 */ HuffmanNode node0 = (HuffmanNode)nodes.removeFirst();
/* 274 */ while (nodes.size() > 0) {
/* 275 */ HuffmanNode node1 = (HuffmanNode)nodes.removeFirst();
/* 276 */ HuffmanNode node2 = new HuffmanNode();
/* */
/* 278 */ node2.addChildren(node0, node1);
/* 279 */ addNodeInOrder(nodes, node2, HuffmanNode.frequencyComparator);
/* */
/* 281 */ node0 = (HuffmanNode)nodes.removeFirst();
/* */ }
/* */
/* 287 */ node0.collectLeaves(0, 0, nodes);
/* */
/* 290 */ Collections.sort(nodes, HuffmanNode.tagLengthComparator);
/* */
/* 293 */ if (((HuffmanNode)nodes.getFirst()).tagLength <= 6) {
/* */ break;
/* */ }
/* 296 */ merge(nodes);
/* */ }
/* */
/* 300 */ expand(nodes, minComponentCount);
/* */ }
/* */
/* */ private void merge(LinkedList nodes)
/* */ {
/* 313 */ ListIterator i = nodes.listIterator(0);
/* */
/* 315 */ int index = 0;
/* */
/* 317 */ while (i.hasNext())
/* */ {
/* 319 */ HuffmanNode node0 = (HuffmanNode)i.next();
/* 320 */ if (!node0.unmergeable())
/* */ {
/* 324 */ i.remove();
/* 325 */ while (i.hasNext()) {
/* 326 */ HuffmanNode node1 = (HuffmanNode)i.next();
/* 327 */ if (node0.mergeInto(node1))
/* */ {
/* 332 */ i.remove();
/* 333 */ while (i.hasNext()) {
/* 334 */ HuffmanNode node2 = (HuffmanNode)i.next();
/* 335 */ if (node1.tokenEquals(node2)) {
/* 336 */ node1.mergeInto(node2);
/* 337 */ return;
/* */ }
/* */ }
/* */
/* 341 */ i.add(node1);
/* 342 */ return;
/* */ }
/* */
/* */ }
/* */
/* 350 */ node0.setUnmergeable();
/* 351 */ i.add(node0);
/* */
/* 354 */ i = nodes.listIterator(0);
/* */ }
/* */ }
/* */ }
/* */
/* */ private void expand(LinkedList nodes, int minComponentCount)
/* */ {
/* 364 */ Iterator i = nodes.iterator();
/* */
/* 366 */ while (i.hasNext()) {
/* 367 */ HuffmanNode n = (HuffmanNode)i.next();
/* */
/* 370 */ while (n.tagLength + minComponentCount * (n.dataLength - n.shift) < 6)
/* */ {
/* 372 */ n.incrementLength();
/* */ }
/* */ }
/* */ }
/* */
/* */ private void addNodeInOrder(LinkedList l, HuffmanNode node, Comparator c)
/* */ {
/* 381 */ ListIterator i = l.listIterator(0);
/* */
/* 383 */ while (i.hasNext()) {
/* 384 */ HuffmanNode n = (HuffmanNode)i.next();
/* 385 */ if (c.compare(n, node) > 0) {
/* 386 */ n = (HuffmanNode)i.previous();
/* 387 */ break;
/* */ }
/* */ }
/* 390 */ i.add(node);
/* */ }
/* */
/* */ void outputCommands(CommandStream output)
/* */ {
/* 400 */ LinkedList nodeList = new LinkedList();
/* 401 */ getEntries(this.positions, nodeList);
/* 402 */ outputCommands(nodeList, output, 0);
/* */
/* 404 */ nodeList.clear();
/* 405 */ getEntries(this.colors, nodeList);
/* 406 */ outputCommands(nodeList, output, 1);
/* */
/* 408 */ nodeList.clear();
/* 409 */ getEntries(this.normals, nodeList);
/* 410 */ outputCommands(nodeList, output, 2);
/* */ }
/* */
/* */ private void outputCommands(Collection nodes, CommandStream output, int tableId)
/* */ {
/* 419 */ Iterator i = nodes.iterator();
/* 420 */ while (i.hasNext()) {
/* 421 */ HuffmanNode n = (HuffmanNode)i.next();
/* 422 */ int addressRange = 1 << n.tagLength | n.tag;
/* 423 */ int dataLength = n.dataLength == 16 ? 0 : n.dataLength;
/* */
/* 425 */ int command = 0x10 | tableId << 1 | addressRange >> 6;
/* */
/* 428 */ long body = (addressRange & 0x3F) << 9 | dataLength << 5 | (n.absolute ? 16 : 0) | n.shift;
/* */
/* 432 */ output.addCommand(command, 8, body, 15);
/* */ }
/* */ }
/* */
/* */ void print(String header, Collection nodes)
/* */ {
/* 443 */ System.out.println(header + "\nentries: " + nodes.size() + "\n");
/* */
/* 445 */ Iterator i = nodes.iterator();
/* 446 */ while (i.hasNext()) {
/* 447 */ HuffmanNode n = (HuffmanNode)i.next();
/* 448 */ System.out.println(n.toString() + "\n");
/* */ }
/* */ }
/* */
/* */ void print()
/* */ {
/* 456 */ LinkedList nodeList = new LinkedList();
/* */
/* 458 */ getEntries(this.positions, nodeList);
/* 459 */ Collections.sort(nodeList, HuffmanNode.frequencyComparator);
/* 460 */ print("\nposition tokens and tags", nodeList);
/* */
/* 462 */ nodeList.clear();
/* 463 */ getEntries(this.colors, nodeList);
/* 464 */ Collections.sort(nodeList, HuffmanNode.frequencyComparator);
/* 465 */ print("\ncolor tokens and tags", nodeList);
/* */
/* 467 */ nodeList.clear();
/* 468 */ getEntries(this.normals, nodeList);
/* 469 */ Collections.sort(nodeList, HuffmanNode.frequencyComparator);
/* 470 */ print("\nnormal tokens and tags", nodeList);
/* */ }
/* */ }
/* Location: Z:\System\Library\Java\Extensions\j3dutils.jar
* Qualified Name: com.sun.j3d.utils.compression.HuffmanTable
* JD-Core Version: 0.6.2
*/