Trick for FPDI free pdf parser that supports PDF version above 1.4
5
up 25 down 5
Already voted!

Trick for FPDI free pdf parser that supports PDF version above 1.4

One of our website visitor asked a question –

Is there any free/open-source for FPDI free Pdf parser to make it compatible with PDF version higher than 1.4 ?

Starting from the introduction of FDPI , it’s a collection of PHP classes allowing developers to read pages from PDF files & use them as templates in FPDF package, which was developed by Olivier Plathey. Apart from a copy of FPDF, FPDI doesn’t require any special PHP extensions. For encrypting PDF files FDPI with FDPF and FDPI-protection package is required.

Directly coming to the point , By default FPDI pdf-parser can “only” handle PDF documents up to PDF version 1.4. With PDF version 1.5 there were new compression features introduced which involve changes in internal structure of a PDF document. Commercial version of FPDI PDF-parser supporting PDF document above 1.4 is available at Setasign but as said its commercial version and ask for payment.
There are many developers who may want to Encrypt PDF (version above 1.4) from free version of FPDI PDF parser but FPDI free PDF parser doesn’t support it and display one of the following error messages like –

PHP Fatal error: Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings

PHP Fatal error: Uncaught exception 'Exception' with message 'This document (/tmp/document.pdf) probably uses a compression technique which is not supported by the free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)' in /FPDI-1.5.2/pdf_parser.php:329

[... 11:01:06 2015] [error] [client 333.333.333.333] PHP Fatal error:
Uncaught exception 'Exception' with message 'This document (/tmp/label_55a780e22172f.pdf) probably uses a compression technique which is not supported by the free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)' in
...lib/FPDI-1.5.2/pdf_parser.php:329
Stack trace:
#0 ...lib/FPDI-1.5.2/pdf_parser.php(202): pdf_parser->_readXref(Array, 87345)
#1 ...lib/FPDI-1.5.2/fpdi_pdf_parser.php(71): pdf_parser->__construct('/tmp/...')
#2 ...lib/FPDI-1.5.2/fpdi.php(128): fpdi_pdf_parser->__construct('/tmp/..')
#3 ...lib/FPDI-1.5.2/fpdi.php(108): FPDI->_getPdfParser('/tmp/...')
#4 ...php/utils/concatpdf.class.php(37): FPDI->setSourceFile('/tmp/...')
#5 ...php/utils/shipping/provider in ...lib/FPDI-1.5.2/pdf_parser.php on line 329

Indeed getting a code trick and making a free tool compatible for our premium need is much better idea than buying a commercial version of tool. Think like a real smart developer and you will get the code idea of what you want to get done.

Indeed , the simplest way is to convert the PDF file version before it is submitted to FDPI pdf parser. we need to first check the PDF version of file with a PHP code.

// pdf version information
$filepdf = fopen("document.pdf","r");
if ($filepdf) {
$line_first = fgets($filepdf);
fclose($filepdf);
} else{
echo "error opening the file.";
}

PDF version of file is mostly present in first line of PDF. so we need to read the first line of PDF which will give us something like below response stored in a variable $line_first when using above PHP code –

%PDF-1.5%

Here we get the PDF version but we need to separate version number(1.5) from complete line %PDF-1.5%. so extracting the number from variable $line_first and storing the numeric value in variable $pdfversion using below code.

// extract number such as 1.4 ,1.5 from first read line of pdf file
preg_match_all('!\d+!', $line_first, $matches);
// save that number in a variable
$pdfversion = implode('.', $matches[0]);

we need to now compare the PDF version of submitted file from 1.4 in such away that if value of variable $pdfversion is greater than 1.4 than proceed with if condition otherwise proceed with else condition.

