Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
JDK 11 java.desktop.jmod - Desktop Module
JDK 11 java.desktop.jmod is the JMOD file for JDK 11 Desktop module.
JDK 11 Desktop module compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\java.desktop.jmod.
JDK 11 Desktop module compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.
JDK 11 Desktop module source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\java.desktop.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ com/sun/imageio/plugins/png/PNGImageWriter.java
/* * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.imageio.plugins.png; import java.awt.Rectangle; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.Locale; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import javax.imageio.IIOException; import javax.imageio.IIOImage; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOMetadata; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageOutputStream; import javax.imageio.stream.ImageOutputStreamImpl; final class CRC { private static final int[] crcTable = new int[256]; private int crc = 0xffffffff; static { // Initialize CRC table for (int n = 0; n < 256; n++) { int c = n; for (int k = 0; k < 8; k++) { if ((c & 1) == 1) { c = 0xedb88320 ^ (c >>> 1); } else { c >>>= 1; } crcTable[n] = c; } } } CRC() {} void reset() { crc = 0xffffffff; } void update(byte[] data, int off, int len) { int c = crc; for (int n = 0; n < len; n++) { c = crcTable[(c ^ data[off + n]) & 0xff] ^ (c >>> 8); } crc = c; } void update(int data) { crc = crcTable[(crc ^ data) & 0xff] ^ (crc >>> 8); } int getValue() { return crc ^ 0xffffffff; } } final class ChunkStream extends ImageOutputStreamImpl { private final ImageOutputStream stream; private final long startPos; private final CRC crc = new CRC(); ChunkStream(int type, ImageOutputStream stream) throws IOException { this.stream = stream; this.startPos = stream.getStreamPosition(); stream.writeInt(-1); // length, will backpatch writeInt(type); } @Override public int read() throws IOException { throw new RuntimeException("Method not available"); } @Override public int read(byte[] b, int off, int len) throws IOException { throw new RuntimeException("Method not available"); } @Override public void write(byte[] b, int off, int len) throws IOException { crc.update(b, off, len); stream.write(b, off, len); } @Override public void write(int b) throws IOException { crc.update(b); stream.write(b); } void finish() throws IOException { // Write CRC stream.writeInt(crc.getValue()); // Write length long pos = stream.getStreamPosition(); stream.seek(startPos); stream.writeInt((int)(pos - startPos) - 12); // Return to end of chunk and flush to minimize buffering stream.seek(pos); stream.flushBefore(pos); } @Override @SuppressWarnings("deprecation") protected void finalize() throws Throwable { // Empty finalizer (for improved performance; no need to call // super.finalize() in this case) } } // Compress output and write as a series of 'IDAT' chunks of // fixed length. final class IDATOutputStream extends ImageOutputStreamImpl { private static final byte[] chunkType = { (byte)'I', (byte)'D', (byte)'A', (byte)'T' }; private final ImageOutputStream stream; private final int chunkLength; private long startPos; private final CRC crc = new CRC(); private final Deflater def; private final byte[] buf = new byte[512]; // reused 1 byte[] array: private final byte[] wbuf1 = new byte[1]; private int bytesRemaining; IDATOutputStream(ImageOutputStream stream, int chunkLength, int deflaterLevel) throws IOException { this.stream = stream; this.chunkLength = chunkLength; this.def = new Deflater(deflaterLevel); startChunk(); } private void startChunk() throws IOException { crc.reset(); this.startPos = stream.getStreamPosition(); stream.writeInt(-1); // length, will backpatch crc.update(chunkType, 0, 4); stream.write(chunkType, 0, 4); this.bytesRemaining = chunkLength; } private void finishChunk() throws IOException { // Write CRC stream.writeInt(crc.getValue()); // Write length long pos = stream.getStreamPosition(); stream.seek(startPos); stream.writeInt((int)(pos - startPos) - 12); // Return to end of chunk and flush to minimize buffering stream.seek(pos); try { stream.flushBefore(pos); } catch (IOException e) { /* * If flushBefore() fails we try to access startPos in finally * block of write_IDAT(). We should update startPos to avoid * IndexOutOfBoundException while seek() is happening. */ this.startPos = stream.getStreamPosition(); throw e; } } @Override public int read() throws IOException { throw new RuntimeException("Method not available"); } @Override public int read(byte[] b, int off, int len) throws IOException { throw new RuntimeException("Method not available"); } @Override public void write(byte[] b, int off, int len) throws IOException { if (len == 0) { return; } if (!def.finished()) { def.setInput(b, off, len); while (!def.needsInput()) { deflate(); } } } void deflate() throws IOException { int len = def.deflate(buf, 0, buf.length); int off = 0; while (len > 0) { if (bytesRemaining == 0) { finishChunk(); startChunk(); } int nbytes = Math.min(len, bytesRemaining); crc.update(buf, off, nbytes); stream.write(buf, off, nbytes); off += nbytes; len -= nbytes; bytesRemaining -= nbytes; } } @Override public void write(int b) throws IOException { wbuf1[0] = (byte)b; write(wbuf1, 0, 1); } void finish() throws IOException { try { if (!def.finished()) { def.finish(); while (!def.finished()) { deflate(); } } finishChunk(); } finally { def.end(); } } @Override @SuppressWarnings("deprecation") protected void finalize() throws Throwable { // Empty finalizer (for improved performance; no need to call // super.finalize() in this case) } } final class PNGImageWriteParam extends ImageWriteParam { /** Default quality level = 0.5 ie medium compression */ private static final float DEFAULT_QUALITY = 0.5f; private static final String[] compressionNames = {"Deflate"}; private static final float[] qualityVals = { 0.00F, 0.30F, 0.75F, 1.00F }; private static final String[] qualityDescs = { "High compression", // 0.00 -> 0.30 "Medium compression", // 0.30 -> 0.75 "Low compression" // 0.75 -> 1.00 }; PNGImageWriteParam(Locale locale) { super(); this.canWriteProgressive = true; this.locale = locale; this.canWriteCompressed = true; this.compressionTypes = compressionNames; this.compressionType = compressionTypes[0]; this.compressionMode = MODE_DEFAULT; this.compressionQuality = DEFAULT_QUALITY; } /** * Removes any previous compression quality setting. * * <p> The default implementation resets the compression quality * to <code>0.5F</code>. * * @exception IllegalStateException if the compression mode is not * <code>MODE_EXPLICIT</code>. */ @Override public void unsetCompression() { super.unsetCompression(); this.compressionType = compressionTypes[0]; this.compressionQuality = DEFAULT_QUALITY; } /** * Returns <code>true</code> since the PNG plug-in only supports * lossless compression. * * @return <code>true</code>. */ @Override public boolean isCompressionLossless() { return true; } @Override public String[] getCompressionQualityDescriptions() { super.getCompressionQualityDescriptions(); return qualityDescs.clone(); } @Override public float[] getCompressionQualityValues() { super.getCompressionQualityValues(); return qualityVals.clone(); } } /** */ public final class PNGImageWriter extends ImageWriter { /** Default compression level = 4 ie medium compression */ private static final int DEFAULT_COMPRESSION_LEVEL = 4; ImageOutputStream stream = null; PNGMetadata metadata = null; // Factors from the ImageWriteParam int sourceXOffset = 0; int sourceYOffset = 0; int sourceWidth = 0; int sourceHeight = 0; int[] sourceBands = null; int periodX = 1; int periodY = 1; int numBands; int bpp; RowFilter rowFilter = new RowFilter(); byte[] prevRow = null; byte[] currRow = null; byte[][] filteredRows = null; // Per-band scaling tables // // After the first call to initializeScaleTables, either scale and scale0 // will be valid, or scaleh and scalel will be valid, but not both. // // The tables will be designed for use with a set of input but depths // given by sampleSize, and an output bit depth given by scalingBitDepth. // int[] sampleSize = null; // Sample size per band, in bits int scalingBitDepth = -1; // Output bit depth of the scaling tables // Tables for 1, 2, 4, or 8 bit output byte[][] scale = null; // 8 bit table byte[] scale0 = null; // equivalent to scale[0] // Tables for 16 bit output byte[][] scaleh = null; // High bytes of output byte[][] scalel = null; // Low bytes of output int totalPixels; // Total number of pixels to be written by write_IDAT int pixelsDone; // Running count of pixels written by write_IDAT public PNGImageWriter(ImageWriterSpi originatingProvider) { super(originatingProvider); } @Override public void setOutput(Object output) { super.setOutput(output); if (output != null) { if (!(output instanceof ImageOutputStream)) { throw new IllegalArgumentException("output not an ImageOutputStream!"); } this.stream = (ImageOutputStream)output; } else { this.stream = null; } } @Override public ImageWriteParam getDefaultWriteParam() { return new PNGImageWriteParam(getLocale()); } @Override public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) { return null; } @Override public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, ImageWriteParam param) { PNGMetadata m = new PNGMetadata(); m.initialize(imageType, imageType.getSampleModel().getNumBands()); return m; } @Override public IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param) { return null; } @Override public IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param) { // TODO - deal with imageType if (inData instanceof PNGMetadata) { return (PNGMetadata)((PNGMetadata)inData).clone(); } else { return new PNGMetadata(inData); } } private void write_magic() throws IOException { // Write signature byte[] magic = { (byte)137, 80, 78, 71, 13, 10, 26, 10 }; stream.write(magic); } private void write_IHDR() throws IOException { // Write IHDR chunk ChunkStream cs = new ChunkStream(PNGImageReader.IHDR_TYPE, stream); cs.writeInt(metadata.IHDR_width); cs.writeInt(metadata.IHDR_height); cs.writeByte(metadata.IHDR_bitDepth); cs.writeByte(metadata.IHDR_colorType); if (metadata.IHDR_compressionMethod != 0) { throw new IIOException( "Only compression method 0 is defined in PNG 1.1"); } cs.writeByte(metadata.IHDR_compressionMethod); if (metadata.IHDR_filterMethod != 0) { throw new IIOException( "Only filter method 0 is defined in PNG 1.1"); } cs.writeByte(metadata.IHDR_filterMethod); if (metadata.IHDR_interlaceMethod < 0 || metadata.IHDR_interlaceMethod > 1) { throw new IIOException( "Only interlace methods 0 (node) and 1 (adam7) are defined in PNG 1.1"); } cs.writeByte(metadata.IHDR_interlaceMethod); cs.finish(); } private void write_cHRM() throws IOException { if (metadata.cHRM_present) { ChunkStream cs = new ChunkStream(PNGImageReader.cHRM_TYPE, stream); cs.writeInt(metadata.cHRM_whitePointX); cs.writeInt(metadata.cHRM_whitePointY); cs.writeInt(metadata.cHRM_redX); cs.writeInt(metadata.cHRM_redY); cs.writeInt(metadata.cHRM_greenX); cs.writeInt(metadata.cHRM_greenY); cs.writeInt(metadata.cHRM_blueX); cs.writeInt(metadata.cHRM_blueY); cs.finish(); } } private void write_gAMA() throws IOException { if (metadata.gAMA_present) { ChunkStream cs = new ChunkStream(PNGImageReader.gAMA_TYPE, stream); cs.writeInt(metadata.gAMA_gamma); cs.finish(); } } private void write_iCCP() throws IOException { if (metadata.iCCP_present) { ChunkStream cs = new ChunkStream(PNGImageReader.iCCP_TYPE, stream); cs.writeBytes(metadata.iCCP_profileName); cs.writeByte(0); // null terminator cs.writeByte(metadata.iCCP_compressionMethod); cs.write(metadata.iCCP_compressedProfile); cs.finish(); } } private void write_sBIT() throws IOException { if (metadata.sBIT_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sBIT_TYPE, stream); int colorType = metadata.IHDR_colorType; if (metadata.sBIT_colorType != colorType) { processWarningOccurred(0, "sBIT metadata has wrong color type.\n" + "The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_GRAY || colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { cs.writeByte(metadata.sBIT_grayBits); } else if (colorType == PNGImageReader.PNG_COLOR_RGB || colorType == PNGImageReader.PNG_COLOR_PALETTE || colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) { cs.writeByte(metadata.sBIT_redBits); cs.writeByte(metadata.sBIT_greenBits); cs.writeByte(metadata.sBIT_blueBits); } if (colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA || colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) { cs.writeByte(metadata.sBIT_alphaBits); } cs.finish(); } } private void write_sRGB() throws IOException { if (metadata.sRGB_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sRGB_TYPE, stream); cs.writeByte(metadata.sRGB_renderingIntent); cs.finish(); } } private void write_PLTE() throws IOException { if (metadata.PLTE_present) { if (metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY || metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { // PLTE cannot occur in a gray image processWarningOccurred(0, "A PLTE chunk may not appear in a gray or gray alpha image.\n" + "The chunk will not be written"); return; } ChunkStream cs = new ChunkStream(PNGImageReader.PLTE_TYPE, stream); int numEntries = metadata.PLTE_red.length; byte[] palette = new byte[numEntries*3]; int index = 0; for (int i = 0; i < numEntries; i++) { palette[index++] = metadata.PLTE_red[i]; palette[index++] = metadata.PLTE_green[i]; palette[index++] = metadata.PLTE_blue[i]; } cs.write(palette); cs.finish(); } } private void write_hIST() throws IOException, IIOException { if (metadata.hIST_present) { ChunkStream cs = new ChunkStream(PNGImageReader.hIST_TYPE, stream); if (!metadata.PLTE_present) { throw new IIOException("hIST chunk without PLTE chunk!"); } cs.writeChars(metadata.hIST_histogram, 0, metadata.hIST_histogram.length); cs.finish(); } } private void write_tRNS() throws IOException, IIOException { if (metadata.tRNS_present) { ChunkStream cs = new ChunkStream(PNGImageReader.tRNS_TYPE, stream); int colorType = metadata.IHDR_colorType; int chunkType = metadata.tRNS_colorType; // Special case: image is RGB and chunk is Gray // Promote chunk contents to RGB int chunkRed = metadata.tRNS_red; int chunkGreen = metadata.tRNS_green; int chunkBlue = metadata.tRNS_blue; if (colorType == PNGImageReader.PNG_COLOR_RGB && chunkType == PNGImageReader.PNG_COLOR_GRAY) { chunkType = colorType; chunkRed = chunkGreen = chunkBlue = metadata.tRNS_gray; } if (chunkType != colorType) { processWarningOccurred(0, "tRNS metadata has incompatible color type.\n" + "The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_PALETTE) { if (!metadata.PLTE_present) { throw new IIOException("tRNS chunk without PLTE chunk!"); } cs.write(metadata.tRNS_alpha); } else if (colorType == PNGImageReader.PNG_COLOR_GRAY) { cs.writeShort(metadata.tRNS_gray); } else if (colorType == PNGImageReader.PNG_COLOR_RGB) { cs.writeShort(chunkRed); cs.writeShort(chunkGreen); cs.writeShort(chunkBlue); } else { throw new IIOException("tRNS chunk for color type 4 or 6!"); } cs.finish(); } } private void write_bKGD() throws IOException { if (metadata.bKGD_present) { ChunkStream cs = new ChunkStream(PNGImageReader.bKGD_TYPE, stream); int colorType = metadata.IHDR_colorType & 0x3; int chunkType = metadata.bKGD_colorType; int chunkRed = metadata.bKGD_red; int chunkGreen = metadata.bKGD_green; int chunkBlue = metadata.bKGD_blue; // Special case: image is RGB(A) and chunk is Gray // Promote chunk contents to RGB if (colorType == PNGImageReader.PNG_COLOR_RGB && chunkType == PNGImageReader.PNG_COLOR_GRAY) { // Make a gray bKGD chunk look like RGB chunkType = colorType; chunkRed = chunkGreen = chunkBlue = metadata.bKGD_gray; } // Ignore status of alpha in colorType if (chunkType != colorType) { processWarningOccurred(0, "bKGD metadata has incompatible color type.\n" + "The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_PALETTE) { cs.writeByte(metadata.bKGD_index); } else if (colorType == PNGImageReader.PNG_COLOR_GRAY || colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { cs.writeShort(metadata.bKGD_gray); } else { // colorType == PNGImageReader.PNG_COLOR_RGB || // colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA cs.writeShort(chunkRed); cs.writeShort(chunkGreen); cs.writeShort(chunkBlue); } cs.finish(); } } private void write_pHYs() throws IOException { if (metadata.pHYs_present) { ChunkStream cs = new ChunkStream(PNGImageReader.pHYs_TYPE, stream); cs.writeInt(metadata.pHYs_pixelsPerUnitXAxis); cs.writeInt(metadata.pHYs_pixelsPerUnitYAxis); cs.writeByte(metadata.pHYs_unitSpecifier); cs.finish(); } } private void write_sPLT() throws IOException { if (metadata.sPLT_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sPLT_TYPE, stream); cs.writeBytes(metadata.sPLT_paletteName); cs.writeByte(0); // null terminator cs.writeByte(metadata.sPLT_sampleDepth); int numEntries = metadata.sPLT_red.length; if (metadata.sPLT_sampleDepth == 8) { for (int i = 0; i < numEntries; i++) { cs.writeByte(metadata.sPLT_red[i]); cs.writeByte(metadata.sPLT_green[i]); cs.writeByte(metadata.sPLT_blue[i]); cs.writeByte(metadata.sPLT_alpha[i]); cs.writeShort(metadata.sPLT_frequency[i]); } } else { // sampleDepth == 16 for (int i = 0; i < numEntries; i++) { cs.writeShort(metadata.sPLT_red[i]); cs.writeShort(metadata.sPLT_green[i]); cs.writeShort(metadata.sPLT_blue[i]); cs.writeShort(metadata.sPLT_alpha[i]); cs.writeShort(metadata.sPLT_frequency[i]); } } cs.finish(); } } private void write_tIME() throws IOException { if (metadata.tIME_present) { ChunkStream cs = new ChunkStream(PNGImageReader.tIME_TYPE, stream); cs.writeShort(metadata.tIME_year); cs.writeByte(metadata.tIME_month); cs.writeByte(metadata.tIME_day); cs.writeByte(metadata.tIME_hour); cs.writeByte(metadata.tIME_minute); cs.writeByte(metadata.tIME_second); cs.finish(); } } private void write_tEXt() throws IOException { Iterator<String> keywordIter = metadata.tEXt_keyword.iterator(); Iterator<String> textIter = metadata.tEXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.tEXt_TYPE, stream); String keyword = keywordIter.next(); cs.writeBytes(keyword); cs.writeByte(0); String text = textIter.next(); cs.writeBytes(text); cs.finish(); } } private byte[] deflate(byte[] b) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream dos = new DeflaterOutputStream(baos); dos.write(b); dos.close(); return baos.toByteArray(); } private void write_iTXt() throws IOException { Iterator<String> keywordIter = metadata.iTXt_keyword.iterator(); Iterator<Boolean> flagIter = metadata.iTXt_compressionFlag.iterator(); Iterator<Integer> methodIter = metadata.iTXt_compressionMethod.iterator(); Iterator<String> languageIter = metadata.iTXt_languageTag.iterator(); Iterator<String> translatedKeywordIter = metadata.iTXt_translatedKeyword.iterator(); Iterator<String> textIter = metadata.iTXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.iTXt_TYPE, stream); cs.writeBytes(keywordIter.next()); cs.writeByte(0); Boolean compressed = flagIter.next(); cs.writeByte(compressed ? 1 : 0); cs.writeByte(methodIter.next().intValue()); cs.writeBytes(languageIter.next()); cs.writeByte(0); cs.write(translatedKeywordIter.next().getBytes("UTF8")); cs.writeByte(0); String text = textIter.next(); if (compressed) { cs.write(deflate(text.getBytes("UTF8"))); } else { cs.write(text.getBytes("UTF8")); } cs.finish(); } } private void write_zTXt() throws IOException { Iterator<String> keywordIter = metadata.zTXt_keyword.iterator(); Iterator<Integer> methodIter = metadata.zTXt_compressionMethod.iterator(); Iterator<String> textIter = metadata.zTXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.zTXt_TYPE, stream); String keyword = keywordIter.next(); cs.writeBytes(keyword); cs.writeByte(0); int compressionMethod = (methodIter.next()).intValue(); cs.writeByte(compressionMethod); String text = textIter.next(); cs.write(deflate(text.getBytes("ISO-8859-1"))); cs.finish(); } } private void writeUnknownChunks() throws IOException { Iterator<String> typeIter = metadata.unknownChunkType.iterator(); Iterator<byte[]> dataIter = metadata.unknownChunkData.iterator(); while (typeIter.hasNext() && dataIter.hasNext()) { String type = typeIter.next(); ChunkStream cs = new ChunkStream(chunkType(type), stream); byte[] data = dataIter.next(); cs.write(data); cs.finish(); } } private static int chunkType(String typeString) { char c0 = typeString.charAt(0); char c1 = typeString.charAt(1); char c2 = typeString.charAt(2); char c3 = typeString.charAt(3); int type = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3; return type; } private void encodePass(ImageOutputStream os, RenderedImage image, int xOffset, int yOffset, int xSkip, int ySkip) throws IOException { int minX = sourceXOffset; int minY = sourceYOffset; int width = sourceWidth; int height = sourceHeight; // Adjust offsets and skips based on source subsampling factors xOffset *= periodX; xSkip *= periodX; yOffset *= periodY; ySkip *= periodY; // Early exit if no data for this pass int hpixels = (width - xOffset + xSkip - 1)/xSkip; int vpixels = (height - yOffset + ySkip - 1)/ySkip; if (hpixels == 0 || vpixels == 0) { return; } // Convert X offset and skip from pixels to samples xOffset *= numBands; xSkip *= numBands; // Create row buffers int samplesPerByte = 8/metadata.IHDR_bitDepth; int numSamples = width*numBands; int[] samples = new int[numSamples]; int bytesPerRow = hpixels*numBands; if (metadata.IHDR_bitDepth < 8) { bytesPerRow = (bytesPerRow + samplesPerByte - 1)/samplesPerByte; } else if (metadata.IHDR_bitDepth == 16) { bytesPerRow *= 2; } IndexColorModel icm_gray_alpha = null; if (metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA && image.getColorModel() instanceof IndexColorModel) { // reserve space for alpha samples bytesPerRow *= 2; // will be used to calculate alpha value for the pixel icm_gray_alpha = (IndexColorModel)image.getColorModel(); } currRow = new byte[bytesPerRow + bpp]; prevRow = new byte[bytesPerRow + bpp]; filteredRows = new byte[5][bytesPerRow + bpp]; int bitDepth = metadata.IHDR_bitDepth; for (int row = minY + yOffset; row < minY + height; row += ySkip) { Rectangle rect = new Rectangle(minX, row, width, 1); Raster ras = image.getData(rect); if (sourceBands != null) { ras = ras.createChild(minX, row, width, 1, minX, row, sourceBands); } ras.getPixels(minX, row, width, 1, samples); if (image.getColorModel().isAlphaPremultiplied()) { WritableRaster wr = ras.createCompatibleWritableRaster(); wr.setPixels(wr.getMinX(), wr.getMinY(), wr.getWidth(), wr.getHeight(), samples); image.getColorModel().coerceData(wr, false); wr.getPixels(wr.getMinX(), wr.getMinY(), wr.getWidth(), wr.getHeight(), samples); } // Reorder palette data if necessary int[] paletteOrder = metadata.PLTE_order; if (paletteOrder != null) { for (int i = 0; i < numSamples; i++) { samples[i] = paletteOrder[samples[i]]; } } int count = bpp; // leave first 'bpp' bytes zero int pos = 0; int tmp = 0; switch (bitDepth) { case 1: case 2: case 4: // Image can only have a single band int mask = samplesPerByte - 1; for (int s = xOffset; s < numSamples; s += xSkip) { byte val = scale0[samples[s]]; tmp = (tmp << bitDepth) | val; if ((pos++ & mask) == mask) { currRow[count++] = (byte)tmp; tmp = 0; pos = 0; } } // Left shift the last byte if ((pos & mask) != 0) { tmp <<= ((8/bitDepth) - pos)*bitDepth; currRow[count++] = (byte)tmp; } break; case 8: if (numBands == 1) { for (int s = xOffset; s < numSamples; s += xSkip) { currRow[count++] = scale0[samples[s]]; if (icm_gray_alpha != null) { currRow[count++] = scale0[icm_gray_alpha.getAlpha(0xff & samples[s])]; } } } else { for (int s = xOffset; s < numSamples; s += xSkip) { for (int b = 0; b < numBands; b++) { currRow[count++] = scale[b][samples[s + b]]; } } } break; case 16: for (int s = xOffset; s < numSamples; s += xSkip) { for (int b = 0; b < numBands; b++) { currRow[count++] = scaleh[b][samples[s + b]]; currRow[count++] = scalel[b][samples[s + b]]; } } break; } // Perform filtering int filterType = rowFilter.filterRow(metadata.IHDR_colorType, currRow, prevRow, filteredRows, bytesPerRow, bpp); os.write(filterType); os.write(filteredRows[filterType], bpp, bytesPerRow); // Swap current and previous rows byte[] swap = currRow; currRow = prevRow; prevRow = swap; pixelsDone += hpixels; processImageProgress(100.0F*pixelsDone/totalPixels); // If write has been aborted, just return; // processWriteAborted will be called later if (abortRequested()) { return; } } } // Use sourceXOffset, etc. private void write_IDAT(RenderedImage image, int deflaterLevel) throws IOException { IDATOutputStream ios = new IDATOutputStream(stream, 32768, deflaterLevel); try { if (metadata.IHDR_interlaceMethod == 1) { for (int i = 0; i < 7; i++) { encodePass(ios, image, PNGImageReader.adam7XOffset[i], PNGImageReader.adam7YOffset[i], PNGImageReader.adam7XSubsampling[i], PNGImageReader.adam7YSubsampling[i]); if (abortRequested()) { break; } } } else { encodePass(ios, image, 0, 0, 1, 1); } } finally { ios.finish(); } } private void writeIEND() throws IOException { ChunkStream cs = new ChunkStream(PNGImageReader.IEND_TYPE, stream); cs.finish(); } // Check two int arrays for value equality, always returns false // if either array is null private boolean equals(int[] s0, int[] s1) { if (s0 == null || s1 == null) { return false; } if (s0.length != s1.length) { return false; } for (int i = 0; i < s0.length; i++) { if (s0[i] != s1[i]) { return false; } } return true; } // Initialize the scale/scale0 or scaleh/scalel arrays to // hold the results of scaling an input value to the desired // output bit depth private void initializeScaleTables(int[] sampleSize) { int bitDepth = metadata.IHDR_bitDepth; // If the existing tables are still valid, just return if (bitDepth == scalingBitDepth && equals(sampleSize, this.sampleSize)) { return; } // Compute new tables this.sampleSize = sampleSize; this.scalingBitDepth = bitDepth; int maxOutSample = (1 << bitDepth) - 1; if (bitDepth <= 8) { scale = new byte[numBands][]; for (int b = 0; b < numBands; b++) { int maxInSample = (1 << sampleSize[b]) - 1; int halfMaxInSample = maxInSample/2; scale[b] = new byte[maxInSample + 1]; for (int s = 0; s <= maxInSample; s++) { scale[b][s] = (byte)((s*maxOutSample + halfMaxInSample)/maxInSample); } } scale0 = scale[0]; scaleh = scalel = null; } else { // bitDepth == 16 // Divide scaling table into high and low bytes scaleh = new byte[numBands][]; scalel = new byte[numBands][]; for (int b = 0; b < numBands; b++) { int maxInSample = (1 << sampleSize[b]) - 1; int halfMaxInSample = maxInSample/2; scaleh[b] = new byte[maxInSample + 1]; scalel[b] = new byte[maxInSample + 1]; for (int s = 0; s <= maxInSample; s++) { int val = (s*maxOutSample + halfMaxInSample)/maxInSample; scaleh[b][s] = (byte)(val >> 8); scalel[b][s] = (byte)(val & 0xff); } } scale = null; scale0 = null; } } @Override public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IIOException { if (stream == null) { throw new IllegalStateException("output == null!"); } if (image == null) { throw new IllegalArgumentException("image == null!"); } if (image.hasRaster()) { throw new UnsupportedOperationException("image has a Raster!"); } RenderedImage im = image.getRenderedImage(); SampleModel sampleModel = im.getSampleModel(); this.numBands = sampleModel.getNumBands(); // Set source region and subsampling to default values this.sourceXOffset = im.getMinX(); this.sourceYOffset = im.getMinY(); this.sourceWidth = im.getWidth(); this.sourceHeight = im.getHeight(); this.sourceBands = null; this.periodX = 1; this.periodY = 1; if (param != null) { // Get source region and subsampling factors Rectangle sourceRegion = param.getSourceRegion(); if (sourceRegion != null) { Rectangle imageBounds = new Rectangle(im.getMinX(), im.getMinY(), im.getWidth(), im.getHeight()); // Clip to actual image bounds sourceRegion = sourceRegion.intersection(imageBounds); sourceXOffset = sourceRegion.x; sourceYOffset = sourceRegion.y; sourceWidth = sourceRegion.width; sourceHeight = sourceRegion.height; } // Adjust for subsampling offsets int gridX = param.getSubsamplingXOffset(); int gridY = param.getSubsamplingYOffset(); sourceXOffset += gridX; sourceYOffset += gridY; sourceWidth -= gridX; sourceHeight -= gridY; // Get subsampling factors periodX = param.getSourceXSubsampling(); periodY = param.getSourceYSubsampling(); int[] sBands = param.getSourceBands(); if (sBands != null) { sourceBands = sBands; numBands = sourceBands.length; } } // Compute output dimensions int destWidth = (sourceWidth + periodX - 1)/periodX; int destHeight = (sourceHeight + periodY - 1)/periodY; if (destWidth <= 0 || destHeight <= 0) { throw new IllegalArgumentException("Empty source region!"); } // Compute total number of pixels for progress notification this.totalPixels = destWidth*destHeight; this.pixelsDone = 0; // Create metadata IIOMetadata imd = image.getMetadata(); if (imd != null) { metadata = (PNGMetadata)convertImageMetadata(imd, ImageTypeSpecifier.createFromRenderedImage(im), null); } else { metadata = new PNGMetadata(); } // reset compression level to default: int deflaterLevel = DEFAULT_COMPRESSION_LEVEL; if (param != null) { switch(param.getCompressionMode()) { case ImageWriteParam.MODE_DISABLED: deflaterLevel = Deflater.NO_COMPRESSION; break; case ImageWriteParam.MODE_EXPLICIT: float quality = param.getCompressionQuality(); if (quality >= 0f && quality <= 1f) { deflaterLevel = 9 - Math.round(9f * quality); } break; default: } // Use Adam7 interlacing if set in write param switch (param.getProgressiveMode()) { case ImageWriteParam.MODE_DEFAULT: metadata.IHDR_interlaceMethod = 1; break; case ImageWriteParam.MODE_DISABLED: metadata.IHDR_interlaceMethod = 0; break; // MODE_COPY_FROM_METADATA should already be taken care of // MODE_EXPLICIT is not allowed default: } } // Initialize bitDepth and colorType metadata.initialize(new ImageTypeSpecifier(im), numBands); // Overwrite IHDR width and height values with values from image metadata.IHDR_width = destWidth; metadata.IHDR_height = destHeight; this.bpp = numBands*((metadata.IHDR_bitDepth == 16) ? 2 : 1); // Initialize scaling tables for this image initializeScaleTables(sampleModel.getSampleSize()); clearAbortRequest(); processImageStarted(0); if (abortRequested()) { processWriteAborted(); } else { try { write_magic(); write_IHDR(); write_cHRM(); write_gAMA(); write_iCCP(); write_sBIT(); write_sRGB(); write_PLTE(); write_hIST(); write_tRNS(); write_bKGD(); write_pHYs(); write_sPLT(); write_tIME(); write_tEXt(); write_iTXt(); write_zTXt(); writeUnknownChunks(); write_IDAT(im, deflaterLevel); if (abortRequested()) { processWriteAborted(); } else { // Finish up and inform the listeners we are done writeIEND(); processImageComplete(); } } catch (IOException e) { throw new IIOException("I/O error writing PNG file!", e); } } } }
⏎ com/sun/imageio/plugins/png/PNGImageWriter.java
Or download all of them as a single archive file:
File name: java.desktop-11.0.1-src.zip File size: 7974380 bytes Release date: 2018-11-04 Download
⇒ JDK 11 java.instrument.jmod - Instrument Module
2022-08-06, 192938👍, 5💬
Popular Posts:
What Is log4j-1.2.13.jar? I got the JAR file from logging-log4j-1.2.13.zip .log4j-1.2.13.jar is the ...
JRE 8 rt.jar is the JAR file for JRE 8 RT (Runtime) libraries. JRE (Java Runtime) 8 is the runtime e...
JDK 11 jdk.internal.opt.jmod is the JMOD file for JDK 11 Internal Opt module. JDK 11 Internal Opt mo...
How to perform XML Schema validation with dom\Writer.java provided in the Apache Xerces package? You...
JRE 8 plugin.jar is the JAR file for JRE 8 Java Control Panel Plugin interface and tools. JRE (Java ...