📄 compressedgeometryfile.java
字号:
// Set fields as if they have been read. magicNumber = MAGIC_NUMBER ; majorVersionNumber = 1 ; minorVersionNumber = 0 ; minorMinorVersionNumber = 0 ; directoryOffset = HEADER_SIZE ; // Write the file header. writeFileHeader() ; } else { // Read the file header. readFileHeader() ; // Check file type. if (magicNumber != MAGIC_NUMBER) { close() ; throw new IllegalArgumentException ("\n" + fileName + " is not a compressed geometry file") ; } // Read the directory and determine object sizes. directory = new long[objectCount] ; readDirectory(directoryOffset, directory) ; objectSizes = new int[objectCount] ; for (int i = 0 ; i < objectCount-1 ; i++) { objectSizes[i] = (int)(directory[i+1] - directory[i]) ; if (objectSizes[i] > maxSize) maxSize = objectSizes[i] ; } if (objectCount > 0) { objectSizes[objectCount-1] = (int)(directoryOffset - directory[objectCount-1]) ; if (objectSizes[objectCount-1] > maxSize) maxSize = objectSizes[objectCount-1] ; } // Allocate a buffer big enough to read the largest object. cgBuffer = new byte[maxSize] ; // Move to the first object. setFilePointer(HEADER_SIZE) ; } // Set up common parts of the compressed geometry object header. cgh = new CompressedGeometryHeader() ; cgh.majorVersionNumber = this.majorVersionNumber ; cgh.minorVersionNumber = this.minorVersionNumber ; cgh.minorMinorVersionNumber = this.minorMinorVersionNumber ; if (print) { System.out.println(fileName + ": " + objectCount + " objects") ; System.out.println("magic number 0x" + Integer.toHexString(magicNumber) + ", version number " + majorVersionNumber + "." + minorVersionNumber + "." + minorMinorVersionNumber) ; System.out.println("largest object is " + maxSize + " bytes") ; } } // // Read the file header. // void readFileHeader() throws IOException { byte header[] = new byte[HEADER_SIZE] ; try { setFilePointer(0) ; if (cgFile.read(header) != HEADER_SIZE) { close() ; throw new IOException("failed header read") ; } } catch (IOException e) { if (cgFile != null) { close() ; } throw e ; } magicNumber = ((header[MAGIC_NUMBER_OFFSET+0] & 0xff) << 24) | ((header[MAGIC_NUMBER_OFFSET+1] & 0xff) << 16) | ((header[MAGIC_NUMBER_OFFSET+2] & 0xff) << 8) | ((header[MAGIC_NUMBER_OFFSET+3] & 0xff)) ; majorVersionNumber = ((header[MAJOR_VERSION_OFFSET+0] & 0xff) << 24) | ((header[MAJOR_VERSION_OFFSET+1] & 0xff) << 16) | ((header[MAJOR_VERSION_OFFSET+2] & 0xff) << 8) | ((header[MAJOR_VERSION_OFFSET+3] & 0xff)) ; minorVersionNumber = ((header[MINOR_VERSION_OFFSET+0] & 0xff) << 24) | ((header[MINOR_VERSION_OFFSET+1] & 0xff) << 16) | ((header[MINOR_VERSION_OFFSET+2] & 0xff) << 8) | ((header[MINOR_VERSION_OFFSET+3] & 0xff)) ; minorMinorVersionNumber = ((header[MINOR_MINOR_VERSION_OFFSET+0] & 0xff) << 24) | ((header[MINOR_MINOR_VERSION_OFFSET+1] & 0xff) << 16) | ((header[MINOR_MINOR_VERSION_OFFSET+2] & 0xff) << 8) | ((header[MINOR_MINOR_VERSION_OFFSET+3] & 0xff)) ; objectCount = ((header[OBJECT_COUNT_OFFSET+0] & 0xff) << 24) | ((header[OBJECT_COUNT_OFFSET+1] & 0xff) << 16) | ((header[OBJECT_COUNT_OFFSET+2] & 0xff) << 8) | ((header[OBJECT_COUNT_OFFSET+3] & 0xff)) ; directoryOffset = ((long)(header[DIRECTORY_OFFSET_OFFSET+0] & 0xff) << 56) | ((long)(header[DIRECTORY_OFFSET_OFFSET+1] & 0xff) << 48) | ((long)(header[DIRECTORY_OFFSET_OFFSET+2] & 0xff) << 40) | ((long)(header[DIRECTORY_OFFSET_OFFSET+3] & 0xff) << 32) | ((long)(header[DIRECTORY_OFFSET_OFFSET+4] & 0xff) << 24) | ((long)(header[DIRECTORY_OFFSET_OFFSET+5] & 0xff) << 16) | ((long)(header[DIRECTORY_OFFSET_OFFSET+6] & 0xff) << 8) | ((long)(header[DIRECTORY_OFFSET_OFFSET+7] & 0xff)) ; } // // Write the file header based on current field values. // void writeFileHeader() throws IOException { setFilePointer(0) ; try { cgFile.writeInt(MAGIC_NUMBER) ; cgFile.writeInt(majorVersionNumber) ; cgFile.writeInt(minorVersionNumber) ; cgFile.writeInt(minorMinorVersionNumber) ; cgFile.writeInt(objectCount) ; cgFile.writeInt(0) ; // long word alignment cgFile.writeLong(directoryOffset) ; if (print) System.out.println("wrote file header for " + fileName) ; } catch (IOException e) { throw new IOException (e.getMessage() + "\ncould not write file header for " + fileName) ; } } // // Read the directory of compressed geometry object offsets. // void readDirectory(long offset, long[] directory) throws IOException { byte buff[] = new byte[directory.length * 8] ; setFilePointer(offset) ; try { cgFile.read(buff) ; if (print) System.out.println("read " + buff.length + " byte directory") ; } catch (IOException e) { throw new IOException (e.getMessage() + "\nfailed to read " + buff.length + " byte directory, offset " + offset + " in file " + fileName) ; } for (int i = 0 ; i < directory.length ; i++) { directory[i] = ((long)(buff[i*8+0] & 0xff) << 56) | ((long)(buff[i*8+1] & 0xff) << 48) | ((long)(buff[i*8+2] & 0xff) << 40) | ((long)(buff[i*8+3] & 0xff) << 32) | ((long)(buff[i*8+4] & 0xff) << 24) | ((long)(buff[i*8+5] & 0xff) << 16) | ((long)(buff[i*8+6] & 0xff) << 8) | ((long)(buff[i*8+7] & 0xff)) ; } } // // Write the file directory. // void writeFileDirectory() throws IOException { setFilePointer(directoryOffset) ; int directoryAlign = (int)(directoryOffset % 8) ; if (directoryAlign != 0) { // Align to long word before writing directory of long offsets. byte bytes[] = new byte[8-directoryAlign] ; try { cgFile.write(bytes) ; if (print) System.out.println ("wrote " + (8-directoryAlign) + " bytes long alignment") ; } catch (IOException e) { throw new IOException (e.getMessage() + "\ncould not write " + directoryAlign + " bytes to long word align directory for " + fileName) ; } directoryOffset += 8-directoryAlign ; } try { for (int i = 0 ; i < objectCount ; i++) cgFile.writeLong(directory[i]) ; if (print) System.out.println("wrote file directory for " + fileName) ; } catch (IOException e) { throw new IOException (e.getMessage() + "\ncould not write directory for " + fileName) ; } } // // Get the next compressed object in the file, either from the read-ahead // cache or from the file itself. // CompressedGeometry readNext(int bufferReadLimit) throws IOException { if (objectIndex == objectCount) return null ; if (bufferNextObjectCount == 0) { // No valid objects are in the cache. int curSize = 0 ; bufferObjectCount = 0 ; // See how much we have room to read. for (int i = objectIndex ; i < objectCount ; i++) { if (curSize + objectSizes[i] > bufferReadLimit) break ; curSize += objectSizes[i] ; bufferObjectCount++ ; } // Try to read that amount. try { int n = cgFile.read(cgBuffer, 0, curSize) ; if (print) System.out.println("\nread " + n + " bytes from " + fileName) ; } catch (IOException e) { throw new IOException (e.getMessage() + "\nfailed to read " + curSize + " bytes, object " + objectIndex + " in file " + fileName) ; } // Point at the first object in the buffer. bufferObjectStart = objectIndex ; bufferNextObjectCount = bufferObjectCount ; bufferNextObjectOffset = 0 ; } // Get block header info. geomSize = ((cgBuffer[bufferNextObjectOffset+OBJECT_SIZE_OFFSET+0]&0xff)<<24) | ((cgBuffer[bufferNextObjectOffset+OBJECT_SIZE_OFFSET+1]&0xff)<<16) | ((cgBuffer[bufferNextObjectOffset+OBJECT_SIZE_OFFSET+2]&0xff)<< 8) | ((cgBuffer[bufferNextObjectOffset+OBJECT_SIZE_OFFSET+3]&0xff)) ; geomDataType = ((cgBuffer[bufferNextObjectOffset+GEOM_DATA_OFFSET+0]&0xff) << 24) | ((cgBuffer[bufferNextObjectOffset+GEOM_DATA_OFFSET+1]&0xff) << 16) | ((cgBuffer[bufferNextObjectOffset+GEOM_DATA_OFFSET+2]&0xff) << 8) | ((cgBuffer[bufferNextObjectOffset+GEOM_DATA_OFFSET+3]&0xff)) ; // Get offset of compressed geometry data from start of buffer. geomStart = bufferNextObjectOffset + BLOCK_HEADER_SIZE ; if (print) { System.out.println("\nobject " + objectIndex + "\nfile offset " + directory[objectIndex] + ", buffer offset " + bufferNextObjectOffset) ; System.out.println("size " + geomSize + " bytes, " + "data descriptor 0x" + Integer.toHexString(geomDataType)) ; } // Update cache info. bufferNextObjectOffset += objectSizes[objectIndex] ; bufferNextObjectCount-- ; objectIndex++ ; return newCG(geomSize, geomStart, geomDataType) ; } // // Construct and return a compressed geometry node. // CompressedGeometry newCG(int geomSize, int geomStart, int geomDataType) { cgh.size = geomSize ; cgh.start = geomStart ; if ((geomDataType & TYPE_MASK) == TYPE_POINT) cgh.bufferType = CompressedGeometryHeader.POINT_BUFFER ; else if ((geomDataType & TYPE_MASK) == TYPE_LINE) cgh.bufferType = CompressedGeometryHeader.LINE_BUFFER ; else if ((geomDataType & TYPE_MASK) == TYPE_TRIANGLE) cgh.bufferType = CompressedGeometryHeader.TRIANGLE_BUFFER ; cgh.bufferDataPresent = 0 ; if ((geomDataType & NORMAL_PRESENT_MASK) != 0) cgh.bufferDataPresent |= CompressedGeometryHeader.NORMAL_IN_BUFFER ; if ((geomDataType & COLOR_PRESENT_MASK) != 0) cgh.bufferDataPresent |= CompressedGeometryHeader.COLOR_IN_BUFFER ; if ((geomDataType & ALPHA_PRESENT_MASK) != 0) cgh.bufferDataPresent |= CompressedGeometryHeader.ALPHA_IN_BUFFER ; return new CompressedGeometry(cgh, cgBuffer) ; } /** * Release file resources when this object is garbage collected. */ protected void finalize() { close() ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -