/** * Checks if the specified {@code SampleModel} is compatible with this {@code ColorModel}. If * {@code sm} is {@code null}, this method returns {@code false}. * * @param sm the specified {@code SampleModel}, or {@code null} * @return {@code true} if the specified {@code SampleModel} is compatible with this {@code * ColorModel}; {@code false} otherwise. * @see SampleModel */ public boolean isCompatibleSampleModel(SampleModel sm) { if (!(sm instanceof SinglePixelPackedSampleModel)) { return false; } // Must have the same number of components if (numComponents != sm.getNumBands()) { return false; } // Transfer type must be the same if (sm.getTransferType() != transferType) { return false; } SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm; // Now compare the specific masks int[] bitMasks = sppsm.getBitMasks(); if (bitMasks.length != maskArray.length) { return false; } /* compare 'effective' masks only, i.e. only part of the mask * which fits the capacity of the transfer type. */ int maxMask = (int) ((1L << DataBuffer.getDataTypeSize(transferType)) - 1); for (int i = 0; i < bitMasks.length; i++) { if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) { return false; } } return true; }
/** * Returns a width- and height-aligned image representation sharing data w/ {@link #image}. * * @param width * @param height * @return * @throws IllegalArgumentException if requested size exceeds image size */ public BufferedImage getAlignedImage(int width, int height) throws IllegalArgumentException { if (width * height > image.getWidth() * image.getHeight()) { throw new IllegalArgumentException( "Requested size exceeds image size: " + width + "x" + height + " > " + image.getWidth() + "x" + image.getHeight()); } if (width == image.getWidth() && height == image.getHeight()) { return image; } else { final ColorModel cm = image.getColorModel(); final WritableRaster raster0 = image.getRaster(); final DataBuffer dataBuffer = raster0.getDataBuffer(); final SinglePixelPackedSampleModel sppsm0 = (SinglePixelPackedSampleModel) raster0.getSampleModel(); final SinglePixelPackedSampleModel sppsm1 = new SinglePixelPackedSampleModel( dataBuffer.getDataType(), width, height, width /* scanLineStride */, sppsm0.getBitMasks()); final WritableRaster raster1 = WritableRaster.createWritableRaster(sppsm1, dataBuffer, null); return new BufferedImage(cm, raster1, cm.isAlphaPremultiplied(), null); } }
private void writeSinglePixelPackedSampleModel(DataOutput out, SinglePixelPackedSampleModel model) throws IOException { int[] masks = model.getBitMasks(); out.writeInt(masks.length); for (int i = 0; i < masks.length; i++) out.writeInt(masks[i]); out.writeInt(model.getDataType()); out.writeInt(model.getWidth()); out.writeInt(model.getHeight()); out.writeInt(model.getScanlineStride()); }
public static boolean is_INT_PACK_Data(SampleModel sm, boolean requireAlpha) { // Check ColorModel is of type DirectColorModel if (!(sm instanceof SinglePixelPackedSampleModel)) return false; // Check transfer type if (sm.getDataType() != DataBuffer.TYPE_INT) return false; SinglePixelPackedSampleModel sppsm; sppsm = (SinglePixelPackedSampleModel) sm; int[] masks = sppsm.getBitMasks(); if (masks.length == 3) { if (requireAlpha) return false; } else if (masks.length != 4) return false; if (masks[0] != 0x00ff0000) return false; if (masks[1] != 0x0000ff00) return false; if (masks[2] != 0x000000ff) return false; return !((masks.length == 4) && (masks[3] != 0xff000000)); }
/** * Ipp filter. * * @param src the src. * @param dst the dst. * @param imageType the image type. * @return the int. */ @SuppressWarnings("unused") private int ippFilter(Raster src, WritableRaster dst, int imageType) { int srcStride, dstStride; boolean skipChannel = false; int channels; int offsets[] = null; switch (imageType) { case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_BGR: { channels = 4; srcStride = src.getWidth() * 4; dstStride = dst.getWidth() * 4; skipChannel = true; break; } case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: { channels = 4; srcStride = src.getWidth() * 4; dstStride = dst.getWidth() * 4; break; } case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_INDEXED: { channels = 1; srcStride = src.getWidth(); dstStride = dst.getWidth(); break; } case BufferedImage.TYPE_3BYTE_BGR: { channels = 3; srcStride = src.getWidth() * 3; dstStride = dst.getWidth() * 3; break; } case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in // native code? case BufferedImage.TYPE_USHORT_565_RGB: case BufferedImage.TYPE_USHORT_555_RGB: case BufferedImage.TYPE_BYTE_BINARY: { return slowFilter(src, dst); } default: { SampleModel srcSM = src.getSampleModel(); SampleModel dstSM = dst.getSampleModel(); if (srcSM instanceof PixelInterleavedSampleModel && dstSM instanceof PixelInterleavedSampleModel) { // Check PixelInterleavedSampleModel if (srcSM.getDataType() != DataBuffer.TYPE_BYTE || dstSM.getDataType() != DataBuffer.TYPE_BYTE) { return slowFilter(src, dst); } channels = srcSM.getNumBands(); // Have IPP functions for 1, // 3 and 4 channels if (channels != 1 && channels != 3 && channels != 4) { return slowFilter(src, dst); } int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8; srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize; dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize; } else if (srcSM instanceof SinglePixelPackedSampleModel && dstSM instanceof SinglePixelPackedSampleModel) { // Check SinglePixelPackedSampleModel SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM; SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM; // No IPP function for this type if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) { return slowFilter(src, dst); } channels = sppsm1.getNumBands(); // Have IPP functions for 1, 3 and 4 channels if (channels != 1 && channels != 3 && channels != 4) { return slowFilter(src, dst); } // Check compatibility of sample models if (sppsm1.getDataType() != sppsm2.getDataType() || !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) { return slowFilter(src, dst); } for (int i = 0; i < channels; i++) { if (sppsm1.getSampleSize(i) != 8) { return slowFilter(src, dst); } } if (channels == 3) { channels = 4; } int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8; srcStride = sppsm1.getScanlineStride() * dataTypeSize; dstStride = sppsm2.getScanlineStride() * dataTypeSize; } else { return slowFilter(src, dst); } // Fill offsets if there's a child raster if (src.getParent() != null || dst.getParent() != null) { if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) { offsets = new int[4]; offsets[0] = -src.getSampleModelTranslateX() + src.getMinX(); offsets[1] = -src.getSampleModelTranslateY() + src.getMinY(); offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX(); offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY(); } } } } double m00 = at.getScaleX(); double m01 = at.getShearX(); double m02 = at.getTranslateX(); double m10 = at.getShearY(); double m11 = at.getScaleY(); double m12 = at.getTranslateY(); Object srcData, dstData; AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance(); try { srcData = dbAccess.getData(src.getDataBuffer()); dstData = dbAccess.getData(dst.getDataBuffer()); } catch (IllegalArgumentException e) { return -1; // Unknown data buffer type } return ippAffineTransform( m00, m01, m02, m10, m11, m12, srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(), dstStride, iType, channels, skipChannel, offsets); }
public WritableRaster copyData(WritableRaster wr) { // Get my source. CachableRed src = (CachableRed) getSources().get(0); ColorModel srcCM = src.getColorModel(); SampleModel srcSM = src.getSampleModel(); // Fast case, SRGB source, INT Pack writable raster... if (srcIssRGB && Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) { src.copyData(wr); if (srcCM.hasAlpha()) GraphicsUtil.coerceData(wr, srcCM, false); Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut); return wr; } if (srcCM == null) { // We don't really know much about this source, let's // guess based on the number of bands... float[][] matrix = null; switch (srcSM.getNumBands()) { case 1: matrix = new float[1][3]; matrix[0][0] = 1; // Red matrix[0][1] = 1; // Grn matrix[0][2] = 1; // Blu break; case 2: matrix = new float[2][4]; matrix[0][0] = 1; // Red matrix[0][1] = 1; // Grn matrix[0][2] = 1; // Blu matrix[1][3] = 1; // Alpha break; case 3: matrix = new float[3][3]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu break; default: matrix = new float[srcSM.getNumBands()][4]; matrix[0][0] = 1; // Red matrix[1][1] = 1; // Grn matrix[2][2] = 1; // Blu matrix[3][3] = 1; // Alpha break; } Raster srcRas = src.getData(wr.getBounds()); BandCombineOp op = new BandCombineOp(matrix, null); op.filter(srcRas, wr); } else { ColorModel dstCM = getColorModel(); BufferedImage dstBI; if (!dstCM.hasAlpha()) { // No alpha ao we don't have to work around the bug // in the color convert op. dstBI = new BufferedImage( dstCM, wr.createWritableTranslatedChild(0, 0), dstCM.isAlphaPremultiplied(), null); } else { // All this nonsense is to work around the fact that // the Color convert op doesn't properly copy the // Alpha from src to dst. SinglePixelPackedSampleModel dstSM; dstSM = (SinglePixelPackedSampleModel) wr.getSampleModel(); int[] masks = dstSM.getBitMasks(); SampleModel dstSMNoA = new SinglePixelPackedSampleModel( dstSM.getDataType(), dstSM.getWidth(), dstSM.getHeight(), dstSM.getScanlineStride(), new int[] {masks[0], masks[1], masks[2]}); ColorModel dstCMNoA = GraphicsUtil.Linear_sRGB; WritableRaster dstWr; dstWr = Raster.createWritableRaster(dstSMNoA, wr.getDataBuffer(), new Point(0, 0)); dstWr = dstWr.createWritableChild( wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY(), wr.getWidth(), wr.getHeight(), 0, 0, null); dstBI = new BufferedImage(dstCMNoA, dstWr, false, null); } // Divide out alpha if we have it. We need to do this since // the color convert may not be a linear operation which may // lead to out of range values. ColorModel srcBICM = srcCM; WritableRaster srcWr; if ((srcCM.hasAlpha() == true) && (srcCM.isAlphaPremultiplied() != false)) { Rectangle wrR = wr.getBounds(); SampleModel sm = srcCM.createCompatibleSampleModel(wrR.width, wrR.height); srcWr = Raster.createWritableRaster(sm, new Point(wrR.x, wrR.y)); src.copyData(srcWr); srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false); } else { Raster srcRas = src.getData(wr.getBounds()); srcWr = GraphicsUtil.makeRasterWritable(srcRas); } BufferedImage srcBI; srcBI = new BufferedImage(srcBICM, srcWr.createWritableTranslatedChild(0, 0), false, null); /* * System.out.println("src: " + srcBI.getWidth() + "x" + * srcBI.getHeight()); * System.out.println("dst: " + dstBI.getWidth() + "x" + * dstBI.getHeight()); */ ColorConvertOp op = new ColorConvertOp(null); op.filter(srcBI, dstBI); if (dstCM.hasAlpha()) copyBand( srcWr, srcSM.getNumBands() - 1, wr, getSampleModel().getNumBands() - 1); } return wr; }