(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *) unit wpcubed_pdf_plugin; // -------------------------------------------------------------------- // This unit integrates the WPCUBED PDF render component into ImageEn // It can be used with WPViewPDF V4.32 or later in // the editions "MakeImage", "Standard" and "Plus" // // MakeImage: this edition supports the method pdfMakeImageExt // to convert PDF pages to bitmaps only // Standard: PDF Display, Print // PLUS: PDF Display, Print, merging, stamping // // Written in July 2016 by Julian Ziersch // Copyright by WPCubed GmbH // // This source file may be distributed with ImageEn // The WPViewPDF Demo DLL may not be distributed. They can be downloaded // here: http://www.wpcubed.com // // Registered copies of WPViewPDF may be distributed with the // created applications which may not be modules of any kind. // -------------------------------------------------------------------- // Please purchase your WPViewPDF License at // www.wpcubed.com. There you can also download the current demo. // Please send questions and comments to support@wptools.de // -------------------------------------------------------------------- (* Usage: Add wpcubed_pdf_plugin to your uses clause and call this code: Then this variables need to be initailized, i.e. if TIEWPCubedPDF.Initialize then TIEWPCubedPDF.RegisterPlugin else ShowMessage('PDF decoder DLL could not be found'); at the end of your main unit please do this: {$I PDFLicense.INC} initialization glWPViewPDF_DLLName := WPViewPDF_DLLName; glWPViewPDF_DLLName64 := WPViewPDF_DLLName64; glWPViewPDF_LicName := WPViewPDF_LicName; glWPViewPDF_LicKey := WPViewPDF_LicKey; glWPViewPDF_LicCode := WPViewPDF_LicCode; (The WPViewPDF DLL name and the license code is defined in the file PDFLicense.INC) *) {-$DEFINE WPVIEW_AUTOINIT} // If defined, explicit call of TIEWPCubedPDF.RegisterPlugin is not required. interface uses Windows, Messages, Classes, Graphics, SysUtils, Forms, Math, // ImageEn units hyiedefs, imageenproc, hyieutils, iesettings, imageenio, iexBitmaps; {--$I ie.inc} {$DEFINE IEINCLUDEMISCPLUGINS} {--$I PDFLicense.INC} // contains DLLname and License for WPViewPDF {$IFDEF IEINCLUDEMISCPLUGINS} const THUMB_SIZE = 250; // Desired size of a thumbnail (size of large side) (* class to load the wpcubed_pdf plugin to be used by ImageEn *) type PDFException = Exception; TIEWPCubedPDF = class public class function IsAvailable(): boolean; class function Initialize( reinitialize: boolean = false; // Force Reload WPViewPDF_DLLFilePath : String = '' // Optional: Full qualified path to WPViewPDF DLL ) : Boolean; class procedure Finalize(); class procedure RegisterPlugin(); end; var // This variables need to be initialized glWPViewPDF_DLLName : String = 'UNDEF'; glWPViewPDF_DLLName64 : String; glWPViewPDF_LicName : String; glWPViewPDF_LicKey : String; glWPViewPDF_LicCode : Integer; implementation uses ActiveX, AxCtrls, CommCtrl, ComObj, ComCtrls, iemiscplugins; type fktpdfMakeImageExt = function( InStream : IUnknown; // Load PDF from here. OutStream : IUnknown; // Save the image data here filename : PWideChar; // Not used if InStream was specified PageCount : PInteger; // Receives count of pages in PDF password : PWideChar; // Password for the PDF licname, lickey: PWideChar; liccode: Cardinal; destpath: PWideChar; // Not used except to specify format // if OutStream was specified (Use %d store page number) frompage, to_page: Integer; // If OutStream was specified only one page is written imageres : Integer; // The resolution, i.e. 200 // or HighWord=Height, LowWord=Width of desired image size. // The bitmap will fit into the specified rectangle imagemode : Integer // This is a bit field // Bit 1 (1) : BW Image // Bit 2 (2) : Grayscale Image - default 24 bit color Image // Bit 3 (4) : Reserved // Bit 4 (8) : Reserved // .... // Bit 16 (32768): Special Stream Mode. // If active, multiple images will be saved to the stream. // This header will be used // INTEGER = total size of data (=StreamSize) // INTEGER = Count of Images // INTEGER[Count of Images] = Offset of each Image // If the Offset is 0, the image is empty. // The Length of the image data can be calculated as difference of the following // or, for the last image, the stream size ): Integer; stdcall; var wpcubed_pdfMakeImageExt: fktpdfMakeImageExt; wpcubed_PDFDLLHandle: HMODULE; // HMODULE=NativeUInteger! { Read image from PDF stream into Bitmap Stream: Can be either a TMemoryStream or a TIEWideFileStream (file) Progress: Provide loading progress feedback Preview: If true, we only want PageCount to be filled. Read from IOParams: ImageIndex: The index of the page to load DpiX : DPI of the image Written to IOParams: ImageCount: Number of pages for a multi-page image, such as TIFF or PDF, otherwise 1 } procedure WPViewPDF_ReadImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec; Preview: boolean); var InAdapter, OutAdapter: TStreamAdapter; filename, os: WideString; password : WideString; PageCount: Integer; InStream, OutStream : IUnknown; outmstream : TMemoryStream; aBitmap : TBitmap; res: Integer; ImageResolution : Integer; begin if TIEWPCubedPDF.IsAvailable() then begin if Stream is TIEWideFileStream then begin filename := (Stream as TIEWideFileStream).FileName; InAdapter := nil; InStream := nil; end else begin InAdapter := TStreamAdapter.Create(Stream); filename := ''; InStream := InAdapter as IStream; end; outmstream := TMemoryStream.Create; OutAdapter := TStreamAdapter.Create(outmstream); OutStream := OutAdapter as IStream; aBitmap := TBitmap.Create; try if Preview then os := 'page.XXX' // Do not create a bitmap, just read the page count else os := 'page.bmp'; try if IOParams.GetThumbnail then ImageResolution := THUMB_SIZE shl 16 + THUMB_SIZE else ImageResolution := Max(IOParams.fDpiX, IOParams.fDpiY); if ImageResolution < 1 then ImageResolution := 300; password := ''; if IOParams.Dict.HasKey( 'PDF:Password' ) then password := IOParams.Dict.GetString( 'PDF:Password', true ); res := wpcubed_pdfMakeImageExt( InStream, OutStream, PWideChar(filename), @PageCount, PWideChar(password), PWideChar(glWPViewPDF_LicName), PWideChar(glWPViewPDF_LicKey), glWPViewPDF_LicCode, PWideChar(os), IOParams.ImageIndex+1, IOParams.ImageIndex+1, ImageResolution, 0 ); except res := -1; end; if (res >= 0) then begin IOParams.ImageCount := PageCount; if not Preview and (outmstream.Size>0) then begin outmstream.Position := 0; aBitmap.LoadFromStream(outmstream); Bitmap.CopyFromTBitmap(aBitmap); end; end else if res=-1 then raise PDFException.Create('Error in pdfMakeImageExt') else if res=-2 then raise PDFException.Create('Unexpected parameters for pdfMakeImageExt'); finally InStream := nil; OutStream:= nil; outmstream.Free; aBitmap.Free; end; end else Progress.Aborting^ := true; end; procedure WPViewPDF_WriteImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec); begin // NOT IMPLEMENTED // If you need to write to PDF please use WPViewPDF PLUS or wPDF. end; // Returns true if the image in Stream matches the format, TryingFormat function WPViewPDF_TryImageStream(Stream: TStream; TryingFormat: TIOFileType): boolean; const BUFSIZE = 10; // file head to analyse VAR buf : AnsiString; lpos: Int64; begin result := false; if TIEWPCubedPDF.IsAvailable() then begin lpos := Stream.Position; try SetLength(buf, BUFSIZE); Stream.Read(buf[1], BUFSIZE); if Pos('%PDF-', String( buf ))=1 then result := true; finally Stream.Position := lpos; end; end; end; // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- class function TIEWPCubedPDF.IsAvailable(): boolean; begin Result := assigned(wpcubed_pdfMakeImageExt); end; class function TIEWPCubedPDF.Initialize(reinitialize: boolean = false; WPViewPDF_DLLFilePath : String = ''): boolean; var DLLName : String; begin if glWPViewPDF_DLLName = 'UNDEF' then raise Exception.Create('TIEWPCubedPDF requires this varaiables to be initialized:' + #13 + 'glWPViewPDF_DLLName,' + #13 + 'glWPViewPDF_DLLName64,' + #13 + 'glWPViewPDF_LicName,' + #13 + 'glWPViewPDF_LicKey' + #13 + 'and glWPViewPDF_LicCode from unit wpcubed_pdf_plugin.' ); if not reinitialize and (wpcubed_PDFDLLHandle<>0) and assigned(wpcubed_pdfMakeImageExt) then begin Result := true; exit; end; if wpcubed_PDFDLLHandle<>0 then begin FreeLibrary(wpcubed_PDFDLLHandle); wpcubed_pdfMakeImageExt := nil; wpcubed_PDFDLLHandle := 0; end; if WPViewPDF_DLLFilePath<>'' then DLLName := WPViewPDF_DLLFilePath else {$IFDEF WIN64} // The name is defined in PDFLicense.INC DLLName := ExtractFilePath(Application.ExeName) + glWPViewPDF_DLLName64; {$ELSE} DLLName := ExtractFilePath(Application.ExeName) + glWPViewPDF_DLLName; {$ENDIF} wpcubed_PDFDLLHandle := LoadLibrary(PChar(DLLName)); if wpcubed_PDFDLLHandle > 0 then begin wpcubed_pdfMakeImageExt := GetProcAddress(wpcubed_PDFDLLHandle, 'pdfMakeImageExt'); if not assigned(wpcubed_pdfMakeImageExt) then begin FreeLibrary(wpcubed_PDFDLLHandle); wpcubed_PDFDLLHandle := 0; end; end; Result := assigned(wpcubed_pdfMakeImageExt); end; class procedure TIEWPCubedPDF.Finalize(); begin if wpcubed_PDFDLLHandle<>0 then begin FreeLibrary(wpcubed_PDFDLLHandle); wpcubed_pdfMakeImageExt := nil; wpcubed_PDFDLLHandle := 0; end; end; class procedure TIEWPCubedPDF.RegisterPlugin(); const local_iomscWPPDF = iomscWPPDF; // ioMiscDLLPlugIns + 30; // must be synchronized with unit hyieutils begin // first remove native ImageEn and other PDF support IEFileFormatRemove( ioPDF ); IEFileFormatRemove( local_iomscWPPDF ); // Register the new format IEFileFormatAdd( TIEFileFormatInfo.Create(local_iomscWPPDF, // we only handle PDF 'Portable Document Format', 'PDF;PDFA;EPDF', 'pdf', false, [], @WPViewPDF_ReadImageStream, @WPViewPDF_WriteImageStream, @WPViewPDF_TryImageStream) ); end; initialization {$IFDEF WPVIEW_AUTOINIT} if TIEWPCubedPDF.Initialize then TIEWPCubedPDF.RegisterPlugin; {$ENDIF} finalization {$IFDEF WPVIEW_AUTOINIT} TIEWPCubedPDF.Finalize; {$ENDIF} {$ELSE} // not IEINCLUDEMISCPLUGINS implementation {$ENDIF} end.