public void write(BufferedImage image, AVList params) throws IOException { if (image == null) { String msg = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (0 == image.getWidth() || 0 == image.getHeight()) { String msg = Logging.getMessage("generic.InvalidImageSize", image.getWidth(), image.getHeight()); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (null == params || 0 == params.getValues().size()) { String reason = Logging.getMessage("nullValue.AVListIsNull"); Logging.logger().finest(Logging.getMessage("GeotiffWriter.GeoKeysMissing", reason)); params = new AVListImpl(); } else { this.validateParameters(params, image.getWidth(), image.getHeight()); } // how we proceed in part depends upon the image type... int type = image.getType(); // handle CUSTOM type which comes from our GeoTiffreader (for now) if (BufferedImage.TYPE_CUSTOM == type) { int numColorComponents = 0, numComponents = 0, pixelSize = 0, dataType = 0, csType = 0; boolean hasAlpha = false; if (null != image.getColorModel()) { ColorModel cm = image.getColorModel(); numColorComponents = cm.getNumColorComponents(); numComponents = cm.getNumComponents(); pixelSize = cm.getPixelSize(); hasAlpha = cm.hasAlpha(); ColorSpace cs = cm.getColorSpace(); if (null != cs) csType = cs.getType(); } if (null != image.getSampleModel()) { SampleModel sm = image.getSampleModel(); dataType = sm.getDataType(); } if (dataType == DataBuffer.TYPE_FLOAT && pixelSize == Float.SIZE && numComponents == 1) { type = BufferedImage_TYPE_ELEVATION_FLOAT32; } else if (dataType == DataBuffer.TYPE_SHORT && pixelSize == Short.SIZE && numComponents == 1) { type = BufferedImage_TYPE_ELEVATION_SHORT16; } else if (ColorSpace.CS_GRAY == csType && pixelSize == Byte.SIZE) { type = BufferedImage.TYPE_BYTE_GRAY; } else if (dataType == DataBuffer.TYPE_USHORT && ColorSpace.CS_GRAY == csType && pixelSize == Short.SIZE) { type = BufferedImage.TYPE_USHORT_GRAY; } else if (ColorSpace.TYPE_RGB == csType && pixelSize == 3 * Byte.SIZE && numColorComponents == 3) { type = BufferedImage.TYPE_3BYTE_BGR; } else if (ColorSpace.TYPE_RGB == csType && hasAlpha && pixelSize == 4 * Byte.SIZE && numComponents == 4) { type = BufferedImage.TYPE_4BYTE_ABGR; } } switch (type) { case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: { this.writeColorImage(image, params); } break; case BufferedImage.TYPE_USHORT_GRAY: case BufferedImage.TYPE_BYTE_GRAY: { this.writeGrayscaleImage(image, params); } break; case BufferedImage_TYPE_ELEVATION_SHORT16: case BufferedImage_TYPE_ELEVATION_FLOAT32: { String msg = Logging.getMessage("GeotiffWriter.FeatureNotImplementedd", type); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } // break; case BufferedImage.TYPE_CUSTOM: default: { ColorModel cm = image.getColorModel(); SampleModel sm = image.getSampleModel(); StringBuffer sb = new StringBuffer(Logging.getMessage("GeotiffWriter.UnsupportedType", type)); sb.append("\n"); sb.append("NumBands=").append(sm.getNumBands()).append("\n"); sb.append("NumDataElements=").append(sm.getNumDataElements()).append("\n"); sb.append("NumColorComponents=").append(cm.getNumColorComponents()).append("\n"); sb.append("NumComponents=").append(cm.getNumComponents()).append("\n"); sb.append("PixelSize=").append(cm.getPixelSize()).append("\n"); sb.append("hasAlpha=").append(cm.hasAlpha()); String msg = sb.toString(); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } }
@Override protected void computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect) { synchronized (this) { if (transform == null) { int lcms_intent = intent.getValue() < 4 ? intent.getValue() : LCMS.INTENT_RELATIVE_COLORIMETRIC; int lcms_proofIntent = proofIntent.getValue() < 4 ? proofIntent.getValue() : LCMS.INTENT_RELATIVE_COLORIMETRIC; int lcms_flags = intent.getValue() == 4 || proofIntent.getValue() == 4 ? LCMS.cmsFLAGS_BLACKPOINTCOMPENSATION : 0; ColorSpace sourceCS = source.getColorModel().getColorSpace(); LCMS.Profile sourceProfile = sourceCS instanceof LCMS_ColorSpace ? ((LCMS_ColorSpace) sourceCS).getProfile() : new LCMS.Profile(((ICC_ColorSpace) sourceCS).getProfile()); ColorSpace targetCS = targetColorModel.getColorSpace(); LCMS.Profile targetProfile = targetCS instanceof LCMS_ColorSpace ? ((LCMS_ColorSpace) targetCS).getProfile() : new LCMS.Profile(((ICC_ColorSpace) targetCS).getProfile()); LCMS.Profile proofProfile = proof != null ? new LCMS.Profile(proof) : null; int inType = mapLCMSType(sourceCS.getType(), source.getColorModel().getTransferType()); int outType = mapLCMSType(targetCS.getType(), colorModel.getTransferType()); transform = proofProfile != null ? new LCMS.Transform( sourceProfile, inType, targetProfile, outType, proofProfile, lcms_proofIntent, lcms_intent, lcms_flags) : new LCMS.Transform( sourceProfile, inType, targetProfile, outType, lcms_intent, lcms_flags); } } RasterFormatTag[] formatTags = getFormatTags(); Rectangle srcRect = mapDestRect(destRect, 0); RasterAccessor src = new RasterAccessor(sources[0], srcRect, formatTags[0], getSourceImage(0).getColorModel()); RasterAccessor dst = new RasterAccessor(dest, destRect, formatTags[1], this.getColorModel()); if (src.getDataType() == dst.getDataType()) { transform.doTransform( src, formatTags[0], getSourceImage(0).getColorModel(), dst, formatTags[1], this.getColorModel()); } else { throw new IllegalArgumentException("Input and output rasters don't match!"); } }
/** * {@collect.stats} Rescales the source BufferedImage. If the color model in the source image is * not the same as that in the destination image, the pixels will be converted in the destination. * If the destination image is null, a BufferedImage will be created with the source ColorModel. * An IllegalArgumentException may be thrown if the number of scaling factors/offsets in this * object does not meet the restrictions stated in the class comments above, or if the source * image has an IndexColorModel. * * @param src the <code>BufferedImage</code> to be filtered * @param dst the destination for the filtering operation or <code>null</code> * @return the filtered <code>BufferedImage</code>. * @throws IllegalArgumentException if the <code>ColorModel</code> of <code>src</code> is an * <code>IndexColorModel</code>, or if the number of scaling factors and offsets in this * <code>RescaleOp</code> do not meet the requirements stated in the class comments. */ public final BufferedImage filter(BufferedImage src, BufferedImage dst) { ColorModel srcCM = src.getColorModel(); ColorModel dstCM; int numBands = srcCM.getNumColorComponents(); if (srcCM instanceof IndexColorModel) { throw new IllegalArgumentException("Rescaling cannot be " + "performed on an indexed image"); } if (length != 1 && length != numBands && length != srcCM.getNumComponents()) { throw new IllegalArgumentException( "Number of scaling constants " + "does not equal the number of" + " of color or color/alpha " + " components"); } boolean needToConvert = false; // Include alpha if (length > numBands && srcCM.hasAlpha()) { length = numBands + 1; } int width = src.getWidth(); int height = src.getHeight(); if (dst == null) { dst = createCompatibleDestImage(src, null); dstCM = srcCM; } else { if (width != dst.getWidth()) { throw new IllegalArgumentException( "Src width (" + width + ") not equal to dst width (" + dst.getWidth() + ")"); } if (height != dst.getHeight()) { throw new IllegalArgumentException( "Src height (" + height + ") not equal to dst height (" + dst.getHeight() + ")"); } dstCM = dst.getColorModel(); if (srcCM.getColorSpace().getType() != dstCM.getColorSpace().getType()) { needToConvert = true; dst = createCompatibleDestImage(src, null); } } BufferedImage origDst = dst; // // Try to use a native BI rescale operation first // if (ImagingLib.filter(this, src, dst) == null) { // // Native BI rescale failed - convert to rasters // WritableRaster srcRaster = src.getRaster(); WritableRaster dstRaster = dst.getRaster(); if (srcCM.hasAlpha()) { if (numBands - 1 == length || length == 1) { int minx = srcRaster.getMinX(); int miny = srcRaster.getMinY(); int[] bands = new int[numBands - 1]; for (int i = 0; i < numBands - 1; i++) { bands[i] = i; } srcRaster = srcRaster.createWritableChild( minx, miny, srcRaster.getWidth(), srcRaster.getHeight(), minx, miny, bands); } } if (dstCM.hasAlpha()) { int dstNumBands = dstRaster.getNumBands(); if (dstNumBands - 1 == length || length == 1) { int minx = dstRaster.getMinX(); int miny = dstRaster.getMinY(); int[] bands = new int[numBands - 1]; for (int i = 0; i < numBands - 1; i++) { bands[i] = i; } dstRaster = dstRaster.createWritableChild( minx, miny, dstRaster.getWidth(), dstRaster.getHeight(), minx, miny, bands); } } // // Call the raster filter method // filter(srcRaster, dstRaster); } if (needToConvert) { // ColorModels are not the same ColorConvertOp ccop = new ColorConvertOp(hints); ccop.filter(dst, origDst); } return origDst; }