BSOne.SFC/EM.Lib/ImageEn_SRC/Source/iemiscplugins.pas

1339 lines
56 KiB
Plaintext

(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *)
(*
Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved.
Copyright (c) 2011-2017 by Xequte Software.
This software comes without express or implied warranty.
In no case shall the author be liable for any damage or unwanted behavior of any
computer hardware and/or software.
Author grants you the right to include the component
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE.
ImageEn, IEvolution and ImageEn ActiveX may not be included in any
commercial, shareware or freeware libraries or components.
www.ImageEn.com
*)
(*
File version 1001
*)
unit iemiscplugins;
{$R-}
{$Q-}
{$J+}
{$Z4}
{$I ie.inc}
interface
uses
Windows, Messages, Classes, Graphics, SysUtils, hyiedefs, imageenio, hyieutils, iesettings, iexBitmaps;
{$IFDEF IEINCLUDEMISCPLUGINS}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// TIEMiscPluginsImageMagick
const iomscFITS = ioMiscDLLPlugIns + 1;
const iomscPCD = ioMiscDLLPlugIns + 2;
const iomscPCL = ioMiscDLLPlugIns + 3;
const iomscPDF = ioMiscDLLPlugIns + 4;
const iomscBIE = ioMiscDLLPlugIns + 5;
const iomscCIN = ioMiscDLLPlugIns + 6;
const iomscDDS = ioMiscDLLPlugIns + 7;
const iomscDFONT = ioMiscDLLPlugIns + 8;
const iomscDPX = ioMiscDLLPlugIns + 9;
const iomscJBIG = ioMiscDLLPlugIns + 10;
const iomscJNG = ioMiscDLLPlugIns + 11;
const iomscM2V = ioMiscDLLPlugIns + 12;
const iomscMAT = ioMiscDLLPlugIns + 13;
const iomscMIFF = ioMiscDLLPlugIns + 14;
const iomscMNG = ioMiscDLLPlugIns + 15;
const iomscMP4 = ioMiscDLLPlugIns + 16;
const iomscMSVG = ioMiscDLLPlugIns + 17;
const iomscPES = ioMiscDLLPlugIns + 18;
const iomscPS = ioMiscDLLPlugIns + 19;
const iomscPSB = ioMiscDLLPlugIns + 20;
const iomscPTIF = ioMiscDLLPlugIns + 21;
const iomscSVG = ioMiscDLLPlugIns + 22;
const iomscTIFF64 = ioMiscDLLPlugIns + 23;
const iomscXCF = ioMiscDLLPlugIns + 24;
const iomscXPS = ioMiscDLLPlugIns + 25;
const Min_ImageMagick_Type = iomscFITS;
const Max_ImageMagick_Type = iomscXPS;
const IEIMAGEMAGICK_WAND_DLL_FILENAMES: array [0..1] of WideString = ('CORE_RL_wand_.dll', 'CORE_RL_MagickWand_.dll');
const IEIMAGEMAGICK_MAGICK_DLL_FILENAMES: array [0..1] of WideString = ('CORE_RL_magick_.dll', 'CORE_RL_MagickCore_.dll');
type TIEImageMagick_MagickWand = pointer;
type TIEImageMagick_MagickBooleanType = longbool;
type TIEImageMagick_size_t = {$ifdef WIN64} uint64; {$else} dword; {$endif}
type TIEImageMagick_ssize_t = {$ifdef WIN64} int64; {$else} integer; {$endif}
type TIEImageMagick_MagickOffsetType = int64;
type TIEImageMagick_MagickSizeType = uint64;
type TIEImageMagick_MagicInfo = pointer;
type TIEImageMagick_ExceptionInfo = pointer;
type TIEImageMagick_ExceptionType = integer;
type TIEImageMagick_PixelWand = pointer;
type TIEImageMagick_StorageType = (
imck_UndefinedPixel,
imck_CharPixel,
imck_DoublePixel,
imck_FloatPixel,
imck_IntegerPixel,
imck_LongPixel,
imck_QuantumPixel,
imck_ShortPixel
);
type TIEImageMagick_ChannelType = (
imck_UndefinedChannel = 0,
imck_RedChannel = $0001,
imck_GrayChannel = $0001,
imck_CyanChannel = $0001,
imck_GreenChannel = $0002,
imck_MagentaChannel = $0002,
imck_BlueChannel = $0004,
imck_YellowChannel = $0004,
imck_AlphaChannel = $0008,
imck_OpacityChannel = $0008,
imck_MatteChannel = $0008,
imck_BlackChannel = $0020,
imck_IndexChannel = $0020,
imck_CompositeChannels = $002F,
imck_AllChannels = $7ffffff,
imck_TrueAlphaChannel = $0040,
imck_RGBChannels = $0080,
imck_GrayChannels = $0080,
imck_SyncChannels = $0100,
imck_DefaultChannels = $7FFFFF7
);
type TIEImageMagick_ColorspaceType = (
imck_UndefinedColorspace,
imck_RGBColorspace,
imck_GRAYColorspace,
imck_TransparentColorspace,
imck_OHTAColorspace,
imck_LabColorspace,
imck_XYZColorspace,
imck_YCbCrColorspace,
imck_YCCColorspace,
imck_YIQColorspace,
imck_YPbPrColorspace,
imck_YUVColorspace,
imck_CMYKColorspace,
imck_sRGBColorspace,
imck_HSBColorspace,
imck_HSLColorspace,
imck_HWBColorspace,
imck_Rec601LumaColorspace,
imck_Rec601YCbCrColorspace,
imck_Rec709LumaColorspace,
imck_Rec709YCbCrColorspace,
imck_LogColorspace,
imck_CMYColorspace,
imck_LuvColorspace,
imck_HCLColorspace,
imck_LCHColorspace,
imck_LMSColorspace,
imck_LCHabColorspace,
imck_LCHuvColorspace,
imck_scRGBColorspace,
imck_HSIColorspace,
imck_HSVColorspace,
imck_HCLpColorspace,
imck_YDbDrColorspace
);
type TIEImageMagick_ResolutionType = (
imck_UndefinedResolution,
imck_PixelsPerInchResolution,
imck_PixelsPerCentimeterResolution
);
type TIEImageMagick_ImageType = (
imck_UndefinedType,
imck_BilevelType,
imck_GrayscaleType,
imck_GrayscaleMatteType,
imck_PaletteType,
imck_PaletteMatteType,
imck_TrueColorType,
imck_TrueColorMatteType,
imck_ColorSeparationType,
imck_ColorSeparationMatteType,
imck_OptimizeType,
imck_PaletteBilevelMatteType
);
type TIEImageMagick_MagickProgressMonitor = function(text: PAnsiChar; offset: TIEImageMagick_MagickOffsetType; span: TIEImageMagick_MagickSizeType; client_data: pointer): TIEImageMagick_MagickBooleanType; cdecl;
procedure TIEMiscPluginsImageMagick_ReadImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec; Preview: boolean);
procedure TIEMiscPluginsImageMagick_WriteImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec);
function TIEMiscPluginsImageMagick_TryImageStream(Stream: TStream; TryingFormat: TIOFileType): boolean;
function TIEMiscPluginsImageMagick_PDFFrameCount(Stream: TStream): integer;
{!!
<FS>TIEMiscPluginsImageMagick
<FM>Declaration<FC>
TIEMiscPluginsImageMagick = class;
<FM>Description<FN>
TIEMiscPluginsImageMagick is a wrapper around ImageMagick library, allowing ImageEn to load many formats like PDF, PS, PCD and many others.
To setup ImageMagick wrapper just call, one time, the <A TIEMiscPluginsImageMagick.RegisterPlugin> class method.
You can download ImageMagick from:
<L http://www.imagemagick.org/script/binary-releases.php#windows>http://www.imagemagick.org/script/binary-releases.php#windows</L>
In order to load PDF, PS, PCL and you must install the Ghostscript library:
<L http://www.ghostscript.com/download/>http://www.ghostscript.com/download/</L>
<FM>Methods and Properties<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TIEMiscPluginsImageMagick.IsAvailable></C> </R>
<R> <C_IMG_METHOD> <C><A TIEMiscPluginsImageMagick.RegisterPlugin></C> </R>
</TABLE>
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\ImageMagick\ImageMagick.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// rasterizes page number 5 of mybook.pdf at 200dpi
TIEMiscPluginsImageMagick.RegisterPlugin(); // call only one time!
ImageEnView1.IO.Params.ImageIndex := 5;
ImageEnView1.IO.Params.Dict.Insert('PDF:Density', 200);
ImageEnView1.IO.LoadFromFile('mybook.pdf');
!!}
type TIEMiscPluginsImageMagick = class
public
class function IsAvailable(): boolean;
class procedure Initialize(reinitialize: boolean = true);
class procedure Finalize();
class procedure RegisterPlugin();
private
class function HandleWand(Handle: THandle = 0; Setup: boolean = false): THandle;
class function HandleMagick(Handle: THandle = 0; Setup: boolean = false): THandle;
class procedure CheckCallWand(var exec: pointer; name: AnsiString);
class procedure CheckCallMagick(var exec: pointer; name: AnsiString);
public
// MagickWand API wrappers
class procedure MagickWandGenesis();
class procedure MagickWandTerminus();
class function NewMagickWand(): TIEImageMagick_MagickWand;
class function DestroyMagickWand(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickWand;
class function MagickReadImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
class function MagickReadImageBlob(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
class function MagickPingImageBlob(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
class function MagickPingImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
class procedure MagickResetIterator(wand: TIEImageMagick_MagickWand);
class function MagickNextImage(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickBooleanType;
class function MagickSetIteratorIndex(wand: TIEImageMagick_MagickWand; index: TIEImageMagick_ssize_t): TIEImageMagick_MagickBooleanType;
class procedure MagickSetLastIterator(wand: TIEImageMagick_MagickWand);
class function MagickGetIteratorIndex(wand: TIEImageMagick_MagickWand): TIEImageMagick_ssize_t;
class function MagickExportImagePixels(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType;
class function MagickGetImageWidth(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
class function MagickGetImageHeight(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
class function MagickGetImageChannelDepth(wand: TIEImageMagick_MagickWand; channel: TIEImageMagick_ChannelType): TIEImageMagick_size_t;
class function MagickGetImageColorspace(wand: TIEImageMagick_MagickWand): TIEImageMagick_ColorspaceType;
class function MagickSetImageColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
class function MagickTransformImageColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
class function MagickGetImageDepth(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
class function MagickGetImageResolution(wand: TIEImageMagick_MagickWand; var x: double; var y: double): TIEImageMagick_MagickBooleanType;
class function MagickGetImageUnits(wand: TIEImageMagick_MagickWand): TIEImageMagick_ResolutionType;
class function MagickGetImageFormat(wand: TIEImageMagick_MagickWand): PAnsiChar;
class function MagickGetType(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType;
class function MagickSetImageType(wand: TIEImageMagick_MagickWand; image_type: TIEImageMagick_ImageType): TIEImageMagick_MagickBooleanType;
class function MagickIdentifyImageType(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType;
class function MagickSetProgressMonitor(wand: TIEImageMagick_MagickWand; progress_monitor: TIEImageMagick_MagickProgressMonitor; client_data: pointer): TIEImageMagick_MagickProgressMonitor;
class function MagickSetImageProperty(wand: TIEImageMagick_MagickWand; prop: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType;
class function MagickSetOption(wand: TIEImageMagick_MagickWand; key: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType;
class function MagickGetException(wand: TIEImageMagick_MagickWand; var severity: TIEImageMagick_ExceptionType): PAnsiChar;
class function MagickRelinquishMemory(resource: pointer): pointer;
class function MagickSetColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
class function MagickSetDepth(wand: TIEImageMagick_MagickWand; depth: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
class function MagickSetFormat(wand: TIEImageMagick_MagickWand; format: PAnsiChar): TIEImageMagick_MagickBooleanType;
class function MagickSetResolution(wand: TIEImageMagick_MagickWand; x_resolution: double; y_resolution: double): TIEImageMagick_MagickBooleanType;
class function MagickSetImageUnits(wand: TIEImageMagick_MagickWand; units: TIEImageMagick_ResolutionType): TIEImageMagick_MagickBooleanType;
class function MagickGetImageBlob(wand: TIEImageMagick_MagickWand; var length: TIEImageMagick_size_t): pbyte;
class function MagickWriteImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
class function MagickWriteImages(wand: TIEImageMagick_MagickWand; filename: PAnsiChar; adjoin: TIEImageMagick_MagickBooleanType): TIEImageMagick_MagickBooleanType;
class function MagickImportImagePixels(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType;
class function MagickNewImage(wand: TIEImageMagick_MagickWand; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; background: TIEImageMagick_PixelWand): TIEImageMagick_MagickBooleanType;
class function NewPixelWand(): TIEImageMagick_PixelWand;
class function DestroyPixelWand(pixelWand: TIEImageMagick_PixelWand): TIEImageMagick_PixelWand;
// MagickCore API wrappers
class function GetMagicInfo(magic: pointer; length: TIEImageMagick_size_t; exception: TIEImageMagick_ExceptionInfo): TIEImageMagick_MagicInfo;
class function GetMagicName(magic_info: TIEImageMagick_MagicInfo): PAnsiChar;
class function AcquireExceptionInfo(): TIEImageMagick_ExceptionInfo;
class function DestroyExceptionInfo(e: TIEImageMagick_ExceptionInfo): TIEImageMagick_ExceptionInfo;
//class function GetAuthenticPixels(image: TIEImageMagick_Image; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; exception: TIEImageMagick_ExceptionInfo): TIEImageMagick_PixelPacket;
end;
// TIEMiscPluginsImageMagick
///////////////////////////////////////////////////////////////////////////////////////////////////////
implementation
uses
imageenproc;
var
IEMiscPluginsCS: TRTLCriticalSection;
///////////////////////////////////////////////////////////////////////////////////////////////////////
// TIEMiscPluginsImageMagick
type TIEMiscPluginsImageMagick_Format = record
Typ: TIOFileType; // Const for this file type
Des: string; // Description of file type
Ext: string; // Extensions of this file type
Sue: string; // Most common extension for the file type
Wrt: boolean; // Whether writing is supported for this type
end;
const
ImageMagickFormats: array [0..24] of TIEMiscPluginsImageMagick_Format = (
(Typ: iomscFITS; Des: 'Flexible Image Transport System'; Ext: 'FITS;FTS'; Sue: 'fits'; Wrt: true),
(Typ: iomscPCD; Des: 'Photo CD'; Ext: 'PCD;PCDS'; Sue: 'pcd'; Wrt: true),
(Typ: iomscPCL; Des: 'Printer Control Language'; Ext: 'PCL'; Sue: 'pcl'; Wrt: true),
(Typ: iomscPDF; Des: 'Portable Document Format'; Ext: 'PDF;PDFA;EPDF'; Sue: 'pdf'; Wrt: true),
(Typ: iomscBIE; Des: 'Joint Bi-level Image experts Group interchange format'; Ext: 'BIE'; Sue: 'bie'; Wrt: true),
(Typ: iomscCIN; Des: 'Cineon Image File'; Ext: 'CIN'; Sue: 'cin'; Wrt: true),
(Typ: iomscDDS; Des: 'Microsoft DirectDraw Surface'; Ext: 'DDS'; Sue: 'dds'; Wrt: true),
(Typ: iomscDFONT; Des: 'Multi-face font package'; Ext: 'DFONT'; Sue: 'dfont'; Wrt: false),
(Typ: iomscDPX; Des: 'SMPTE 268M-2003 (DPX 2.0)'; Ext: 'DPX'; Sue: 'dpx'; Wrt: true),
(Typ: iomscJBIG; Des: 'Joint Bi-level Image experts Group interchange format'; Ext: 'JBIG;JBG'; Sue: 'jbig'; Wrt: true),
(Typ: iomscJNG; Des: 'JPEG Network Graphics'; Ext: 'JNG'; Sue: 'jng'; Wrt: true),
(Typ: iomscM2V; Des: 'MPEG Video Stream'; Ext: 'M2V;MOV;MPEG;MPG'; Sue: 'm2v'; Wrt: true),
(Typ: iomscMAT; Des: 'MATLAB level 5 image format'; Ext: 'MAT'; Sue: 'mat'; Wrt: true),
(Typ: iomscMIFF; Des: 'Magick Image File Format'; Ext: 'MIFF'; Sue: 'miff'; Wrt: true),
(Typ: iomscMNG; Des: 'Multiple-image Network Graphics'; Ext: 'MNG'; Sue: 'mng'; Wrt: true),
(Typ: iomscMP4; Des: 'MPEG-4 Video'; Ext: 'MP4;M4V'; Sue: 'mp4'; Wrt: true),
(Typ: iomscMSVG; Des: 'ImageMagick''s own SVG internal renderer'; Ext: 'MSVG'; Sue: 'msvg'; Wrt: true),
(Typ: iomscPES; Des: 'Embrid Embroidery Format'; Ext: 'PES'; Sue: 'pes'; Wrt: false),
(Typ: iomscPS; Des: 'PostScript'; Ext: 'PS;EPS;EPSF;EPSI;EPI;EPT'; Sue: 'ps'; Wrt: true),
(Typ: iomscPSB; Des: 'Adobe Large Document Format'; Ext: 'PSB'; Sue: 'psb'; Wrt: true),
(Typ: iomscPTIF; Des: 'Pyramid encoded TIFF'; Ext: 'PTIF'; Sue: 'ptif'; Wrt: true),
(Typ: iomscSVG; Des: 'Scalable Vector Graphics'; Ext: 'SVG;SVGZ'; Sue: 'svg'; Wrt: true),
(Typ: iomscTIFF64; Des: 'Tagged Image File Format (64-bit)'; Ext: 'TIFF64'; Sue: 'tiff64'; Wrt: true),
(Typ: iomscXCF; Des: 'GIMP image'; Ext: 'XCF'; Sue: 'xcf'; Wrt: false),
(Typ: iomscXPS; Des: 'Microsoft XML Paper Specification'; Ext: 'XPS'; Sue: 'xps'; Wrt: false)
);
{!!
<FS>TIEMiscPluginsImageMagick.RegisterPlugin
<FM>Declaration<FC>
class procedure RegisterPlugin();
<FM>Description<FN>
Registers ImageMagick file formats into ImageEn (adding support for all its formats).
Applications should call this method once only (generally at the start of the application).
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\ImageMagick\ImageMagick.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// Rasterizes page number 5 of mybook.pdf at 200dpi
TIEMiscPluginsImageMagick.RegisterPlugin(); // call only once!
ImageEnView1.IO.Params.ImageIndex := 5;
ImageEnView1.IO.Params.Dict.Insert('PDF:Density', 200);
ImageEnView1.IO.LoadFromFile('mybook.pdf');
!!}
class procedure TIEMiscPluginsImageMagick.RegisterPlugin();
var
i: integer;
begin
for i := 0 to high(ImageMagickFormats) do
begin
if ( ImageMagickFormats[i].typ = iomscPDF ) and ( IEFileFormatGetInfo( iomscWPPDF ) <> nil ) then
continue; // skip if PDF already supported
IEFileFormatAdd( TIEFileFormatInfo.Create(ImageMagickFormats[i].typ,
ImageMagickFormats[i].des,
ImageMagickFormats[i].ext,
ImageMagickFormats[i].sue,
false,
[],
@TIEMiscPluginsImageMagick_ReadImageStream,
@TIEMiscPluginsImageMagick_WriteImageStream,
@TIEMiscPluginsImageMagick_TryImageStream) );
end;
// remove native ImageEn formats
IEFileFormatRemove( ioPDF );
IEFileFormatRemove( ioPS );
end;
// Warning: in future "identify" command may change the SPATTERN!
// At the moment this is the fastest way to know pages count using imagemagick/ghostscript
function TIEMiscPluginsImageMagick_PDFFrameCount(Stream: TStream): integer;
const
SPATTERN: AnsiString = 'number of pages in the file: ';
var
filename: AnsiString;
dosout: AnsiString;
p: integer;
begin
result := 0;
if TIEMiscPluginsImageMagick.IsAvailable() and (Stream is TIEWideFileStream) then
begin
filename := AnsiString((Stream as TIEWideFileStream).FileName);
dosout := IEGetDosOutput('identify ' + filename + '[999999999]');
p := IEPos(SPATTERN, dosout);
if p > 0 then
begin
dosout := IECopy(dosout, p + length(SPATTERN), length(dosout));
p := IEPos(#$D#$A, dosout);
result := IEStrToIntDef(IECopy(dosout, 1, p - 1), 0);
end;
end;
end;
// Note: may be executed inside another thread. So Progress method should not update UI (to avoid locks!)
function TIEMiscPluginsImageMagick_MagickProgressMonitor(text: PAnsiChar; offset: TIEImageMagick_MagickOffsetType; span: TIEImageMagick_MagickSizeType; client_data: pointer): TIEImageMagick_MagickBooleanType; cdecl;
var
pr: ^TProgressRec;
per: integer;
begin
pr := client_data;
if ((span < 100) or (offset = TIEImageMagick_MagickOffsetType(span - 1)) or (offset mod (TIEImageMagick_MagickOffsetType(span) div 100) = 0))
and assigned(pr)
and assigned(pr^.fOnProgress) then
begin
if GetCurrentThreadId() = System.MainThreadID then
begin
per := trunc(100 * integer(offset) / integer(span) / pr^.tot + 100 / pr^.tot * pr^.val);
pr^.fOnProgress(pr^.Sender, per);
end;
result := not pr^.Aborting^;
end
else
result := true;
end;
// to-do:
// - more reading options (other than PDF:Density)
{
Read image from stream into Bitmap
Stream: Can be either a TMemoryStream or a TIEWideFileStream (file)
Progress: Provide loading progress feedback
Preview: If true, we only want IOParams to be filled.
Read from IOParams:
ImageIndex: The index of the page to load for a multi-page image, such as TIFF or PDF
GetThumbnail: If true, return only a small thumbnail of the image if it can be done efficiently (optional)
Dict: Optional parameters needed for this file type, e.g. 'PDF:Density' could be used to specify a resolution for loading
Written to IOParams:
ImageCount: Number of pages for a multi-page image, such as TIFF or PDF, otherwise 1
DpiX/DpiY: DPI of the image
BitsPerSample/SamplesPerPixel: Image color depth
Width: Bitmap.Width
Height: Bitmap.Height
OriginalWidth: Actual width of the image
OriginalHeight: Actual height of the image
}
procedure TIEMiscPluginsImageMagick_ReadImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec; Preview: boolean);
var
mwand: TIEImageMagick_MagickWand;
mstream: TMemoryStream;
filename: AnsiString;
height, width: integer;
i, j: integer;
readOK: TIEImageMagick_MagickBooleanType;
dpix, dpiy: double;
imtype: TIEImageMagick_ImageType;
imdepth: TIEImageMagick_size_t;
imcolorspc: TIEImageMagick_ColorspaceType;
pixfrmt: TIEPixelFormat;
outfrmt: AnsiString;
outstor: TIEImageMagick_StorageType;
bytebuf: array of byte;
px: pointer;
begin
if TIEMiscPluginsImageMagick.IsAvailable() then
begin
Progress.tot := 2; // number of steps
mwand := TIEMiscPluginsImageMagick.NewMagickWand();
mstream := nil;
try
if assigned(Progress.fOnProgress) then
TIEMiscPluginsImageMagick.MagickSetProgressMonitor(mwand, @TIEMiscPluginsImageMagick_MagickProgressMonitor, @Progress);
if Stream is TIEWideFileStream then
begin
filename := AnsiString((Stream as TIEWideFileStream).FileName);
end
else
begin
mstream := TMemoryStream.Create();
mstream.LoadFromStream(Stream);
end;
Progress.val := 0; // step one (0) - load
if IOParams.Dict.HasKey('PDF:Density') then
TIEMiscPluginsImageMagick.MagickSetOption(mwand, 'density', PAnsiChar(AnsiString(IOParams.Dict.GetString('PDF:Density'))));
// it is too expensive to calculate page count (consider PDF and PS). For PDF one may use TIEMiscPluginsImageMagick_PDFFrameCount or IEPDFFrameCount instead
IOParams.ImageCount := 1;
// PCD files contain multiple resolutions, don't use [1] which is lowest res. Best resolution is usually 5 or 6. If index exceeds count, ImageMagick will load the best resolution
if ( IOParams.FileType = iomscPCD ) and ( IOParams.ImageIndex = 0 ) then
filename := filename + '[6]'
else
filename := filename + '[' + AnsiString(IntToStr(IOParams.ImageIndex)) + ']';
readOK := false;
if Preview then
begin
if filename <> '' then
readOK := TIEMiscPluginsImageMagick.MagickPingImage(mwand, PAnsiChar(filename))
else
if mstream <> nil then
readOK := TIEMiscPluginsImageMagick.MagickPingImageBlob(mwand, mstream.Memory, mstream.Size);
end
else
begin
if filename <> '' then
readOK := TIEMiscPluginsImageMagick.MagickReadImage(mwand, PAnsiChar(filename))
else
if mstream <> nil then
readOK := TIEMiscPluginsImageMagick.MagickReadImageBlob(mwand, mstream.Memory, mstream.Size);
end;
if readOK then
begin
// resolution
TIEMiscPluginsImageMagick.MagickGetImageResolution(mwand, dpix, dpiy);
case TIEMiscPluginsImageMagick.MagickGetImageUnits(mwand) of
imck_UndefinedResolution,
imck_PixelsPerInchResolution:
begin
IOParams.DpiX := trunc(dpix);
IOParams.DpiY := trunc(dpiy);
end;
imck_PixelsPerCentimeterResolution:
begin
IOParams.DpiX := trunc(dpix / CM_per_Inch);
IOParams.DpiY := trunc(dpiy / CM_per_Inch);
end;
end;
if IOParams.DpiX = 0 then
IOParams.DpiX := IEGlobalSettings().DefaultDPIX;
if IOParams.DpiY = 0 then
IOParams.DpiY := IEGlobalSettings().DefaultDPIY;
// decode image
Progress.val := 1; // step two (1) - convert color space
imtype := TIEMiscPluginsImageMagick.MagickIdentifyImageType(mwand);
if imtype in [imck_BilevelType, imck_GrayscaleType, imck_GrayscaleMatteType] then
begin
TIEMiscPluginsImageMagick.MagickSetImageType(mwand, imck_BilevelType);
TIEMiscPluginsImageMagick.MagickSetImageColorspace(mwand, imck_GRAYColorspace);
end
else if imtype <> imck_UndefinedType then
begin
TIEMiscPluginsImageMagick.MagickSetImageType(mwand, imck_TrueColorType);
TIEMiscPluginsImageMagick.MagickSetImageColorspace(mwand, imck_sRGBColorspace);
end;
imdepth := TIEMiscPluginsImageMagick.MagickGetImageDepth(mwand);
imcolorspc := TIEMiscPluginsImageMagick.MagickGetImageColorspace(mwand);
case imcolorspc of
imck_GRAYColorspace:
begin
if imdepth = 1 then
begin
pixfrmt := ie1g;
outfrmt := 'I';
outstor := imck_CharPixel;
IOParams.BitsPerSample := 1;
IOParams.SamplesPerPixel := 1;
end
else
if imdepth = 8 then
begin
pixfrmt := ie8g;
outfrmt := 'I';
outstor := imck_CharPixel;
IOParams.BitsPerSample := 8;
IOParams.SamplesPerPixel := 1;
end
else
if (imdepth = 16) and (IOParams.IsNativePixelFormat) then
begin
pixfrmt := ie16g;
outfrmt := 'I';
outstor := imck_ShortPixel;
IOParams.BitsPerSample := 16;
IOParams.SamplesPerPixel := 1;
end
else
begin
pixfrmt := ie8g;
outfrmt := 'I';
outstor := imck_CharPixel;
IOParams.BitsPerSample := 8;
IOParams.SamplesPerPixel := 1;
end;
end;
else
begin
TIEMiscPluginsImageMagick.MagickTransformImageColorspace(mwand, imck_sRGBColorspace);
pixfrmt := ie24RGB;
outfrmt := 'BGR';
outstor := imck_CharPixel;
IOParams.BitsPerSample := 8;
IOParams.SamplesPerPixel := 3;
end;
end;
width := TIEMiscPluginsImageMagick.MagickGetImageWidth(mwand);
height := TIEMiscPluginsImageMagick.MagickGetImageHeight(mwand);
Bitmap.Allocate(width, height, pixfrmt);
IOParams.Width := width;
IOParams.OriginalWidth := width;
IOParams.Height := height;
IOParams.OriginalHeight := height;
IOParams.FreeColorMap();
if not Preview then
begin
if pixfrmt = ie1g then
begin
// special case, packet 1 bit channels
SetLength(bytebuf, width);
for i := 0 to height - 1 do
begin
TIEMiscPluginsImageMagick.MagickExportImagePixels(mwand, 0, i, width, 1, PAnsiChar(outfrmt), outstor, bytebuf);
px := Bitmap.ScanLine[i];
for j := 0 to width - 1 do
_SetPixelbw(px, j, bytebuf[j]);
end;
end
else
begin
// other cases (non packet channels)
for i := 0 to height - 1 do
TIEMiscPluginsImageMagick.MagickExportImagePixels(mwand, 0, i, width, 1, PAnsiChar(outfrmt), outstor, Bitmap.ScanLine[i]);
end;
end;
end
else
Progress.Aborting^ := true;
finally
mstream.Free();
TIEMiscPluginsImageMagick.DestroyMagickWand(mwand);
end;
end
else
Progress.Aborting^ := true;
end;
// to-do:
// - implement other pixel formats.
// - multipages
// - more writing options
// known bugs: resulting PCD has wrong colors
{
Outputs the Bitmap to Stream in format IOParams.FileType (for formats that support writing)
Progress: Provide loading progress feedback
Read from IOParams (Optional):
DpiX/DpiY: DPI of the image
BitsPerSample/SamplesPerPixel: Image color depth
Dict: Optional parameters needed for this file type, e.g. 'PDF:Density' could be used to specify an output resolution
}
procedure TIEMiscPluginsImageMagick_WriteImageStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var Progress: TProgressRec);
var
mwand: TIEImageMagick_MagickWand;
bkgrnd: TIEImageMagick_PixelWand;
i: integer;
frmt: AnsiString;
imageBlob: pbyte;
imageBlobLen: TIEImageMagick_size_t;
begin
if TIEMiscPluginsImageMagick.IsAvailable() then
begin
mwand := TIEMiscPluginsImageMagick.NewMagickWand();
bkgrnd := TIEMiscPluginsImageMagick.NewPixelWand();
try
TIEMiscPluginsImageMagick.MagickNewImage(mwand, Bitmap.Width, Bitmap.Height, bkgrnd);
TIEMiscPluginsImageMagick.MagickSetDepth(mwand, 8);
frmt := AnsiString(Uppercase(IEFileFormatGetExt(IOParams.FileType, 0)));
TIEMiscPluginsImageMagick.MagickSetImageUnits(mwand, imck_PixelsPerInchResolution);
TIEMiscPluginsImageMagick.MagickSetResolution(mwand, IOParams.DpiX, IOParams.DpiY);
TIEMiscPluginsImageMagick.MagickSetColorspace(mwand, imck_sRGBColorspace);
TIEMiscPluginsImageMagick.MagickSetFormat(mwand, PAnsiChar(frmt));
for i := 0 to Bitmap.Height - 1 do
TIEMiscPluginsImageMagick.MagickImportImagePixels(mwand, 0, i, Bitmap.Width, 1, 'BGR', imck_CharPixel, Bitmap.ScanLine[i]);
imageBlob := TIEMiscPluginsImageMagick.MagickGetImageBlob(mwand, imageBlobLen);
Stream.Write(imageBlob^, imageBlobLen);
TIEMiscPluginsImageMagick.MagickRelinquishMemory(imageBlob);
finally
TIEMiscPluginsImageMagick.DestroyPixelWand(bkgrnd);
TIEMiscPluginsImageMagick.DestroyMagickWand(mwand);
end;
end;
end;
// Returns true if the image in Stream matches the format, TryingFormat
function TIEMiscPluginsImageMagick_TryImageStream(Stream: TStream; TryingFormat: TIOFileType): boolean;
const
BUFSIZE = 8192; // file head to analyse
var
lpos: int64;
frmt: string;
i: integer;
buf: array of byte;
ex: TIEImageMagick_ExceptionInfo;
info: TIEImageMagick_MagicInfo;
begin
result := false;
if TIEMiscPluginsImageMagick.IsAvailable() then
begin
lpos := Stream.Position;
try
SetLength(buf, BUFSIZE);
Stream.Read(buf[0], BUFSIZE);
ex := TIEMiscPluginsImageMagick.AcquireExceptionInfo();
info := TIEMiscPluginsImageMagick.GetMagicInfo(@buf[0], BUFSIZE, ex);
if info <> nil then
frmt := string(AnsiString(TIEMiscPluginsImageMagick.GetMagicName(info)))
else
frmt := '';
TIEMiscPluginsImageMagick.DestroyExceptionInfo(ex);
if frmt <> '' then
for i := 0 to high(ImageMagickFormats) do
if (TryingFormat = ImageMagickFormats[i].typ) and (pos(';' + frmt + ';', ';' + ImageMagickFormats[i].ext + ';') > 0) then
begin
result := true;
break;
end;
finally
Stream.Position := lpos;
end;
end;
end;
class procedure TIEMiscPluginsImageMagick.CheckCallWand(var exec: pointer; name: AnsiString);
begin
if exec = nil then
exec := GetProcAddress(HandleWand(), PAnsiChar(name));
end;
class procedure TIEMiscPluginsImageMagick.CheckCallMagick(var exec: pointer; name: AnsiString);
begin
if exec = nil then
exec := GetProcAddress(HandleMagick(), PAnsiChar(name));
end;
class function TIEMiscPluginsImageMagick.HandleWand(Handle: THandle; Setup: boolean): THandle;
const
LibHandle: THandle = 0;
begin
if Setup then
LibHandle := Handle;
result := LibHandle;
end;
class function TIEMiscPluginsImageMagick.HandleMagick(Handle: THandle; Setup: boolean): THandle;
const
LibHandle: THandle = 0;
begin
if Setup then
LibHandle := Handle;
result := LibHandle;
end;
{!!
<FS>TIEMiscPluginsImageMagick.IsAvailable
<FM>Declaration<FC>
class function IsAvailable(): boolean;
<FM>Description<FN>
Returns True if the ImageMagick library is present and successfully loaded.
!!}
class function TIEMiscPluginsImageMagick.IsAvailable(): boolean;
begin
if (HandleWand() = 0) or (HandleMagick() = 0) then
Initialize(false);
result := (HandleWand() <> 0) and (HandleMagick() <> 0);
end;
class procedure TIEMiscPluginsImageMagick.Initialize(reinitialize: boolean = true);
{}
procedure TryLoad();
var
verIndex: integer;
begin
verIndex := 0;
if HandleWand() = 0 then
begin
while verIndex < length(IEIMAGEMAGICK_WAND_DLL_FILENAMES) do
begin
HandleWand(LoadLibraryW(PWideChar(WideString(IEIMAGEMAGICK_WAND_DLL_FILENAMES[verIndex]))), true);
if (HandleWand() = 0) and IsLibrary then // if this is a DLL try to load from dll path
HandleWand(LoadLibraryW(PWideChar( ExtractFilePath(GetModuleName(HInstance)) + WideString(IEIMAGEMAGICK_WAND_DLL_FILENAMES[verIndex]) )), true);
if HandleWand() <> 0 then
begin
MagickWandGenesis();
break;
end;
inc(verIndex);
end;
end;
if HandleMagick() = 0 then
begin
// verIndex starts from last loaded library to maintain the same version (in case of multiple installations of magick)
while verIndex < length(IEIMAGEMAGICK_MAGICK_DLL_FILENAMES) do
begin
HandleMagick(LoadLibraryW(PWideChar(WideString(IEIMAGEMAGICK_MAGICK_DLL_FILENAMES[verIndex]))), true);
if (HandleMagick() = 0) and IsLibrary then // if this is a DLL try to load from dll path
HandleMagick(LoadLibraryW(PWideChar( ExtractFilePath(GetModuleName(HInstance)) + WideString(IEIMAGEMAGICK_MAGICK_DLL_FILENAMES[verIndex]) )), true);
if HandleMagick() <> 0 then
break;
inc(verIndex);
end;
end;
end;
{}
begin
EnterCriticalSection(IEMiscPluginsCS);
try
if reinitialize then
Finalize();
TryLoad();
finally
LeaveCriticalSection(IEMiscPluginsCS);
end;
end;
class procedure TIEMiscPluginsImageMagick.Finalize();
begin
if HandleMagick() <> 0 then
begin
FreeLibrary(HandleMagick());
HandleMagick(0, true);
end;
if HandleWand() <> 0 then
begin
MagickWandTerminus();
FreeLibrary(HandleWand());
HandleWand(0, true);
end;
end;
class procedure TIEMiscPluginsImageMagick.MagickWandGenesis();
const
exec: procedure(); cdecl = nil;
begin
CheckCallWand(@exec, 'MagickWandGenesis');
exec();
end;
class procedure TIEMiscPluginsImageMagick.MagickWandTerminus();
const
exec: procedure(); cdecl = nil;
begin
CheckCallWand(@exec, 'MagickWandTerminus');
exec();
end;
class function TIEMiscPluginsImageMagick.NewMagickWand(): TIEImageMagick_MagickWand;
const
exec: function(): TIEImageMagick_MagickWand; cdecl = nil;
begin
CheckCallWand(@exec, 'NewMagickWand');
result := exec();
end;
class function TIEMiscPluginsImageMagick.DestroyMagickWand(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickWand;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickWand; cdecl = nil;
begin
CheckCallWand(@exec, 'DestroyMagickWand');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickReadImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickReadImage');
result := exec(wand, filename);
end;
class function TIEMiscPluginsImageMagick.MagickReadImageBlob(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickReadImageBlob');
result := exec(wand, blob, length);
end;
class function TIEMiscPluginsImageMagick.MagickPingImageBlob(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; blob: pointer; length: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickPingImageBlob');
result := exec(wand, blob, length);
end;
class function TIEMiscPluginsImageMagick.MagickPingImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickPingImage');
result := exec(wand, filename);
end;
class procedure TIEMiscPluginsImageMagick.MagickResetIterator(wand: TIEImageMagick_MagickWand);
const
exec: procedure(wand: TIEImageMagick_MagickWand); cdecl = nil;
begin
CheckCallWand(@exec, 'MagickResetIterator');
exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickNextImage(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickNextImage');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickSetIteratorIndex(wand: TIEImageMagick_MagickWand; index: TIEImageMagick_ssize_t): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; index: TIEImageMagick_ssize_t): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetIteratorIndex');
result := exec(wand, index);
end;
class procedure TIEMiscPluginsImageMagick.MagickSetLastIterator(wand: TIEImageMagick_MagickWand);
const
exec: procedure(wand: TIEImageMagick_MagickWand); cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetLastIterator');
exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetIteratorIndex(wand: TIEImageMagick_MagickWand): TIEImageMagick_ssize_t;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_ssize_t; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetIteratorIndex');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickWriteImages(wand: TIEImageMagick_MagickWand; filename: PAnsiChar; adjoin: TIEImageMagick_MagickBooleanType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; filename: PAnsiChar; adjoin: TIEImageMagick_MagickBooleanType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickWriteImages');
result := exec(wand, filename, adjoin);
end;
class function TIEMiscPluginsImageMagick.MagickExportImagePixels(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickExportImagePixels');
result := exec(wand, x, y, columns, rows, map, storage, pixels);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageWidth(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageWidth');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageHeight(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageHeight');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageChannelDepth(wand: TIEImageMagick_MagickWand; channel: TIEImageMagick_ChannelType): TIEImageMagick_size_t;
const
exec: function(wand: TIEImageMagick_MagickWand; channel: TIEImageMagick_ChannelType): TIEImageMagick_size_t; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageChannelDepth');
result := exec(wand, channel);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageColorspace(wand: TIEImageMagick_MagickWand): TIEImageMagick_ColorspaceType;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_ColorspaceType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageColorspace');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickSetImageColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetImageColorspace');
result := exec(wand, colorspace);
end;
class function TIEMiscPluginsImageMagick.MagickTransformImageColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickTransformImageColorspace');
result := exec(wand, colorspace);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageDepth(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_size_t; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageDepth');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageResolution(wand: TIEImageMagick_MagickWand; var x: double; var y: double): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; var x: double; var y: double): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageResolution');
result := exec(wand, x, y);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageUnits(wand: TIEImageMagick_MagickWand): TIEImageMagick_ResolutionType;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_ResolutionType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageUnits');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageFormat(wand: TIEImageMagick_MagickWand): PAnsiChar;
const
exec: function(wand: TIEImageMagick_MagickWand): PAnsiChar; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageFormat');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickGetType(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetType');
result := exec(wand);
end;
class function TIEMiscPluginsImageMagick.MagickIdentifyImageType(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType;
const
exec: function(wand: TIEImageMagick_MagickWand): TIEImageMagick_ImageType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickIdentifyImageType');
if assigned(exec) then
result := exec(wand)
else
result := imck_UndefinedType; // not implemented
end;
class function TIEMiscPluginsImageMagick.MagickSetImageType(wand: TIEImageMagick_MagickWand; image_type: TIEImageMagick_ImageType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; image_type: TIEImageMagick_ImageType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetImageType');
result := exec(wand, image_type);
end;
class function TIEMiscPluginsImageMagick.MagickSetProgressMonitor(wand: TIEImageMagick_MagickWand; progress_monitor: TIEImageMagick_MagickProgressMonitor; client_data: pointer): TIEImageMagick_MagickProgressMonitor;
const
exec: function(wand: TIEImageMagick_MagickWand; progress_monitor: TIEImageMagick_MagickProgressMonitor; client_data: pointer): TIEImageMagick_MagickProgressMonitor; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetProgressMonitor');
result := exec(wand, progress_monitor, client_data);
end;
class function TIEMiscPluginsImageMagick.GetMagicInfo(magic: pointer; length: TIEImageMagick_size_t; exception: TIEImageMagick_ExceptionInfo): TIEImageMagick_MagicInfo;
const
exec: function(magic: pointer; length: TIEImageMagick_size_t; exception: TIEImageMagick_ExceptionInfo): TIEImageMagick_MagicInfo; cdecl = nil;
begin
CheckCallMagick(@exec, 'GetMagicInfo');
result := exec(magic, length, exception);
end;
class function TIEMiscPluginsImageMagick.GetMagicName(magic_info: TIEImageMagick_MagicInfo): PAnsiChar;
const
exec: function(magic_info: TIEImageMagick_MagicInfo): PAnsiChar; cdecl = nil;
begin
CheckCallMagick(@exec, 'GetMagicName');
result := exec(magic_info);
end;
class function TIEMiscPluginsImageMagick.AcquireExceptionInfo(): TIEImageMagick_ExceptionInfo;
const
exec: function(): TIEImageMagick_ExceptionInfo; cdecl = nil;
begin
CheckCallMagick(@exec, 'AcquireExceptionInfo');
result := exec();
end;
class function TIEMiscPluginsImageMagick.DestroyExceptionInfo(e: TIEImageMagick_ExceptionInfo): TIEImageMagick_ExceptionInfo;
const
exec: function(e: TIEImageMagick_ExceptionInfo): TIEImageMagick_ExceptionInfo; cdecl = nil;
begin
CheckCallMagick(@exec, 'DestroyExceptionInfo');
result := exec(e);
end;
class function TIEMiscPluginsImageMagick.MagickSetImageProperty(wand: TIEImageMagick_MagickWand; prop: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; prop: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetImageProperty');
result := exec(wand, prop, value);
end;
class function TIEMiscPluginsImageMagick.MagickSetOption(wand: TIEImageMagick_MagickWand; key: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; key: PAnsiChar; value: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetOption');
result := exec(wand, key, value);
end;
class function TIEMiscPluginsImageMagick.MagickGetException(wand: TIEImageMagick_MagickWand; var severity: TIEImageMagick_ExceptionType): PAnsiChar;
const
exec: function(wand: TIEImageMagick_MagickWand; var severity: TIEImageMagick_ExceptionType): PAnsiChar; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetException');
result := exec(wand, severity);
end;
class function TIEMiscPluginsImageMagick.MagickRelinquishMemory(resource: pointer): pointer;
const
exec: function(resource: pointer): pointer; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickRelinquishMemory');
result := exec(resource);
end;
class function TIEMiscPluginsImageMagick.MagickSetColorspace(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; colorspace: TIEImageMagick_ColorspaceType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetColorspace');
result := exec(wand, colorspace);
end;
class function TIEMiscPluginsImageMagick.MagickSetDepth(wand: TIEImageMagick_MagickWand; depth: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; depth: TIEImageMagick_size_t): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetDepth');
result := exec(wand, depth);
end;
class function TIEMiscPluginsImageMagick.MagickSetFormat(wand: TIEImageMagick_MagickWand; format: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; format: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetFormat');
result := exec(wand, format);
end;
class function TIEMiscPluginsImageMagick.MagickSetResolution(wand: TIEImageMagick_MagickWand; x_resolution: double; y_resolution: double): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; x_resolution: double; y_resolution: double): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetResolution');
result := exec(wand, x_resolution, y_resolution);
end;
class function TIEMiscPluginsImageMagick.MagickSetImageUnits(wand: TIEImageMagick_MagickWand; units: TIEImageMagick_ResolutionType): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; units: TIEImageMagick_ResolutionType): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickSetImageUnits');
result := exec(wand, units);
end;
class function TIEMiscPluginsImageMagick.MagickGetImageBlob(wand: TIEImageMagick_MagickWand; var length: TIEImageMagick_size_t): pbyte;
const
exec: function(wand: TIEImageMagick_MagickWand; var length: TIEImageMagick_size_t): pbyte; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickGetImageBlob');
result := exec(wand, length);
end;
class function TIEMiscPluginsImageMagick.MagickWriteImage(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; filename: PAnsiChar): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickWriteImage');
result := exec(wand, filename);
end;
class function TIEMiscPluginsImageMagick.MagickImportImagePixels(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; x: TIEImageMagick_ssize_t; y: TIEImageMagick_ssize_t; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; map: PAnsiChar; storage: TIEImageMagick_StorageType; pixels: pointer): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickImportImagePixels');
result := exec(wand, x, y, columns, rows, map, storage, pixels);
end;
class function TIEMiscPluginsImageMagick.MagickNewImage(wand: TIEImageMagick_MagickWand; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; background: TIEImageMagick_PixelWand): TIEImageMagick_MagickBooleanType;
const
exec: function(wand: TIEImageMagick_MagickWand; columns: TIEImageMagick_size_t; rows: TIEImageMagick_size_t; background: TIEImageMagick_PixelWand): TIEImageMagick_MagickBooleanType; cdecl = nil;
begin
CheckCallWand(@exec, 'MagickNewImage');
result := exec(wand, columns, rows, background);
end;
class function TIEMiscPluginsImageMagick.NewPixelWand(): TIEImageMagick_PixelWand;
const
exec: function(): TIEImageMagick_PixelWand; cdecl = nil;
begin
CheckCallWand(@exec, 'NewPixelWand');
result := exec();
end;
class function TIEMiscPluginsImageMagick.DestroyPixelWand(pixelWand: TIEImageMagick_PixelWand): TIEImageMagick_PixelWand;
const
exec: function(pixelWand: TIEImageMagick_PixelWand): TIEImageMagick_PixelWand; cdecl = nil;
begin
CheckCallWand(@exec, 'DestroyPixelWand');
result := exec(pixelWand);
end;
// TIEMiscPluginsImageMagick
///////////////////////////////////////////////////////////////////////////////////////////////////////
initialization
InitializeCriticalSection(IEMiscPluginsCS);
finalization
DeleteCriticalSection(IEMiscPluginsCS);
{$ELSE} // not IEINCLUDEMISCPLUGINS
implementation
{$ENDIF}
end.