org.apache.fop.util.ColorSpaceCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fop Show documentation
Show all versions of fop Show documentation
Apache FOP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, AFP, TIFF, PNG, SVG, XML (area tree representation), Print, AWT and TXT. The primary output target is PDF.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: ColorSpaceCache.java 1364567 2012-07-23 10:21:23Z mehdi $ */
package org.apache.fop.util;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent;
import org.apache.xmlgraphics.java2d.color.RenderingIntent;
import org.apache.fop.apps.io.InternalResourceResolver;
/**
* Map with cached ICC based ColorSpace objects.
*/
public class ColorSpaceCache {
/** logger instance */
private static Log log = LogFactory.getLog(ColorSpaceCache.class);
private InternalResourceResolver resourceResolver;
private Map colorSpaceMap = Collections.synchronizedMap(new HashMap());
/**
* Default constructor
* @param resourceResolver uri resolver
*/
public ColorSpaceCache(InternalResourceResolver resourceResolver) {
this.resourceResolver = resourceResolver;
}
/**
* Create (if needed) and return an ICC ColorSpace instance.
*
* The ICC profile source is taken from the src attribute of the color-profile FO element.
* If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache.
*
* The FOP URI resolver is used to try and locate the ICC file.
* If that fails null is returned.
*
* @param profileName the profile name
* @param iccProfileSrc ICC Profile source to return a ColorSpace
* @param renderingIntent overriding rendering intent
* @return ICC ColorSpace object or null if ColorSpace could not be created
*/
public ColorSpace get(String profileName, String iccProfileSrc, RenderingIntent renderingIntent) {
String key = profileName + ":" + iccProfileSrc;
// TODO: This stuff needs some TLC, fix it!!
ColorSpace colorSpace = null;
if (!colorSpaceMap.containsKey(key)) {
try {
ICC_Profile iccProfile = null;
// First attempt to use the FOP URI resolver to locate the ICC
// profile
InputStream stream = resourceResolver.getResource(iccProfileSrc);
if (stream != null) {
// FOP URI resolver found ICC profile - create ICC profile
// from the Source
iccProfile = ICC_Profile.getInstance(stream);
} else {
// TODO - Would it make sense to fall back on VM ICC
// resolution
// Problem is the cache might be more difficult to maintain
//
// FOP URI resolver did not find ICC profile - perhaps the
// Java VM can find it?
// iccProfile = ICC_Profile.getInstance(iccProfileSrc);
}
if (iccProfile != null) {
colorSpace = new ICCColorSpaceWithIntent(iccProfile, renderingIntent,
profileName, iccProfileSrc);
}
} catch (Exception e) {
// Ignore exception - will be logged a bit further down
// (colorSpace == null case)
log.warn("Exception thrown resolving the color space: " + e.getMessage());
}
if (colorSpace != null) {
// Put in cache (not when VM resolved it as we can't control
colorSpaceMap.put(key, colorSpace);
} else {
// TODO To avoid an excessive amount of warnings perhaps
// register a null ColorMap in the colorSpaceMap
log.warn("Color profile '" + iccProfileSrc + "' not found.");
}
} else {
colorSpace = colorSpaceMap.get(key);
}
return colorSpace;
}
}