Skip to main content
edited body
Source Link
zwol
  • 7.5k
  • 3
  • 21
  • 33

If you don't use PDF 1.5 object and cross-reference streams (which has the advantage that the file can be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...), and that there is not supposed to be a final newline after the %%EOF.)

If you don't use PDF 1.5 object and cross-reference streams (which has the advantage that the file can be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<..., and that there is not supposed to be a final newline after the %%EOF.)

If you don't use PDF 1.5 object and cross-reference streams (which has the advantage that the file can be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...), and that there is not supposed to be a final newline after the %%EOF.

added 1628 characters in body
Source Link
zwol
  • 7.5k
  • 3
  • 21
  • 33

This is the best I can do: 317 bytes. Use ofIf you don't use PDF 1.5 features like object and cross-reference streams actually winds up making this bigger, partly because of compression overhead and partly because qpdf doesn't do whitespace minimization and insists on including /ID in(which has the trailer. Conveniently, sticking to 1.4 and not using any compression meansadvantage that the file iscan be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<..., and that there is not supposed to be a final newline after the %%EOF.)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

Replacing the cross-reference table with a manually crafted v1.5 cross-reference stream does make the file slightly smaller, at the price of its no longer being printable ASCII: 294 bytes. (For the sake of readability, not to mention being able to type it in at all, the xref stream below has been hexdumped, but this is not reflected in its stream dictionary. To recover a valid PDF you must either replace the hexdump with the corresponding raw binary bytes, or change /Length 15 to /Length 30/Filter/ASCIIHexDecode and accept a file that is 328 bytes long.)

%PDF-1.5 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj 4 0 obj<</Type/XRef/Size 5/W[1 1 1]/Root 1 0 R/Length 15>>stream 0000ff01090001340001650001b200endstream endobj startxref 178 %%EOF 

I also experimented with wrapping objects 1 through 3 into an object stream, but this adds back more overhead than it saves, even when the stream is compressed.

A possible alternative formulation of the xref stream is

4 0 obj<</Type/XRef/Size 4/W[0 1 0]/Index[1 4]/Root 1 0 R/Length 4>>stream 091365b2endstream endobj 

Sadly, despite the substantial savings in the length of the actual stream data, the additional /Index[1 4] eats up all but one byte of the savings. Also, it is unclear to me whether you're allowed to leave object 0 completely out of the file. (It's also unclear to me whether object 0 must have generation number -1. If that's not required, you actually save more bytes with

4 0 obj<</Type/XRef/Size 5/W[1 1 0]/Root 1 0 R/Length 10>>stream 000001090134016501b2endstream endobj 

.)

This is the best I can do: 317 bytes. Use of PDF 1.5 features like object and cross-reference streams actually winds up making this bigger, partly because of compression overhead and partly because qpdf doesn't do whitespace minimization and insists on including /ID in the trailer. Conveniently, sticking to 1.4 and not using any compression means that the file is completely printable ASCII. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

If you don't use PDF 1.5 object and cross-reference streams (which has the advantage that the file can be completely printable ASCII) I believe the best you can do is 317 bytes. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<..., and that there is not supposed to be a final newline after the %%EOF.)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

Replacing the cross-reference table with a manually crafted v1.5 cross-reference stream does make the file slightly smaller, at the price of its no longer being printable ASCII: 294 bytes. (For the sake of readability, not to mention being able to type it in at all, the xref stream below has been hexdumped, but this is not reflected in its stream dictionary. To recover a valid PDF you must either replace the hexdump with the corresponding raw binary bytes, or change /Length 15 to /Length 30/Filter/ASCIIHexDecode and accept a file that is 328 bytes long.)

%PDF-1.5 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj 4 0 obj<</Type/XRef/Size 5/W[1 1 1]/Root 1 0 R/Length 15>>stream 0000ff01090001340001650001b200endstream endobj startxref 178 %%EOF 

I also experimented with wrapping objects 1 through 3 into an object stream, but this adds back more overhead than it saves, even when the stream is compressed.

A possible alternative formulation of the xref stream is

4 0 obj<</Type/XRef/Size 4/W[0 1 0]/Index[1 4]/Root 1 0 R/Length 4>>stream 091365b2endstream endobj 

