diff --git a/PdfPageCount.pas b/PdfPageCount.pas index c955612..030e2b1 100644 --- a/PdfPageCount.pas +++ b/PdfPageCount.pas @@ -10,7 +10,7 @@ *******************************************************************************) //////////////////////////////////////////////////////////////////////////////// -// 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,18 @@ interface uses - Windows, SysUtils, Classes, AnsiStrings, ZLib, Md5; +{$IFNDEF LINUX} + Windows, +{$ENDIF} + SysUtils, + Classes, +{$IFNDEF FPC} + AnsiStrings, + ZLib, +{$ELSE} + PasZLib, +{$ENDIF} + MD5; const PDF_NO_ERROR = 0; @@ -39,6 +50,7 @@ interface PDF_ERROR_FILE_OPEN = -2; PDF_ERROR_FILE_FORMAT = -3; PDF_ERROR_ENCRYPTED_STRM = -4; + PDF_ERROR_NO_INDEX = -5; (******************************************************************************* * GetPageCount * @@ -51,6 +63,9 @@ function GetPageCount(const filename: string): integer; overload; implementation +const + MAX_buffer_Size = 64*1024*1024; + type PPdfObj = ^TPdfObj; @@ -116,8 +131,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; @@ -777,12 +795,18 @@ 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. {$IFDEF UNICODE} zlib.ZDecompress(p, len, pointer(buffer), Integer(bufferSize)); {$ELSE} zlib.DecompressBuf(p, len, len*3, pointer(buffer), Integer(bufferSize)); {$ENDIF} +{$ENDIF} except ErrorFlag := PDF_ERROR_ENCRYPTED_STRM; DisposeBuffer; @@ -811,7 +835,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); @@ -833,7 +862,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; @@ -902,6 +935,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); @@ -950,7 +984,8 @@ function TPdfPageCounter.GetPageNumUsingCrossRefStream: integer; DisposeBuffer; - 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 ... @@ -1002,7 +1037,11 @@ function TPdfPageCounter.GetPdfPageCount(stream: TStream): 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+) @@ -1057,7 +1096,8 @@ function TPdfPageCounter.GetPdfPageCount(stream: TStream): integer; //Make sure we've got Root's object number ... if rootNum = $FFFFFFFF 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; @@ -1122,3 +1162,5 @@ function GetPageCount(const filename: string): integer; //------------------------------------------------------------------------------ end. + +