/* */ package com.sun.j3d.utils.compression;
/* */
/* */ import java.io.FileNotFoundException;
/* */ import java.io.IOException;
/* */ import java.io.PrintStream;
/* */ import java.io.RandomAccessFile;
/* */ import javax.media.j3d.CompressedGeometry;
/* */ import javax.media.j3d.CompressedGeometryHeader;
/* */
/* */ public class CompressedGeometryFile
/* */ {
/* */ private static final boolean print = false;
/* */ private static final boolean benchmark = false;
/* */ static final int MAGIC_NUMBER = -1159857484;
/* */ static final int MAGIC_NUMBER_OFFSET = 0;
/* */ static final int MAJOR_VERSION_OFFSET = 4;
/* */ static final int MINOR_VERSION_OFFSET = 8;
/* */ static final int MINOR_MINOR_VERSION_OFFSET = 12;
/* */ static final int OBJECT_COUNT_OFFSET = 16;
/* */ static final int DIRECTORY_OFFSET_OFFSET = 24;
/* */ static final int HEADER_SIZE = 32;
/* */ static final int OBJECT_SIZE_OFFSET = 0;
/* */ static final int GEOM_DATA_OFFSET = 4;
/* */ static final int TYPE_MASK = 3;
/* */ static final int NORMAL_PRESENT_MASK = 4;
/* */ static final int COLOR_PRESENT_MASK = 8;
/* */ static final int ALPHA_PRESENT_MASK = 16;
/* */ static final int TYPE_POINT = 1;
/* */ static final int TYPE_LINE = 2;
/* */ static final int TYPE_TRIANGLE = 3;
/* */ static final int BLOCK_HEADER_SIZE = 8;
/* 162 */ String fileName = null;
/* */ int majorVersionNumber;
/* */ int minorVersionNumber;
/* */ int minorMinorVersionNumber;
/* */ int objectCount;
/* 175 */ int objectIndex = 0;
/* */
/* 178 */ RandomAccessFile cgFile = null;
/* */ int magicNumber;
/* */ byte[] cgBuffer;
/* */ int geomSize;
/* */ int geomStart;
/* */ int geomDataType;
/* */ long[] directory;
/* */ long directoryOffset;
/* */ int[] objectSizes;
/* */ int bufferObjectStart;
/* */ int bufferObjectCount;
/* */ int bufferNextObjectCount;
/* */ int bufferNextObjectOffset;
/* */ CompressedGeometryHeader cgh;
/* 206 */ boolean fileUpdate = false;
/* */
/* */ public CompressedGeometryFile(String file)
/* */ throws IOException
/* */ {
/* 221 */ this(file, false);
/* */ }
/* */
/* */ public CompressedGeometryFile(String file, boolean rw)
/* */ throws IOException
/* */ {
/* 240 */ open(file, rw);
/* */
/* 243 */ this.fileName = new String(file);
/* */
/* 246 */ initialize();
/* */ }
/* */
/* */ public CompressedGeometryFile(RandomAccessFile file)
/* */ throws IOException
/* */ {
/* 260 */ this.cgFile = file;
/* */
/* 263 */ initialize();
/* */ }
/* */
/* */ public void clear()
/* */ throws IOException
/* */ {
/* 278 */ this.cgFile.setLength(0L);
/* */
/* 281 */ initialize();
/* */ }
/* */
/* */ public String getFileName()
/* */ {
/* 292 */ return this.fileName;
/* */ }
/* */
/* */ public int getMajorVersionNumber()
/* */ {
/* 302 */ return this.majorVersionNumber;
/* */ }
/* */
/* */ public int getMinorVersionNumber()
/* */ {
/* 312 */ return this.minorVersionNumber;
/* */ }
/* */
/* */ public int getMinorMinorVersionNumber()
/* */ {
/* 322 */ return this.minorMinorVersionNumber;
/* */ }
/* */
/* */ public int getObjectCount()
/* */ {
/* 331 */ return this.objectCount;
/* */ }
/* */
/* */ public int getCurrentIndex()
/* */ {
/* 343 */ if (this.objectIndex == this.objectCount) {
/* 344 */ return -1;
/* */ }
/* 346 */ return this.objectIndex;
/* */ }
/* */
/* */ public CompressedGeometry readNext()
/* */ throws IOException
/* */ {
/* 362 */ return readNext(this.cgBuffer.length);
/* */ }
/* */
/* */ public CompressedGeometry[] read()
/* */ throws IOException
/* */ {
/* 374 */ long startTime = 0L;
/* 375 */ CompressedGeometry[] cg = new CompressedGeometry[this.objectCount];
/* */
/* 380 */ this.objectIndex = 0;
/* 381 */ setFilePointer(this.directory[0]);
/* 382 */ this.bufferNextObjectCount = 0;
/* */
/* 384 */ for (int i = 0; i < this.objectCount; i++) {
/* 385 */ cg[i] = readNext(this.cgBuffer.length);
/* */ }
/* */
/* 395 */ return cg;
/* */ }
/* */
/* */ public CompressedGeometry read(int index)
/* */ throws IOException
/* */ {
/* 411 */ this.objectIndex = index;
/* */
/* 413 */ if (this.objectIndex < 0) {
/* 414 */ throw new IndexOutOfBoundsException("\nobject index must be >= 0");
/* */ }
/* */
/* 417 */ if (this.objectIndex >= this.objectCount) {
/* 418 */ throw new IndexOutOfBoundsException("\nobject index must be < " + this.objectCount);
/* */ }
/* */
/* 423 */ if ((this.objectIndex >= this.bufferObjectStart) && (this.objectIndex < this.bufferObjectStart + this.bufferObjectCount))
/* */ {
/* 427 */ this.bufferNextObjectOffset = ((int)(this.directory[this.objectIndex] - this.directory[this.bufferObjectStart]));
/* */
/* 430 */ this.bufferNextObjectCount = (this.bufferObjectCount - (this.objectIndex - this.bufferObjectStart));
/* */
/* 433 */ return readNext();
/* */ }
/* */
/* 437 */ setFilePointer(this.directory[this.objectIndex]);
/* */
/* 441 */ this.bufferNextObjectCount = 0;
/* 442 */ return readNext(this.objectSizes[this.objectIndex]);
/* */ }
/* */
/* */ public void write(CompressedGeometry cg)
/* */ throws IOException
/* */ {
/* 459 */ CompressedGeometryHeader cgh = new CompressedGeometryHeader();
/* 460 */ cg.getCompressedGeometryHeader(cgh);
/* */
/* 463 */ if (cgh.size + 8 > this.cgBuffer.length) {
/* 464 */ this.cgBuffer = new byte[cgh.size + 8];
/* */ }
/* */
/* 470 */ cg.getCompressedGeometry(this.cgBuffer);
/* 471 */ write(cgh, this.cgBuffer);
/* */ }
/* */
/* */ public void write(CompressedGeometryHeader cgh, byte[] geometry)
/* */ throws IOException
/* */ {
/* 491 */ if (cgh.size + 8 > this.cgBuffer.length) {
/* 492 */ this.cgBuffer = new byte[cgh.size + 8];
/* */ }
/* */
/* 500 */ if ((cgh.majorVersionNumber > this.majorVersionNumber) || ((cgh.majorVersionNumber == this.majorVersionNumber) && (cgh.minorVersionNumber > this.minorVersionNumber)) || ((cgh.majorVersionNumber == this.majorVersionNumber) && (cgh.minorVersionNumber == this.minorVersionNumber) && (cgh.minorMinorVersionNumber > this.minorMinorVersionNumber)))
/* */ {
/* 509 */ this.majorVersionNumber = cgh.majorVersionNumber;
/* 510 */ this.minorVersionNumber = cgh.minorVersionNumber;
/* 511 */ this.minorMinorVersionNumber = cgh.minorMinorVersionNumber;
/* */
/* 513 */ this.cgh.majorVersionNumber = cgh.majorVersionNumber;
/* 514 */ this.cgh.minorVersionNumber = cgh.minorVersionNumber;
/* 515 */ this.cgh.minorMinorVersionNumber = cgh.minorMinorVersionNumber;
/* */ }
/* */
/* 519 */ int geomDataType = 0;
/* */
/* 521 */ switch (cgh.bufferType) {
/* */ case 0:
/* 523 */ geomDataType = 1;
/* 524 */ break;
/* */ case 1:
/* 526 */ geomDataType = 2;
/* 527 */ break;
/* */ case 2:
/* 529 */ geomDataType = 3;
/* */ }
/* */
/* 533 */ if ((cgh.bufferDataPresent & 0x1) != 0)
/* */ {
/* 535 */ geomDataType |= 4;
/* */ }
/* 537 */ if ((cgh.bufferDataPresent & 0x2) != 0)
/* */ {
/* 539 */ geomDataType |= 8;
/* */ }
/* 541 */ if ((cgh.bufferDataPresent & 0x4) != 0)
/* */ {
/* 543 */ geomDataType |= 16;
/* */ }
/* */
/* 546 */ if (this.objectCount == this.directory.length) {
/* 547 */ long[] newDirectory = new long[2 * this.objectCount];
/* 548 */ int[] newObjectSizes = new int[2 * this.objectCount];
/* */
/* 550 */ System.arraycopy(this.directory, 0, newDirectory, 0, this.objectCount);
/* */
/* 552 */ System.arraycopy(this.objectSizes, 0, newObjectSizes, 0, this.objectCount);
/* */
/* 555 */ this.directory = newDirectory;
/* 556 */ this.objectSizes = newObjectSizes;
/* */ }
/* */
/* 564 */ this.directory[this.objectCount] = this.directoryOffset;
/* 565 */ this.objectSizes[this.objectCount] = (cgh.size + 8);
/* 566 */ this.objectCount += 1;
/* */
/* 569 */ setFilePointer(this.directoryOffset);
/* 570 */ this.cgFile.writeInt(cgh.size);
/* 571 */ this.cgFile.writeInt(geomDataType);
/* 572 */ this.cgFile.write(geometry, 0, cgh.size);
/* */
/* 579 */ this.directoryOffset += cgh.size + 8;
/* */
/* 582 */ this.objectIndex = this.objectCount;
/* */
/* 585 */ this.fileUpdate = true;
/* */ }
/* */
/* */ public void close()
/* */ {
/* 595 */ if (this.cgFile != null) {
/* */ try {
/* 597 */ if (this.fileUpdate) {
/* 598 */ writeFileDirectory();
/* 599 */ writeFileHeader();
/* */ }
/* 601 */ this.cgFile.close();
/* */ }
/* */ catch (IOException e)
/* */ {
/* 605 */ System.out.println("\nException: " + e.getMessage());
/* 606 */ System.out.println("failed to close " + this.fileName);
/* */ }
/* */ }
/* 609 */ this.cgFile = null;
/* 610 */ this.cgBuffer = null;
/* 611 */ this.directory = null;
/* 612 */ this.objectSizes = null;
/* */ }
/* */
/* */ void open(String fname, boolean rw)
/* */ throws FileNotFoundException, IOException
/* */ {
/* 623 */ this.cgFile = null;
/* */ String mode;
/* */ String mode;
/* 626 */ if (rw)
/* 627 */ mode = "rw";
/* */ else
/* 629 */ mode = "r";
/* */ try
/* */ {
/* 632 */ this.cgFile = new RandomAccessFile(fname, mode);
/* */ }
/* */ catch (FileNotFoundException e)
/* */ {
/* 638 */ throw new FileNotFoundException(e.getMessage() + "\n" + fname + ": open mode " + mode + " failed");
/* */ }
/* */ }
/* */
/* */ void setFilePointer(long offset)
/* */ throws IOException
/* */ {
/* 647 */ this.cgFile.seek(offset);
/* */
/* 650 */ this.bufferNextObjectCount = 0;
/* */ }
/* */
/* */ void initialize()
/* */ throws IOException
/* */ {
/* 658 */ int maxSize = 0;
/* */
/* 660 */ if (this.cgFile.length() == 0L)
/* */ {
/* 662 */ this.objectCount = 0;
/* 663 */ this.cgBuffer = new byte[32768];
/* 664 */ this.directory = new long[16];
/* 665 */ this.objectSizes = new int[this.directory.length];
/* */
/* 668 */ this.magicNumber = -1159857484;
/* 669 */ this.majorVersionNumber = 1;
/* 670 */ this.minorVersionNumber = 0;
/* 671 */ this.minorMinorVersionNumber = 0;
/* 672 */ this.directoryOffset = 32L;
/* */
/* 675 */ writeFileHeader();
/* */ }
/* */ else
/* */ {
/* 679 */ readFileHeader();
/* */
/* 682 */ if (this.magicNumber != -1159857484) {
/* 683 */ close();
/* 684 */ throw new IllegalArgumentException("\n" + this.fileName + " is not a compressed geometry file");
/* */ }
/* */
/* 689 */ this.directory = new long[this.objectCount];
/* 690 */ readDirectory(this.directoryOffset, this.directory);
/* */
/* 692 */ this.objectSizes = new int[this.objectCount];
/* 693 */ for (int i = 0; i < this.objectCount - 1; i++) {
/* 694 */ this.objectSizes[i] = ((int)(this.directory[(i + 1)] - this.directory[i]));
/* 695 */ if (this.objectSizes[i] > maxSize) maxSize = this.objectSizes[i];
/* */ }
/* */
/* 698 */ if (this.objectCount > 0) {
/* 699 */ this.objectSizes[(this.objectCount - 1)] = ((int)(this.directoryOffset - this.directory[(this.objectCount - 1)]));
/* */
/* 702 */ if (this.objectSizes[(this.objectCount - 1)] > maxSize) {
/* 703 */ maxSize = this.objectSizes[(this.objectCount - 1)];
/* */ }
/* */ }
/* */
/* 707 */ this.cgBuffer = new byte[maxSize];
/* */
/* 710 */ setFilePointer(32L);
/* */ }
/* */
/* 714 */ this.cgh = new CompressedGeometryHeader();
/* 715 */ this.cgh.majorVersionNumber = this.majorVersionNumber;
/* 716 */ this.cgh.minorVersionNumber = this.minorVersionNumber;
/* 717 */ this.cgh.minorMinorVersionNumber = this.minorMinorVersionNumber;
/* */ }
/* */
/* */ void readFileHeader()
/* */ throws IOException
/* */ {
/* 734 */ byte[] header = new byte[32];
/* */ try
/* */ {
/* 737 */ setFilePointer(0L);
/* 738 */ if (this.cgFile.read(header) != 32) {
/* 739 */ close();
/* 740 */ throw new IOException("failed header read");
/* */ }
/* */ }
/* */ catch (IOException e) {
/* 744 */ if (this.cgFile != null) {
/* 745 */ close();
/* */ }
/* 747 */ throw e;
/* */ }
/* */
/* 750 */ this.magicNumber = ((header[0] & 0xFF) << 24 | (header[1] & 0xFF) << 16 | (header[2] & 0xFF) << 8 | header[3] & 0xFF);
/* */
/* 756 */ this.majorVersionNumber = ((header[4] & 0xFF) << 24 | (header[5] & 0xFF) << 16 | (header[6] & 0xFF) << 8 | header[7] & 0xFF);
/* */
/* 762 */ this.minorVersionNumber = ((header[8] & 0xFF) << 24 | (header[9] & 0xFF) << 16 | (header[10] & 0xFF) << 8 | header[11] & 0xFF);
/* */
/* 768 */ this.minorMinorVersionNumber = ((header[12] & 0xFF) << 24 | (header[13] & 0xFF) << 16 | (header[14] & 0xFF) << 8 | header[15] & 0xFF);
/* */
/* 774 */ this.objectCount = ((header[16] & 0xFF) << 24 | (header[17] & 0xFF) << 16 | (header[18] & 0xFF) << 8 | header[19] & 0xFF);
/* */
/* 780 */ this.directoryOffset = ((header[24] & 0xFF) << 56 | (header[25] & 0xFF) << 48 | (header[26] & 0xFF) << 40 | (header[27] & 0xFF) << 32 | (header[28] & 0xFF) << 24 | (header[29] & 0xFF) << 16 | (header[30] & 0xFF) << 8 | header[31] & 0xFF);
/* */ }
/* */
/* */ void writeFileHeader()
/* */ throws IOException
/* */ {
/* 795 */ setFilePointer(0L);
/* */ try {
/* 797 */ this.cgFile.writeInt(-1159857484);
/* 798 */ this.cgFile.writeInt(this.majorVersionNumber);
/* 799 */ this.cgFile.writeInt(this.minorVersionNumber);
/* 800 */ this.cgFile.writeInt(this.minorMinorVersionNumber);
/* 801 */ this.cgFile.writeInt(this.objectCount);
/* 802 */ this.cgFile.writeInt(0);
/* 803 */ this.cgFile.writeLong(this.directoryOffset);
/* */ }
/* */ catch (IOException e)
/* */ {
/* 808 */ throw new IOException(e.getMessage() + "\ncould not write file header for " + this.fileName);
/* */ }
/* */ }
/* */
/* */ void readDirectory(long offset, long[] directory)
/* */ throws IOException
/* */ {
/* 820 */ byte[] buff = new byte[directory.length * 8];
/* 821 */ setFilePointer(offset);
/* */ try
/* */ {
/* 824 */ this.cgFile.read(buff);
/* */ }
/* */ catch (IOException e)
/* */ {
/* 829 */ throw new IOException(e.getMessage() + "\nfailed to read " + buff.length + " byte directory, offset " + offset + " in file " + this.fileName);
/* */ }
/* */
/* 835 */ for (int i = 0; i < directory.length; i++)
/* 836 */ directory[i] = ((buff[(i * 8 + 0)] & 0xFF) << 56 | (buff[(i * 8 + 1)] & 0xFF) << 48 | (buff[(i * 8 + 2)] & 0xFF) << 40 | (buff[(i * 8 + 3)] & 0xFF) << 32 | (buff[(i * 8 + 4)] & 0xFF) << 24 | (buff[(i * 8 + 5)] & 0xFF) << 16 | (buff[(i * 8 + 6)] & 0xFF) << 8 | buff[(i * 8 + 7)] & 0xFF);
/* */ }
/* */
/* */ void writeFileDirectory()
/* */ throws IOException
/* */ {
/* 852 */ setFilePointer(this.directoryOffset);
/* */
/* 854 */ int directoryAlign = (int)(this.directoryOffset % 8L);
/* 855 */ if (directoryAlign != 0)
/* */ {
/* 857 */ byte[] bytes = new byte[8 - directoryAlign];
/* */ try
/* */ {
/* 860 */ this.cgFile.write(bytes);
/* */ }
/* */ catch (IOException e)
/* */ {
/* 866 */ throw new IOException(e.getMessage() + "\ncould not write " + directoryAlign + " bytes to long word align directory for " + this.fileName);
/* */ }
/* */
/* 871 */ this.directoryOffset += 8 - directoryAlign;
/* */ }
/* */ try
/* */ {
/* 875 */ for (int i = 0; i < this.objectCount; i++) {
/* 876 */ this.cgFile.writeLong(this.directory[i]);
/* */ }
/* */
/* */ }
/* */ catch (IOException e)
/* */ {
/* 882 */ throw new IOException(e.getMessage() + "\ncould not write directory for " + this.fileName);
/* */ }
/* */ }
/* */
/* */ CompressedGeometry readNext(int bufferReadLimit)
/* */ throws IOException
/* */ {
/* 894 */ if (this.objectIndex == this.objectCount) {
/* 895 */ return null;
/* */ }
/* 897 */ if (this.bufferNextObjectCount == 0)
/* */ {
/* 899 */ int curSize = 0;
/* 900 */ this.bufferObjectCount = 0;
/* */
/* 903 */ for (int i = this.objectIndex; (i < this.objectCount) &&
/* 904 */ (curSize + this.objectSizes[i] <= bufferReadLimit); i++)
/* */ {
/* 905 */ curSize += this.objectSizes[i];
/* 906 */ this.bufferObjectCount += 1;
/* */ }
/* */
/* */ try
/* */ {
/* 911 */ n = this.cgFile.read(this.cgBuffer, 0, curSize);
/* */ }
/* */ catch (IOException e)
/* */ {
/* */ int n;
/* 917 */ throw new IOException(e.getMessage() + "\nfailed to read " + curSize + " bytes, object " + this.objectIndex + " in file " + this.fileName);
/* */ }
/* */
/* 924 */ this.bufferObjectStart = this.objectIndex;
/* 925 */ this.bufferNextObjectCount = this.bufferObjectCount;
/* 926 */ this.bufferNextObjectOffset = 0;
/* */ }
/* */
/* 930 */ this.geomSize = ((this.cgBuffer[(this.bufferNextObjectOffset + 0 + 0)] & 0xFF) << 24 | (this.cgBuffer[(this.bufferNextObjectOffset + 0 + 1)] & 0xFF) << 16 | (this.cgBuffer[(this.bufferNextObjectOffset + 0 + 2)] & 0xFF) << 8 | this.cgBuffer[(this.bufferNextObjectOffset + 0 + 3)] & 0xFF);
/* */
/* 936 */ this.geomDataType = ((this.cgBuffer[(this.bufferNextObjectOffset + 4 + 0)] & 0xFF) << 24 | (this.cgBuffer[(this.bufferNextObjectOffset + 4 + 1)] & 0xFF) << 16 | (this.cgBuffer[(this.bufferNextObjectOffset + 4 + 2)] & 0xFF) << 8 | this.cgBuffer[(this.bufferNextObjectOffset + 4 + 3)] & 0xFF);
/* */
/* 943 */ this.geomStart = (this.bufferNextObjectOffset + 8);
/* */
/* 955 */ this.bufferNextObjectOffset += this.objectSizes[this.objectIndex];
/* 956 */ this.bufferNextObjectCount -= 1;
/* 957 */ this.objectIndex += 1;
/* */
/* 959 */ return newCG(this.geomSize, this.geomStart, this.geomDataType);
/* */ }
/* */
/* */ CompressedGeometry newCG(int geomSize, int geomStart, int geomDataType)
/* */ {
/* 969 */ this.cgh.size = geomSize;
/* 970 */ this.cgh.start = geomStart;
/* */
/* 972 */ if ((geomDataType & 0x3) == 1)
/* 973 */ this.cgh.bufferType = 0;
/* 974 */ else if ((geomDataType & 0x3) == 2)
/* 975 */ this.cgh.bufferType = 1;
/* 976 */ else if ((geomDataType & 0x3) == 3) {
/* 977 */ this.cgh.bufferType = 2;
/* */ }
/* 979 */ this.cgh.bufferDataPresent = 0;
/* */
/* 981 */ if ((geomDataType & 0x4) != 0) {
/* 982 */ this.cgh.bufferDataPresent |= 1;
/* */ }
/* */
/* 985 */ if ((geomDataType & 0x8) != 0) {
/* 986 */ this.cgh.bufferDataPresent |= 2;
/* */ }
/* */
/* 989 */ if ((geomDataType & 0x10) != 0) {
/* 990 */ this.cgh.bufferDataPresent |= 4;
/* */ }
/* */
/* 993 */ return new CompressedGeometry(this.cgh, this.cgBuffer);
/* */ }
/* */
/* */ protected void finalize()
/* */ {
/* 1000 */ close();
/* */ }
/* */ }
/* Location: Z:\System\Library\Java\Extensions\j3dutils.jar
* Qualified Name: com.sun.j3d.utils.compression.CompressedGeometryFile
* JD-Core Version: 0.6.2
*/