private void writeBlocks(byte[] data) throws IOException { if (data != null && data.length > 0) { int offset = 0; while (offset < data.length) { int len = Math.min(data.length - offset, 255); stream.write(len); stream.write(data, offset, len); offset += len; } } }
private void writeCommentExtension(GIFWritableImageMetadata im) throws IOException { if (im.comments != null) { try { Iterator iter = im.comments.iterator(); while (iter.hasNext()) { stream.write(0x21); stream.write(0xfe); writeBlocks((byte[]) iter.next()); stream.write(0x00); } } catch (IOException e) { throw new IIOException("I/O error writing Comment Extension!", e); } } }
private void writeGraphicControlExtension( int disposalMethod, boolean userInputFlag, boolean transparentColorFlag, int delayTime, int transparentColorIndex) throws IOException { try { stream.write(0x21); stream.write(0xf9); stream.write(4); int packedFields = (disposalMethod & 0x3) << 2; if (userInputFlag) { packedFields |= 0x2; } if (transparentColorFlag) { packedFields |= 0x1; } stream.write(packedFields); stream.writeShort((short) delayTime); stream.write(transparentColorIndex); stream.write(0x00); } catch (IOException e) { throw new IIOException("I/O error writing Graphic Control Extension!", e); } }
private void writeApplicationExtension(GIFWritableImageMetadata im) throws IOException { if (im.applicationIDs != null) { Iterator iterIDs = im.applicationIDs.iterator(); Iterator iterCodes = im.authenticationCodes.iterator(); Iterator iterData = im.applicationData.iterator(); while (iterIDs.hasNext()) { try { stream.write(0x21); stream.write(0xff); stream.write(11); stream.write((byte[]) iterIDs.next(), 0, 8); stream.write((byte[]) iterCodes.next(), 0, 3); writeBlocks((byte[]) iterData.next()); stream.write(0x00); } catch (IOException e) { throw new IIOException("I/O error writing Application Extension!", e); } } } }
private void writeHeader( String version, int logicalScreenWidth, int logicalScreenHeight, int colorResolution, int pixelAspectRatio, int backgroundColorIndex, boolean sortFlag, int bitsPerPixel, byte[] globalColorTable) throws IOException { try { // Signature stream.writeBytes("GIF" + version); // Screen Descriptor // Width stream.writeShort((short) logicalScreenWidth); // Height stream.writeShort((short) logicalScreenHeight); // Global Color Table // Packed fields int packedFields = globalColorTable != null ? 0x80 : 0x00; packedFields |= ((colorResolution - 1) & 0x7) << 4; if (sortFlag) { packedFields |= 0x8; } packedFields |= (bitsPerPixel - 1); stream.write(packedFields); // Background color index stream.write(backgroundColorIndex); // Pixel aspect ratio stream.write(pixelAspectRatio); // Global Color Table if (globalColorTable != null) { stream.write(globalColorTable); } } catch (IOException e) { throw new IIOException("I/O error writing header!", e); } }
private void writeImageDescriptor( int imageLeftPosition, int imageTopPosition, int imageWidth, int imageHeight, boolean interlaceFlag, boolean sortFlag, int bitsPerPixel, byte[] localColorTable) throws IOException { try { stream.write(0x2c); stream.writeShort((short) imageLeftPosition); stream.writeShort((short) imageTopPosition); stream.writeShort((short) imageWidth); stream.writeShort((short) imageHeight); int packedFields = localColorTable != null ? 0x80 : 0x00; if (interlaceFlag) { packedFields |= 0x40; } if (sortFlag) { packedFields |= 0x8; } packedFields |= (bitsPerPixel - 1); stream.write(packedFields); if (localColorTable != null) { stream.write(localColorTable); } } catch (IOException e) { throw new IIOException("I/O error writing Image Descriptor!", e); } }
private void writeRasterData( RenderedImage image, Rectangle sourceBounds, Dimension destSize, ImageWriteParam param, boolean interlaceFlag) throws IOException { int sourceXOffset = sourceBounds.x; int sourceYOffset = sourceBounds.y; int sourceWidth = sourceBounds.width; int sourceHeight = sourceBounds.height; int destWidth = destSize.width; int destHeight = destSize.height; int periodX; int periodY; if (param == null) { periodX = 1; periodY = 1; } else { periodX = param.getSourceXSubsampling(); periodY = param.getSourceYSubsampling(); } SampleModel sampleModel = image.getSampleModel(); int bitsPerPixel = sampleModel.getSampleSize()[0]; int initCodeSize = bitsPerPixel; if (initCodeSize == 1) { initCodeSize++; } stream.write(initCodeSize); LZWCompressor compressor = new LZWCompressor(stream, initCodeSize, false); boolean isOptimizedCase = periodX == 1 && periodY == 1 && sampleModel instanceof ComponentSampleModel && image.getNumXTiles() == 1 && image.getNumYTiles() == 1 && image.getTile(0, 0).getDataBuffer() instanceof DataBufferByte; int numRowsWritten = 0; int progressReportRowPeriod = Math.max(destHeight / 20, 1); processImageStarted(imageIndex); if (interlaceFlag) { if (DEBUG) System.out.println("Writing interlaced"); if (isOptimizedCase) { Raster tile = image.getTile(0, 0); byte[] data = ((DataBufferByte) tile.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel) tile.getSampleModel(); int offset = csm.getOffset(sourceXOffset, sourceYOffset, 0); int lineStride = csm.getScanlineStride(); writeRowsOpt( data, offset, lineStride, compressor, 0, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += destHeight / 8; writeRowsOpt( data, offset, lineStride, compressor, 4, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 4) / 8; writeRowsOpt( data, offset, lineStride, compressor, 2, 4, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 2) / 4; writeRowsOpt( data, offset, lineStride, compressor, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } else { writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset, 8 * periodY, sourceWidth, 0, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += destHeight / 8; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + 4 * periodY, 8 * periodY, sourceWidth, 4, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 4) / 8; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + 2 * periodY, 4 * periodY, sourceWidth, 2, 4, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 2) / 4; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + periodY, 2 * periodY, sourceWidth, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } } else { if (DEBUG) System.out.println("Writing non-interlaced"); if (isOptimizedCase) { Raster tile = image.getTile(0, 0); byte[] data = ((DataBufferByte) tile.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel) tile.getSampleModel(); int offset = csm.getOffset(sourceXOffset, sourceYOffset, 0); int lineStride = csm.getScanlineStride(); writeRowsOpt( data, offset, lineStride, compressor, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } else { writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset, periodY, sourceWidth, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } } if (abortRequested()) { return; } processImageProgress(100.0F); compressor.flush(); stream.write(0x00); processImageComplete(); }
private void writeTrailer() throws IOException { stream.write(0x3b); }
private void writePlainTextExtension(GIFWritableImageMetadata im) throws IOException { if (im.hasPlainTextExtension) { try { stream.write(0x21); stream.write(0x1); stream.write(12); stream.writeShort(im.textGridLeft); stream.writeShort(im.textGridTop); stream.writeShort(im.textGridWidth); stream.writeShort(im.textGridHeight); stream.write(im.characterCellWidth); stream.write(im.characterCellHeight); stream.write(im.textForegroundColor); stream.write(im.textBackgroundColor); writeBlocks(im.text); stream.write(0x00); } catch (IOException e) { throw new IIOException("I/O error writing Plain Text Extension!", e); } } }