<?php>
if($pdfversion > "1.4"){
// proceed if PDF version greater than 1.4
// convert with ghostscript to version 1.4
// continue with FPDI + FDPF + FDPI PROTECTION
}
else{
// proceed if PDF version upto 1.4
// continue with FPDI + FDPF + FDPI PROTECTION}
<?>

Here we get the PDF version in “only” numeric value stored in a variable/string , as we know very well that free PDF parser only support PDF file upto version 1.4 , so now its time to implement the main logic of converting our PDF file(version above 1.4) into PDF version 1.4 using GHOSTSCRIPT command line. Please make sure that GHOSTSCRIPT is already installed on your server.

use the below command line GHOSTSCRIPT code under PHP exec()

// USE GHOSTSCRIPT IF PDF VERSION ABOVE 1.4 AND SAVE ANY PDF TO VERSION 1.4 , SAVE NEW PDF OF 1.4 VERSION TO NEW LOCATION 
<?php
exec('gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="'.$srcfile_new.'" "'.$srcfile.'"');
?>

Example Code:

<?php
// Report all errors
error_reporting(E_ALL);
ini_set('display_errors', true);

$random = rand(1,10000);

// get name of pdf file , send name from ajax on other side and received here
$filename = $_POST['filenamepdf'];

// compete path location of pdf file
$srcfile = 'pdf-uploaded/'.$filename;

// new path location of new pdf file created by ghostscript if file above 1.4
$srcfile_new = 'pdf-compatible/'.$filename;

// path location of saved encrypted pdf file by fdpi
$dest_file = 'pdf-encrypted/encrypted-'.$random.'.pdf';

// read pdf file first line because pdf first line contains
// pdf version information
$filepdf = fopen($srcfile,"r");
if ($filepdf) {
$line_first = fgets($filepdf);
fclose($filepdf);
} else{
echo "error opening the file.";
}

// extract number such as 1.4 ,1.5 from first read line of pdf file
preg_match_all('!\d+!', $line_first, $matches);

// save that number in a variable
$pdfversion = implode('.', $matches[0]);

// compare that number from 1.4(if greater than proceed with ghostscript)
if($pdfversion > "1.4"){
// USE GHOSTSCRIPT IF PDF VERSION ABOVE 1.4 AND SAVE ANY PDF TO VERSION 1.4 , SAVE NEW PDF OF 1.4 VERSION TO NEW LOCATION
shell_exec('gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="'.$srcfile_new.'" "'.$srcfile.'"');

// use now fpdi with pdf parser and fpdi protection
require_once('fpdi/FPDI_Protection.php');
$pdf = new \FPDI_Protection();
$pagecount = $pdf->setSourceFile($srcfile_new);

for ($loop = 1; $loop <= $pagecount; $loop++) {
$tplidx = $pdf->importPage($loop);
$pdf->addPage();
$pdf->useTemplate($tplidx);
}

$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, "password");
//$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, '123456', 'ABCDEF');

$pdf->Output($dest_file, 'F');

}else{

// use FPDI if pdf version upto 1.4 no need for ghostscript
require_once('fpdi/FPDI_Protection.php');
$pdf = new \FPDI_Protection();
$pagecount = $pdf->setSourceFile($srcfile);

for ($loop = 1; $loop <= $pagecount; $loop++) {
$tplidx = $pdf->importPage($loop);
$pdf->addPage();
$pdf->useTemplate($tplidx);
}

$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, "password");
//$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, '123456', 'ABCDEF');

$pdf->Output($dest_file, 'F');
}
?>

From below You can generate the download link for complete zip for Encrypting any version of PDF files (Includes FPDI + FPDI-protection + FDPF). After generating the link, it will expire in 1 hour. Once expired, you need to re-generate it again in order to download zip.

Generate Download link

Subscribe right now for new blogs notifications and always stay connected with us. please click here

5 thoughts on “Trick for FPDI free pdf parser that supports PDF version above 1.4”

  • Jason

    Thanks for sharing, the information came in very useful in a small project I am working on. 🙂

    • webnius_admin

      Jason , thank you too for your positive comment. Myself shoaib and Let me know anytime if I can help you for your any project issue. you can contact me anytime via email / skype.

    • webnius_admin

      muyideen mohammed , it was a server fault and we have fixed it. The download link has started working. you can please try downloading the source code now.

  • jérome

    thank you for sharing your trick !

Something To Say ?

Your email address will not be published. Required fields are marked *

*