diff options
author | brunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2009-12-09 18:35:28 +0000 |
---|---|---|
committer | brunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2009-12-09 18:35:28 +0000 |
commit | e4f413fdcf003ac0ad20d145f61dd370994e79db (patch) | |
tree | 692f725464654d0a82cdb0888c28e4dd21d68517 /Medley/src/lib/FreeImage/FreeBitmap.pas | |
parent | d267ce95e1743fad0d383d1d7fe51e9b8bf5b66f (diff) | |
download | usdx-e4f413fdcf003ac0ad20d145f61dd370994e79db.tar.gz usdx-e4f413fdcf003ac0ad20d145f61dd370994e79db.tar.xz usdx-e4f413fdcf003ac0ad20d145f61dd370994e79db.zip |
just a first experimental version
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2011 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to '')
-rw-r--r-- | Medley/src/lib/FreeImage/FreeBitmap.pas | 1742 |
1 files changed, 1742 insertions, 0 deletions
diff --git a/Medley/src/lib/FreeImage/FreeBitmap.pas b/Medley/src/lib/FreeImage/FreeBitmap.pas new file mode 100644 index 00000000..d32fb5cb --- /dev/null +++ b/Medley/src/lib/FreeImage/FreeBitmap.pas @@ -0,0 +1,1742 @@ +unit FreeBitmap; + +// ========================================================== +// +// Delphi wrapper for FreeImage 3 +// +// Design and implementation by +// - Anatoliy Pulyaevskiy (xvel84@rambler.ru) +// +// Contributors: +// - Enzo Costantini (enzocostantini@libero.it) +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// +// ========================================================== +// +// From begining all code of this file is based on C++ wrapper to +// FreeImage - FreeImagePlus. +// +// ========================================================== + +{$IFDEF FPC} + {$MODE Delphi} + {$H+} // use long strings +{$ENDIF} + +interface + +uses + SysUtils, Classes, Windows, FreeImage; + +type + { TFreeObject } + + TFreeObject = class(TObject) + public + function IsValid: Boolean; virtual; + end; + + { TFreeTag } + + TFreeTag = class(TFreeObject) + private + // fields + FTag: PFITAG; + + // getters & setters + function GetCount: Cardinal; + function GetDescription: string; + function GetID: Word; + function GetKey: string; + function GetLength: Cardinal; + function GetTagType: FREE_IMAGE_MDTYPE; + function GetValue: Pointer; + procedure SetCount(const Value: Cardinal); + procedure SetDescription(const Value: string); + procedure SetID(const Value: Word); + procedure SetKey(const Value: string); + procedure SetLength(const Value: Cardinal); + procedure SetTagType(const Value: FREE_IMAGE_MDTYPE); + procedure SetValue(const Value: Pointer); + public + // construction & destruction + constructor Create(ATag: PFITAG = nil); virtual; + destructor Destroy; override; + + // methods + function Clone: TFreeTag; + function IsValid: Boolean; override; + function ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar = nil): string; + + // properties + property Key: string read GetKey write SetKey; + property Description: string read GetDescription write SetDescription; + property ID: Word read GetID write SetID; + property TagType: FREE_IMAGE_MDTYPE read GetTagType write SetTagType; + property Count: Cardinal read GetCount write SetCount; + property Length: Cardinal read GetLength write SetLength; + property Value: Pointer read GetValue write SetValue; + property Tag: PFITAG read FTag; + end; + + { forward declarations } + + TFreeBitmap = class; + TFreeMemoryIO = class; + + { TFreeBitmap } + + TFreeBitmapChangingEvent = procedure(Sender: TFreeBitmap; var OldDib, NewDib: PFIBITMAP; var Handled: Boolean) of object; + + TFreeBitmap = class(TFreeObject) + private + // fields + FDib: PFIBITMAP; + FOnChange: TNotifyEvent; + FOnChanging: TFreeBitmapChangingEvent; + + procedure SetDib(Value: PFIBITMAP); + protected + function DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean; dynamic; + function Replace(NewDib: PFIBITMAP): Boolean; dynamic; + public + constructor Create(ImageType: FREE_IMAGE_TYPE = FIT_BITMAP; Width: Integer = 0; Height: Integer = 0; Bpp: Integer = 0); + destructor Destroy; override; + function SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height, Bpp: Integer; RedMask: Cardinal = 0; GreenMask: Cardinal = 0; BlueMask: Cardinal = 0): Boolean; + procedure Change; dynamic; + procedure Assign(Source: TFreeBitmap); + function CopySubImage(Left, Top, Right, Bottom: Integer; Dest: TFreeBitmap): Boolean; + function PasteSubImage(Src: TFreeBitmap; Left, Top: Integer; Alpha: Integer = 256): Boolean; + procedure Clear; virtual; + function Load(const FileName: string; Flag: Integer = 0): Boolean; + function LoadU(const FileName: WideString; Flag: Integer = 0): Boolean; + function LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean; + function LoadFromMemory(MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean; + function LoadFromStream(Stream: TStream; Flag: Integer = 0): Boolean; + // save functions + function CanSave(fif: FREE_IMAGE_FORMAT): Boolean; + function Save(const FileName: string; Flag: Integer = 0): Boolean; + function SaveU(const FileName: WideString; Flag: Integer = 0): Boolean; + function SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO; Handle: fi_handle; Flag: Integer = 0): Boolean; + function SaveToMemory(fif: FREE_IMAGE_FORMAT; MemIO: TFreeMemoryIO; Flag: Integer = 0): Boolean; + function SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream; Flag: Integer = 0): Boolean; + // image information + function GetImageType: FREE_IMAGE_TYPE; + function GetWidth: Integer; + function GetHeight: Integer; + function GetScanWidth: Integer; + function IsValid: Boolean; override; + function GetInfo: PBitmapInfo; + function GetInfoHeader: PBitmapInfoHeader; + function GetImageSize: Cardinal; + function GetBitsPerPixel: Integer; + function GetLine: Integer; + function GetHorizontalResolution: Double; + function GetVerticalResolution: Double; + procedure SetHorizontalResolution(Value: Double); + procedure SetVerticalResolution(Value: Double); + // palette operations + function GetPalette: PRGBQUAD; + function GetPaletteSize: Integer; + function GetColorsUsed: Integer; + function GetColorType: FREE_IMAGE_COLOR_TYPE; + function IsGrayScale: Boolean; + // pixels access + function AccessPixels: PByte; + function GetScanLine(ScanLine: Integer): PByte; + function GetPixelIndex(X, Y: Cardinal; var Value: PByte): Boolean; + function GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean; + function SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean; + function SetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean; + // convertion + function ConvertToStandardType(ScaleLinear: Boolean): Boolean; + function ConvertToType(ImageType: FREE_IMAGE_TYPE; ScaleLinear: Boolean): Boolean; + function Threshold(T: Byte): Boolean; + function ConvertTo4Bits: Boolean; + function ConvertTo8Bits: Boolean; + function ConvertTo16Bits555: Boolean; + function ConvertTo16Bits565: Boolean; + function ConvertTo24Bits: Boolean; + function ConvertTo32Bits: Boolean; + function ConvertToGrayscale: Boolean; + function ColorQuantize(Algorithm: FREE_IMAGE_QUANTIZE): Boolean; + function Dither(Algorithm: FREE_IMAGE_DITHER): Boolean; + function ConvertToRGBF: Boolean; + function ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam, SecondParam: Double): Boolean; + // transparency + function IsTransparent: Boolean; + function GetTransparencyCount: Cardinal; + function GetTransparencyTable: PByte; + procedure SetTransparencyTable(Table: PByte; Count: Integer); + function HasFileBkColor: Boolean; + function GetFileBkColor(var BkColor: PRGBQuad): Boolean; + function SetFileBkColor(BkColor: PRGBQuad): Boolean; + // channel processing routines + function GetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; + function SetChannel(Bitmap: TFreeBitmap; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; + function SplitChannels(RedChannel, GreenChannel, BlueChannel: TFreeBitmap): Boolean; + function CombineChannels(Red, Green, Blue: TFreeBitmap): Boolean; + // rotation and flipping + function RotateEx(Angle, XShift, YShift, XOrigin, YOrigin: Double; UseMask: Boolean): Boolean; + function Rotate(Angle: Double): Boolean; + function FlipHorizontal: Boolean; + function FlipVertical: Boolean; + // color manipulation routines + function Invert: Boolean; + function AdjustCurve(Lut: PByte; Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; + function AdjustGamma(Gamma: Double): Boolean; + function AdjustBrightness(Percentage: Double): Boolean; + function AdjustContrast(Percentage: Double): Boolean; + function GetHistogram(Histo: PDWORD; Channel: FREE_IMAGE_COLOR_CHANNEL = FICC_BLACK): Boolean; + // upsampling / downsampling + procedure MakeThumbnail(const Width, Height: Integer; DestBitmap: TFreeBitmap); + function Rescale(NewWidth, NewHeight: Integer; Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap = nil): Boolean; + // metadata routines + function FindFirstMetadata(Model: FREE_IMAGE_MDMODEL; var Tag: TFreeTag): PFIMETADATA; + function FindNextMetadata(MDHandle: PFIMETADATA; var Tag: TFreeTag): Boolean; + procedure FindCloseMetadata(MDHandle: PFIMETADATA); + function SetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; Tag: TFreeTag): Boolean; + function GetMetadata(Model: FREE_IMAGE_MDMODEL; const Key: string; var Tag: TFreeTag): Boolean; + function GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal; + + // properties + property Dib: PFIBITMAP read FDib write SetDib; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChanging: TFreeBitmapChangingEvent read FOnChanging write FOnChanging; + end; + + { TFreeWinBitmap } + + + { TFreeMemoryIO } + + TFreeMemoryIO = class(TFreeObject) + private + FHMem: PFIMEMORY; + public + // construction and destruction + constructor Create(Data: PByte = nil; SizeInBytes: DWORD = 0); + destructor Destroy; override; + + function GetFileType: FREE_IMAGE_FORMAT; + function Read(fif: FREE_IMAGE_FORMAT; Flag: Integer = 0): PFIBITMAP; + function Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; Flag: Integer = 0): Boolean; + function Tell: Longint; + function Seek(Offset: Longint; Origin: Word): Boolean; + function Acquire(var Data: PByte; var SizeInBytes: DWORD): Boolean; + // overriden methods + function IsValid: Boolean; override; + end; + + { TFreeMultiBitmap } + + TFreeMultiBitmap = class(TFreeObject) + private + FMPage: PFIMULTIBITMAP; + FMemoryCache: Boolean; + public + // constructor and destructor + constructor Create(KeepCacheInMemory: Boolean = False); + destructor Destroy; override; + + // methods + function Open(const FileName: string; CreateNew, ReadOnly: Boolean; Flags: Integer = 0): Boolean; + function Close(Flags: Integer = 0): Boolean; + function GetPageCount: Integer; + procedure AppendPage(Bitmap: TFreeBitmap); + procedure InsertPage(Page: Integer; Bitmap: TFreeBitmap); + procedure DeletePage(Page: Integer); + function MovePage(Target, Source: Integer): Boolean; + procedure LockPage(Page: Integer; DestBitmap: TFreeBitmap); + procedure UnlockPage(Bitmap: TFreeBitmap; Changed: Boolean); + function GetLockedPageNumbers(var Pages: Integer; var Count: Integer): Boolean; + // overriden methods + function IsValid: Boolean; override; + + // properties + // change of this property influences only on the next opening of a file + property MemoryCache: Boolean read FMemoryCache write FMemoryCache; + end; + +implementation + +const + ThumbSize = 150; + +// marker used for clipboard copy / paste + +procedure SetFreeImageMarker(bmih: PBitmapInfoHeader; dib: PFIBITMAP); +begin + // Windows constants goes from 0L to 5L + // Add $FF to avoid conflicts + bmih.biCompression := $FF + FreeImage_GetImageType(dib); +end; + +function GetFreeImageMarker(bmih: PBitmapInfoHeader): FREE_IMAGE_TYPE; +begin + Result := FREE_IMAGE_TYPE(bmih.biCompression - $FF); +end; + +{ TFreePersistent } + +function TFreeObject.IsValid: Boolean; +begin + Result := False +end; + +{ TFreeBitmap } + +function TFreeBitmap.AccessPixels: PByte; +begin + Result := FreeImage_GetBits(FDib) +end; + +function TFreeBitmap.AdjustBrightness(Percentage: Double): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_AdjustBrightness(FDib, Percentage); + Change; + end + else + Result := False +end; + +function TFreeBitmap.AdjustContrast(Percentage: Double): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_AdjustContrast(FDib, Percentage); + Change; + end + else + Result := False +end; + +function TFreeBitmap.AdjustCurve(Lut: PByte; + Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_AdjustCurve(FDib, Lut, Channel); + Change; + end + else + Result := False +end; + +function TFreeBitmap.AdjustGamma(Gamma: Double): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_AdjustGamma(FDib, Gamma); + Change; + end + else + Result := False +end; + +procedure TFreeBitmap.Assign(Source: TFreeBitmap); +var + SourceBmp: TFreeBitmap; + Clone: PFIBITMAP; +begin + if Source = nil then + begin + Clear; + Exit; + end; + + if Source is TFreeBitmap then + begin + SourceBmp := TFreeBitmap(Source); + if SourceBmp <> Self then + begin + if SourceBmp.IsValid then + begin + Clone := FreeImage_Clone(SourceBmp.FDib); + Replace(Clone); + end + else + Clear; + end; + end; +end; + +function TFreeBitmap.CanSave(fif: FREE_IMAGE_FORMAT): Boolean; +var + ImageType: FREE_IMAGE_TYPE; + Bpp: Word; +begin + Result := False; + if not IsValid then Exit; + + if fif <> FIF_UNKNOWN then + begin + // check that the dib can be saved in this format + ImageType := FreeImage_GetImageType(FDib); + if ImageType = FIT_BITMAP then + begin + // standard bitmap type + Bpp := FreeImage_GetBPP(FDib); + Result := FreeImage_FIFSupportsWriting(fif) + and FreeImage_FIFSupportsExportBPP(fif, Bpp); + end + else // special bitmap type + Result := FreeImage_FIFSupportsExportType(fif, ImageType); + end; +end; + +procedure TFreeBitmap.Change; +begin + if Assigned(FOnChange) then FOnChange(Self) +end; + +procedure TFreeBitmap.Clear; +begin + if FDib <> nil then + begin + FreeImage_Unload(FDib); + FDib := nil; + Change; + end; +end; + +function TFreeBitmap.ColorQuantize( + Algorithm: FREE_IMAGE_QUANTIZE): Boolean; +var + dib8: PFIBITMAP; +begin + if FDib <> nil then + begin + dib8 := FreeImage_ColorQuantize(FDib, Algorithm); + Result := Replace(dib8); + end + else + Result := False; +end; + +function TFreeBitmap.CombineChannels(Red, Green, + Blue: TFreeBitmap): Boolean; +var + Width, Height: Integer; +begin + if FDib = nil then + begin + Width := Red.GetWidth; + Height := Red.GetHeight; + FDib := FreeImage_Allocate(Width, Height, 24, FI_RGBA_RED_MASK, + FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); + end; + + if FDib <> nil then + begin + Result := FreeImage_SetChannel(FDib, Red.FDib, FICC_RED) and + FreeImage_SetChannel(FDib, Green.FDib, FICC_GREEN) and + FreeImage_SetChannel(FDib, Blue.FDib, FICC_BLUE); + + Change + end + else + Result := False; +end; + +function TFreeBitmap.ConvertTo16Bits555: Boolean; +var + dib16_555: PFIBITMAP; +begin + if FDib <> nil then + begin + dib16_555 := FreeImage_ConvertTo16Bits555(FDib); + Result := Replace(dib16_555); + end + else + Result := False +end; + +function TFreeBitmap.ConvertTo16Bits565: Boolean; +var + dib16_565: PFIBITMAP; +begin + if FDib <> nil then + begin + dib16_565 := FreeImage_ConvertTo16Bits565(FDib); + Result := Replace(dib16_565); + end + else + Result := False +end; + +function TFreeBitmap.ConvertTo24Bits: Boolean; +var + dibRGB: PFIBITMAP; +begin + if FDib <> nil then + begin + dibRGB := FreeImage_ConvertTo24Bits(FDib); + Result := Replace(dibRGB); + end + else + Result := False +end; + +function TFreeBitmap.ConvertTo32Bits: Boolean; +var + dib32: PFIBITMAP; +begin + if FDib <> nil then + begin + dib32 := FreeImage_ConvertTo32Bits(FDib); + Result := Replace(dib32); + end + else + Result := False +end; + +function TFreeBitmap.ConvertTo4Bits: Boolean; +var + dib4: PFIBITMAP; +begin + Result := False; + if IsValid then + begin + dib4 := FreeImage_ConvertTo4Bits(FDib); + Result := Replace(dib4); + end; +end; + +function TFreeBitmap.ConvertTo8Bits: Boolean; +var + dib8: PFIBITMAP; +begin + if FDib <> nil then + begin + dib8 := FreeImage_ConvertTo8Bits(FDib); + Result := Replace(dib8); + end + else + Result := False +end; + +function TFreeBitmap.ConvertToGrayscale: Boolean; +var + dib8: PFIBITMAP; +begin + Result := False; + + if IsValid then + begin + dib8 := FreeImage_ConvertToGreyscale(FDib); + Result := Replace(dib8); + end +end; + +function TFreeBitmap.ConvertToRGBF: Boolean; +var + ImageType: FREE_IMAGE_TYPE; + NewDib: PFIBITMAP; +begin + Result := False; + if not IsValid then Exit; + + ImageType := GetImageType; + + if (ImageType = FIT_BITMAP) then + begin + if GetBitsPerPixel < 24 then + if not ConvertTo24Bits then + Exit + end; + NewDib := FreeImage_ConvertToRGBF(FDib); + Result := Replace(NewDib); +end; + +function TFreeBitmap.ConvertToStandardType(ScaleLinear: Boolean): Boolean; +var + dibStandard: PFIBITMAP; +begin + if IsValid then + begin + dibStandard := FreeImage_ConvertToStandardType(FDib, ScaleLinear); + Result := Replace(dibStandard); + end + else + Result := False; +end; + +function TFreeBitmap.ConvertToType(ImageType: FREE_IMAGE_TYPE; + ScaleLinear: Boolean): Boolean; +var + dib: PFIBITMAP; +begin + if FDib <> nil then + begin + dib := FreeImage_ConvertToType(FDib, ImageType, ScaleLinear); + Result := Replace(dib) + end + else + Result := False +end; + +function TFreeBitmap.CopySubImage(Left, Top, Right, Bottom: Integer; + Dest: TFreeBitmap): Boolean; +begin + if FDib <> nil then + begin + Dest.FDib := FreeImage_Copy(FDib, Left, Top, Right, Bottom); + Result := Dest.IsValid; + end else + Result := False; +end; + +constructor TFreeBitmap.Create(ImageType: FREE_IMAGE_TYPE; Width, Height, + Bpp: Integer); +begin + inherited Create; + + FDib := nil; + if (Width > 0) and (Height > 0) and (Bpp > 0) then + SetSize(ImageType, Width, Height, Bpp); +end; + +destructor TFreeBitmap.Destroy; +begin + if FDib <> nil then + FreeImage_Unload(FDib); + inherited; +end; + +function TFreeBitmap.Dither(Algorithm: FREE_IMAGE_DITHER): Boolean; +var + dib: PFIBITMAP; +begin + if FDib <> nil then + begin + dib := FreeImage_Dither(FDib, Algorithm); + Result := Replace(dib); + end + else + Result := False; +end; + +function TFreeBitmap.DoChanging(var OldDib, NewDib: PFIBITMAP): Boolean; +begin + Result := False; + if (OldDib <> NewDib) and Assigned(FOnChanging) then + FOnChanging(Self, OldDib, NewDib, Result); +end; + +procedure TFreeBitmap.FindCloseMetadata(MDHandle: PFIMETADATA); +begin + FreeImage_FindCloseMetadata(MDHandle); +end; + +function TFreeBitmap.FindFirstMetadata(Model: FREE_IMAGE_MDMODEL; + var Tag: TFreeTag): PFIMETADATA; +begin + Result := FreeImage_FindFirstMetadata(Model, FDib, Tag.FTag); +end; + +function TFreeBitmap.FindNextMetadata(MDHandle: PFIMETADATA; + var Tag: TFreeTag): Boolean; +begin + Result := FreeImage_FindNextMetadata(MDHandle, Tag.FTag); +end; + +function TFreeBitmap.FlipHorizontal: Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_FlipHorizontal(FDib); + Change; + end + else + Result := False +end; + +function TFreeBitmap.FlipVertical: Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_FlipVertical(FDib); + Change; + end + else + Result := False +end; + +function TFreeBitmap.GetBitsPerPixel: Integer; +begin + Result := FreeImage_GetBPP(FDib) +end; + +function TFreeBitmap.GetChannel(Bitmap: TFreeBitmap; + Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; +begin + if FDib <> nil then + begin + Bitmap.Dib := FreeImage_GetChannel(FDib, Channel); + Result := Bitmap.IsValid; + end + else + Result := False +end; + +function TFreeBitmap.GetColorsUsed: Integer; +begin + Result := FreeImage_GetColorsUsed(FDib) +end; + +function TFreeBitmap.GetColorType: FREE_IMAGE_COLOR_TYPE; +begin + Result := FreeImage_GetColorType(FDib); +end; + +function TFreeBitmap.GetFileBkColor(var BkColor: PRGBQuad): Boolean; +begin + Result := FreeImage_GetBackgroundColor(FDib, BkColor) +end; + +function TFreeBitmap.GetHeight: Integer; +begin + Result := FreeImage_GetHeight(FDib) +end; + +function TFreeBitmap.GetHistogram(Histo: PDWORD; + Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; +begin + if FDib <> nil then + Result := FreeImage_GetHistogram(FDib, Histo, Channel) + else + Result := False +end; + +function TFreeBitmap.GetHorizontalResolution: Double; +begin + Result := FreeImage_GetDotsPerMeterX(FDib) / 100 +end; + +function TFreeBitmap.GetImageSize: Cardinal; +begin + Result := FreeImage_GetDIBSize(FDib); +end; + +function TFreeBitmap.GetImageType: FREE_IMAGE_TYPE; +begin + Result := FreeImage_GetImageType(FDib); +end; + +function TFreeBitmap.GetInfo: PBitmapInfo; +begin + Result := FreeImage_GetInfo(FDib^) +end; + +function TFreeBitmap.GetInfoHeader: PBITMAPINFOHEADER; +begin + Result := FreeImage_GetInfoHeader(FDib) +end; + +function TFreeBitmap.GetLine: Integer; +begin + Result := FreeImage_GetLine(FDib) +end; + +function TFreeBitmap.GetMetadata(Model: FREE_IMAGE_MDMODEL; + const Key: string; var Tag: TFreeTag): Boolean; +begin + Result := FreeImage_GetMetaData(Model, FDib, PChar(Key), Tag.FTag); +end; + +function TFreeBitmap.GetMetadataCount(Model: FREE_IMAGE_MDMODEL): Cardinal; +begin + Result := FreeImage_GetMetadataCount(Model, FDib); +end; + +function TFreeBitmap.GetPalette: PRGBQUAD; +begin + Result := FreeImage_GetPalette(FDib) +end; + +function TFreeBitmap.GetPaletteSize: Integer; +begin + Result := FreeImage_GetColorsUsed(FDib) * SizeOf(RGBQUAD) +end; + +function TFreeBitmap.GetPixelColor(X, Y: Cardinal; Value: PRGBQUAD): Boolean; +begin + Result := FreeImage_GetPixelColor(FDib, X, Y, Value) +end; + +function TFreeBitmap.GetPixelIndex(X, Y: Cardinal; + var Value: PByte): Boolean; +begin + Result := FreeImage_GetPixelIndex(FDib, X, Y, Value) +end; + +function TFreeBitmap.GetScanLine(ScanLine: Integer): PByte; +var + H: Integer; +begin + H := FreeImage_GetHeight(FDib); + if ScanLine < H then + Result := FreeImage_GetScanLine(FDib, ScanLine) + else + Result := nil; +end; + +function TFreeBitmap.GetScanWidth: Integer; +begin + Result := FreeImage_GetPitch(FDib) +end; + +function TFreeBitmap.GetTransparencyCount: Cardinal; +begin + Result := FreeImage_GetTransparencyCount(FDib) +end; + +function TFreeBitmap.GetTransparencyTable: PByte; +begin + Result := FreeImage_GetTransparencyTable(FDib) +end; + +function TFreeBitmap.GetVerticalResolution: Double; +begin + Result := FreeImage_GetDotsPerMeterY(Fdib) / 100 +end; + +function TFreeBitmap.GetWidth: Integer; +begin + Result := FreeImage_GetWidth(FDib) +end; + +function TFreeBitmap.HasFileBkColor: Boolean; +begin + Result := FreeImage_HasBackgroundColor(FDib) +end; + +function TFreeBitmap.Invert: Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_Invert(FDib); + Change; + end + else + Result := False +end; + +function TFreeBitmap.IsGrayScale: Boolean; +begin + Result := (FreeImage_GetBPP(FDib) = 8) + and (FreeImage_GetColorType(FDib) = FIC_PALETTE); +end; + +function TFreeBitmap.IsTransparent: Boolean; +begin + Result := FreeImage_IsTransparent(FDib); +end; + +function TFreeBitmap.IsValid: Boolean; +begin + Result := FDib <> nil +end; + +function TFreeBitmap.Load(const FileName: string; Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + + // check the file signature and get its format + fif := FreeImage_GetFileType(PChar(Filename), 0); + if fif = FIF_UNKNOWN then + // no signature? + // try to guess the file format from the file extention + fif := FreeImage_GetFIFFromFilename(PChar(FileName)); + + // check that the plugin has reading capabilities ... + if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then + begin + // free the previous dib + if FDib <> nil then + FreeImage_Unload(dib); + + // load the file + FDib := FreeImage_Load(fif, PChar(FileName), Flag); + + Change; + Result := IsValid; + end else + Result := False; +end; + +function TFreeBitmap.LoadFromHandle(IO: PFreeImageIO; Handle: fi_handle; + Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + // check the file signature and get its format + fif := FreeImage_GetFileTypeFromHandle(IO, Handle, 16); + if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then + begin + // free the previous dib + if FDib <> nil then + FreeImage_Unload(FDib); + + // load the file + FDib := FreeImage_LoadFromHandle(fif, IO, Handle, Flag); + + Change; + Result := IsValid; + end else + Result := False; +end; + +function TFreeBitmap.LoadFromMemory(MemIO: TFreeMemoryIO; + Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + + // check the file signature and get its format + fif := MemIO.GetFileType; + if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(fif) then + begin + // free the previous dib + if FDib <> nil then + FreeImage_Unload(FDib); + + // load the file + FDib := MemIO.Read(fif, Flag); + + Result := IsValid; + Change; + end else + Result := False; +end; + +function TFreeBitmap.LoadFromStream(Stream: TStream; + Flag: Integer): Boolean; +var + MemIO: TFreeMemoryIO; + Data: PByte; + MemStream: TMemoryStream; + Size: Cardinal; +begin + Size := Stream.Size; + + MemStream := TMemoryStream.Create; + try + MemStream.CopyFrom(Stream, Size); + Data := MemStream.Memory; + + MemIO := TFreeMemoryIO.Create(Data, Size); + try + Result := LoadFromMemory(MemIO); + finally + MemIO.Free; + end; + finally + MemStream.Free; + end; +end; + +function TFreeBitmap.LoadU(const FileName: WideString; + Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + + // check the file signature and get its format + fif := FreeImage_GetFileTypeU(PWideChar(Filename), 0); + if fif = FIF_UNKNOWN then + // no signature? + // try to guess the file format from the file extention + fif := FreeImage_GetFIFFromFilenameU(PWideChar(FileName)); + + // check that the plugin has reading capabilities ... + if (fif <> FIF_UNKNOWN) and FreeImage_FIFSupportsReading(FIF) then + begin + // free the previous dib + if FDib <> nil then + FreeImage_Unload(dib); + + // load the file + FDib := FreeImage_LoadU(fif, PWideChar(FileName), Flag); + + Change; + Result := IsValid; + end else + Result := False; +end; + +procedure TFreeBitmap.MakeThumbnail(const Width, Height: Integer; + DestBitmap: TFreeBitmap); +type + PRGB24 = ^TRGB24; + TRGB24 = packed record + B: Byte; + G: Byte; + R: Byte; + end; +var + x, y, ix, iy: integer; + x1, x2, x3: integer; + + xscale, yscale: single; + iRed, iGrn, iBlu, iRatio: Longword; + p, c1, c2, c3, c4, c5: TRGB24; + pt, pt1: PRGB24; + iSrc, iDst, s1: integer; + i, j, r, g, b, tmpY: integer; + + RowDest, RowSource, RowSourceStart: integer; + w, h: Integer; + dxmin, dymin: integer; + ny1, ny2, ny3: integer; + dx, dy: integer; + lutX, lutY: array of integer; + + SrcBmp, DestBmp: PFIBITMAP; +begin + if not IsValid then Exit; + + if (GetWidth <= ThumbSize) and (GetHeight <= ThumbSize) then + begin + DestBitmap.Assign(Self); + Exit; + end; + + w := Width; + h := Height; + + // prepare bitmaps + if GetBitsPerPixel <> 24 then + SrcBmp := FreeImage_ConvertTo24Bits(FDib) + else + SrcBmp := FDib; + DestBmp := FreeImage_Allocate(w, h, 24); + Assert(DestBmp <> nil, 'TFreeBitmap.MakeThumbnail error'); + +{ iDst := (w * 24 + 31) and not 31; + iDst := iDst div 8; //BytesPerScanline + iSrc := (GetWidth * 24 + 31) and not 31; + iSrc := iSrc div 8; +} + // BytesPerScanline + iDst := FreeImage_GetPitch(DestBmp); + iSrc := FreeImage_GetPitch(SrcBmp); + + xscale := 1 / (w / FreeImage_GetWidth(SrcBmp)); + yscale := 1 / (h / FreeImage_GetHeight(SrcBmp)); + + // X lookup table + SetLength(lutX, w); + x1 := 0; + x2 := trunc(xscale); + for x := 0 to w - 1 do + begin + lutX[x] := x2 - x1; + x1 := x2; + x2 := trunc((x + 2) * xscale); + end; + + // Y lookup table + SetLength(lutY, h); + x1 := 0; + x2 := trunc(yscale); + for x := 0 to h - 1 do + begin + lutY[x] := x2 - x1; + x1 := x2; + x2 := trunc((x + 2) * yscale); + end; + + Dec(w); + Dec(h); + RowDest := integer(FreeImage_GetScanLine(DestBmp, 0)); + RowSourceStart := integer(FreeImage_GetScanLine(SrcBmp, 0)); + RowSource := RowSourceStart; + + for y := 0 to h do + // resampling + begin + dy := lutY[y]; + x1 := 0; + x3 := 0; + for x := 0 to w do // loop through row + begin + dx:= lutX[x]; + iRed:= 0; + iGrn:= 0; + iBlu:= 0; + RowSource := RowSourceStart; + for iy := 1 to dy do + begin + pt := PRGB24(RowSource + x1); + for ix := 1 to dx do + begin + iRed := iRed + pt.R; + iGrn := iGrn + pt.G; + iBlu := iBlu + pt.B; + inc(pt); + end; + RowSource := RowSource + iSrc; + end; + iRatio := 65535 div (dx * dy); + pt1 := PRGB24(RowDest + x3); + pt1.R := (iRed * iRatio) shr 16; + pt1.G := (iGrn * iRatio) shr 16; + pt1.B := (iBlu * iRatio) shr 16; + x1 := x1 + 3 * dx; + inc(x3,3); + end; + RowDest := RowDest + iDst; + RowSourceStart := RowSource; + end; // resampling + + if FreeImage_GetHeight(DestBmp) >= 3 then + // Sharpening... + begin + s1 := integer(FreeImage_GetScanLine(DestBmp, 0)); + iDst := integer(FreeImage_GetScanLine(DestBmp, 1)) - s1; + ny1 := Integer(s1); + ny2 := ny1 + iDst; + ny3 := ny2 + iDst; + for y := 1 to FreeImage_GetHeight(DestBmp) - 2 do + begin + for x := 0 to FreeImage_GetWidth(DestBmp) - 3 do + begin + x1 := x * 3; + x2 := x1 + 3; + x3 := x1 + 6; + + c1 := pRGB24(ny1 + x1)^; + c2 := pRGB24(ny1 + x3)^; + c3 := pRGB24(ny2 + x2)^; + c4 := pRGB24(ny3 + x1)^; + c5 := pRGB24(ny3 + x3)^; + + r := (c1.R + c2.R + (c3.R * -12) + c4.R + c5.R) div -8; + g := (c1.G + c2.G + (c3.G * -12) + c4.G + c5.G) div -8; + b := (c1.B + c2.B + (c3.B * -12) + c4.B + c5.B) div -8; + + if r < 0 then r := 0 else if r > 255 then r := 255; + if g < 0 then g := 0 else if g > 255 then g := 255; + if b < 0 then b := 0 else if b > 255 then b := 255; + + pt1 := pRGB24(ny2 + x2); + pt1.R := r; + pt1.G := g; + pt1.B := b; + end; + inc(ny1, iDst); + inc(ny2, iDst); + inc(ny3, iDst); + end; + end; // sharpening + + if SrcBmp <> FDib then + FreeImage_Unload(SrcBmp); + DestBitmap.Replace(DestBmp); +end; + +function TFreeBitmap.PasteSubImage(Src: TFreeBitmap; Left, Top, + Alpha: Integer): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_Paste(FDib, Src.Dib, Left, Top, Alpha); + Change; + end else + Result := False; +end; + +function TFreeBitmap.Replace(NewDib: PFIBITMAP): Boolean; +begin + Result := False; + if NewDib = nil then Exit; + + if not DoChanging(FDib, NewDib) and IsValid then + FreeImage_Unload(FDib); + + FDib := NewDib; + Result := True; + Change; +end; + +function TFreeBitmap.Rescale(NewWidth, NewHeight: Integer; + Filter: FREE_IMAGE_FILTER; Dest: TFreeBitmap): Boolean; +var + Bpp: Integer; + DstDib: PFIBITMAP; +begin + Result := False; + + if FDib <> nil then + begin + Bpp := FreeImage_GetBPP(FDib); + + if Bpp < 8 then + if not ConvertToGrayscale then Exit + else + if Bpp = 16 then + // convert to 24-bit + if not ConvertTo24Bits then Exit; + + // perform upsampling / downsampling + DstDib := FreeImage_Rescale(FDib, NewWidth, NewHeight, Filter); + if Dest = nil then + Result := Replace(DstDib) + else + Result := Dest.Replace(DstDib) + end +end; + +function TFreeBitmap.Rotate(Angle: Double): Boolean; +var + Bpp: Integer; + Rotated: PFIBITMAP; +begin + Result := False; + if IsValid then + begin + Bpp := FreeImage_GetBPP(FDib); + if Bpp in [1, 8, 24, 32] then + begin + Rotated := FreeImage_RotateClassic(FDib, Angle); + Result := Replace(Rotated); + end + end; +end; + +function TFreeBitmap.RotateEx(Angle, XShift, YShift, XOrigin, + YOrigin: Double; UseMask: Boolean): Boolean; +var + Rotated: PFIBITMAP; +begin + Result := False; + if FDib <> nil then + begin + if FreeImage_GetBPP(FDib) >= 8 then + begin + Rotated := FreeImage_RotateEx(FDib, Angle, XShift, YShift, XOrigin, YOrigin, UseMask); + Result := Replace(Rotated); + end + end; +end; + +function TFreeBitmap.Save(const FileName: string; Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + Result := False; + + // try to guess the file format from the file extension + fif := FreeImage_GetFIFFromFilename(PChar(Filename)); + if CanSave(fif) then + Result := FreeImage_Save(fif, FDib, PChar(FileName), Flag); +end; + +function TFreeBitmap.SaveToHandle(fif: FREE_IMAGE_FORMAT; IO: PFreeImageIO; + Handle: fi_handle; Flag: Integer): Boolean; +begin + Result := False; + if CanSave(fif) then + Result := FreeImage_SaveToHandle(fif, FDib, IO, Handle, Flag) +end; + +function TFreeBitmap.SaveToMemory(fif: FREE_IMAGE_FORMAT; + MemIO: TFreeMemoryIO; Flag: Integer): Boolean; +begin + Result := False; + + if CanSave(fif) then + Result := MemIO.Write(fif, FDib, Flag) +end; + +function TFreeBitmap.SaveToStream(fif: FREE_IMAGE_FORMAT; Stream: TStream; + Flag: Integer): Boolean; +var + MemIO: TFreeMemoryIO; + Data: PByte; + Size: Cardinal; +begin + MemIO := TFreeMemoryIO.Create; + try + Result := SaveToMemory(fif, MemIO, Flag); + if Result then + begin + MemIO.Acquire(Data, Size); + Stream.WriteBuffer(Data^, Size); + end; + finally + MemIO.Free; + end; +end; + +function TFreeBitmap.SaveU(const FileName: WideString; + Flag: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + Result := False; + + // try to guess the file format from the file extension + fif := FreeImage_GetFIFFromFilenameU(PWideChar(Filename)); + if CanSave(fif) then + Result := FreeImage_SaveU(fif, FDib, PWideChar(FileName), Flag); +end; + +function TFreeBitmap.SetChannel(Bitmap: TFreeBitmap; + Channel: FREE_IMAGE_COLOR_CHANNEL): Boolean; +begin + if FDib <> nil then + begin + Result := FreeImage_SetChannel(FDib, Bitmap.FDib, Channel); + Change; + end + else + Result := False +end; + +procedure TFreeBitmap.SetDib(Value: PFIBITMAP); +begin + Replace(Value); +end; + +function TFreeBitmap.SetFileBkColor(BkColor: PRGBQuad): Boolean; +begin + Result := FreeImage_SetBackgroundColor(FDib, BkColor); + Change; +end; + +procedure TFreeBitmap.SetHorizontalResolution(Value: Double); +begin + if IsValid then + begin + FreeImage_SetDotsPerMeterX(FDib, Trunc(Value * 100 + 0.5)); + Change; + end; +end; + +function TFreeBitmap.SetMetadata(Model: FREE_IMAGE_MDMODEL; + const Key: string; Tag: TFreeTag): Boolean; +begin + Result := FreeImage_SetMetadata(Model, FDib, PChar(Key), Tag.Tag); +end; + +function TFreeBitmap.SetPixelColor(X, Y: Cardinal; + Value: PRGBQUAD): Boolean; +begin + Result := FreeImage_SetPixelColor(FDib, X, Y, Value); + Change; +end; + +function TFreeBitmap.SetPixelIndex(X, Y: Cardinal; Value: PByte): Boolean; +begin + Result := FreeImage_SetPixelIndex(FDib, X, Y, Value); + Change; +end; + +function TFreeBitmap.SetSize(ImageType: FREE_IMAGE_TYPE; Width, Height, + Bpp: Integer; RedMask, GreenMask, BlueMask: Cardinal): Boolean; +var + Pal: PRGBQuad; + I: Cardinal; +begin + Result := False; + + if FDib <> nil then + FreeImage_Unload(FDib); + + FDib := FreeImage_Allocate(Width, Height, Bpp, RedMask, GreenMask, BlueMask); + if FDib = nil then Exit; + + if ImageType = FIT_BITMAP then + case Bpp of + 1, 4, 8: + begin + Pal := FreeImage_GetPalette(FDib); + for I := 0 to FreeImage_GetColorsUsed(FDib) - 1 do + begin + Pal.rgbBlue := I; + Pal.rgbGreen := I; + Pal.rgbRed := I; + Inc(Pal, SizeOf(RGBQUAD)); + end; + end; + end; + + Result := True; + Change; +end; + +procedure TFreeBitmap.SetTransparencyTable(Table: PByte; Count: Integer); +begin + FreeImage_SetTransparencyTable(FDib, Table, Count); + Change; +end; + +procedure TFreeBitmap.SetVerticalResolution(Value: Double); +begin + if IsValid then + begin + FreeImage_SetDotsPerMeterY(FDib, Trunc(Value * 100 + 0.5)); + Change; + end; +end; + +function TFreeBitmap.SplitChannels(RedChannel, GreenChannel, + BlueChannel: TFreeBitmap): Boolean; +begin + if FDib <> nil then + begin + RedChannel.FDib := FreeImage_GetChannel(FDib, FICC_RED); + GreenChannel.FDib := FreeImage_GetChannel(FDib, FICC_GREEN); + BlueChannel.FDib := FreeImage_GetChannel(FDib, FICC_BLUE); + Result := RedChannel.IsValid and GreenChannel.IsValid and BlueChannel.IsValid; + end + else + Result := False +end; + +function TFreeBitmap.Threshold(T: Byte): Boolean; +var + dib1: PFIBITMAP; +begin + if FDib <> nil then + begin + dib1 := FreeImage_Threshold(FDib, T); + Result := Replace(dib1); + end + else + Result := False +end; + +function TFreeBitmap.ToneMapping(TMO: FREE_IMAGE_TMO; FirstParam, + SecondParam: Double): Boolean; +var + NewDib: PFIBITMAP; +begin + Result := False; + if not IsValid then Exit; + + NewDib := FreeImage_ToneMapping(Fdib, TMO, FirstParam, SecondParam); + Result := Replace(NewDib); +end; + + +{ TFreeMultiBitmap } + +procedure TFreeMultiBitmap.AppendPage(Bitmap: TFreeBitmap); +begin + if IsValid then + FreeImage_AppendPage(FMPage, Bitmap.FDib); +end; + +function TFreeMultiBitmap.Close(Flags: Integer): Boolean; +begin + Result := FreeImage_CloseMultiBitmap(FMPage, Flags); + FMPage := nil; +end; + +constructor TFreeMultiBitmap.Create(KeepCacheInMemory: Boolean); +begin + inherited Create; + FMemoryCache := KeepCacheInMemory; +end; + +procedure TFreeMultiBitmap.DeletePage(Page: Integer); +begin + if IsValid then + FreeImage_DeletePage(FMPage, Page); +end; + +destructor TFreeMultiBitmap.Destroy; +begin + if FMPage <> nil then Close; + inherited; +end; + +function TFreeMultiBitmap.GetLockedPageNumbers(var Pages, + Count: Integer): Boolean; +begin + Result := False; + if not IsValid then Exit; + Result := FreeImage_GetLockedPageNumbers(FMPage, Pages, Count) +end; + +function TFreeMultiBitmap.GetPageCount: Integer; +begin + Result := 0; + if IsValid then + Result := FreeImage_GetPageCount(FMPage) +end; + +procedure TFreeMultiBitmap.InsertPage(Page: Integer; Bitmap: TFreeBitmap); +begin + if IsValid then + FreeImage_InsertPage(FMPage, Page, Bitmap.FDib); +end; + +function TFreeMultiBitmap.IsValid: Boolean; +begin + Result := FMPage <> nil +end; + +procedure TFreeMultiBitmap.LockPage(Page: Integer; DestBitmap: TFreeBitmap); +begin + if not IsValid then Exit; + + if Assigned(DestBitmap) then + begin + DestBitmap.Replace(FreeImage_LockPage(FMPage, Page)); + end; +end; + +function TFreeMultiBitmap.MovePage(Target, Source: Integer): Boolean; +begin + Result := False; + if not IsValid then Exit; + Result := FreeImage_MovePage(FMPage, Target, Source); +end; + +function TFreeMultiBitmap.Open(const FileName: string; CreateNew, + ReadOnly: Boolean; Flags: Integer): Boolean; +var + fif: FREE_IMAGE_FORMAT; +begin + Result := False; + + // try to guess the file format from the filename + fif := FreeImage_GetFIFFromFilename(PChar(FileName)); + + // check for supported file types + if (fif <> FIF_UNKNOWN) and (not fif in [FIF_TIFF, FIF_ICO, FIF_GIF]) then + Exit; + + // open the stream + FMPage := FreeImage_OpenMultiBitmap(fif, PChar(FileName), CreateNew, ReadOnly, FMemoryCache, Flags); + + Result := FMPage <> nil; +end; + +procedure TFreeMultiBitmap.UnlockPage(Bitmap: TFreeBitmap; + Changed: Boolean); +begin + if IsValid then + begin + FreeImage_UnlockPage(FMPage, Bitmap.FDib, Changed); + // clear the image so that it becomes invalid. + // don't use Bitmap.Clear method because it calls FreeImage_Unload + // just clear the pointer + Bitmap.FDib := nil; + Bitmap.Change; + end; +end; + +{ TFreeMemoryIO } + +function TFreeMemoryIO.Acquire(var Data: PByte; + var SizeInBytes: DWORD): Boolean; +begin + Result := FreeImage_AcquireMemory(FHMem, Data, SizeInBytes); +end; + +constructor TFreeMemoryIO.Create(Data: PByte; SizeInBytes: DWORD); +begin + inherited Create; + FHMem := FreeImage_OpenMemory(Data, SizeInBytes); +end; + +destructor TFreeMemoryIO.Destroy; +begin + FreeImage_CloseMemory(FHMem); + inherited; +end; + +function TFreeMemoryIO.GetFileType: FREE_IMAGE_FORMAT; +begin + Result := FreeImage_GetFileTypeFromMemory(FHMem); +end; + +function TFreeMemoryIO.IsValid: Boolean; +begin + Result := FHMem <> nil +end; + +function TFreeMemoryIO.Read(fif: FREE_IMAGE_FORMAT; + Flag: Integer): PFIBITMAP; +begin + Result := FreeImage_LoadFromMemory(fif, FHMem, Flag) +end; + +function TFreeMemoryIO.Seek(Offset: Longint; Origin: Word): Boolean; +begin + Result := FreeImage_SeekMemory(FHMem, Offset, Origin) +end; + +function TFreeMemoryIO.Tell: Longint; +begin + Result := FreeImage_TellMemory(FHMem) +end; + +function TFreeMemoryIO.Write(fif: FREE_IMAGE_FORMAT; dib: PFIBITMAP; + Flag: Integer): Boolean; +begin + Result := FreeImage_SaveToMemory(fif, dib, FHMem, Flag) +end; + +{ TFreeTag } + +function TFreeTag.Clone: TFreeTag; +var + CloneTag: PFITAG; +begin + Result := nil; + if not IsValid then Exit; + + CloneTag := FreeImage_CloneTag(FTag); + Result := TFreeTag.Create(CloneTag); +end; + +constructor TFreeTag.Create(ATag: PFITAG); +begin + inherited Create; + + if ATag <> nil then + FTag := ATag + else + FTag := FreeImage_CreateTag; +end; + +destructor TFreeTag.Destroy; +begin + if IsValid then + FreeImage_DeleteTag(FTag); + + inherited; +end; + +function TFreeTag.GetCount: Cardinal; +begin + Result := 0; + if not IsValid then Exit; + + Result := FreeImage_GetTagCount(FTag); +end; + +function TFreeTag.GetDescription: string; +begin + Result := ''; + if not IsValid then Exit; + + Result := FreeImage_GetTagDescription(FTag); +end; + +function TFreeTag.GetID: Word; +begin + Result := 0; + if not IsValid then Exit; + + Result := FreeImage_GetTagID(FTag); +end; + +function TFreeTag.GetKey: string; +begin + Result := ''; + if not IsValid then Exit; + + Result := FreeImage_GetTagKey(FTag); +end; + +function TFreeTag.GetLength: Cardinal; +begin + Result := 0; + if not IsValid then Exit; + + Result := FreeImage_GetTagLength(FTag); +end; + +function TFreeTag.GetTagType: FREE_IMAGE_MDTYPE; +begin + Result := FIDT_NOTYPE; + if not IsValid then Exit; + + Result := FreeImage_GetTagType(FTag); +end; + +function TFreeTag.GetValue: Pointer; +begin + Result := nil; + if not IsValid then Exit; + + Result := FreeImage_GetTagValue(FTag); +end; + +function TFreeTag.IsValid: Boolean; +begin + Result := FTag <> nil; +end; + +procedure TFreeTag.SetCount(const Value: Cardinal); +begin + if IsValid then + FreeImage_SetTagCount(FTag, Value); +end; + +procedure TFreeTag.SetDescription(const Value: string); +begin + if IsValid then + FreeImage_SetTagDescription(FTag, PChar(Value)); +end; + +procedure TFreeTag.SetID(const Value: Word); +begin + if IsValid then + FreeImage_SetTagID(FTag, Value); +end; + +procedure TFreeTag.SetKey(const Value: string); +begin + if IsValid then + FreeImage_SetTagKey(FTag, PChar(Value)); +end; + +procedure TFreeTag.SetLength(const Value: Cardinal); +begin + if IsValid then + FreeImage_SetTagLength(FTag, Value); +end; + +procedure TFreeTag.SetTagType(const Value: FREE_IMAGE_MDTYPE); +begin + if IsValid then + FreeImage_SetTagType(FTag, Value); +end; + +procedure TFreeTag.SetValue(const Value: Pointer); +begin + if IsValid then + FreeImage_SetTagValue(FTag, Value); +end; + +function TFreeTag.ToString(Model: FREE_IMAGE_MDMODEL; Make: PChar): string; +begin + Result := FreeImage_TagToString(Model, FTag, Make); +end; + +end. |