📄 gifimagereader.java
字号:
(gcePackedFields & 0x1) != 0; imageMetadata.delayTime = stream.readUnsignedShort(); imageMetadata.transparentColorIndex = stream.readUnsignedByte(); int terminator = stream.readUnsignedByte(); } else if (label == 0x1) { // Plain text extension int length = stream.readUnsignedByte(); imageMetadata.hasPlainTextExtension = true; imageMetadata.textGridLeft = stream.readUnsignedShort(); imageMetadata.textGridTop = stream.readUnsignedShort(); imageMetadata.textGridWidth = stream.readUnsignedShort(); imageMetadata.textGridHeight = stream.readUnsignedShort(); imageMetadata.characterCellWidth = stream.readUnsignedByte(); imageMetadata.characterCellHeight = stream.readUnsignedByte(); imageMetadata.textForegroundColor = stream.readUnsignedByte(); imageMetadata.textBackgroundColor = stream.readUnsignedByte(); imageMetadata.text = concatenateBlocks(); } else if (label == 0xfe) { // Comment extension byte[] comment = concatenateBlocks(); if (imageMetadata.comments == null) { imageMetadata.comments = new ArrayList(); } imageMetadata.comments.add(comment); } else if (label == 0xff) { // Application extension int blockSize = stream.readUnsignedByte(); byte[] applicationID = new byte[8]; stream.readFully(applicationID); byte[] authCode = new byte[3]; stream.readFully(authCode); byte[] applicationData = concatenateBlocks(); // Init lists if necessary if (imageMetadata.applicationIDs == null) { imageMetadata.applicationIDs = new ArrayList(); imageMetadata.authenticationCodes = new ArrayList(); imageMetadata.applicationData = new ArrayList(); } imageMetadata.applicationIDs.add(applicationID); imageMetadata.authenticationCodes.add(authCode); imageMetadata.applicationData.add(applicationData); } else { // Skip over unknown extension blocks int length = 0; do { length = stream.readUnsignedByte(); stream.skipBytes(length); } while (length > 0); } } else if (blockType == 0x3b) { // Trailer throw new IndexOutOfBoundsException ("Attempt to read past end of image sequence!"); } else { throw new IIOException("Unexpected block type " + blockType + "!"); } } } catch (IIOException iioe) { throw iioe; } catch (IOException ioe) { throw new IIOException("I/O error reading image metadata!", ioe); } } private void startPass(int pass) { if (updateListeners == null) { return; } int y = 0; int yStep = 1; if (imageMetadata.interlaceFlag) { y = interlaceOffset[interlacePass]; yStep = interlaceIncrement[interlacePass]; } int[] vals = ReaderUtil. computeUpdatedPixels(sourceRegion, destinationOffset, destinationRegion.x, destinationRegion.y, destinationRegion.x + destinationRegion.width - 1, destinationRegion.y + destinationRegion.height - 1, sourceXSubsampling, sourceYSubsampling, 0, y, destinationRegion.width, (destinationRegion.height + yStep - 1)/yStep, 1, yStep); // Initialized updateMinY and updateYStep this.updateMinY = vals[1]; this.updateYStep = vals[5]; // Inform IIOReadUpdateListeners of new pass int[] bands = { 0 }; processPassStarted(theImage, interlacePass, sourceMinProgressivePass, sourceMaxProgressivePass, 0, updateMinY, 1, updateYStep, bands); } public BufferedImage read(int imageIndex, ImageReadParam param) throws IIOException { if (stream == null) { throw new IllegalStateException("Input not set!"); } checkIndex(imageIndex); int index = locateImage(imageIndex); if (index != imageIndex) { throw new IndexOutOfBoundsException("imageIndex out of bounds!"); } clearAbortRequest(); readMetadata(); // A null ImageReadParam means we use the default if (param == null) { param = getDefaultReadParam(); } // Initialize the destination image Iterator imageTypes = getImageTypes(imageIndex); this.theImage = getDestination(param, imageTypes, imageMetadata.imageWidth, imageMetadata.imageHeight); this.theTile = theImage.getWritableTile(0, 0); this.width = imageMetadata.imageWidth; this.height = imageMetadata.imageHeight; this.streamX = 0; this.streamY = 0; this.rowsDone = 0; this.interlacePass = 0; // Get source region, taking subsampling offsets into account, // and clipping against the true source bounds this.sourceRegion = new Rectangle(0, 0, 0, 0); this.destinationRegion = new Rectangle(0, 0, 0, 0); computeRegions(param, width, height, theImage, sourceRegion, destinationRegion); this.destinationOffset = new Point(destinationRegion.x, destinationRegion.y); this.sourceXSubsampling = param.getSourceXSubsampling(); this.sourceYSubsampling = param.getSourceYSubsampling(); this.sourceMinProgressivePass = Math.max(param.getSourceMinProgressivePass(), 0); this.sourceMaxProgressivePass = Math.min(param.getSourceMaxProgressivePass(), 3); this.destY = destinationRegion.y + (streamY - sourceRegion.y)/sourceYSubsampling; computeDecodeThisRow(); // Inform IIOReadProgressListeners of start of image processImageStarted(imageIndex); startPass(0); this.rowBuf = new byte[width]; try { // Read and decode the image data, fill in theImage this.initCodeSize = stream.readUnsignedByte(); // Read first data block this.blockLength = stream.readUnsignedByte(); int left = blockLength; int off = 0; while (left > 0) { int nbytes = stream.read(block, off, left); left -= nbytes; off += nbytes; } this.bitPos = 0; this.nextByte = 0; this.lastBlockFound = false; this.interlacePass = 0; // Init 32-bit buffer initNext32Bits(); this.clearCode = 1 << initCodeSize; this.eofCode = clearCode + 1; int code, oldCode = 0; int[] prefix = new int[4096]; byte[] suffix = new byte[4096]; byte[] initial = new byte[4096]; int[] length = new int[4096]; byte[] string = new byte[4096]; initializeStringTable(prefix, suffix, initial, length); int tableIndex = (1 << initCodeSize) + 2; int codeSize = initCodeSize + 1; int codeMask = (1 << codeSize) - 1; while (!abortRequested()) { code = getCode(codeSize, codeMask); if (code == clearCode) { initializeStringTable(prefix, suffix, initial, length); tableIndex = (1 << initCodeSize) + 2; codeSize = initCodeSize + 1; codeMask = (1 << codeSize) - 1; code = getCode(codeSize, codeMask); if (code == eofCode) { // Inform IIOReadProgressListeners of end of image processImageComplete(); return theImage; } } else if (code == eofCode) { // Inform IIOReadProgressListeners of end of image processImageComplete(); return theImage; } else { int newSuffixIndex; if (code < tableIndex) { newSuffixIndex = code; } else { // code == tableIndex newSuffixIndex = oldCode; if (code != tableIndex) { // warning - code out of sequence // possibly data corruption processWarningOccurred("Out-of-sequence code!"); } } int ti = tableIndex; int oc = oldCode; prefix[ti] = oc; suffix[ti] = initial[newSuffixIndex]; initial[ti] = initial[oc]; length[ti] = length[oc] + 1; ++tableIndex; if ((tableIndex == (1 << codeSize)) && (tableIndex < 4096)) { ++codeSize; codeMask = (1 << codeSize) - 1; } } // Reverse code int c = code; int len = length[c]; for (int i = len - 1; i >= 0; i--) { string[i] = suffix[c]; c = prefix[c]; } outputPixels(string, len); oldCode = code; } processReadAborted(); return theImage; } catch (IOException e) { e.printStackTrace(); throw new IIOException("I/O error reading image!", e); } } /** * Remove all settings including global settings such as * <code>Locale</code>s and listeners, as well as stream settings. */ public void reset() { super.reset(); resetStreamSettings(); } /** * Remove local settings based on parsing of a stream. */ private void resetStreamSettings() { gotHeader = false; streamMetadata = null; currIndex = -1; imageMetadata = null; imageStartPosition = new ArrayList(); numImages = -1; // No need to reinitialize 'block' blockLength = 0; bitPos = 0; nextByte = 0; next32Bits = 0; lastBlockFound = false; theImage = null; theTile = null; width = -1; height = -1; streamX = -1; streamY = -1; rowsDone = 0; interlacePass = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -