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