Resized PDF file does not conform to Adobe's published PDF specification

Sample.pdf (143.4 KB)
Aspose Team,
We use the Aspose PDF java package to add stamps to each page of PDF files, and then use the following Ghostscipt command to conver the PDF file to grayscale.

sudo gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite
-sFONTPATH=/usr/share/fonts/
-dHaveTransparency=false
-dProcessColorModel=/DeviceGray
-dColorConversionStrategy=/Gray
-o Sample_gray.pdf
-f Sample.pdf

We found the following error with some PDF files.

GPL Ghostscript 9.52 (2020-03-19)
Copyright © 2020 Artifex Software, Inc. All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 2.
Page 1
**** Warning: Found circular references in resource dictionaries while checking for transparency.
Page 2
**** This file had errors that were repaired or ignored.
**** The file was produced by:
**** >>>> Aspose.PDF for Java 20.7 <<<<
**** Please notify the author of the software that produced this
**** file that it does not conform to Adobe’s published PDF
**** specification.

Following is the sample code that reproduces the problem and attached is the sample file. Note that the problem is caused by the following statement that resizes the page before adding the stamps.

editor.resizeContents(document, parameters);

The operating system is Ubuntu 18.04. Java version is 1.8. Aspose PDF java package is 20.7 and Ghostscript version is 9.52.

import com.aspose.pdf.*;
import com.aspose.pdf.facades.FormattedText;
import com.aspose.pdf.facades.PdfFileEditor;
import java.util.ArrayList;
import java.util.List;

public class TestStamp {
public static void main(String[] args) {
try {
System.out.println(“Start”);

        String path = "/home/ubuntu/testdir/Sample.pdf";
        String ucStr = "Test";
        String llStr = "1";
        String lrStr = "YAX.PC.00000198";
        String fontFamily = "DejaVu Sans";
        Font font = FontRepository.findFont(fontFamily);;
        int fontSize = 10;

        // Stamps
        List<TextStamp> stampsToAdd = new ArrayList<>();
        // Uper Center
        stampsToAdd.add(convertToStamp(ucStr, HorizontalAlignment.Center, VerticalAlignment.Top, font, fontSize));
        // Lower Left
        stampsToAdd.add(convertToStamp(llStr, HorizontalAlignment.Left, VerticalAlignment.Bottom, font, fontSize));
        // Lower Right
        stampsToAdd.add(convertToStamp(lrStr, HorizontalAlignment.Right, VerticalAlignment.Bottom, font, fontSize));

        // Resize the page before adding the stamps
        int leftMargin = 5;
        int rightMargin = 5;
        int topMargin = 11;
        int bottomMargin = 11;
        PdfFileEditor.ContentsResizeParameters parameters = new PdfFileEditor.ContentsResizeParameters(
                PdfFileEditor.ContentsResizeValue.units(leftMargin),
                null,
                PdfFileEditor.ContentsResizeValue.units(rightMargin),
                PdfFileEditor.ContentsResizeValue.units(topMargin),
                null,
                PdfFileEditor.ContentsResizeValue.units(bottomMargin)
        );

        PdfFileEditor editor = new PdfFileEditor();
        Document document = new Document(path);
        editor.resizeContents(document, parameters);

        for (Page page : document.getPages()) {
            for(TextStamp stamp : stampsToAdd){
                page.addStamp(stamp);
            }
        }
        document.save();

        System.out.println("Done");
    }
    catch(Exception ex) {
        ex.printStackTrace();
    }
}

private static TextStamp convertToStamp(String text, int horizontalAlignment, int verticalAlignment,
                                        Font font, int fontSize) {
    FormattedText formattedText = new FormattedText();
    formattedText.addNewLineText(text);
    TextStamp textStamp = new TextStamp(formattedText);
    textStamp.setWordWrap(true);
    textStamp.setHorizontalAlignment(horizontalAlignment);
    textStamp.setVerticalAlignment(verticalAlignment);
    textStamp.getTextState().setFont(font);
    textStamp.getTextState().setFontSize(fontSize);
    textStamp.setTopMargin(0);
    return textStamp;
}

}

@xyang

Would you please try using Aspose.PDF for Java 20.8 at your side and in case you still face any issue, please let us know. We will further proceed to assist you accordingly.

I tested with Aspose.PDF for Java 20.8 and still have the problem:

GPL Ghostscript 9.52 (2020-03-19)
Copyright © 2020 Artifex Software, Inc. All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 2.
Page 1
**** Warning: Found circular references in resource dictionaries while checking for transparency.
Page 2
**** This file had errors that were repaired or ignored.
**** The file was produced by:
**** >>>> Aspose.PDF for Java 20.8 <<<<
**** Please notify the author of the software that produced this
**** file that it does not conform to Adobe’s published PDF
**** specification.

@xyang

We have logged an investigation ticket as PDFJAVA-39716 in our issue tracking system. We will further investigate this scenario in details and keep you informed with the status of ticket resolution. Please have patience and spare us some time.

We are sorry for the inconvenience.

@asad.ali Hello, do you have any information to share on this ticket?

@aweech

This ticket was resolved and identified as Not A Bug. It looked like some issue of GhostScript as according to Adobe Preflight (Adobe PDF validation tools) the output document fully conforms PDF specification.

Also, we tried to re-save the document using Adobe Acrobat (in process of re-saving the file is recreated by Adobe Acrobat), but this too didn’t change the output log of the GhostScript tool. As we know GhostScript has many opened tickets with transparency issues. Pay attention that this message in GhostScript is only a WARNING that is not leading to rendering errors in the output file.

Please, also mind that the method save() should be used for an incremental saving only (that saves the initial document inside). If you’re not working with signatures the method save(outputFileName) is more preferable.