1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai.opimage; 4 5 import com.lightcrafts.mediax.jai.PointOpImage; 6 import com.lightcrafts.mediax.jai.ImageLayout; 7 import com.lightcrafts.mediax.jai.RasterAccessor; 8 import com.lightcrafts.mediax.jai.RasterFormatTag; 9 10 import java.awt.image.*; 11 import java.awt.*; 12 import java.util.Map; 13 14 /** 15 * Copyright (C) 2007 Light Crafts, Inc. 16 * User: fabio 17 * Date: Mar 14, 2007 18 * Time: 5:31:50 PM 19 */ 20 public class RedMaskBlackener extends PointOpImage { 21 private static short powTable[] = new short[0x10000]; 22 23 static { 24 for (int i = 0; i < 0x10000; i++) 25 powTable[i] = (short) (0xffff * Math.pow(i / (double) 0xffff, 1.4D)); 26 } 27 RedMaskBlackener(RenderedImage source, RenderedImage mask, Map config)28 public RedMaskBlackener(RenderedImage source, RenderedImage mask, Map config) { 29 super(source, mask, new ImageLayout(source), config, true); 30 permitInPlaceOperation(); 31 } 32 33 @Override computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)34 protected void computeRect(Raster[] sources, 35 WritableRaster dest, 36 Rectangle destRect) { 37 // Retrieve format tags. 38 RasterFormatTag[] formatTags = getFormatTags(); 39 40 RasterAccessor src = new RasterAccessor(sources[0], destRect, 41 formatTags[0], 42 getSourceImage(0).getColorModel()); 43 RasterAccessor mask = new RasterAccessor(sources[1], destRect, 44 formatTags[1], 45 getSourceImage(1).getColorModel()); 46 RasterAccessor dst = new RasterAccessor(dest, destRect, 47 formatTags[2], getColorModel()); 48 49 switch (dst.getDataType()) { 50 case DataBuffer.TYPE_USHORT: 51 ushortLoop(src, mask, dst); 52 break; 53 default: 54 throw new UnsupportedOperationException("Unsupported data type: " + dst.getDataType()); 55 } 56 } 57 ushortLoop(RasterAccessor src, RasterAccessor mask, RasterAccessor dst)58 protected void ushortLoop(RasterAccessor src, RasterAccessor mask, RasterAccessor dst) { 59 int width = src.getWidth(); 60 int height = src.getHeight(); 61 62 short dstData[] = dst.getShortDataArray(0); 63 int dstBandOffsets[] = dst.getBandOffsets(); 64 int dstLineStride = dst.getScanlineStride(); 65 int dstPixelStride = dst.getPixelStride(); 66 67 short srcData[] = src.getShortDataArray(0); 68 int srcBandOffsets[] = src.getBandOffsets(); 69 int srcLineStride = src.getScanlineStride(); 70 int srcPixelStride = src.getPixelStride(); 71 72 byte maskData[] = mask.getByteDataArray(0); 73 int maskBandOffsets[] = mask.getBandOffsets(); 74 int maskLineStride = mask.getScanlineStride(); 75 76 int srcROffset = srcBandOffsets[0]; 77 int srcGOffset = srcBandOffsets[1]; 78 int srcBOffset = srcBandOffsets[2]; 79 80 int dstROffset = dstBandOffsets[0]; 81 int dstGOffset = dstBandOffsets[1]; 82 int dstBOffset = dstBandOffsets[2]; 83 84 int maskOffset = maskBandOffsets[0]; 85 86 for (int row = 0; row < height; row++) { 87 for (int col = 0; col < width; col++) { 88 short r = srcData[srcPixelStride * col + row * srcLineStride + srcROffset]; 89 short g = srcData[srcPixelStride * col + row * srcLineStride + srcGOffset]; 90 short b = srcData[srcPixelStride * col + row * srcLineStride + srcBOffset]; 91 92 int m = 0xff & maskData[col + row * maskLineStride + maskOffset]; 93 94 if (m == 0) { 95 dstData[dstPixelStride * col + row * dstLineStride + dstROffset] = r; 96 dstData[dstPixelStride * col + row * dstLineStride + dstGOffset] = g; 97 dstData[dstPixelStride * col + row * dstLineStride + dstBOffset] = b; 98 } else { 99 int gg = powTable[0xffff & g]; 100 101 int r1 = ((255 - m) * (0xffff & r) + m * gg) / 255; 102 int g1 = ((255 - m) * (0xffff & g) + m * gg) / 255; 103 int b1 = ((255 - m) * (0xffff & b) + m * gg) / 255; 104 105 dstData[dstPixelStride * col + row * dstLineStride + dstROffset] = (short) r1; 106 dstData[dstPixelStride * col + row * dstLineStride + dstGOffset] = (short) g1; 107 dstData[dstPixelStride * col + row * dstLineStride + dstBOffset] = (short) b1; 108 } 109 } 110 } 111 } 112 } 113