Skip to content

Commit 747d8eb

Browse files
author
Dmitry Radchuk
committed
Add some pdf/a-4 checks for graphics
DEVSIX-7742
1 parent 5e695c4 commit 747d8eb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1478
-289
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfName.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
244244
public static final PdfName DefaultCMYK = createDirectName("DefaultCMYK");
245245

246246
public static final PdfName CMYK = createDirectName("CMYK");
247+
public static final PdfName Cyan = createDirectName("Cyan");
248+
public static final PdfName Magenta = createDirectName("Magenta");
249+
public static final PdfName Yellow = createDirectName("Yellow");
250+
public static final PdfName Black = createDirectName("Black");
247251
public static final PdfName DefaultCryptFilter = createDirectName("DefaultCryptFilter");
248252
public static final PdfName DefaultGray = createDirectName("DefaultGray");
249253
public static final PdfName DefaultRGB = createDirectName("DefaultRGB");
@@ -833,6 +837,7 @@ public class PdfName extends PdfPrimitiveObject implements Comparable<PdfName> {
833837
public static final PdfName ToUnicode = createDirectName("ToUnicode");
834838
public static final PdfName TR = createDirectName("TR");
835839
public static final PdfName TR2 = createDirectName("TR2");
840+
public static final PdfName TransferFunction = createDirectName("TransferFunction");
836841
public static final PdfName Trans = createDirectName("Trans");
837842
public static final PdfName TransformMethod = createDirectName("TransformMethod");
838843
public static final PdfName TransformParams = createDirectName("TransformParams");

pdfa/src/main/java/com/itextpdf/pdfa/PdfADocument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public PdfADocument(PdfReader reader, PdfWriter writer, StampingProperties prope
146146
isPdfADocument = false;
147147
} else {
148148
throw new PdfAConformanceException(
149-
PdfAConformanceException.
149+
PdfaExceptionMessageConstant.
150150
DOCUMENT_TO_READ_FROM_SHALL_BE_A_PDFA_CONFORMANT_FILE_WITH_VALID_XMP_METADATA);
151151
}
152152
}

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfA1Checker.java

Lines changed: 63 additions & 63 deletions
Large diffs are not rendered by default.

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfA2Checker.java

Lines changed: 72 additions & 68 deletions
Large diffs are not rendered by default.

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfA3Checker.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This file is part of the iText (R) project.
2828
import com.itextpdf.kernel.pdf.PdfStream;
2929
import com.itextpdf.pdfa.exceptions.PdfAConformanceException;
3030
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
31+
import com.itextpdf.pdfa.exceptions.PdfaExceptionMessageConstant;
3132
import com.itextpdf.pdfa.logs.PdfAConformanceLogMessageConstant;
3233

3334
import java.util.Collections;
@@ -68,32 +69,32 @@ public PdfA3Checker(PdfAConformanceLevel conformanceLevel) {
6869
protected void checkFileSpec(PdfDictionary fileSpec) {
6970
PdfName relationship = fileSpec.getAsName(PdfName.AFRelationship);
7071
if (relationship == null || !allowedAFRelationships.contains(relationship)) {
71-
throw new PdfAConformanceException(PdfAConformanceException.FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_ONE_OF_THE_PREDEFINED_AFRELATIONSHIP_KEYS);
72+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_ONE_OF_THE_PREDEFINED_AFRELATIONSHIP_KEYS);
7273
}
7374

7475
if (fileSpec.containsKey(PdfName.EF)) {
7576
if (!fileSpec.containsKey(PdfName.F) || !fileSpec.containsKey(PdfName.UF) || !fileSpec.containsKey(PdfName.Desc)) {
76-
throw new PdfAConformanceException(PdfAConformanceException.FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_F_KEY_AND_UF_KEY);
77+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_F_KEY_AND_UF_KEY);
7778
}
7879

7980

8081
PdfDictionary ef = fileSpec.getAsDictionary(PdfName.EF);
8182
PdfStream embeddedFile = ef.getAsStream(PdfName.F);
8283
if (embeddedFile == null) {
83-
throw new PdfAConformanceException(PdfAConformanceException.EF_KEY_OF_FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_DICTIONARY_WITH_VALID_F_KEY);
84+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.EF_KEY_OF_FILE_SPECIFICATION_DICTIONARY_SHALL_CONTAIN_DICTIONARY_WITH_VALID_F_KEY);
8485
}
8586

8687
if (!embeddedFile.containsKey(PdfName.Subtype)) {
87-
throw new PdfAConformanceException(PdfAConformanceException.MIME_TYPE_SHALL_BE_SPECIFIED_USING_THE_SUBTYPE_KEY_OF_THE_FILE_SPECIFICATION_STREAM_DICTIONARY);
88+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.MIME_TYPE_SHALL_BE_SPECIFIED_USING_THE_SUBTYPE_KEY_OF_THE_FILE_SPECIFICATION_STREAM_DICTIONARY);
8889
}
8990

