ColorTest.java
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2025 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itextpdf.kernel.colors;
import com.itextpdf.kernel.exceptions.KernelExceptionMessageConstant;
import com.itextpdf.kernel.exceptions.PdfException;
import com.itextpdf.kernel.pdf.PdfArray;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfNumber;
import com.itextpdf.kernel.pdf.colorspace.PdfCieBasedCs;
import com.itextpdf.kernel.pdf.colorspace.PdfColorSpace;
import com.itextpdf.kernel.pdf.colorspace.PdfDeviceCs;
import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs;
import com.itextpdf.test.ExtendedITextTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Tag;
@Tag("UnitTest")
public class ColorTest extends ExtendedITextTest {
private static final float EPS = 1e-4f;
@Test
public void convertCmykToRgbTest() {
DeviceCmyk cmyk = new DeviceCmyk(0, 0, 0, 0);
DeviceRgb rgb = new DeviceRgb(255, 255, 255);
Assertions.assertArrayEquals(rgb.colorValue, Color.convertCmykToRgb(cmyk).colorValue, EPS);
}
@Test
public void convertRgbToCmykTest() {
DeviceCmyk cmyk = new DeviceCmyk(0, 0, 0, 0);
DeviceRgb rgb = new DeviceRgb(255, 255, 255);
Assertions.assertArrayEquals(cmyk.colorValue, Color.convertRgbToCmyk(rgb).colorValue, EPS);
}
@Test
public void setColorValueIncorrectComponentsNumberTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
Exception e = Assertions.assertThrows(PdfException.class,
() -> color.setColorValue(new float[] {0.1f, 0.2f})
);
Assertions.assertEquals(KernelExceptionMessageConstant.INCORRECT_NUMBER_OF_COMPONENTS, e.getMessage());
}
@Test
public void equalsAndHashCodeTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color1 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
Color color2 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
boolean result = color1.equals(color2);
Assertions.assertTrue(result);
Assertions.assertEquals(color1.hashCode(), color2.hashCode());
}
@Test
public void equalsAndHashCodeNullColorSpacesTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color1 = new Color(null, colorValues);
Color color2 = new Color(null, colorValues);
boolean result = color1.equals(color2);
Assertions.assertTrue(result);
Assertions.assertEquals(color1.hashCode(), color2.hashCode());
}
@Test
public void equalsAndHashCodeNullColorValuesTest() {
Color color1 = new Color(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), null);
Color color2 = new Color(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), null);
boolean result = color1.equals(color2);
Assertions.assertTrue(result);
Assertions.assertEquals(color1.hashCode(), color2.hashCode());
}
@Test
public void notEqualsAndHashCodeDifferentColorSpacesTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color1 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
Color color2 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceGray), colorValues);
boolean result = color1.equals(color2);
Assertions.assertFalse(result);
Assertions.assertNotEquals(color1.hashCode(), color2.hashCode());
}
@Test
public void notEqualsNullObjectTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color1 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
boolean result = color1.equals(null);
Assertions.assertFalse(result);
}
@Test
public void notEqualsDifferentClassesTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Color color1 = Color.makeColor(PdfColorSpace.makeColorSpace(PdfName.DeviceRGB), colorValues);
DeviceCmyk cmyk = new DeviceCmyk(0, 0, 0, 0);
boolean result = color1.equals(cmyk);
Assertions.assertFalse(result);
}
@Test
public void nullColorSpaceTest() {
float[] colorValues = new float[] {0.0f, 0.5f, 0.1f};
Exception e = Assertions.assertThrows(PdfException.class, () -> Color.makeColor(null, colorValues));
Assertions.assertEquals("Unknown color space.", e.getMessage());
}
@Test
public void makeDeviceGrayNullColorValuesTest() {
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(PdfName.DeviceGray);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof DeviceGray);
Assertions.assertArrayEquals(new float[] {0.0f}, color.getColorValue(), EPS);
}
@Test
public void makeDeviceGrayTest() {
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f};
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(PdfName.DeviceGray);
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof DeviceGray);
Assertions.assertArrayEquals(new float[] {0.7f}, color.getColorValue(), EPS);
}
@Test
public void makeDeviceCmykNullColorValuesTest() {
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(PdfName.DeviceCMYK);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof DeviceCmyk);
Assertions.assertArrayEquals(new float[] {0.0f, 0.0f, 0.0f, 1.0f}, color.getColorValue(), EPS);
}
@Test
public void makeDeviceCmykTest() {
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f, 0.3f};
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(PdfName.DeviceCMYK);
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof DeviceCmyk);
Assertions.assertArrayEquals(colorValues, color.getColorValue(), EPS);
}
@Test
public void unknownDeviceCsTest() {
Exception e = Assertions.assertThrows(PdfException.class, () -> Color.makeColor(new CustomDeviceCs(null)));
Assertions.assertEquals("Unknown color space.", e.getMessage());
}
@Test
public void makeCalGrayNullColorValuesTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calGray = new PdfArray();
calGray.add(PdfName.CalGray);
calGray.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calGray);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof CalGray);
Assertions.assertArrayEquals(new float[] {0.0f}, color.getColorValue(), EPS);
}
@Test
public void makeCalGrayTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calGray = new PdfArray();
calGray.add(PdfName.CalGray);
calGray.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calGray);
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f};
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof CalGray);
Assertions.assertArrayEquals(new float[] {0.7f}, color.getColorValue(), EPS);
}
@Test
public void makeCalRgbNullColorValuesTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calRgb = new PdfArray();
calRgb.add(PdfName.CalRGB);
calRgb.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calRgb);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof CalRgb);
Assertions.assertArrayEquals(new float[] {0.0f, 0.0f, 0.0f}, color.getColorValue(), EPS);
}
@Test
public void makeCalRgbTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calRgb = new PdfArray();
calRgb.add(PdfName.CalRGB);
calRgb.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calRgb);
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f};
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof CalRgb);
Assertions.assertArrayEquals(colorValues, color.getColorValue(), EPS);
}
@Test
public void makeLabNullColorValuesTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calLab = new PdfArray();
calLab.add(PdfName.Lab);
calLab.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calLab);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof Lab);
Assertions.assertArrayEquals(new float[] {0.0f, 0.0f, 0.0f}, color.getColorValue(), EPS);
}
@Test
public void makeLabTest() {
PdfDictionary dictionary = new PdfDictionary();
dictionary.put(PdfName.Gamma, new PdfNumber(2.2));
PdfArray calLab = new PdfArray();
calLab.add(PdfName.Lab);
calLab.add(dictionary);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(calLab);
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f};
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof Lab);
Assertions.assertArrayEquals(colorValues, color.getColorValue(), EPS);
}
@Test
public void unknownCieBasedCsTest() {
Exception e = Assertions.assertThrows(PdfException.class,
() -> Color.makeColor(new CustomPdfCieBasedCs(new PdfArray()))
);
Assertions.assertEquals("Unknown color space.", e.getMessage());
}
@Test
public void makeDeviceNNullColorValuesTest() {
PdfArray deviceN = new PdfArray();
deviceN.add(PdfName.DeviceN);
deviceN.add(new PdfArray());
deviceN.add(null);
deviceN.add(null);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(deviceN);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof DeviceN);
Assertions.assertArrayEquals(new float[] {}, color.getColorValue(), EPS);
}
@Test
public void makeDeviceNTest() {
PdfArray deviceN = new PdfArray();
deviceN.add(PdfName.DeviceN);
deviceN.add(new PdfArray());
deviceN.add(null);
deviceN.add(null);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(deviceN);
float[] colorValues = new float[] {0.7f, 0.5f, 0.1f};
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof DeviceN);
Assertions.assertArrayEquals(colorValues, color.getColorValue(), EPS);
}
@Test
public void makeIndexedNullColorValuesTest() {
PdfArray indexed = new PdfArray();
indexed.add(PdfName.Indexed);
indexed.add(new PdfArray());
indexed.add(null);
indexed.add(null);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(indexed);
Color color = Color.makeColor(colorSpace);
Assertions.assertTrue(color instanceof Indexed);
Assertions.assertArrayEquals(new float[] {0.0f}, color.getColorValue(), EPS);
}
@Test
public void makeIndexedTest() {
PdfArray indexed = new PdfArray();
indexed.add(PdfName.Indexed);
indexed.add(new PdfArray());
indexed.add(null);
indexed.add(null);
PdfColorSpace colorSpace = PdfColorSpace.makeColorSpace(indexed);
float[] colorValues = new float[] {1.0f, 0.5f, 0.1f};
Color color = Color.makeColor(colorSpace, colorValues);
Assertions.assertTrue(color instanceof Indexed);
Assertions.assertArrayEquals(new float[] {1f}, color.getColorValue(), EPS);
}
@Test
public void unknownSpecialCsTest() {
Exception e = Assertions.assertThrows(PdfException.class,
() -> Color.makeColor(new CustomPdfSpecialCs(new PdfArray()))
);
Assertions.assertEquals("Unknown color space.", e.getMessage());
}
@Test
public void createColorWithColorSpaceRgb() {
Assertions.assertEquals(ColorConstants.BLACK, Color.createColorWithColorSpace(new float[] {
0.0F, 0.0F, 0.0F
}));
}
@Test
public void createColorWithColorSpaceGraySpace() {
Assertions.assertEquals(new DeviceGray(), Color.createColorWithColorSpace(new float[] {
0.0F
}));
}
@Test
public void createColorWithColorSpaceCmyk() {
Assertions.assertEquals(new DeviceCmyk(), Color.createColorWithColorSpace(new float[] {
0.0F, 0.0F, 0.0F, 1F
}));
}
@Test
public void createColorWithInvalidValueNull() {
Assertions.assertNull(Color.createColorWithColorSpace(null));
}
@Test
public void createColorWithInvalidNoValues() {
Assertions.assertNull(Color.createColorWithColorSpace(new float[] {}));
}
@Test
public void createColorWithInvalidMoreThen4Values() {
Assertions.assertNull(Color.createColorWithColorSpace(new float[] {
0.0F, 0.0F, 0.0F, 0.0F, 0.0F,
}));
}
private static class CustomDeviceCs extends PdfDeviceCs {
public CustomDeviceCs(PdfName pdfObject) {
super(pdfObject);
}
@Override
public int getNumberOfComponents() {
return 0;
}
}
private static class CustomPdfCieBasedCs extends PdfCieBasedCs {
public CustomPdfCieBasedCs(PdfArray pdfObject) {
super(pdfObject);
}
@Override
public int getNumberOfComponents() {
return 0;
}
}
private static class CustomPdfSpecialCs extends PdfSpecialCs {
public CustomPdfSpecialCs(PdfArray pdfObject) {
super(pdfObject);
}
@Override
public int getNumberOfComponents() {
return 0;
}
}
}