📄 jpegimagewriter.java
字号:
if (rasterOnly) { srcRas = image.getRaster(); } else { rimage = image.getRenderedImage(); if (rimage instanceof BufferedImage) { // Use the Raster directly. srcRas = ((BufferedImage)rimage).getRaster(); } else if (rimage.getNumXTiles() == 1 && rimage.getNumYTiles() == 1) { // Get the unique tile. srcRas = rimage.getTile(rimage.getMinTileX(), rimage.getMinTileY()); // Ensure the Raster has dimensions of the image, // as the tile dimensions might differ. if (srcRas.getWidth() != rimage.getWidth() || srcRas.getHeight() != rimage.getHeight()) { srcRas = srcRas.createChild(srcRas.getMinX(), srcRas.getMinY(), rimage.getWidth(), rimage.getHeight(), srcRas.getMinX(), srcRas.getMinY(), null); } } else { // Image is tiled so get a contiguous raster by copying. srcRas = rimage.getData(); } } // Now determine if we are using a band subset // By default, we are using all source bands int numSrcBands = srcRas.getNumBands(); indexed = false; indexCM = null; ColorModel cm = null; ColorSpace cs = null; isAlphaPremultiplied = false; srcCM = null; if (!rasterOnly) { cm = rimage.getColorModel(); if (cm != null) { cs = cm.getColorSpace(); if (cm instanceof IndexColorModel) { indexed = true; indexCM = (IndexColorModel) cm; numSrcBands = cm.getNumComponents(); } if (cm.isAlphaPremultiplied()) { isAlphaPremultiplied = true; srcCM = cm; } } } srcBands = JPEG.bandOffsets[numSrcBands-1]; int numBandsUsed = numSrcBands; // Consult the param to determine if we're writing a subset if (param != null) { int[] sBands = param.getSourceBands(); if (sBands != null) { if (indexed) { warningOccurred(WARNING_NO_BANDS_ON_INDEXED); } else { srcBands = sBands; numBandsUsed = srcBands.length; if (numBandsUsed > numSrcBands) { throw new IIOException ("ImageWriteParam specifies too many source bands"); } } } } boolean usingBandSubset = (numBandsUsed != numSrcBands); boolean fullImage = ((!rasterOnly) && (!usingBandSubset)); int [] bandSizes = null; if (!indexed) { bandSizes = srcRas.getSampleModel().getSampleSize(); // If this is a subset, we must adjust bandSizes if (usingBandSubset) { int [] temp = new int [numBandsUsed]; for (int i = 0; i < numBandsUsed; i++) { temp[i] = bandSizes[srcBands[i]]; } bandSizes = temp; } } else { int [] tempSize = srcRas.getSampleModel().getSampleSize(); bandSizes = new int [numSrcBands]; for (int i = 0; i < numSrcBands; i++) { bandSizes[i] = tempSize[0]; // All the same } } for (int i = 0; i < bandSizes.length; i++) { // 4450894 part 1: The IJG libraries are compiled so they only // handle <= 8-bit samples. We now check the band sizes and throw // an exception for images, such as USHORT_GRAY, with > 8 bits // per sample. if (bandSizes[i] > 8) { throw new IIOException("Sample size must be <= 8"); } // 4450894 part 2: We expand IndexColorModel images to full 24- // or 32-bit in grabPixels() for each scanline. For indexed // images such as BYTE_BINARY, we need to ensure that we update // bandSizes to account for the scaling from 1-bit band sizes // to 8-bit. if (indexed) { bandSizes[i] = 8; } } if (debug) { System.out.println("numSrcBands is " + numSrcBands); System.out.println("numBandsUsed is " + numBandsUsed); System.out.println("usingBandSubset is " + usingBandSubset); System.out.println("fullImage is " + fullImage); System.out.print("Band sizes:"); for (int i = 0; i< bandSizes.length; i++) { System.out.print(" " + bandSizes[i]); } System.out.println(); } // Destination type, if there is one ImageTypeSpecifier destType = null; if (param != null) { destType = param.getDestinationType(); // Ignore dest type if we are writing a complete image if ((fullImage) && (destType != null)) { warningOccurred(WARNING_DEST_IGNORED); destType = null; } } // Examine the param sourceXOffset = srcRas.getMinX(); sourceYOffset = srcRas.getMinY(); int imageWidth = srcRas.getWidth(); int imageHeight = srcRas.getHeight(); sourceWidth = imageWidth; sourceHeight = imageHeight; int periodX = 1; int periodY = 1; int gridX = 0; int gridY = 0; JPEGQTable [] qTables = null; JPEGHuffmanTable[] DCHuffmanTables = null; JPEGHuffmanTable[] ACHuffmanTables = null; boolean optimizeHuffman = false; JPEGImageWriteParam jparam = null; int progressiveMode = ImageWriteParam.MODE_DISABLED; if (param != null) { Rectangle sourceRegion = param.getSourceRegion(); if (sourceRegion != null) { Rectangle imageBounds = new Rectangle(sourceXOffset, sourceYOffset, sourceWidth, sourceHeight); sourceRegion = sourceRegion.intersection(imageBounds); sourceXOffset = sourceRegion.x; sourceYOffset = sourceRegion.y; sourceWidth = sourceRegion.width; sourceHeight = sourceRegion.height; } if (sourceWidth + sourceXOffset > imageWidth) { sourceWidth = imageWidth - sourceXOffset; } if (sourceHeight + sourceYOffset > imageHeight) { sourceHeight = imageHeight - sourceYOffset; } periodX = param.getSourceXSubsampling(); periodY = param.getSourceYSubsampling(); gridX = param.getSubsamplingXOffset(); gridY = param.getSubsamplingYOffset(); switch(param.getCompressionMode()) { case ImageWriteParam.MODE_DISABLED: throw new IIOException("JPEG compression cannot be disabled"); case ImageWriteParam.MODE_EXPLICIT: float quality = param.getCompressionQuality(); quality = JPEG.convertToLinearQuality(quality); qTables = new JPEGQTable[2]; qTables[0] = JPEGQTable.K1Luminance.getScaledInstance (quality, true); qTables[1] = JPEGQTable.K2Chrominance.getScaledInstance (quality, true); break; case ImageWriteParam.MODE_DEFAULT: qTables = new JPEGQTable[2]; qTables[0] = JPEGQTable.K1Div2Luminance; qTables[1] = JPEGQTable.K2Div2Chrominance; break; // We'll handle the metadata case later } progressiveMode = param.getProgressiveMode(); if (param instanceof JPEGImageWriteParam) { jparam = (JPEGImageWriteParam)param; optimizeHuffman = jparam.getOptimizeHuffmanTables(); } } // Now examine the metadata IIOMetadata mdata = image.getMetadata(); if (mdata != null) { if (mdata instanceof JPEGMetadata) { metadata = (JPEGMetadata) mdata; if (debug) { System.out.println ("We have metadata, and it's JPEG metadata"); } } else { if (!rasterOnly) { ImageTypeSpecifier type = destType; if (type == null) { type = new ImageTypeSpecifier(rimage); } metadata = (JPEGMetadata) convertImageMetadata(mdata, type, param); } else { warningOccurred(WARNING_METADATA_NOT_JPEG_FOR_RASTER); } } } // First set a default state ignoreJFIF = false; // If it's there, use it ignoreAdobe = false; // If it's there, use it newAdobeTransform = JPEG.ADOBE_IMPOSSIBLE; // Change if needed writeDefaultJFIF = false; writeAdobe = false; // By default we'll do no conversion: int inCsType = JPEG.JCS_UNKNOWN; int outCsType = JPEG.JCS_UNKNOWN; JFIFMarkerSegment jfif = null; AdobeMarkerSegment adobe = null; SOFMarkerSegment sof = null; if (metadata != null) { jfif = (JFIFMarkerSegment) metadata.findMarkerSegment (JFIFMarkerSegment.class, true); adobe = (AdobeMarkerSegment) metadata.findMarkerSegment (AdobeMarkerSegment.class, true); sof = (SOFMarkerSegment) metadata.findMarkerSegment (SOFMarkerSegment.class, true); } iccProfile = null; // By default don't write one convertTosRGB = false; // PhotoYCC does this converted = null; if (destType != null) { if (numBandsUsed != destType.getNumBands()) { throw new IIOException ("Number of source bands != number of destination bands"); } cs = destType.getColorModel().getColorSpace(); // Check the metadata against the destination type if (metadata != null) { checkSOFBands(sof, numBandsUsed); checkJFIF(jfif, destType, false); // Do we want to write an ICC profile? if ((jfif != null) && (ignoreJFIF == false)) { if (JPEG.isNonStandardICC(cs)) { iccProfile = ((ICC_ColorSpace) cs).getProfile(); } } checkAdobe(adobe, destType, false); } else { // no metadata, but there is a dest type // If we can add a JFIF or an Adobe marker segment, do so if (JPEG.isJFIFcompliant(destType, false)) { writeDefaultJFIF = true; // Do we want to write an ICC profile? if (JPEG.isNonStandardICC(cs)) { iccProfile = ((ICC_ColorSpace) cs).getProfile(); } } else { int transform = JPEG.transformForType(destType, false); if (transform != JPEG.ADOBE_IMPOSSIBLE) { writeAdobe = true; newAdobeTransform = transform; } } // re-create the metadata metadata = new JPEGMetadata(destType, null, this); } inCsType = getSrcCSType(destType); outCsType = getDefaultDestCSType(destType); } else { // no destination type if (metadata == null) { if (fullImage) { // no dest, no metadata, full image // Use default metadata matching the image and param metadata = new JPEGMetadata(new ImageTypeSpecifier(rimage), param, this); if (metadata.findMarkerSegment (JFIFMarkerSegment.class, true) != null) { cs = rimage.getColorModel().getColorSpace(); if (JPEG.isNonStandardICC(cs)) { iccProfile = ((ICC_ColorSpace) cs).getProfile(); } } inCsType = getSrcCSType(rimage); outCsType = getDefaultDestCSType(rimage); } // else no dest, no metadata, not an image, // so no special headers, no color conversion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -