special/output_intents updated
Analyze PDF/A, PDF/X and PDF 2.0 output intents on document or page level and print information about the corresponding ICC profiles.
Download Java Code Show Output Show Output Show Input (pdfa.pdf)
/*
* Analyze PDF/A, PDF/X and PDF 2.0 output intents on document or page level
* and print information about the corresponding ICC profiles.
*
* Required software: pCOS interface 10 (PDFlib+PDI 10, TET 5.x, PLOP 5.x)
*
* Required data: PDF document
*/
package com.pdflib.cookbook.pcos.special;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.pdflib.IpCOS;
import com.pdflib.cookbook.pcos.pcos_cookbook_example;
public class output_intents extends pcos_cookbook_example {
/* This is where the data files are. Adjust as necessary. */
private final static String SEARCH_PATH = "../input";
public void example_code(IpCOS p, int doc) throws Exception {
String filename = p.pcos_get_string(doc, "filename");
System.out.println("File name: " + filename);
int output_intent_count = (int) p.pcos_get_number(doc,
"length:/Root/OutputIntents");
// Search document output intents
if (output_intent_count == 0)
System.out.println("No document output intent found");
else
for (int oi = 0; oi < output_intent_count; oi += 1)
{
System.out.println("Document output intent " + (oi + 1) + ":");
process_output_intent(p, doc, filename, oi);
}
// Search page output intents (requires PDF 2.0)
int page_count = (int) p.pcos_get_number(doc, "length:pages");
for (int page = 0; page < page_count; page += 1)
{
output_intent_count = (int) p.pcos_get_number(doc,
"length:pages[" + page + "]/OutputIntents");
for (int oi = 0; oi < output_intent_count; oi += 1)
{
System.out.println("Page " + (page + 1) + ", output intent " + (oi + 1) + ":");
process_output_intent(p, doc, filename, oi);
}
}
}
/**
* Examines the output intent given by parameter oi, and writes out ICC
* profile if applicable.
*
* @param p
* IpCOS object
* @param doc
* document handle
* @param filename
* name of the PDF input document
* @param oi
* index in "/Root/OutputIntents" array
*
* @throws Exception
*/
private void process_output_intent(IpCOS p, int doc, String filename, int oi)
throws Exception {
/*
* The pCOS path to the given output intent
*/
final String oi_key = "/Root/OutputIntents[" + oi + "]";
int iccprofileid = -1;
String objtype;
print_info(p, doc, oi_key + "/S", "Subtype", "name", true);
print_info(p, doc, oi_key + "/OutputConditionIdentifier", "Identifier", "string", true);
// Check whether an ICC profile is directly included in the output intent
objtype = p.pcos_get_string(doc, "type:" + oi_key + "/DestOutputProfile");
if (objtype.equals("stream"))
{
iccprofileid = (int) p.pcos_get_number(doc, oi_key + "/DestOutputProfile/iccprofileid");
byte[] contents = p.pcos_get_stream(doc, "", oi_key + "/DestOutputProfile");
if (contents != null && contents.length > 0)
{
String subtype = p.pcos_get_string(doc, oi_key + "/S");
write_profile(filename, subtype, contents);
}
else {
System.out.println(" No direct ICC profile found");
}
}
else
{
// Check whether an ICC profile is available as embedded file
objtype = p.pcos_get_string(doc, "type:" + oi_key + "/DestOutputProfileRef");
if (objtype.equals("dict")) {
iccprofileid = (int) p.pcos_get_number(doc, oi_key + "/DestOutputProfileRef/iccprofileid");
objtype = p.pcos_get_string(doc, "type:" + oi_key + "/DestOutputProfileRef/URLs[0]/EF/F");
if (objtype.equals("stream"))
{
byte[] contents = p.pcos_get_stream(doc, "", oi_key + "/DestOutputProfileRef/URLs[0]/EF/F");
if (contents != null && contents.length > 0)
{
String subtype = p.pcos_get_string(doc, oi_key + "/S");
System.out.println(" Referenced ICC profile with attached data found");
write_profile(filename, subtype, contents);
}
}
// Check whether a referenced ICC profile is present
objtype = p.pcos_get_string(doc, "type:" + oi_key + "/DestOutputProfileRef/URLs[0]/F");
if (objtype.equals("string")) {
System.out.println(" Externally referenced ICC profile found");
}
objtype = p.pcos_get_string(doc, "type:" + oi_key
+ "/DestOutputProfileRef/ProfileName");
if (objtype.equals("string")) {
System.out.println(" Referenced ICC profile name: '" +
p.pcos_get_string(doc, oi_key + "/DestOutputProfileRef/ProfileName") + "'");
}
}
else {
System.out.println(" Neither direct nor referenced ICC profile found");
}
}
if (iccprofileid != -1)
{
String errormessage = p.pcos_get_string(doc, "iccprofiles[" + iccprofileid + "]/errormessage");
// Check whether the embedded profile is damaged
if (errormessage != null && errormessage.length() > 0) {
System.out.println("ICC profile damaged (" + errormessage + ")");
}
else {
// Print ICC profile details using pCOS pseudo objects
print_info(p, doc, "iccprofiles[" + iccprofileid + "]/deviceclass", "device class", "string", true);
print_info(p, doc, "iccprofiles[" + iccprofileid + "]/profilecs", "profile colorspace", "string", true);
print_info(p, doc, "iccprofiles[" + iccprofileid + "]/iccversion", "ICC version", "string", true);
print_info(p, doc, "iccprofiles[" + iccprofileid + "]/fromCIE", "BtoA1 tag present", "boolean", true);
print_info(p, doc, "iccprofiles[" + iccprofileid + "]/toCIE", "AtoB1 tag present", "boolean", true);
}
}
}
/**
* Prints out one of the keys in the output intent dictionary.
*
* @param p
* IpCOS object
* @param doc
* document handle
* @param key
* key of interest in the output intent dictionary
* @param label
* human-readable lable
* @param type
* expected type of the value in the dictionary
* @param required
* if true the absence of the key causes an exception
*
* @throws Exception
* a pCOS error occurred
* @throws Exception
* a required key was not found, the PDF document is damaged
*/
private void print_info(IpCOS p, int doc, String key, String label,
String type, boolean required) throws Exception {
String objtype = p.pcos_get_string(doc, "type:" + key);
System.out.print(" " + label + ": ");
if (objtype.equals(type)) {
System.out.print("'" + p.pcos_get_string(doc, key) + "'");
}
else {
if (required) {
throw new Exception("Required key '" + key
+ "' is missing, cannot continue");
}
System.out.print("(not found)");
}
System.out.println();
}
/**
* Writes the ICC profile to a file.
*
* @param filename
* name of PDF input document
* @param subtype
* output intent subtype from output intent dictionary
* @param contents
* the contents of the distiller profile
*
* @throws Exception
* unexpected suffix of input file name
*/
private void write_profile(String filename, String subtype, byte[] contents)
throws Exception {
File original_path = new File(filename);
String base_name = original_path.getName();
/*
* Strip off the ".pdf" part of the file name
*/
String suffix = "";
if (base_name.length() >= 4) {
suffix = base_name.substring(base_name.length() - 4);
}
if (suffix.compareToIgnoreCase(".pdf") != 0) {
throw new Exception("Input document has unexpected suffix \""
+ suffix + "\" (expected \".pdf\")");
}
base_name = base_name.substring(0, base_name.length() - 4);
try {
/*
* create a new file in the current directory and write the
* contents of the ICC profile to it
*/
File icc_profile_file = new File(base_name + "_" + subtype + ".icc");
FileOutputStream icc_profile_stream = new FileOutputStream(
icc_profile_file);
icc_profile_stream.write(contents);
icc_profile_stream.close();
System.out.println(" ICC profile extracted to file \""
+ icc_profile_file.getName() + "\"");
}
catch (IOException e) {
System.err.println("IOException occured:");
e.printStackTrace();
}
}
public output_intents(String[] argv, String readable_name,
String search_path) {
super(argv, readable_name, search_path);
}
public static void main(String argv[]) {
output_intents example = new output_intents(argv,
"Output intent ICC profiles", SEARCH_PATH);
example.execute();
}
}