📄 jpegimagereader.java
字号:
ArrayList list = new ArrayList(1); switch (colorSpaceCode) { case JPEG.JCS_GRAYSCALE: list.add(raw); list.add(getImageType(JPEG.JCS_RGB)); break; case JPEG.JCS_RGB: list.add(raw); list.add(getImageType(JPEG.JCS_GRAYSCALE)); if (JPEG.JCS.YCC != null) { list.add(getImageType(JPEG.JCS_YCC)); } break; case JPEG.JCS_RGBA: list.add(raw); break; case JPEG.JCS_YCC: if (raw != null) { // Might be null if PYCC.pf not installed list.add(raw); list.add(getImageType(JPEG.JCS_RGB)); } break; case JPEG.JCS_YCCA: if (raw != null) { // Might be null if PYCC.pf not installed list.add(raw); } break; case JPEG.JCS_YCbCr: // As there is no YCbCr ColorSpace, we can't support // the raw type. // due to 4705399, use RGB as default in order to avoid // slowing down of drawing operations with result image. list.add(getImageType(JPEG.JCS_RGB)); if (iccCS != null) { list.add(ImageTypeSpecifier.createInterleaved (iccCS, JPEG.bOffsRGB, // Assume it's for RGB DataBuffer.TYPE_BYTE, false, false)); } list.add(getImageType(JPEG.JCS_GRAYSCALE)); if (JPEG.JCS.YCC != null) { // Might be null if PYCC.pf not installed list.add(getImageType(JPEG.JCS_YCC)); } break; case JPEG.JCS_YCbCrA: // Default is to convert to RGBA // As there is no YCbCr ColorSpace, we can't support // the raw type. list.add(getImageType(JPEG.JCS_RGBA)); break; } return list.iterator(); } /** * Checks the implied color conversion between the stream and * the target image, altering the IJG output color space if necessary. * If a java color conversion is required, then this sets up * <code>convert</code>. * If bands are being rearranged at all (either source or destination * bands are specified in the param), then the default color * conversions are assumed to be correct. * Throws an IIOException if there is no conversion available. */ private void checkColorConversion(BufferedImage image, ImageReadParam param) throws IIOException { // If we are rearranging channels at all, the default // conversions remain in place. If the user wants // raw channels then he should do this while reading // a Raster. if (param != null) { if ((param.getSourceBands() != null) || (param.getDestinationBands() != null)) { // Accept default conversions out of decoder, silently return; } } // XXX - We do not currently support any indexed color models, // though we could, as IJG will quantize for us. // This is a performance and memory-use issue, as // users can read RGB and then convert to indexed in Java. ColorModel cm = image.getColorModel(); if (cm instanceof IndexColorModel) { throw new IIOException("IndexColorModel not supported"); } // Now check the ColorSpace type against outColorSpaceCode // We may want to tweak the default ColorSpace cs = cm.getColorSpace(); int csType = cs.getType(); convert = null; switch (outColorSpaceCode) { case JPEG.JCS_GRAYSCALE: // Its gray in the file if (csType == ColorSpace.TYPE_RGB) { // We want RGB // IJG can do this for us more efficiently setOutColorSpace(structPointer, JPEG.JCS_RGB); } else if (csType != ColorSpace.TYPE_GRAY) { throw new IIOException("Incompatible color conversion"); } break; case JPEG.JCS_RGB: // IJG wants to go to RGB if (csType == ColorSpace.TYPE_GRAY) { // We want gray if (colorSpaceCode == JPEG.JCS_YCbCr) { // If the jpeg space is YCbCr, IJG can do it setOutColorSpace(structPointer, JPEG.JCS_GRAYSCALE); } } else if ((iccCS != null) && (cm.getNumComponents() == numComponents) && (cs != iccCS)) { // We have an ICC profile but it isn't used in the dest // image. So convert from the profile cs to the target cs convert = new ColorConvertOp(iccCS, cs, null); // Leave IJG conversion in place; we still need it } else if ((iccCS == null) && (!cs.isCS_sRGB()) && (cm.getNumComponents() == numComponents)) { // Target isn't sRGB, so convert from sRGB to the target convert = new ColorConvertOp(JPEG.JCS.sRGB, cs, null); } else if (csType != ColorSpace.TYPE_RGB) { throw new IIOException("Incompatible color conversion"); } break; case JPEG.JCS_RGBA: // No conversions available; image must be RGBA if ((csType != ColorSpace.TYPE_RGB) || (cm.getNumComponents() != numComponents)) { throw new IIOException("Incompatible color conversion"); } break; case JPEG.JCS_YCC: if (JPEG.JCS.YCC == null) { // We can't do YCC at all throw new IIOException("Incompatible color conversion"); } if ((cs != JPEG.JCS.YCC) && (cm.getNumComponents() == numComponents)) { convert = new ColorConvertOp(JPEG.JCS.YCC, cs, null); } break; case JPEG.JCS_YCCA: // No conversions available; image must be YCCA if ((JPEG.JCS.YCC == null) || // We can't do YCC at all (cs != JPEG.JCS.YCC) || (cm.getNumComponents() != numComponents)) { throw new IIOException("Incompatible color conversion"); } break; default: // Anything else we can't handle at all throw new IIOException("Incompatible color conversion"); } } /** * Set the IJG output space to the given value. The library will * perform the appropriate colorspace conversions. */ private native void setOutColorSpace(long structPointer, int id); /////// End of Color Conversion & Image Types public ImageReadParam getDefaultReadParam() { return new JPEGImageReadParam(); } public IIOMetadata getStreamMetadata() throws IOException { if (!tablesOnlyChecked) { checkTablesOnly(); } return streamMetadata; } public IIOMetadata getImageMetadata(int imageIndex) throws IOException { // imageMetadataIndex will always be either a valid index or // -1, in which case imageMetadata will not be null. // So we can leave checking imageIndex for gotoImage. if ((imageMetadataIndex == imageIndex) && (imageMetadata != null)) { return imageMetadata; } gotoImage(imageIndex); imageMetadata = new JPEGMetadata(false, false, iis, this); imageMetadataIndex = imageIndex; return imageMetadata; } public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { try { readInternal(imageIndex, param, false); } catch (RuntimeException e) { resetLibraryState(structPointer); throw e; } catch (IOException e) { resetLibraryState(structPointer); throw e; } BufferedImage ret = image; image = null; // don't keep a reference here return ret; } private Raster readInternal(int imageIndex, ImageReadParam param, boolean wantRaster) throws IOException { readHeader(imageIndex, false); WritableRaster imRas = null; int numImageBands = 0; if (!wantRaster){ // Can we read this image? Iterator imageTypes = getImageTypes(imageIndex); if (imageTypes.hasNext() == false) { throw new IIOException("Unsupported Image Type"); } image = getDestination(param, imageTypes, width, height); imRas = image.getRaster(); // The destination may still be incompatible. numImageBands = image.getSampleModel().getNumBands(); // Check whether we can handle any implied color conversion // Throws IIOException if the stream and the image are // incompatible, and sets convert if a java conversion // is necessary checkColorConversion(image, param); // Check the source and destination bands in the param checkReadParamBandSettings(param, numComponents, numImageBands); } else { // Set the output color space equal to the input colorspace // This disables all conversions setOutColorSpace(structPointer, colorSpaceCode); image = null; } // Create an intermediate 1-line Raster that will hold the decoded, // subsampled, clipped, band-selected image data in a single // byte-interleaved buffer. The above transformations // will occur in C for performance. Every time this Raster // is filled we will call back to acceptPixels below to copy // this to whatever kind of buffer our image has. int [] srcBands = JPEG.bandOffsets[numComponents-1]; int numRasterBands = (wantRaster ? numComponents : numImageBands); destinationBands = null; Rectangle srcROI = new Rectangle(0, 0, 0, 0); destROI = new Rectangle(0, 0, 0, 0); computeRegions(param, width, height, image, srcROI, destROI); int periodX = 1; int periodY = 1; minProgressivePass = 0; maxProgressivePass = Integer.MAX_VALUE; if (param != null) { periodX = param.getSourceXSubsampling(); periodY = param.getSourceYSubsampling(); int[] sBands = param.getSourceBands(); if (sBands != null) { srcBands = sBands; numRasterBands = srcBands.length; } if (!wantRaster) { // ignore dest bands for Raster destinationBands = param.getDestinationBands(); } minProgressivePass = param.getSourceMinProgressivePass(); maxProgressivePass = param.getSourceMaxProgressivePass(); if (param instanceof JPEGImageReadParam) { JPEGImageReadParam jparam = (JPEGImageReadParam) param; if (jparam.areTablesSet()) { abbrevQTables = jparam.getQTables(); abbrevDCHuffmanTables = jparam.getDCHuffmanTables(); abbrevACHuffmanTables = jparam.getACHuffmanTables(); } } } int lineSize = destROI.width*numRasterBands; buffer = new DataBufferByte(lineSize); int [] bandOffs = JPEG.bandOffsets[numRasterBands-1]; raster = Raster.createInterleavedRaster(buffer, destROI.width, 1, lineSize, numRasterBands, bandOffs, null); // Now that we have the Raster we'll decode to, get a view of the // target Raster that will permit a simple setRect for each scanline if (wantRaster) { target = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, destROI.width, destROI.height, lineSize, numRasterBands, bandOffs, null); } else { target = imRas; } int [] bandSizes = target.getSampleModel().getSampleSize(); /* * If the process is sequential, and we have restart markers, * we could skip to the correct restart marker, if the library * lets us. That's an optimization to investigate later. */ // Check for update listeners (don't call back if none) boolean callbackUpdates = ((updateListeners != null) || (progressListeners != null)); // Set up progression data initProgressData(); // if we have a metadata object, we can count the scans // and set knownPassCount if (imageIndex == imageMetadataIndex) { // We have metadata knownPassCount = 0; for (Iterator iter = imageMetadata.markerSequence.iterator(); iter.hasNext();) { if (iter.next() instanceof SOSMarkerSegment) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -