1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai.opimage; 4 5 import com.lightcrafts.mediax.jai.ImageLayout; 6 import com.lightcrafts.mediax.jai.PointOpImage; 7 import com.lightcrafts.mediax.jai.RasterFormatTag; 8 import com.lightcrafts.mediax.jai.RasterAccessor; 9 import java.awt.image.RenderedImage; 10 import java.awt.image.Raster; 11 import java.awt.image.WritableRaster; 12 import java.awt.image.DataBuffer; 13 import java.awt.*; 14 import java.util.Map; 15 16 public class RawAdjustmentsOpImage extends PointOpImage { 17 private float exposureCompensation; 18 private float[][] cameraRGB; 19 RawAdjustmentsOpImage(RenderedImage source, Map config, ImageLayout layout, float exposureCompensation, float colorTemperature, float[][] cameraRGB)20 public RawAdjustmentsOpImage(RenderedImage source, 21 Map config, 22 ImageLayout layout, 23 float exposureCompensation, 24 float colorTemperature, 25 float[][] cameraRGB) { 26 super(source, layout, config, true); 27 28 this.exposureCompensation = exposureCompensation; 29 this.cameraRGB = cameraRGB; 30 31 permitInPlaceOperation(); 32 } 33 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 Raster source = sources[0]; 41 Rectangle srcRect = mapDestRect(destRect, 0); 42 43 RasterAccessor srcAccessor = 44 new RasterAccessor(source, srcRect, formatTags[0], 45 getSourceImage(0).getColorModel()); 46 RasterAccessor dstAccessor = 47 new RasterAccessor(dest, destRect, formatTags[1], 48 this.getColorModel()); 49 50 switch (dstAccessor.getDataType()) { 51 case DataBuffer.TYPE_USHORT: 52 ushortLoop(srcAccessor, dstAccessor); 53 break; 54 default: 55 } 56 57 // If the RasterAccessor object set up a temporary buffer for the 58 // op to write to, tell the RasterAccessor to write that data 59 // to the raster no that we're done with it. 60 if (dstAccessor.isDataCopy()) { 61 dstAccessor.clampDataArrays(); 62 dstAccessor.copyDataToRaster(); 63 } 64 } 65 ushortLoop(RasterAccessor src, RasterAccessor dst)66 protected void ushortLoop(RasterAccessor src, RasterAccessor dst) { 67 int width = src.getWidth(); 68 int height = src.getHeight(); 69 70 short dstDataArrays[][] = dst.getShortDataArrays(); 71 int dstBandOffsets[] = dst.getBandOffsets(); 72 int dstLineStride = dst.getScanlineStride(); 73 74 short srcDataArrays[][] = src.getShortDataArrays(); 75 int srcBandOffsets[] = src.getBandOffsets(); 76 int srcLineStride = src.getScanlineStride(); 77 78 short dstData[] = dstDataArrays[0]; 79 short srcData[] = srcDataArrays[0]; 80 81 int srcROffset = srcBandOffsets[0]; 82 int srcGOffset = srcBandOffsets[1]; 83 int srcBOffset = srcBandOffsets[2]; 84 85 int dstROffset = dstBandOffsets[0]; 86 int dstGOffset = dstBandOffsets[1]; 87 int dstBOffset = dstBandOffsets[2]; 88 89 float t00 = cameraRGB[0][0], t01 = cameraRGB[0][1], t02 = cameraRGB[0][2], 90 t10 = cameraRGB[1][0], t11 = cameraRGB[1][1], t12 = cameraRGB[1][2], 91 t20 = cameraRGB[2][0], t21 = cameraRGB[2][1], t22 = cameraRGB[2][2]; 92 93 for (int row = 0; row < height; row++) { 94 for (int col = 0; col < width; col++) { 95 int r = 0xffff & srcData[3 * col + row * srcLineStride + srcROffset]; 96 int g = 0xffff & srcData[3 * col + row * srcLineStride + srcGOffset]; 97 int b = 0xffff & srcData[3 * col + row * srcLineStride + srcBOffset]; 98 99 float r1 = t00 * r + t01 * g + t02 * b; 100 float g1 = t10 * r + t11 * g + t12 * b; 101 float b1 = t20 * r + t21 * g + t22 * b; 102 103 // Highlight recovery code 104 105 float c = exposureCompensation; 106 107 if (c < 1 && (g1 > 0xffff || r1 > 0xffff || b1 > 0xffff)) { 108 float rs = Math.min(r1, 0xffff); 109 float gs = Math.min(g1, 0xffff); 110 float bs = Math.min(b1, 0xffff); 111 112 float c1s = gs - rs; 113 float c2s = gs - bs; 114 115 r1 = c * (g1 - c1s); 116 b1 = c * (g1 - c2s); 117 } else { 118 r1 *= c; 119 b1 *= c; 120 } 121 g1 *= c; 122 123 dstData[3 * col + row * dstLineStride + dstROffset] = (short) (r1 < 0 ? 0 : r1 > 0xffff ? 0xffff : (int) r1); 124 dstData[3 * col + row * dstLineStride + dstGOffset] = (short) (g1 < 0 ? 0 : g1 > 0xffff ? 0xffff : (int) g1); 125 dstData[3 * col + row * dstLineStride + dstBOffset] = (short) (b1 < 0 ? 0 : b1 > 0xffff ? 0xffff : (int) b1); 126 } 127 } 128 } 129 } 130