From 85dd7714a1dea6fe87817473e4a8ab50dc8f38bc Mon Sep 17 00:00:00 2001 From: deep-soft Date: Thu, 4 Sep 2025 20:20:07 +0300 Subject: [PATCH 1/3] fpc Allow compilation with fpc (windows and linux). Not the last version but code was tested on this 2.02 version with fpc 3.2.2. --- PdfPageCount.pas | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/PdfPageCount.pas b/PdfPageCount.pas index 3dd041e..8896554 100644 --- a/PdfPageCount.pas +++ b/PdfPageCount.pas @@ -3,14 +3,14 @@ (******************************************************************************* * Author : Angus Johnson * * Version : 2.02 * -* Date : 26 April 2023 * +* Date : 26 April 2023 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2022 * * License : http://www.boost.org/LICENSE_1_0.txt * *******************************************************************************) //////////////////////////////////////////////////////////////////////////////// -// Summary of steps taken to parse a PDF doc for its page count :-   +// Summary of steps taken to parse a PDF doc for its page count :-   //////////////////////////////////////////////////////////////////////////////// //1. See if there's a 'Linearization dictionary' for easy parsing. // Mostly there isn't so ... @@ -31,7 +31,17 @@ interface uses - Windows, SysUtils, Classes, AnsiStrings, ZLib; +{$IFNDEF LINUX} + Windows, +{$ENDIF} + SysUtils, + Classes, +{$IFNDEF FPC} + AnsiStrings, + ZLib; +{$ELSE} + PasZLib; +{$ENDIF} const PDF_NO_ERROR = 0; @@ -39,6 +49,7 @@ interface PDF_ERROR_FILE_OPEN = -2; PDF_ERROR_FILE_FORMAT = -3; PDF_ERROR_ENCRYPTED_STRM = -4; + PDF_ERROR_NO_INDEX = -5; (******************************************************************************* * GetPageCount * @@ -102,8 +113,11 @@ TPdfPageCounter = class // Miscellaneous functions //------------------------------------------------------------------------------ -procedure QuickSortList(SortList: TPointerList; - L, R: Integer; sortFunc: TSortFunc); +{$IFDEF FPC} +procedure QuickSortList(SortList: PPointerList; L, R: Integer; sortFunc: TSortFunc); +{$ELSE} +procedure QuickSortList(SortList: TPointerList; L, R: Integer; sortFunc: TSortFunc); +{$ENDIF} var I, J: Integer; P, T: Pointer; @@ -692,12 +706,16 @@ function TPdfPageCounter.DecompressObjIntoBuffer(objNum, genNum: integer): boole try //decompress the stream ... +{$IFDEF FPC} + uncompress(pointer(buffer), cardinal(bufferSize), PChar(p), cardinal(len)); +{$ELSE} //nb: I'm not sure in which Delphi version these functions were renamed. {$IFDEF UNICODE} zlib.ZDecompress(p, len, pointer(buffer), bufferSize); {$ELSE} zlib.DecompressBuf(p, len, len*3, pointer(buffer), bufferSize); {$ENDIF} +{$ENDIF} except ErrorFlag := PDF_ERROR_ENCRYPTED_STRM; buffer := nil; @@ -727,7 +745,12 @@ function TPdfPageCounter.FindStartXRef: boolean; 'f': dec(p, 8); 'e': dec(p, 7); 'x': dec(p, 5); 'r': dec(p, 3); 'a': dec(p, 2); 't': dec(p, 1); 's': + +{$IFDEF FPC} + if StrLComp(p, 'startxref', 9) = 0 then +{$ELSE} if AnsiStrings.StrLComp(p, 'startxref', 9) = 0 then +{$ENDIF} begin result := true; inc(p, 9); @@ -749,7 +772,11 @@ function TPdfPageCounter.GetLinearizedPageNum(out pageNum: integer): boolean; result := false; pStop := p + 32; while (p < pStop) and (p^ <> 'o') do inc(p); +{$IFDEF FPC} + if StrLComp( p, 'obj', 3) <> 0 then exit; +{$ELSE} if AnsiStrings.StrLComp( p, 'obj', 3) <> 0 then exit; +{$ENDIF} pStart := p; if not FindStrInDict('/Linearized') then exit; p := pStart; @@ -819,6 +846,7 @@ function TPdfPageCounter.GetPageNumUsingCrossRefStream: integer; //if the Index array is empty then use the default values ... if length(indexArray) = 0 then begin + Result := PDF_ERROR_NO_INDEX; setLength(indexArray, 2); indexArray[0] := 0; indexArray[1] := bufferSize div (w1 + w2 + w3); @@ -868,7 +896,8 @@ function TPdfPageCounter.GetPageNumUsingCrossRefStream: integer; DisposeBuffer; if rootNum < 0 then exit; - QuickSortList(PdfObjList.List, 0, PdfObjList.Count -1, ListSort); + if PdfObjList.Count > 1 then + QuickSortList(PdfObjList.List, 0, PdfObjList.Count -1, ListSort); if not GotoObject(rootNum) then exit; if not FindStrInDict('/Pages') then exit; //get the Pages' object number, go to it and get the page count ... @@ -920,7 +949,11 @@ function TPdfPageCounter.GetPdfPageCount(const filename: string): integer; (k >= ms.size) then exit; p := PAnsiChar(ms.Memory) + k; +{$IFDEF FPC} + if StrLComp(p, 'xref', 4) <> 0 then +{$ELSE} if AnsiStrings.StrLComp(p, 'xref', 4) <> 0 then +{$ENDIF} begin //'xref' table not found so assume the doc contains //a cross-reference stream instead (ie PDF doc ver 1.5+) @@ -975,7 +1008,8 @@ function TPdfPageCounter.GetPdfPageCount(const filename: string): integer; //Make sure we've got Root's object number ... if rootNum < 0 then exit; - QuickSortList(PdfObjList.List, 0, PdfObjList.Count -1, ListSort); + if PdfObjList.Count > 1 then + QuickSortList(PdfObjList.List, 0, PdfObjList.Count -1, ListSort); if not GotoObject(rootNum) then exit; if not FindStrInDict('/Pages') then exit; From 4f8ce7dfed52d4fa8f6c2682e2858e1d5f037c30 Mon Sep 17 00:00:00 2001 From: deep-soft Date: Mon, 29 Sep 2025 15:56:58 +0300 Subject: [PATCH 2/3] uncompress realloc - in PasZlib.pas uncompress does not allocate buffer as in zlib.pas - reallocate 64MB for buffer - need rework to allocate exact size for uncompressed data --- PdfPageCount.pas | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PdfPageCount.pas b/PdfPageCount.pas index 8896554..95c3e40 100644 --- a/PdfPageCount.pas +++ b/PdfPageCount.pas @@ -61,6 +61,9 @@ function GetPageCount(const filename: string): integer; implementation +const + MAX_buffer_Size = 64*1024*1024; + type PPdfObj = ^TPdfObj; @@ -707,6 +710,8 @@ function TPdfPageCounter.DecompressObjIntoBuffer(objNum, genNum: integer): boole try //decompress the stream ... {$IFDEF FPC} + bufferSize := MAX_buffer_Size; + ReallocMem(buffer, bufferSize); uncompress(pointer(buffer), cardinal(bufferSize), PChar(p), cardinal(len)); {$ELSE} //nb: I'm not sure in which Delphi version these functions were renamed. @@ -1049,3 +1054,4 @@ function GetPageCount(const filename: string): integer; //------------------------------------------------------------------------------ end. + From 166dc35fcace49c4880c17f8f2321582545a532e Mon Sep 17 00:00:00 2001 From: deep-soft Date: Tue, 2 Dec 2025 11:45:09 +0200 Subject: [PATCH 3/3] Update PdfPageCount.pas add MD5 --- PdfPageCount.pas | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PdfPageCount.pas b/PdfPageCount.pas index e16bef4..030e2b1 100644 --- a/PdfPageCount.pas +++ b/PdfPageCount.pas @@ -38,10 +38,11 @@ interface Classes, {$IFNDEF FPC} AnsiStrings, - ZLib; + ZLib, {$ELSE} - PasZLib; + PasZLib, {$ENDIF} + MD5; const PDF_NO_ERROR = 0; @@ -1162,3 +1163,4 @@ function GetPageCount(const filename: string): integer; end. +