1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai; 4 5 import com.lightcrafts.jai.operator.*; 6 import com.lightcrafts.jai.opimage.*; 7 import com.lightcrafts.jai.utils.LCTileCache; 8 import com.lightcrafts.jai.utils.LCRecyclingTileFactory; 9 import com.lightcrafts.utils.ColorScience; 10 import com.lightcrafts.utils.ColorProfileInfo; 11 import com.lightcrafts.platform.Platform; 12 import com.lightcrafts.media.jai.util.SunTileCache; 13 14 import com.lightcrafts.mediax.jai.*; 15 import com.lightcrafts.mediax.jai.registry.CRIFRegistry; 16 import com.lightcrafts.mediax.jai.registry.RIFRegistry; 17 import java.awt.*; 18 import java.awt.color.ColorSpace; 19 import java.awt.color.ICC_ColorSpace; 20 import java.awt.color.ICC_Profile; 21 import java.awt.image.*; 22 import java.awt.image.renderable.ContextualRenderedImageFactory; 23 import java.awt.image.renderable.RenderedImageFactory; 24 import java.io.*; 25 import java.util.Collection; 26 import java.util.ArrayList; 27 28 /** 29 * Created by IntelliJ IDEA. 30 * User: fabio 31 * Date: Feb 27, 2005 32 * Time: 6:33:47 PM 33 * To change this template use File | Settings | File Templates. 34 */ 35 public class JAIContext { 36 public static final Collection<ColorProfileInfo> systemProfiles; 37 38 public static final ICC_Profile linearProfile; 39 public static final ICC_ColorSpace linearColorSpace; 40 public static final ICC_Profile labProfile; 41 public static final ICC_ColorSpace labColorSpace; 42 public static final ICC_Profile gray22Profile; 43 public static final ICC_ColorSpace gray22ColorSpace; 44 public static final ICC_Profile oldLinearProfile; 45 public static final ICC_ColorSpace oldLinearColorSpace; 46 47 public static final ICC_Profile CMYKProfile; 48 public static final ICC_ColorSpace CMYKColorSpace; 49 50 public static final ICC_Profile systemProfile; 51 public static final ColorSpace systemColorSpace; 52 53 public static final ICC_ColorSpace linearGrayColorSpace = (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY); 54 55 public static final ICC_ColorSpace sRGBColorSpace; 56 public static final ICC_Profile sRGBColorProfile; 57 public static final ICC_Profile sRGBExportColorProfile; 58 59 public static final ICC_Profile adobeRGBProfile; 60 public static final ColorSpace adobeRGBColorSpace; 61 62 public static final ColorModel colorModel_linear16; 63 public static final ColorModel colorModel_linear8; 64 public static final ColorModel colorModel_sRGB16; 65 public static final ColorModel colorModel_sRGB8; 66 public static final ColorModel systemColorModel; 67 public static final RenderingHints noCacheHint; 68 public static final String PERSISTENT_CACHE_TAG = "LCPersistentCache"; 69 public static final TileCache noTileCache = new SunTileCache(0); 70 public static final RenderingHints fileCacheHint; 71 public static final TileCache fileCache; 72 public static final TileCache defaultTileCache; 73 74 /** Tile dimensions. */ 75 public static final int TILE_WIDTH = 512; 76 public static final int TILE_HEIGHT = 512; 77 78 // public static final int fastMode = DataBuffer.TYPE_BYTE; 79 // public static final int preciseMode = DataBuffer.TYPE_USHORT; 80 dumpProperty(ICC_Profile profile, int tag, String name)81 static void dumpProperty(ICC_Profile profile, int tag, String name) 82 { 83 byte[] data = profile.getData(tag); 84 if (data != null) { 85 System.out.print(name + " (" + data.length + ") :"); 86 for (byte aData : data) 87 System.out.print(" " + (aData & 0xFF)); 88 System.out.println(); 89 90 for (byte aData : data) 91 System.out.print((char) (aData & 0xFF)); 92 System.out.println(); 93 } else { 94 System.out.println("no " + name + " info"); 95 } 96 } 97 98 /** 99 * Given a {@link ColorSpace} and a {@link Raster}, get the 100 * {@link ColorModel} for them. 101 * 102 * @param colorSpace The {@link ColorSpace}. 103 * @param raster The {@link Raster}. 104 * @return Returns the relevant {@link ColorModel} or <code>null</code> if 105 * none can be determined. 106 */ getColorModelFrom( ColorSpace colorSpace, Raster raster )107 public static ColorModel getColorModelFrom( ColorSpace colorSpace, 108 Raster raster ) { 109 return new ComponentColorModel( 110 colorSpace, false, false, Transparency.OPAQUE, 111 raster.getSampleModel().getDataType() 112 ); 113 } 114 115 /** 116 * Given an {@link ICC_Profile} and a {@link Raster}, get the 117 * {@link ColorModel} for them. 118 * 119 * @param profile The {@link ICC_Profile}. 120 * @param raster The {@link Raster}. 121 * @return Returns the relevant {@link ColorModel} or <code>null</code> if 122 * none can be determined. 123 */ getColorModelFrom( ICC_Profile profile, Raster raster )124 public static ColorModel getColorModelFrom( ICC_Profile profile, 125 Raster raster ) { 126 return getColorModelFrom( 127 getColorSpaceFrom( profile, raster ), raster 128 ); 129 } 130 131 132 /** 133 * Given an {@link ICC_Profile} and a {@link Raster}, get the 134 * {@link ColorSpace} for them. 135 * 136 * @param profile The {@link ICC_Profile}. 137 * @param raster The {@link Raster}. 138 * @return Returns the relevant {@link ColorSpace} or <code>null</code> if 139 * none can be determined. 140 */ getColorSpaceFrom( ICC_Profile profile, Raster raster )141 public static ColorSpace getColorSpaceFrom( ICC_Profile profile, 142 Raster raster ) { 143 if ( profile != null ) 144 return new ICC_ColorSpace( profile ); 145 switch ( raster.getSampleModel().getNumBands() ) { 146 case 1: 147 return gray22ColorSpace; 148 case 3: 149 return sRGBColorSpace; 150 case 4: 151 return CMYKColorSpace; 152 default: 153 return null; 154 } 155 } 156 zlum(ICC_ColorSpace cs)157 static void zlum(ICC_ColorSpace cs) { 158 float[] zero; 159 synchronized (ColorSpace.class) { 160 zero = cs.fromCIEXYZ(new float[] {0, 0, 0}); 161 } 162 System.out.println("zero: " + zero[0] + " : " + zero[1] + " : " + zero[2]); 163 double zlum = ColorScience.Wr * zero[0] + ColorScience.Wg * zero[1] + ColorScience.Wb * zero[2]; 164 System.out.println("zero lum: " + zlum); 165 } 166 167 static { 168 final long maxMemory = Runtime.getRuntime().maxMemory(); 169 System.out.printf("Max Memory: %11d%n", maxMemory); 170 System.out.printf("Total Memory: %11d%n", Runtime.getRuntime().totalMemory()); 171 172 JAI jaiInstance = JAI.getDefaultInstance(); 173 174 // Use our own Tile Scheduler -- TODO: Needs more testing 175 // jaiInstance.setTileScheduler(new LCTileScheduler()); 176 177 int processors = Runtime.getRuntime().availableProcessors(); 178 179 String VMVersion[] = System.getProperty("java.version").split("[._]"); 180 String OSArch = System.getProperty("os.arch"); 181 182 System.out.println("Running on " + processors + " processors"); 183 184 if (OSArch.equals("ppc") && Integer.parseInt(VMVersion[3]) < 7) { 185 processors = Math.min(processors, 2); 186 System.out.println("Old PPC Java, limiting to " + processors + " processors"); 187 } 188 189 // don't use more than 2 processors, it uses too much memory, 190 // and use 2 procs only if we have more than 750MB of heap 191 192 final int MB = 1024 * 1024; 193 194 if (maxMemory >= 400 * MB) 195 jaiInstance.getTileScheduler().setParallelism(processors); 196 else 197 jaiInstance.getTileScheduler().setParallelism(1); 198 199 fileCache = new LCTileCache(maxMemory <= 1024 * MB ? maxMemory/2 : maxMemory - 512 * MB, true); 200 // fileCache.setMemoryThreshold(0.5f); 201 jaiInstance.setTileCache(fileCache); 202 fileCacheHint = new RenderingHints(JAI.KEY_TILE_CACHE, fileCache); 203 defaultTileCache = jaiInstance.getTileCache(); 204 205 TileFactory rtf = new LCRecyclingTileFactory(); jaiInstance.setRenderingHint(JAI.KEY_TILE_FACTORY, rtf)206 jaiInstance.setRenderingHint(JAI.KEY_TILE_FACTORY, rtf); jaiInstance.setRenderingHint(JAI.KEY_TILE_RECYCLER, rtf)207 jaiInstance.setRenderingHint(JAI.KEY_TILE_RECYCLER, rtf); 208 // TODO: causes rendering artifacts 209 // jaiInstance.setRenderingHint(JAI.KEY_CACHED_TILE_RECYCLING_ENABLED, Boolean.TRUE); 210 211 OperationRegistry or = jaiInstance.getOperationRegistry(); 212 213 // register LCColorConvert 214 OperationDescriptor desc = new LCColorConvertDescriptor(); 215 or.registerDescriptor(desc); 216 ContextualRenderedImageFactory crif = new LCColorConvertCRIF(); RIFRegistry.register(or, desc.getName(), R, crif)217 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", crif); CRIFRegistry.register(or, desc.getName(), crif)218 CRIFRegistry.register(or, desc.getName(), crif); 219 220 // register LCMSColorConvert 221 desc = new LCMSColorConvertDescriptor(); 222 or.registerDescriptor(desc); 223 crif = new LCMSColorConvertCRIF(); RIFRegistry.register(or, desc.getName(), R, crif)224 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", crif); CRIFRegistry.register(or, desc.getName(), crif)225 CRIFRegistry.register(or, desc.getName(), crif); 226 227 // register BlendOp 228 desc = new BlendDescriptor(); 229 or.registerDescriptor(desc); 230 crif = new BlendCRIF(); RIFRegistry.register(or, desc.getName(), R, crif)231 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", crif); CRIFRegistry.register(or, desc.getName(), crif)232 CRIFRegistry.register(or, desc.getName(), crif); 233 234 // register LCSeparableConvolve 235 desc = new LCSeparableConvolveDescriptor(); 236 or.registerDescriptor(desc); 237 RenderedImageFactory rif = new LCSeparableConvolveRIF(); RIFRegistry.register(or, desc.getName(), R, rif)238 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", rif); 239 240 // register NOPOp 241 desc = new NOPDescriptor(); 242 or.registerDescriptor(desc); 243 crif = new NOPCRIF(); RIFRegistry.register(or, desc.getName(), R, crif)244 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", crif); CRIFRegistry.register(or, desc.getName(), crif)245 CRIFRegistry.register(or, desc.getName(), crif); 246 247 // register UnSharpMaskOp 248 desc = new UnSharpMaskDescriptor(); 249 or.registerDescriptor(desc); 250 crif = new UnSharpMaskCRIF(); RIFRegistry.register(or, desc.getName(), R, crif)251 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", crif); CRIFRegistry.register(or, desc.getName(), crif)252 CRIFRegistry.register(or, desc.getName(), crif); 253 254 // register LCErode 255 desc = new LCErodeDescriptor(); 256 or.registerDescriptor(desc); 257 rif = new LCErodeRIF(); RIFRegistry.register(or, desc.getName(), R, rif)258 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", rif); 259 260 // register RawAdjustments 261 desc = new RawAdjustmentsDescriptor(); 262 or.registerDescriptor(desc); 263 rif = new RawAdjustmentsCRIF(); RIFRegistry.register(or, desc.getName(), R, rif)264 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", rif); 265 266 // register LCBandCombine 267 desc = new LCBandCombineDescriptor(); 268 or.registerDescriptor(desc); 269 rif = new LCBandCombineCRIF(); RIFRegistry.register(or, desc.getName(), R, rif)270 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", rif); 271 272 // register LCBandCombine 273 desc = new BilateralFilterDescriptor(); 274 or.registerDescriptor(desc); 275 rif = new BilateralFilterRIF(); RIFRegistry.register(or, desc.getName(), R, rif)276 RIFRegistry.register(or, desc.getName(), "com.lightcrafts", rif); 277 JAI.setDefaultTileSize(new Dimension(JAIContext.TILE_WIDTH, JAIContext.TILE_HEIGHT))278 JAI.setDefaultTileSize(new Dimension(JAIContext.TILE_WIDTH, JAIContext.TILE_HEIGHT)); 279 280 systemProfiles = new ArrayList<ColorProfileInfo>(); 281 final Collection<ColorProfileInfo> exportProfiles = 282 Platform.getPlatform().getExportProfiles(); 283 if (exportProfiles != null) { 284 systemProfiles.addAll(exportProfiles); 285 } 286 final Collection<ColorProfileInfo> printerProfiles = 287 Platform.getPlatform().getPrinterProfiles(); 288 if (printerProfiles != null) { 289 systemProfiles.addAll(printerProfiles); 290 } 291 292 ICC_Profile _sRGBColorProfile = null; 293 for (ColorProfileInfo cpi : systemProfiles) { 294 if ((cpi.getName().equals("sRGB Profile") || cpi.getName().equals("sRGB IEC61966-2.1"))) { 295 try { 296 _sRGBColorProfile = ICC_Profile.getInstance(cpi.getPath()); 297 System.out.println("found " + cpi.getName()); 298 if (_sRGBColorProfile != null) 299 break; 300 } catch (IOException e) { 301 e.printStackTrace(); 302 } 303 } 304 } 305 306 if (_sRGBColorProfile == null) { 307 InputStream in = JAIContext.class.getResourceAsStream("resources/sRGB.icc"); 308 try { 309 _sRGBColorProfile = ICC_Profile.getInstance(in); 310 } catch (IOException e) { 311 System.err.println("Can't load resource sRGB profile, defaulting on Java's"); 312 _sRGBColorProfile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); 313 } 314 } 315 sRGBExportColorProfile = _sRGBColorProfile; 316 317 sRGBColorProfile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); 318 sRGBColorSpace = (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB); 319 320 ICC_Profile _linearProfile; 321 ICC_Profile _oldLinearProfile; 322 ICC_Profile _labProfile; 323 // ICC_Profile _uniformLabProfile; 324 ICC_Profile _gray22Profile; 325 ICC_Profile _adobeRGBProfile; 326 ICC_ColorSpace _linearColorSpace; 327 ICC_ColorSpace _oldLinearColorSpace; 328 ICC_ColorSpace _labColorSpace; 329 // ICC_ColorSpace _uniformLabColorSpace; 330 ICC_ColorSpace _gray22ColorSpace; 331 ICC_ColorSpace _adobeRGBColorSpace; 332 ColorModel _colorModel_linear16; 333 ColorModel _colorModel_linear8; 334 ColorModel _colorModel_sRGB16; 335 ColorModel _colorModel_sRGB8; 336 337 ICC_Profile _CMYKProfile; 338 ICC_ColorSpace _CMYKColorSpace; 339 340 RenderingHints _noCacheHint; 341 342 ICC_Profile _systemProfile; 343 ICC_ColorSpace _systemColorSpace; 344 ColorModel _systemColorModel; 345 346 try { 347 InputStream in = JAIContext.class.getResourceAsStream("resources/rimm.icm"); 348 _linearProfile = ICC_Profile.getInstance(in); 349 _linearColorSpace = new ICC_ColorSpace(_linearProfile); 350 351 in = JAIContext.class.getResourceAsStream("resources/CIE 1931 D50 Gamma 1.icm"); 352 _oldLinearProfile = ICC_Profile.getInstance(in); 353 _oldLinearColorSpace = new ICC_ColorSpace(_linearProfile); 354 355 in = JAIContext.class.getResourceAsStream("resources/Generic CMYK Profile.icc"); 356 _CMYKProfile = ICC_Profile.getInstance(in); 357 _CMYKColorSpace = new ICC_ColorSpace(_CMYKProfile); 358 359 in = JAIContext.class.getResourceAsStream("resources/Generic Lab Profile.icm"); 360 _labProfile = ICC_Profile.getInstance(in); 361 _labColorSpace = new ICC_ColorSpace(_labProfile); 362 363 in = JAIContext.class.getResourceAsStream("resources/Gray Gamma 2.2.icc"); 364 _gray22Profile = ICC_Profile.getInstance(in); 365 _gray22ColorSpace = new ICC_ColorSpace(_gray22Profile); 366 367 in = JAIContext.class.getResourceAsStream("resources/compatibleWithAdobeRGB1998.icc"); 368 _adobeRGBProfile = ICC_Profile.getInstance(in); 369 _adobeRGBColorSpace = new ICC_ColorSpace(_adobeRGBProfile); 370 371 _colorModel_linear16 = 372 RasterFactory.createComponentColorModel(DataBuffer.TYPE_USHORT, 373 _linearColorSpace, 374 false, 375 false, 376 Transparency.OPAQUE); 377 _colorModel_linear8 = 378 RasterFactory.createComponentColorModel(DataBuffer.TYPE_BYTE, 379 _linearColorSpace, 380 false, 381 false, 382 Transparency.OPAQUE); 383 _colorModel_sRGB16 = 384 RasterFactory.createComponentColorModel(DataBuffer.TYPE_USHORT, 385 JAIContext.sRGBColorSpace, 386 false, 387 false, 388 Transparency.OPAQUE); 389 _colorModel_sRGB8 = 390 RasterFactory.createComponentColorModel(DataBuffer.TYPE_BYTE, 391 JAIContext.sRGBColorSpace, 392 false, 393 false, 394 Transparency.OPAQUE); 395 396 _systemColorSpace = sRGBColorSpace; 397 _systemColorModel = _colorModel_sRGB8; 398 _systemProfile = _sRGBColorProfile; 399 400 try { 401 final ICC_Profile displayProfile = Platform.getPlatform().getDisplayProfile(); 402 if (displayProfile != null) { 403 _systemProfile = displayProfile; 404 _systemColorSpace = new ICC_ColorSpace(_systemProfile); 405 _systemColorModel = RasterFactory.createComponentColorModel(DataBuffer.TYPE_BYTE, 406 _systemColorSpace, 407 false, 408 false, 409 Transparency.OPAQUE); 410 } 411 } catch (Exception e) { 412 e.printStackTrace(); 413 } 414 415 _noCacheHint = new RenderingHints(JAI.KEY_TILE_CACHE, noTileCache); 416 // _noCacheHint = new RenderingHints(JAI.KEY_TILE_CACHE, defaultTileCache); 417 } catch (IOException e) { 418 e.printStackTrace(); 419 // Rethrow so the Application will notice the problem: 420 throw new RuntimeException( 421 "Couldn't access color space resource", 422 e 423 ); 424 } 425 linearProfile = _linearProfile; 426 linearColorSpace = _linearColorSpace; 427 428 oldLinearProfile = _oldLinearProfile; 429 oldLinearColorSpace = _oldLinearColorSpace; 430 431 colorModel_linear16 = _colorModel_linear16; 432 colorModel_linear8 = _colorModel_linear8; 433 colorModel_sRGB16 = _colorModel_sRGB16; 434 colorModel_sRGB8 = _colorModel_sRGB8; 435 436 CMYKProfile = _CMYKProfile; 437 CMYKColorSpace = _CMYKColorSpace; 438 439 labProfile = _labProfile; 440 labColorSpace = _labColorSpace; 441 442 gray22Profile = _gray22Profile; 443 gray22ColorSpace = _gray22ColorSpace; 444 445 adobeRGBProfile = _adobeRGBProfile; 446 adobeRGBColorSpace = _adobeRGBColorSpace; 447 448 systemProfile = _systemProfile; 449 450 systemColorSpace = _systemColorSpace; 451 systemColorModel = _systemColorModel; 452 453 noCacheHint = _noCacheHint; 454 } 455 } 456 /* vim:set et sw=4 ts=4: */ 457