Skip to content

Commit 1c01b0a

Browse files
IdamkinIitext-teamcity
authored andcommitted
Add support for icc profiles in images
Replace cmps for files that use images with icc profiles. DEVSIX-1714 Autoported commit. Original commit hash: [a5af1aab7]
1 parent 32c7a20 commit 1c01b0a

File tree

8 files changed

+93
-3
lines changed

8 files changed

+93
-3
lines changed

itext.tests/itext.layout.tests/itext/layout/ImageTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ public virtual void PngImageColorProfileTest() {
524524
/// <exception cref="System.IO.IOException"/>
525525
/// <exception cref="System.Exception"/>
526526
[NUnit.Framework.Test]
527+
[LogMessage(iText.IO.LogMessageConstant.PNG_IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS
528+
)]
527529
public virtual void PngImageIncorrectColorProfileTest() {
528530
SimpleImageTest("pngIncorrectColorProfileTest.pdf", "png-incorrect-color-profile-test.png");
529531
}
Binary file not shown.
Binary file not shown.

itext/itext.io/itext/io/LogMessageConstant.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ public const String ENCRYPTED_PAYLOAD_FILE_SPEC_SHALL_HAVE_AFRELATIONSHIP_FILED_
141141

142142
public const String IMAGE_HAS_JPXDECODE_FILTER = "Image cannot be inline if it has JPXDecode filter. It will be added as an ImageXObject";
143143

144+
public const String IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_COLOR_SPACE
145+
= "Image has icc profile with incompatible number of color components compared to image color space. The icc profile will be ignored.";
146+
147+
public const String IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE
148+
= "Image has icc profile with incompatible number of color components compared to base color space in image indexed color space. The icc profile will be ignored.";
149+
150+
public const String IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE
151+
= "Image has incorrect or unsupported base color space in indexed color space, it will be overridden by one based on embedded icc profile.";
152+
153+
public const String IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE = "Image has incorrect or unsupported color space, that will be overridden by one based on embedded icc profile.";
154+
144155
public const String IMAGE_HAS_MASK = "Image cannot be inline if it has a Mask";
145156

146157
public const String IMAGE_SIZE_CANNOT_BE_MORE_4KB = "Inline image size cannot be more than 4KB. It will be added as an ImageXObject";
@@ -197,6 +208,8 @@ public const String ENCRYPTED_PAYLOAD_FILE_SPEC_SHALL_HAVE_AFRELATIONSHIP_FILED_
197208

198209
public const String PDF_WRITER_CLOSING_FAILED = "PdfWriter closing failed due to the error occurred!";
199210

211+
public const String PNG_IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS = "Png image has color profile with incompatible number of color components. It will be ignored.";
212+
200213
public const String POPUP_ENTRY_IS_NOT_POPUP_ANNOTATION = "Popup entry in the markup annotations refers not to the annotation with Popup subtype.";
201214

202215
public const String PROPERTY_IN_PERCENTS_NOT_SUPPORTED = "Property {0} in percents is not supported";

itext/itext.io/itext/io/image/PngImageHelper.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ source product.
4545
using System.Collections.Generic;
4646
using System.IO;
4747
using System.Text;
48+
using Common.Logging;
4849
using iText.IO.Colors;
4950
using iText.IO.Font;
5051
using iText.IO.Source;
@@ -214,6 +215,12 @@ public static void ProcessImage(ImageData image) {
214215
/// <exception cref="System.IO.IOException"/>
215216
private static void ProcessPng(Stream pngStream, PngImageHelper.PngParameters png) {
216217
ReadPng(pngStream, png);
218+
if (png.iccProfile != null && png.iccProfile.GetNumComponents() != GetExpectedNumberOfColorComponents(png)
219+
) {
220+
LogManager.GetLogger(typeof(PngImageHelper)).Error(iText.IO.LogMessageConstant.PNG_IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS
221+
);
222+
png.iccProfile = null;
223+
}
217224
try {
218225
int pal0 = 0;
219226
int palIdx = 0;
@@ -407,6 +414,10 @@ private static Object GetColorspace(PngImageHelper.PngParameters png) {
407414
}
408415
}
409416

417+
private static int GetExpectedNumberOfColorComponents(PngImageHelper.PngParameters png) {
418+
return (png.colorType & 2) == 0 ? 1 : 3;
419+
}
420+
410421
/// <exception cref="System.IO.IOException"/>
411422
private static void ReadPng(Stream pngStream, PngImageHelper.PngParameters png) {
412423
for (int i = 0; i < PNGID.Length; i++) {

itext/itext.kernel/itext/kernel/pdf/colorspace/PdfCieBasedCs.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ public override int GetNumberOfComponents() {
205205

206206
public static PdfStream GetIccProfileStream(Stream iccStream) {
207207
IccProfile iccProfile = IccProfile.GetInstance(iccStream);
208+
return GetIccProfileStream(iccProfile);
209+
}
210+
211+
public static PdfStream GetIccProfileStream(Stream iccStream, float[] range) {
212+
IccProfile iccProfile = IccProfile.GetInstance(iccStream);
213+
return GetIccProfileStream(iccProfile, range);
214+
}
215+
216+
public static PdfStream GetIccProfileStream(IccProfile iccProfile) {
208217
PdfStream stream = new PdfStream(iccProfile.GetData());
209218
stream.Put(PdfName.N, new PdfNumber(iccProfile.GetNumComponents()));
210219
switch (iccProfile.GetNumComponents()) {
@@ -230,8 +239,8 @@ public static PdfStream GetIccProfileStream(Stream iccStream) {
230239
return stream;
231240
}
232241

233-
public static PdfStream GetIccProfileStream(Stream iccStream, float[] range) {
234-
PdfStream stream = GetIccProfileStream(iccStream);
242+
public static PdfStream GetIccProfileStream(IccProfile iccProfile, float[] range) {
243+
PdfStream stream = GetIccProfileStream(iccProfile);
235244
stream.Put(PdfName.Range, new PdfArray(range));
236245
return stream;
237246
}

itext/itext.kernel/itext/kernel/pdf/xobject/PdfImageXObject.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@ source product.
4444
using System;
4545
using System.Collections.Generic;
4646
using System.IO;
47+
using Common.Logging;
4748
using iText.IO.Codec;
49+
using iText.IO.Colors;
4850
using iText.IO.Image;
4951
using iText.Kernel;
5052
using iText.Kernel.Pdf;
5153
using iText.Kernel.Pdf.Canvas.Wmf;
54+
using iText.Kernel.Pdf.Colorspace;
5255
using iText.Kernel.Pdf.Filters;
5356

5457
namespace iText.Kernel.Pdf.Xobject {
@@ -403,6 +406,58 @@ private static PdfStream CreatePdfStream(ImageData image, iText.Kernel.Pdf.Xobje
403406
if (additional != null) {
404407
stream.PutAll(additional);
405408
}
409+
IccProfile iccProfile = image.GetProfile();
410+
if (iccProfile != null) {
411+
PdfStream iccProfileStream = PdfCieBasedCs.IccBased.GetIccProfileStream(iccProfile);
412+
PdfArray iccBasedColorSpace = new PdfArray();
413+
iccBasedColorSpace.Add(PdfName.ICCBased);
414+
iccBasedColorSpace.Add(iccProfileStream);
415+
PdfObject colorSpaceObject = stream.Get(PdfName.ColorSpace);
416+
bool iccProfileShouldBeApplied = true;
417+
if (colorSpaceObject != null) {
418+
PdfColorSpace cs = PdfColorSpace.MakeColorSpace(colorSpaceObject);
419+
if (cs == null) {
420+
LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE
421+
);
422+
}
423+
else {
424+
if (cs is PdfSpecialCs.Indexed) {
425+
PdfColorSpace baseCs = ((PdfSpecialCs.Indexed)cs).GetBaseCs();
426+
if (baseCs == null) {
427+
LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE
428+
);
429+
}
430+
else {
431+
if (baseCs.GetNumberOfComponents() != iccProfile.GetNumComponents()) {
432+
LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE
433+
);
434+
iccProfileShouldBeApplied = false;
435+
}
436+
else {
437+
iccProfileStream.Put(PdfName.Alternate, baseCs.GetPdfObject());
438+
}
439+
}
440+
if (iccProfileShouldBeApplied) {
441+
((PdfArray)colorSpaceObject).Set(1, iccBasedColorSpace);
442+
iccProfileShouldBeApplied = false;
443+
}
444+
}
445+
else {
446+
if (cs.GetNumberOfComponents() != iccProfile.GetNumComponents()) {
447+
LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_COLOR_SPACE
448+
);
449+
iccProfileShouldBeApplied = false;
450+
}
451+
else {
452+
iccProfileStream.Put(PdfName.Alternate, colorSpaceObject);
453+
}
454+
}
455+
}
456+
}
457+
if (iccProfileShouldBeApplied) {
458+
stream.Put(PdfName.ColorSpace, iccBasedColorSpace);
459+
}
460+
}
406461
if (image.IsMask() && (image.GetBpc() == 1 || image.GetBpc() > 0xff)) {
407462
stream.Put(PdfName.ImageMask, PdfBoolean.TRUE);
408463
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
58207a6e0bf46d2d6333a2e8e44db4df58f7052b
1+
a5af1aab7f5ff1918972fc3e2c5246040ccbf1f5

0 commit comments

Comments
 (0)