1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai.opimage; 4 5 import com.lightcrafts.jai.operator.LCMSColorConvertDescriptor; 6 import com.lightcrafts.mediax.jai.RasterAccessor; 7 import com.lightcrafts.mediax.jai.RasterFormatTag; 8 import com.lightcrafts.utils.LCMS; 9 import com.lightcrafts.utils.LCMS_ColorSpace; 10 11 import com.lightcrafts.mediax.jai.PointOpImage; 12 import com.lightcrafts.mediax.jai.ImageLayout; 13 14 import java.awt.image.*; 15 import java.awt.*; 16 import java.awt.color.ICC_ColorSpace; 17 import java.awt.color.ColorSpace; 18 import java.awt.color.ICC_Profile; 19 import java.util.Map; 20 21 public class LCMSColorConvertOpImage extends PointOpImage { 22 private final LCMSColorConvertDescriptor.RenderingIntent intent; 23 private final LCMSColorConvertDescriptor.RenderingIntent proofIntent; 24 private final ColorModel targetColorModel; 25 private final ICC_Profile proof; 26 private LCMS.Transform transform = null; 27 final RenderedImage source; 28 LCMSColorConvertOpImage(RenderedImage source, Map config, ImageLayout layout, ColorModel colorModel, LCMSColorConvertDescriptor.RenderingIntent intent, ICC_Profile proof, LCMSColorConvertDescriptor.RenderingIntent proofingIntent)29 LCMSColorConvertOpImage(RenderedImage source, 30 Map config, 31 ImageLayout layout, 32 ColorModel colorModel, 33 LCMSColorConvertDescriptor.RenderingIntent intent, 34 ICC_Profile proof, 35 LCMSColorConvertDescriptor.RenderingIntent proofingIntent) { 36 super(source, layout, config, true); 37 this.source = source; 38 targetColorModel = colorModel; 39 this.proof = proof; 40 this.intent = intent; 41 this.proofIntent = proofingIntent; 42 43 permitInPlaceOperation(); 44 } 45 mapLCMSType(int csType, int transferType)46 static private int mapLCMSType(int csType, int transferType) { 47 if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT) 48 throw new IllegalArgumentException( "Unsupported Data Type: " + transferType ); 49 50 switch(csType) { 51 case ColorSpace.TYPE_GRAY: 52 return transferType == DataBuffer.TYPE_BYTE ? LCMS.TYPE_GRAY_8 : LCMS.TYPE_GRAY_16; 53 case ColorSpace.TYPE_RGB: 54 return transferType == DataBuffer.TYPE_BYTE ? LCMS.TYPE_RGB_8 : LCMS.TYPE_RGB_16; 55 case ColorSpace.TYPE_CMYK: 56 return transferType == DataBuffer.TYPE_BYTE ? LCMS.TYPE_CMYK_8 : LCMS.TYPE_CMYK_16; 57 case ColorSpace.TYPE_Lab: 58 return transferType == DataBuffer.TYPE_BYTE ? LCMS.TYPE_Lab_8 : LCMS.TYPE_Lab_16; 59 default: 60 throw new IllegalArgumentException( "Unsupported Color Space Type: " + csType ); 61 } 62 } 63 64 @Override computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)65 protected void computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect) { 66 synchronized (this) { 67 if (transform == null) { 68 int lcms_intent = intent.getValue() < 4 ? intent.getValue() : LCMS.INTENT_RELATIVE_COLORIMETRIC; 69 int lcms_proofIntent = proofIntent.getValue() < 4 ? proofIntent.getValue() : LCMS.INTENT_RELATIVE_COLORIMETRIC; 70 int lcms_flags = intent.getValue() == 4 || proofIntent.getValue() == 4 71 ? LCMS.cmsFLAGS_BLACKPOINTCOMPENSATION 72 : 0; 73 74 ColorSpace sourceCS = source.getColorModel().getColorSpace(); 75 LCMS.Profile sourceProfile = sourceCS instanceof LCMS_ColorSpace 76 ? ((LCMS_ColorSpace) sourceCS).getProfile() 77 : new LCMS.Profile(((ICC_ColorSpace)sourceCS).getProfile()); 78 79 ColorSpace targetCS = targetColorModel.getColorSpace(); 80 LCMS.Profile targetProfile = targetCS instanceof LCMS_ColorSpace 81 ? ((LCMS_ColorSpace) targetCS).getProfile() 82 : new LCMS.Profile(((ICC_ColorSpace)targetCS).getProfile()); 83 84 LCMS.Profile proofProfile = proof != null ? new LCMS.Profile(proof) : null; 85 86 int inType = mapLCMSType(sourceCS.getType(), source.getColorModel().getTransferType()); 87 int outType = mapLCMSType(targetCS.getType(), colorModel.getTransferType()); 88 89 transform = proofProfile != null 90 ? new LCMS.Transform(sourceProfile, inType, targetProfile, outType, proofProfile, 91 lcms_proofIntent, lcms_intent, lcms_flags) 92 : new LCMS.Transform(sourceProfile, inType, targetProfile, outType, lcms_intent, lcms_flags); 93 } 94 } 95 96 RasterFormatTag[] formatTags = getFormatTags(); 97 Rectangle srcRect = mapDestRect(destRect, 0); 98 RasterAccessor src = new RasterAccessor(sources[0], srcRect, formatTags[0], getSourceImage(0).getColorModel()); 99 RasterAccessor dst = new RasterAccessor(dest, destRect, formatTags[1], this.getColorModel()); 100 101 if (src.getDataType() == dst.getDataType()) { 102 transform.doTransform(src, formatTags[0], getSourceImage(0).getColorModel(), 103 dst, formatTags[1], this.getColorModel()); 104 } 105 else { 106 throw new IllegalArgumentException("Input and output rasters don't match!"); 107 } 108 } 109 } 110