SmartModeTest.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.pdf;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.kernel.utils.CompareTool;
import com.itextpdf.test.ExtendedITextTest;
import com.itextpdf.test.TestUtil;
import java.io.IOException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("IntegrationTest")
public class SmartModeTest extends ExtendedITextTest {
public static final String destinationFolder = TestUtil.getOutputPath() + "/kernel/pdf/SmartModeTest/";
public static final String sourceFolder = "./src/test/resources/com/itextpdf/kernel/pdf/SmartModeTest/";
@BeforeAll
public static void beforeClass() {
createOrClearDestinationFolder(destinationFolder);
}
@AfterAll
public static void afterClass() {
CompareTool.cleanup(destinationFolder);
}
@Test
public void smartModeSameResourcesCopyingAndFlushing() throws IOException, InterruptedException {
String outFile = destinationFolder + "smartModeSameResourcesCopyingAndFlushing.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSameResourcesCopyingAndFlushing.pdf";
String[] srcFiles = new String[]{
sourceFolder + "indirectResourcesStructure.pdf",
sourceFolder + "indirectResourcesStructure2.pdf"
};
PdfDocument outputDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile, new WriterProperties().useSmartMode()));
for (String srcFile : srcFiles) {
PdfDocument sourceDoc = new PdfDocument(new PdfReader(srcFile));
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), outputDoc);
sourceDoc.close();
outputDoc.flushCopiedObjects(sourceDoc);
}
outputDoc.close();
PdfDocument assertDoc = new PdfDocument(CompareTool.createOutputReader(outFile));
PdfIndirectReference page1ResFontObj = assertDoc.getPage(1).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
PdfIndirectReference page2ResFontObj = assertDoc.getPage(2).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
PdfIndirectReference page3ResFontObj = assertDoc.getPage(3).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
Assertions.assertTrue(page1ResFontObj.equals(page2ResFontObj));
Assertions.assertTrue(page1ResFontObj.equals(page3ResFontObj));
assertDoc.close();
Assertions.assertNull(new CompareTool().compareByContent(outFile, cmpFile, destinationFolder));
}
@Test
public void smartModeSameResourcesCopyingModifyingAndFlushing() throws IOException {
String outFile = destinationFolder + "smartModeSameResourcesCopyingModifyingAndFlushing.pdf";
String[] srcFiles = new String[]{
sourceFolder + "indirectResourcesStructure.pdf",
sourceFolder + "indirectResourcesStructure2.pdf"
};
boolean exceptionCaught = false;
PdfDocument outputDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile, new WriterProperties().useSmartMode()));
int lastPageNum = 1;
PdfFont font = PdfFontFactory.createFont();
for (String srcFile : srcFiles) {
PdfDocument sourceDoc = new PdfDocument(new PdfReader(srcFile));
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), outputDoc);
sourceDoc.close();
int i;
for (i = lastPageNum; i <= outputDoc.getNumberOfPages(); ++i) {
PdfCanvas canvas;
try {
canvas = new PdfCanvas(outputDoc.getPage(i));
} catch (NullPointerException expected) {
// Smart mode makes it possible to share objects coming from different source documents.
// Flushing one object documents might make it impossible to modify further copied objects.
Assertions.assertEquals(2, i);
exceptionCaught = true;
break;
}
canvas.beginText().moveText(36, 36).setFontAndSize(font, 12).showText("Page " + i).endText();
}
lastPageNum = i;
if (exceptionCaught) {
break;
}
outputDoc.flushCopiedObjects(sourceDoc);
}
if (!exceptionCaught) {
Assertions.fail();
}
}
@Test
public void smartModeSameResourcesCopyingModifyingAndFlushing_ensureObjectFresh() throws IOException, InterruptedException {
String outFile = destinationFolder + "smartModeSameResourcesCopyingModifyingAndFlushing_ensureObjectFresh.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSameResourcesCopyingModifyingAndFlushing_ensureObjectFresh.pdf";
String[] srcFiles = new String[]{
sourceFolder + "indirectResourcesStructure.pdf",
sourceFolder + "indirectResourcesStructure2.pdf"
};
PdfDocument outputDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile, new WriterProperties().useSmartMode()));
int lastPageNum = 1;
PdfFont font = PdfFontFactory.createFont();
for (String srcFile : srcFiles) {
PdfDocument sourceDoc = new PdfDocument(new PdfReader(srcFile));
for (int i = 1; i <= sourceDoc.getNumberOfPages(); ++i) {
PdfDictionary srcRes = sourceDoc.getPage(i).getPdfObject().getAsDictionary(PdfName.Resources);
// Ensures that objects copied to the output document are fresh,
// i.e. are not reused from already copied objects cache.
boolean ensureObjectIsFresh = true;
// it's crucial to copy first inner objects and then the container object!
for (PdfObject v : srcRes.values()) {
if (v.getIndirectReference() != null) {
// We are not interested in returned copied objects instances, they will be picked up by
// general copying mechanism from copied objects cache by default.
v.copyTo(outputDoc, ensureObjectIsFresh);
}
}
if (srcRes.getIndirectReference() != null) {
srcRes.copyTo(outputDoc, ensureObjectIsFresh);
}
}
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), outputDoc);
sourceDoc.close();
int i;
for (i = lastPageNum; i <= outputDoc.getNumberOfPages(); ++i) {
PdfPage page = outputDoc.getPage(i);
PdfCanvas canvas = new PdfCanvas(page);
canvas.beginText().moveText(36, 36).setFontAndSize(font, 12).showText("Page " + i).endText();
}
lastPageNum = i;
outputDoc.flushCopiedObjects(sourceDoc);
}
outputDoc.close();
PdfDocument assertDoc = new PdfDocument(CompareTool.createOutputReader(outFile));
PdfIndirectReference page1ResFontObj = assertDoc.getPage(1).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
PdfIndirectReference page2ResFontObj = assertDoc.getPage(2).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
PdfIndirectReference page3ResFontObj = assertDoc.getPage(3).getPdfObject().getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.Font).getIndirectReference();
Assertions.assertFalse(page1ResFontObj.equals(page2ResFontObj));
Assertions.assertFalse(page1ResFontObj.equals(page3ResFontObj));
Assertions.assertFalse(page2ResFontObj.equals(page3ResFontObj));
assertDoc.close();
Assertions.assertNull(new CompareTool().compareByContent(outFile, cmpFile, destinationFolder));
}
@Test
public void pageCopyAsFormXObjectWithInheritedResourcesTest() throws IOException, InterruptedException {
String cmpFile = sourceFolder + "cmp_pageCopyAsFormXObjectWithInheritedResourcesTest.pdf";
String srcFile = sourceFolder + "pageCopyAsFormXObjectWithInheritedResourcesTest.pdf";
String destFile = destinationFolder + "pageCopyAsFormXObjectWithInheritedResourcesTest.pdf";
PdfDocument origPdf = new PdfDocument(new PdfReader(srcFile));
PdfDocument copyPdfX = new PdfDocument(CompareTool.createTestPdfWriter(destFile).setSmartMode(true));
PdfDictionary pages = origPdf.getCatalog().getPdfObject().getAsDictionary(PdfName.Pages);
if (pages != null) {
for (int i = 1; i < origPdf.getNumberOfPages() + 1; i++) {
PdfPage origPage = origPdf.getPage(i);
Rectangle ps = origPage.getPageSize();
PdfPage page = copyPdfX.addNewPage(new PageSize(ps));
PdfCanvas canvas = new PdfCanvas(page);
PdfFormXObject pageCopy = origPage.copyAsFormXObject(copyPdfX);
canvas.addXObjectAt(pageCopy, 0, 0);
}
}
copyPdfX.close();
origPdf.close();
Assertions.assertNull(new CompareTool().compareByContent(destFile, cmpFile, destinationFolder));
}
@Test
public void smartModeSameImageResourcesTest() throws IOException, InterruptedException {
String srcFile = sourceFolder + "sameImageResources.pdf";
String outFile = destinationFolder + "smartModeSameImageResources.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSameImageResources.pdf";
try (PdfDocument newDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile).setSmartMode(true))) {
try (PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFile))) {
srcDoc.copyPagesTo(1, srcDoc.getNumberOfPages(), newDoc);
}
PdfIndirectReference page1ImgRes = newDoc.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im0")).getIndirectReference();
PdfIndirectReference page2ImgRes = newDoc.getPage(2).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im0")).getIndirectReference();
Assertions.assertEquals(page1ImgRes, page2ImgRes);
}
Assertions.assertNull(new CompareTool().compareByContent(outFile, cmpFile, destinationFolder));
}
@Test
public void smartModeSameColorSpaceResourcesTest() throws IOException, InterruptedException {
String srcFile = sourceFolder + "colorSpaceResource.pdf";
String outFile = destinationFolder + "smartModeSameColorSpaceResources.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSameColorSpaceResources.pdf";
try (PdfDocument newDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile).setSmartMode(true))) {
for (int i = 0; i < 2; i++) {
try (PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFile))) {
srcDoc.copyPagesTo(1, srcDoc.getNumberOfPages(), newDoc);
}
}
PdfObject page1CsRes = newDoc.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.get(new PdfName("Im0"))
.getIndirectReference();
PdfObject page2CsRes = newDoc.getPage(2).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.get(new PdfName("Im0"))
.getIndirectReference();
// It's expected that indirect arrays are not processed by smart mode.
// Smart mode only merges duplicate dictionaries and streams.
Assertions.assertEquals(page1CsRes, page2CsRes);
PdfIndirectReference page1CsStm = newDoc.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.ColorSpace).getAsArray(new PdfName("CS0"))
.getAsStream(1).getIndirectReference();
PdfIndirectReference page2CsStm = newDoc.getPage(2).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.ColorSpace).getAsArray(new PdfName("CS0"))
.getAsStream(1).getIndirectReference();
Assertions.assertEquals(page1CsStm, page2CsStm);
}
Assertions.assertNull(new CompareTool().compareByContent(outFile, cmpFile, destinationFolder));
}
@Test
public void smartModeSameExtGStateResourcesTest() throws IOException, InterruptedException {
String srcFile = sourceFolder + "extGStateResource.pdf";
String outFile = destinationFolder + "smartModeSameExtGStateResources.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSameExtGStateResources.pdf";
try (PdfDocument newDoc = new PdfDocument(CompareTool.createTestPdfWriter(outFile).setSmartMode(true))) {
for (int i = 0; i < 2; i++) {
try (PdfDocument srcDoc = new PdfDocument(new PdfReader(srcFile))) {
srcDoc.copyPagesTo(1, srcDoc.getNumberOfPages(), newDoc);
}
}
PdfIndirectReference page1GsRes = newDoc.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.ExtGState)
.getAsDictionary(new PdfName("Gs1")).getIndirectReference();
PdfIndirectReference page2GsRes = newDoc.getPage(2).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.ExtGState)
.getAsDictionary(new PdfName("Gs1")).getIndirectReference();
Assertions.assertEquals(page1GsRes, page2GsRes);
}
Assertions.assertNull(new CompareTool().compareByContent(outFile, cmpFile, destinationFolder));
}
@Test
public void smartModeCopyingInTaggedPdfTest() throws IOException, InterruptedException {
String srcFile = sourceFolder + "simpleTaggedDocument.pdf";
String dstFile = destinationFolder + "smartModeCopyingInTaggedPdf.pdf";
String cmpFile = sourceFolder + "cmp_smartModeCopyingInTaggedPdf.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
pdfDest.setTagged();
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
Assertions.assertNotNull(pdfDest.getStructTreeRoot()
.getKidsObject().getAsDictionary(0).getAsArray(PdfName.K)
.getAsDictionary(0).get(PdfName.K));
}
Assertions.assertNull(new CompareTool().compareByContent(dstFile, cmpFile, destinationFolder));
}
@Test
public void smartModeCopyingInPdfWithIdenticalPagesTaggedTest() throws IOException {
String srcFile = sourceFolder + "docWithAllPagesIdenticalTagged.pdf";
String dstFile = destinationFolder + "smartModeCopyingInPdfWithIdenticalPagesTagged.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
pdfDest.setTagged();
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference expectedPageObj = pdfDest.getPage(1).getPdfObject().getIndirectReference();
PdfIndirectReference expectedContStm = pdfDest.getPage(1).getPdfObject()
.getAsStream(PdfName.Contents).getIndirectReference();
for (int i = 2; i <= 10; i++) {
PdfIndirectReference pageObj = pdfDest.getPage(i).getPdfObject().getIndirectReference();
Assertions.assertNotEquals(expectedPageObj, pageObj);
PdfIndirectReference pageContentStm = pdfDest.getPage(i).getPdfObject()
.getAsStream(PdfName.Contents).getIndirectReference();
Assertions.assertEquals(expectedContStm, pageContentStm);
}
}
}
@Test
public void smartModeCopyingInPdfWithIdenticalPagesTest() throws IOException {
String srcFile = sourceFolder + "docWithAllPagesIdenticalNotTagged.pdf";
String dstFile = destinationFolder + "smartModeCopyingInPdfWithIdenticalPagesNotTagged.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference expectedPageObj = pdfDest.getPage(1).getPdfObject().getIndirectReference();
PdfIndirectReference expectedContStm = pdfDest.getPage(1).getPdfObject()
.getAsStream(PdfName.Contents).getIndirectReference();
for (int i = 2; i <= 10; i++) {
PdfIndirectReference pageObj = pdfDest.getPage(i).getPdfObject().getIndirectReference();
Assertions.assertNotEquals(expectedPageObj, pageObj);
PdfIndirectReference pageContentStm = pdfDest.getPage(i).getPdfObject()
.getAsStream(PdfName.Contents).getIndirectReference();
Assertions.assertEquals(expectedContStm, pageContentStm);
}
}
}
@Test
public void smartModeCopyingInPdfSamePagesDifferentXObjectsTest() throws IOException {
String srcFile = sourceFolder + "identicalPagesDifferentXObjects.pdf";
String dstFile = destinationFolder + "smartModeCopyingInPdfSamePagesDifferentXObjects.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference expectedImgRes = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
for (int i = 2; i <= 99; i++) {
PdfIndirectReference pagesImgRes = pdfDest.getPage(i).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
Assertions.assertEquals(expectedImgRes, pagesImgRes);
}
}
}
@Test
public void smartCopyingOfArrayWithStringsTest() throws IOException {
String srcFile = sourceFolder + "keyValueStructure.pdf";
String dstFile = destinationFolder + "smartCopyingOfArrayWithStrings.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference key1Ref = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(new PdfName("Key1")).getIndirectReference();
PdfIndirectReference key2Ref = pdfDest.getPage(2).getPdfObject()
.getAsDictionary(new PdfName("Key2")).getIndirectReference();
// Currently smart mode copying doesn't affect any other objects except streams and dictionaries
Assertions.assertNotEquals(key1Ref, key2Ref);
}
}
@Test
public void smartCopyingOfNestedIndirectDictionariesTest() throws IOException {
String srcFile = sourceFolder + "nestedIndirectDictionaries.pdf";
String dstFile = destinationFolder + "smartCopyingOfNestedIndirectDictionariesTest.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfObject key1Page1Ref = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(new PdfName("Key1")).getIndirectReference();
PdfIndirectReference key1Page2Ref = pdfDest.getPage(2).getPdfObject()
.getAsDictionary(new PdfName("Key1")).getIndirectReference();
PdfIndirectReference key2Page1Ref = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(new PdfName("Key1"))
.getAsDictionary(new PdfName("Key2")).getIndirectReference();
PdfIndirectReference key2Page2Ref = pdfDest.getPage(2).getPdfObject()
.getAsDictionary(new PdfName("Key1"))
.getAsDictionary(new PdfName("Key2")).getIndirectReference();
PdfIndirectReference key3Page1Ref = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(new PdfName("Key1"))
.getAsDictionary(new PdfName("Key2"))
.getAsArray(new PdfName("Key3")).getIndirectReference();
PdfIndirectReference key3Page2Ref = pdfDest.getPage(2).getPdfObject()
.getAsDictionary(new PdfName("Key1"))
.getAsDictionary(new PdfName("Key2"))
.getAsArray(new PdfName("Key3")).getIndirectReference();
// Currently smart mode copying doesn't affect any other objects except streams and dictionaries
Assertions.assertEquals(key1Page1Ref, key1Page2Ref);
Assertions.assertEquals(key2Page1Ref, key2Page2Ref);
Assertions.assertEquals(key3Page1Ref, key3Page2Ref);
}
}
@Test
public void smartModeSeparatedOutlinesCopyingTest() throws IOException, InterruptedException {
String dstFile = destinationFolder + "smartModeSeparatedOutlinesCopying.pdf";
String cmpFile = sourceFolder + "cmp_smartModeSeparatedOutlinesCopying.pdf";
String[] srcFiles = new String[] {
sourceFolder + "separatedOutlinesCopying.pdf",
sourceFolder + "separatedOutlinesCopying.pdf"
};
try (PdfDocument outputDoc = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
outputDoc.initializeOutlines();
for (String srcFile : srcFiles) {
PdfDocument sourceDoc = new PdfDocument(new PdfReader(srcFile));
sourceDoc.copyPagesTo(1, sourceDoc.getNumberOfPages(), outputDoc);
sourceDoc.close();
}
}
Assertions.assertNull(new CompareTool().compareByContent(dstFile, cmpFile, destinationFolder));
}
@Test
public void smartModeCopyingInPdfWithLinksOnOnePageTest() throws IOException {
String srcFile = sourceFolder + "identical100PagesDiffObjectsLinksOnOnePage.pdf";
String dstFile = destinationFolder + "smartModeCopyingInPdfWithLinksOnOnePage.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference expectedImgRes = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
for (int i = 2; i <= 99; i++) {
PdfIndirectReference pagesImgRes = pdfDest.getPage(i).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
Assertions.assertEquals(expectedImgRes, pagesImgRes);
}
}
}
@Test
public void smartModeCopyingInPdfWithDiffImagesTest() throws IOException {
String srcFile = sourceFolder + "docWithDifferentImages.pdf";
String dstFile = destinationFolder + "smartModeCopyingInPdfWithDiffImages.pdf";
try (PdfDocument pdfDest = new PdfDocument(CompareTool.createTestPdfWriter(dstFile, new WriterProperties().useSmartMode()))) {
try (PdfDocument pdfSrc = new PdfDocument(new PdfReader(srcFile))) {
pdfSrc.copyPagesTo(1, pdfSrc.getNumberOfPages(), pdfDest);
}
PdfIndirectReference expectedImgRes = pdfDest.getPage(1).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
for (int i = 2; i <= 99; i++) {
PdfIndirectReference pagesImgRes = pdfDest.getPage(i).getPdfObject()
.getAsDictionary(PdfName.Resources)
.getAsDictionary(PdfName.XObject)
.getAsStream(new PdfName("Im1")).getIndirectReference();
Assertions.assertNotEquals(expectedImgRes, pagesImgRes);
}
}
}
}