2020package  org .apache .xmlgraphics .image .loader .impl .imageio ;
2121
2222import  java .awt .Color ;
23+ import  java .awt .Graphics2D ;
24+ import  java .awt .color .ColorSpace ;
2325import  java .awt .color .ICC_ColorSpace ;
2426import  java .awt .color .ICC_Profile ;
2527import  java .awt .image .BufferedImage ;
28+ import  java .awt .image .ColorConvertOp ;
2629import  java .awt .image .ColorModel ;
2730import  java .awt .image .ComponentColorModel ;
2831import  java .awt .image .IndexColorModel ;
2932import  java .awt .image .Raster ;
3033import  java .awt .image .RenderedImage ;
3134import  java .awt .image .WritableRaster ;
3235import  java .io .ByteArrayOutputStream ;
36+ import  java .io .FileNotFoundException ;
3337import  java .io .IOException ;
3438import  java .util .HashSet ;
3539import  java .util .Iterator ;
5761import  org .apache .commons .logging .Log ;
5862import  org .apache .commons .logging .LogFactory ;
5963
64+ import  org .apache .xmlgraphics .image .codec .util .ImageInputStreamSeekableStreamAdapter ;
6065import  org .apache .xmlgraphics .image .loader .Image ;
6166import  org .apache .xmlgraphics .image .loader .ImageException ;
6267import  org .apache .xmlgraphics .image .loader .ImageFlavor ;
@@ -80,8 +85,8 @@ public class ImageLoaderImageIO extends AbstractImageLoader {
8085    private  ImageFlavor  targetFlavor ;
8186
8287    private  static  final  String  PNG_METADATA_NODE  = "javax_imageio_png_1.0" ;
83- 
8488    private  static  final  String  JPEG_METADATA_NODE  = "javax_imageio_jpeg_image_1.0" ;
89+     public  static  final  String  ICC_CONVERTER  = "icc-converter" ;
8590
8691    private  static  final  Set  PROVIDERS_IGNORING_ICC  = new  HashSet ();
8792
@@ -247,12 +252,44 @@ public Image loadImage(ImageInfo info, Map<String, Object> hints, ImageSessionCo
247252        }
248253
249254        if  (ImageFlavor .BUFFERED_IMAGE .equals (this .targetFlavor )) {
255+             imageData  = rgbToCmyk ((BufferedImage ) imageData , info , session );
250256            return  new  ImageBuffered (info , (BufferedImage )imageData , transparentColor );
251257        } else  {
252258            return  new  ImageRendered (info , imageData , transparentColor );
253259        }
254260    }
255261
262+     /** 
263+      * Convert RGB to CMYK using ICC file passed via fop.xconf 
264+      */ 
265+     private  BufferedImage  rgbToCmyk (BufferedImage  image , ImageInfo  info , ImageSessionContext  session )
266+         throws  IOException  {
267+         String  iccUri  = (String ) info .getCustomObjects ().get (ICC_CONVERTER );
268+         if  (iccUri  != null  && image .getColorModel ().getNumColorComponents () < 4 ) {
269+             if  (image .getType () != BufferedImage .TYPE_INT_RGB ) {
270+                 BufferedImage  rgbImage  =
271+                         new  BufferedImage (image .getWidth (), image .getHeight (), BufferedImage .TYPE_INT_RGB );
272+                 Graphics2D  g  = (Graphics2D ) rgbImage .getGraphics ();
273+                 g .setBackground (Color .WHITE );
274+                 g .clearRect (0 , 0 , image .getWidth (), image .getHeight ());
275+                 g .drawImage (image , 0 , 0 , null );
276+                 g .dispose ();
277+                 image  = rgbImage ;
278+             }
279+             try  {
280+                 Source  src  = session .needSource (iccUri );
281+                 ImageInputStream  iccStream  = ImageUtil .needImageInputStream (src );
282+                 ColorSpace  colorSpace  = new  ICC_ColorSpace (ICC_Profile .getInstance (
283+                         new  ImageInputStreamSeekableStreamAdapter (iccStream )));
284+                 ColorConvertOp  convertOp  = new  ColorConvertOp (image .getColorModel ().getColorSpace (), colorSpace , null );
285+                 return  convertOp .filter (image , null );
286+             } catch  (FileNotFoundException  e ) {
287+                 throw  new  IOException (e );
288+             }
289+         }
290+         return  image ;
291+     }
292+ 
256293    private  ImageReadParam  getParam (ImageReader  reader , Map <String , Object > hints ) throws  IOException  {
257294        if  (hints  != null  && Boolean .TRUE .equals (hints .get ("CMYK" ))) {
258295            Iterator <ImageTypeSpecifier > types  = reader .getImageTypes (0 );
0 commit comments