[simple-scan/gnome-3-10: 6/8] Correct generation of PDF trailer to conform to the PDF standard.



commit 9baad0b10828b79d964e78cb1b863161a2439f4a
Author: Robert Ancell <robert ancell canonical com>
Date:   Tue Apr 22 14:33:45 2014 +1200

    Correct generation of PDF trailer to conform to the PDF standard.

 src/book.vala        |   17 +++++++++++++----
 src/simple-scan.vala |   26 ++++++++++++++++++++------
 2 files changed, 33 insertions(+), 10 deletions(-)
---
diff --git a/src/book.vala b/src/book.vala
index 4427393..981f5af 100644
--- a/src/book.vala
+++ b/src/book.vala
@@ -204,6 +204,11 @@ public class Book
 
     private void save_pdf (File file, int quality) throws Error
     {
+        /* Generate a random ID for this file */
+        var id = "";
+        for (var i = 0; i < 4; i++)
+            id += "%08x".printf (Random.next_int ());
+
         var stream = file.replace (null, false, FileCreateFlags.NONE, null);
         var writer = new PDFWriter (stream);
 
@@ -219,6 +224,7 @@ public class Book
         writer.write_string ("<<\n");
         writer.write_string ("/Type /Catalog\n");
         //FIXMEwriter.write_string ("/Metadata %u 0 R\n".printf (catalog_number + 1));
+        //FIXMEwriter.write_string ("/MarkInfo << /Marked true >>");
         writer.write_string ("/Pages %u 0 R\n".printf (catalog_number + 1)); //+2
         writer.write_string (">>\n");
         writer.write_string ("endobj\n");
@@ -449,7 +455,7 @@ public class Book
             number = writer.start_object ();
             writer.write_string ("%u 0 obj\n".printf (number));
             writer.write_string ("<<\n");
-            writer.write_string ("/Length %d\n".printf (command.length + 1));
+            writer.write_string ("/Length %d\n".printf (command.length));
             writer.write_string (">>\n");
             writer.write_string ("stream\n");
             writer.write_string (command);
@@ -470,19 +476,22 @@ public class Book
         writer.write_string ("endobj\n");
 
         /* Cross-reference table */
+        writer.write_string ("\n");
         var xref_offset = writer.offset;
         writer.write_string ("xref\n");
-        writer.write_string ("1 %zu\n".printf (writer.object_offsets.length ()));
+        writer.write_string ("0 %zu\n".printf (writer.object_offsets.length () + 1));
+        writer.write_string ("0000000000 65535 f \n");
         foreach (var offset in writer.object_offsets)
             writer.write_string ("%010zu 00000 n \n".printf (offset));
 
         /* Trailer */
+        writer.write_string ("\n");
         writer.write_string ("trailer\n");
         writer.write_string ("<<\n");
-        writer.write_string ("/Size %zu\n".printf (writer.object_offsets.length ()));
+        writer.write_string ("/Size %zu\n".printf (writer.object_offsets.length () + 1));
         writer.write_string ("/Info %u 0 R\n".printf (info_number));
         writer.write_string ("/Root %u 0 R\n".printf (catalog_number));
-        //FIXME: writer.write_string ("/ID [<...> <...>]\n");
+        writer.write_string ("/ID [<%s> <%s>]\n".printf (id, id));
         writer.write_string (">>\n");
         writer.write_string ("startxref\n");
         writer.write_string ("%zu\n".printf (xref_offset));
diff --git a/src/simple-scan.vala b/src/simple-scan.vala
index 689ab36..5839bb9 100644
--- a/src/simple-scan.vala
+++ b/src/simple-scan.vala
@@ -463,8 +463,8 @@ public class SimpleScan : Gtk.Application
         var line_number = 0;
         var xref_offset = 0;
         var xref_line = -1;
-        var xref_regex = new Regex ("^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d 0000 n$", RegexCompileFlags.RAW);
-        MatchInfo xref_match;
+        var startxref_line = -1;
+        var fixed_size = -1;
         var line = new StringBuilder ();
         while (offset < data.length)
         {
@@ -480,6 +480,9 @@ public class SimpleScan : Gtk.Application
             }
 
             if (line.str == "startxref\n")
+                startxref_line = line_number;
+
+            if (line.str == "xref\n")
                 xref_line = line_number;
 
             /* Fix PDF header and binary comment */
@@ -489,16 +492,27 @@ public class SimpleScan : Gtk.Application
                 fixed_file.printf ("%s", line.str.substring (1));
             }
 
+            /* Fix xref subsection count */
+            else if (line_number == xref_line + 1 && line.str.has_prefix ("1 "))
+            {
+                fixed_size = int.parse (line.str.substring (2)) + 1;
+                fixed_file.printf ("0 %d\n", fixed_size);
+                fixed_file.printf ("0000000000 65535 f \n");
+            }
+
             /* Fix xref format */
-            else if (xref_regex.match (line.str, 0, out xref_match))
-                fixed_file.printf ("%010d 00000 n \n", int.parse (xref_match.get_string ()) + xref_offset);
+            else if (line_number > xref_line && line.str.has_suffix (" 0000 n\n"))
+                fixed_file.printf ("%010d 00000 n \n", int.parse (line.str) + xref_offset);
 
             /* Fix xref offset */
-            else if (xref_line > 0 && line_number == xref_line + 1)
+            else if (startxref_line > 0 && line_number == startxref_line + 1)
                 fixed_file.printf ("%d\n".printf (int.parse (line.str) + xref_offset));
 
+            else if (fixed_size > 0 && line.str.has_prefix ("/Size "))
+                fixed_file.printf ("/Size %d\n".printf (fixed_size));
+
             /* Fix EOF marker */
-            else if (line_number == xref_line + 2 && line.str.has_prefix ("%%%%"))
+            else if (line_number == startxref_line + 2 && line.str.has_prefix ("%%%%"))
                 fixed_file.printf ("%s", line.str.substring (2));
 
             else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]