Sadly, despite the substantial savings in the length of the actual stream data, the additional /Index[1 4] eats up all but one byte of the savings. Also, it is unclear to me whether you're allowed to leave object 0 completely out of the file. (It's also unclear to me whether object 0 must have generation number -1. If that's not required, you actually save more bytes with

4 0 obj<</Type/XRef/Size 5/W[1 1 0]/Root 1 0 R/Length 10>>stream 000001090134016501b2endstream endobj 

.)

added 211 characters in body
Source Link
zwol
  • 7.5k
  • 3
  • 21
  • 33

Like the smallest possible GIF, the smallest possible blank-page PDF needs to be worked out by hand, because it's so small that unnecessary-but-harmless bits of metadata become a significant part of the file size, and compression actually makes things bigger. It also requires careful attention to the rules in the PDF specification about what bits of the file structure are and are not required. (Did you know that page objects must contain a /Resources dictionary, even if it's empty, but are not required to include a /Contents stream?)

This is the best I can do: 317 bytes. Use of PDF 1.5 features like object and cross-reference streams actually winds up making this bigger, partly because of compression overhead and partly because qpdf doesn't do whitespace minimization and insists on including /ID in the trailer. Conveniently, sticking to 1.4 and not using any compression means that the file is completely printable ASCII. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

To change the paper size, replace 612 792 with the appropriate width and height, expressed in PostScript points (72 PostScript points = 1 U.S. inch or 25.4 millimeters). For instance, 595 842 for A4. You could embed this in a shell script that spits out a blank PDF of whatever paper size is desired; the only tricky part would be making sure that the startxref offset remained accurate even if the size of object 3 changed.

Like the smallest possible GIF, the smallest possible blank-page PDF needs to be worked out by hand, because it's so small that unnecessary-but-harmless bits of metadata become a significant part of the file size, and compression actually makes things bigger. It also requires careful attention to the rules in the PDF specification about what bits of the file structure are and are not required. (Did you know that page objects must contain a /Resources dictionary, even if it's empty, but are not required to include a /Contents stream?)

This is the best I can do: 317 bytes. Use of PDF 1.5 features like object and cross-reference streams actually winds up making this bigger, partly because of compression overhead and partly because qpdf doesn't do whitespace minimization and insists on including /ID in the trailer. Conveniently, sticking to 1.4 and not using any compression means that the file is completely printable ASCII. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

To change the paper size, replace 612 792 with the appropriate width and height, expressed in PostScript points (72 PostScript points = 1 U.S. inch or 25.4 millimeters). For instance, 595 842 for A4.

Like the smallest possible GIF, the smallest possible blank-page PDF needs to be worked out by hand, because it's so small that unnecessary-but-harmless bits of metadata become a significant part of the file size, and compression actually makes things bigger. It also requires careful attention to the rules in the PDF specification about what bits of the file structure are and are not required. (Did you know that page objects must contain a /Resources dictionary, even if it's empty, but are not required to include a /Contents stream?)

This is the best I can do: 317 bytes. Use of PDF 1.5 features like object and cross-reference streams actually winds up making this bigger, partly because of compression overhead and partly because qpdf doesn't do whitespace minimization and insists on including /ID in the trailer. Conveniently, sticking to 1.4 and not using any compression means that the file is completely printable ASCII. If copying and pasting, take note that there needs to be a trailing space on all four of the cross-reference table entries (the lines between 0 4 and trailer<<...)

%PDF-1.4 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Count 1/Kids[3 0 R]>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<<>>>>endobj xref 0 4 0000000000 65535 f 0000000009 00000 n 0000000052 00000 n 0000000101 00000 n trailer<</Size 4/Root 1 0 R>> startxref 178 %%EOF 

To change the paper size, replace 612 792 with the appropriate width and height, expressed in PostScript points (72 PostScript points = 1 U.S. inch or 25.4 millimeters). For instance, 595 842 for A4. You could embed this in a shell script that spits out a blank PDF of whatever paper size is desired; the only tricky part would be making sure that the startxref offset remained accurate even if the size of object 3 changed.

Source Link
zwol
  • 7.5k
  • 3
  • 21
  • 33
Loading