1 /* Copyright (C) 2005-2011 Fabio Riccardi */
2 
3 package com.lightcrafts.jai.opimage;
4 
5 import com.lightcrafts.mediax.jai.*;
6 import com.lightcrafts.utils.DCRaw;
7 import com.lightcrafts.jai.utils.Functions;
8 
9 import java.awt.image.*;
10 import java.awt.*;
11 import java.util.Map;
12 import java.util.Arrays;
13 
14 /**
15  * Copyright (C) 2007 Light Crafts, Inc.
16  * User: fabio
17  * Date: Jun 28, 2007
18  * Time: 11:18:24 AM
19  */
20 public class RGBDemosaicOpImage extends AreaOpImage {
21     private static final BorderExtender copyExtender = BorderExtender.createInstance(BorderExtender.BORDER_ZERO);
22 
23     private final int rx, ry, gx, gy, bx, by;
24 
RGBDemosaicOpImage(RenderedImage source, Map config, int rawFilters)25     public RGBDemosaicOpImage(RenderedImage source, Map config, int rawFilters) {
26         this(source, config, new ImageLayout(source), rawFilters);
27     }
28 
RGBDemosaicOpImage(RenderedImage source, Map config, ImageLayout layout, int rawFilters)29     public RGBDemosaicOpImage(RenderedImage source, Map config, ImageLayout layout, int rawFilters) {
30         super(source, layout, config, true, copyExtender, 4, 4, 4, 4);
31 
32         switch (rawFilters) {
33             case 0x16161616:
34                 rx=1; ry=1; gx=1; gy=0; bx=0; by=0;
35                 break;
36             case 0x61616161:
37                 rx=1; ry=0; gx=0; gy=0; bx=0; by=1;
38                 break;
39             case 0x49494949:
40                 rx=0; ry=1; gx=0; gy=0; bx=1; by=0;
41                 break;
42             case 0x94949494:
43                 rx=0; ry=0; gx=1; gy=0; bx=1; by=1;
44                 break;
45             default:
46                 rx=0; ry=0; gx=0; gy=0; bx=0; by=0;
47                 break;
48         }
49     }
50 
51     private ThreadLocal<Raster> tltmp = new ThreadLocal<Raster>();
52 
computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)53     protected void computeRect(Raster[] sources,
54                                WritableRaster dest,
55                                Rectangle destRect) {
56         // Retrieve format tags.
57         RasterFormatTag[] formatTags = getFormatTags();
58 
59         Rectangle imageRect = getBounds();
60         imageRect.width -= 6;
61         imageRect.height -= 6;
62         destRect = destRect.intersection(imageRect);
63 
64         if (destRect.isEmpty())
65             return;
66 
67         Raster source = sources[0];
68         Rectangle srcRect = mapDestRect(destRect, 0);
69         Rectangle tmpRect = new Rectangle(destRect.x-4, destRect.y-4, destRect.width+8, destRect.height+8);
70 
71         Raster tmp;
72         if ((tmp = tltmp.get()) == null || tmp.getWidth() != tmpRect.width || tmp.getHeight() != tmpRect.height) {
73             tmp = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
74                                                  tmpRect.width, tmpRect.height, 3,
75                                                  new Point(tmpRect.x, tmpRect.y));
76             tltmp.set(tmp);
77         } else {
78             Arrays.fill(((DataBufferUShort) tmp.getDataBuffer()).getData(), (short) 0);
79             tmp = tmp.createTranslatedChild(tmpRect.x, tmpRect.y);
80         }
81 
82         RasterAccessor srcAccessor =
83                 new RasterAccessor(source, srcRect, formatTags[0],
84                                    getSourceImage(0).getColorModel());
85         RasterAccessor dstAccessor =
86                 new RasterAccessor(dest, destRect, formatTags[1],
87                                    getColorModel());
88         RasterAccessor tmpAccessor =
89                 new RasterAccessor(tmp, tmpRect, formatTags[1],
90                                    getColorModel());
91 
92         assert (dstAccessor.getDataType() == DataBuffer.TYPE_USHORT);
93 
94         ushortLoop(srcAccessor, tmpAccessor);
95         Functions.copyData(dest, tmp);
96 
97         // If the RasterAccessor object set up a temporary buffer for the
98         // op to write to, tell the RasterAccessor to write that data
99         // to the raster no that we're done with it.
100         if (dstAccessor.isDataCopy()) {
101             dstAccessor.clampDataArrays();
102             dstAccessor.copyDataToRaster();
103         }
104     }
105 
ushortLoop(RasterAccessor src, RasterAccessor dst)106     protected void ushortLoop(RasterAccessor src, RasterAccessor dst) {
107         short dstDataArrays[][] = dst.getShortDataArrays();
108         int dstBandOffsets[] = dst.getBandOffsets();
109         int dstScanlineStride = dst.getScanlineStride()/3;
110 
111         short srcDataArrays[][] = src.getShortDataArrays();
112         int srcBandOffsets[] = src.getBandOffsets();
113         int srcScanlineStride = src.getScanlineStride();
114 
115         short destData[] = dstDataArrays[0];
116         short srcData[] = srcDataArrays[0];
117 
118         int srcOffset = srcBandOffsets[0];
119 
120         int rOffset = dstBandOffsets[0];
121         int gOffset = dstBandOffsets[1];
122         int bOffset = dstBandOffsets[2];
123 
124         int dWidth = dst.getWidth();
125         int dHeight = dst.getHeight();
126 
127         DCRaw.interpolateGreen(srcData, destData, dWidth, dHeight, srcScanlineStride, dstScanlineStride, srcOffset, rOffset, gOffset, bOffset, gx, gy, ry );
128         DCRaw.interpolateRedBlue(destData, dWidth, dHeight, dstScanlineStride, rOffset, gOffset, bOffset, rx, ry, bx, by );
129     }
130 }
131