9091
if (embeddedFile.containsKey(PdfName.Params)) {
9192
PdfObject params = embeddedFile.get(PdfName.Params);
9293
if (!params.isDictionary()) {
93-
throw new PdfAConformanceException(PdfAConformanceException.EMBEDDED_FILE_SHALL_CONTAIN_PARAMS_KEY_WITH_DICTIONARY_AS_VALUE);
94+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.EMBEDDED_FILE_SHALL_CONTAIN_PARAMS_KEY_WITH_DICTIONARY_AS_VALUE);
9495
}
9596
if (((PdfDictionary)params).getAsString(PdfName.ModDate) == null) {
96-
throw new PdfAConformanceException(PdfAConformanceException.EMBEDDED_FILE_SHALL_CONTAIN_PARAMS_KEY_WITH_VALID_MODDATE_KEY);
97+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.EMBEDDED_FILE_SHALL_CONTAIN_PARAMS_KEY_WITH_VALID_MODDATE_KEY);
9798
}
9899
} else {
99100
Logger logger = LoggerFactory.getLogger(PdfAChecker.class);

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfA4Checker.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ This file is part of the iText (R) project.
3030
import com.itextpdf.kernel.pdf.PdfName;
3131
import com.itextpdf.kernel.pdf.PdfNumber;
3232
import com.itextpdf.kernel.pdf.PdfObject;
33+
import com.itextpdf.kernel.pdf.PdfStream;
3334
import com.itextpdf.kernel.pdf.PdfString;
35+
import com.itextpdf.kernel.pdf.canvas.CanvasGraphicsState;
3436
import com.itextpdf.kernel.pdf.colorspace.PdfSpecialCs;
3537
import com.itextpdf.pdfa.exceptions.PdfAConformanceException;
3638
import com.itextpdf.pdfa.exceptions.PdfaExceptionMessageConstant;
@@ -39,6 +41,7 @@ This file is part of the iText (R) project.
3941
import java.util.Arrays;
4042
import java.util.Collections;
4143
import java.util.HashSet;
44+
import java.util.Map;
4245
import java.util.Set;
4346
import org.slf4j.Logger;
4447
import org.slf4j.LoggerFactory;
@@ -289,6 +292,44 @@ protected void checkNumberOfDeviceNComponents(PdfSpecialCs.DeviceN deviceN) {
289292

290293
}
291294

295+
@Override
296+
public void checkExtGState(CanvasGraphicsState extGState, PdfStream contentStream) {
297+
super.checkExtGState(extGState, contentStream);
298+
if (extGState.getHalftone() instanceof PdfDictionary) {
299+
PdfDictionary halftoneDict = (PdfDictionary) extGState.getHalftone();
300+
if (halftoneDict.containsKey(PdfName.TransferFunction)) {
301+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.ALL_HALFTONES_CONTAINING_TRANSFER_FUNCTION_SHALL_HAVE_HALFTONETYPE_5);
302+
}
303+
int halftoneType = halftoneDict.getAsInt(PdfName.HalftoneType).intValue();
304+
if (halftoneType == 5) {
305+
for (Map.Entry<PdfName, PdfObject> entry : halftoneDict.entrySet()) {
306+
//see ISO_32000_2;2020 table 132
307+
if (PdfName.Type.equals(entry.getKey()) || PdfName.HalftoneType.equals(entry.getKey()) || PdfName.HalftoneName.equals(entry.getKey())) {
308+
continue;
309+
}
310+
if (entry.getValue() instanceof PdfDictionary && isCMYKColorant(entry.getKey()) && entry.getValue() instanceof PdfDictionary && ((PdfDictionary)entry.getValue()).containsKey(PdfName.TransferFunction)) {
311+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.ALL_HALFTONES_CONTAINING_TRANSFER_FUNCTION_SHALL_HAVE_HALFTONETYPE_5);
312+
}
313+
}
314+
}
315+
}
316+
}
317+
@Override
318+
protected void checkFormXObject(PdfStream form) {
319+
if (isAlreadyChecked(form)) {
320+
return;
321+
}
322+
if (form.containsKey(PdfName.OPI)) {
323+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.A_FORM_XOBJECT_DICTIONARY_SHALL_NOT_CONTAIN_OPI_KEY);
324+
}
325+
if (form.containsKey(PdfName.Ref)) {
326+
throw new PdfAConformanceException(PdfaExceptionMessageConstant.A_FORM_XOBJECT_DICTIONARY_SHALL_NOT_CONTAIN_REF_KEY);
327+
}
328+
checkTransparencyGroup(form, null);
329+
checkResources(form.getAsDictionary(PdfName.Resources));
330+
checkContentStream(form);
331+
}
332+
292333
/**
293334
* {@inheritDoc}
294335
*/
@@ -402,4 +443,9 @@ protected void checkBlendMode(PdfName blendMode) {
402443
throw new PdfAConformanceException(PdfAConformanceException.ONLY_STANDARD_BLEND_MODES_SHALL_BE_USED_FOR_THE_VALUE_OF_THE_BM_KEY_IN_AN_EXTENDED_GRAPHIC_STATE_DICTIONARY);
403444
}
404445
}
446+
447+
private boolean isCMYKColorant(PdfName colourant) {
448+
return PdfName.Cyan.equals(colourant) || PdfName.Magenta.equals(colourant)
449+
|| PdfName.Yellow.equals(colourant) || PdfName.Black.equals(colourant);
450+
}
405451
}

0 commit comments

Comments
 (0)