001    /*
002     * CMYKConversion
003     * 
004     * Copyright (c) 2002 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.color.conversion;
009    
010    import net.sourceforge.jiu.data.RGBIndex;
011    
012    /**
013     * Convert from CMYK color space to RGB color space.
014     * @author Marco Schmidt
015     * @since 0.10.0
016     */
017    public class CMYKConversion
018    {
019            private CMYKConversion()
020            {
021            }
022    
023            private static int convertToByte(int value)
024            {
025                    if (value <= 0)
026                    {
027                            return 0;
028                    }
029                    else
030                    if (value >= 255)
031                    {
032                            return 255;
033                    }
034                    else
035                    {
036                            return value;
037                    }
038            }
039    
040            /**
041             * Converts a 32 bit CMYK pixel to a 24 bit RGB pixel.
042             * Red, green and blue sample will be written at the indexes that {@link net.sourceforge.jiu.data.RGBIndex} defines for them.
043             * @param cyan the cyan sample, must lie in the interval 0 to 255
044             * @param magenta the magenta sample, must lie in the interval 0 to 255
045             * @param yellow the yellow sample, must lie in the interval 0 to 255
046             * @param black the black sample, must lie in the interval 0 to 255
047             * @param rgb byte array for the destination R-G-B pixel, must have length 3 or larger, will be accessed using RGBIndex, each sample will lie in the interval 0 to 255
048             */
049            public static void convertCMYK32ToRGB24(int cyan, int magenta, int yellow, int black, int[] rgb)
050            {
051                    int red = 255 - cyan;
052                    int green = 255 - magenta;
053                    int blue = 255 - yellow;
054                    red -= black;
055                    green -= black;
056                    blue -= black;
057                    rgb[RGBIndex.INDEX_RED] = convertToByte(red);
058                    rgb[RGBIndex.INDEX_GREEN] = convertToByte(green);
059                    rgb[RGBIndex.INDEX_BLUE] = convertToByte(blue);
060            }
061    
062            /**
063             * Converts a number of CMYK pixels stored in interleaved order (all samples of one pixel 
064             * together: CMYKCMYKCMYK...) to RGB pixels which are stored as planes (all red samples 
065             * together, etc.).
066             * @param cmyk a byte array with numPixels times four samples stored in order C-M-Y-K
067             * @param cmykOffset the index of the first byte that is to be accessed
068             * @param red the byte array to which the red samples will be written by this method
069             * @param redOffset the offset into the red array of the first sample to be written
070             * @param green the byte array to which the green samples will be written by this method
071             * @param greenOffset the offset into the green array of the first sample to be written
072             * @param blue the byte array to which the blue samples will be written by this method
073             * @param blueOffset the offset into the blue array of the first sample to be written
074             */
075            public static void convertCMYK32InterleavedToRGB24Planar(
076                    byte[] cmyk, int cmykOffset, 
077                    byte[] red, int redOffset, 
078                    byte[] green, int greenOffset, 
079                    byte[] blue, int blueOffset, 
080                    int numPixels)
081            {
082                    int[] rgb = new int[3];
083                    while (numPixels-- != 0)
084                    {
085                            convertCMYK32ToRGB24(
086                                    cmyk[cmykOffset] & 0xff, 
087                                    cmyk[cmykOffset + 1] & 0xff, 
088                                    cmyk[cmykOffset + 2] & 0xff, 
089                                    cmyk[cmykOffset + 3] & 0xff, 
090                                    rgb);
091                            cmykOffset += 4;
092                            red[redOffset++] = (byte)rgb[RGBIndex.INDEX_RED];
093                            green[greenOffset++] = (byte)rgb[RGBIndex.INDEX_GREEN];
094                            blue[blueOffset++] = (byte)rgb[RGBIndex.INDEX_BLUE];
095                    }
096            }
097    
098            public static void convertCMYK32PlanarToRGB24Planar(
099                    byte[] cyan, int cyanOffset,
100                    byte[] magenta, int magentaOffset,
101                    byte[] yellow, int yellowOffset,
102                    byte[] black, int blackOffset,
103                    byte[] red, int redOffset, 
104                    byte[] green, int greenOffset, 
105                    byte[] blue, int blueOffset, 
106                    int numPixels)
107            {
108                    int[] rgb = new int[3];
109                    while (numPixels-- != 0)
110                    {
111                            convertCMYK32ToRGB24(
112                                    cyan[cyanOffset++] & 0xff, 
113                                    magenta[magentaOffset++] & 0xff, 
114                                    yellow[yellowOffset++] & 0xff, 
115                                    black[blackOffset++] & 0xff, 
116                                    rgb);
117                            red[redOffset++] = (byte)rgb[RGBIndex.INDEX_RED];
118                            green[greenOffset++] = (byte)rgb[RGBIndex.INDEX_GREEN];
119                            blue[blueOffset++] = (byte)rgb[RGBIndex.INDEX_BLUE];
120                    }
121            }
122    }