From 79fb46a12b3999eb46576392ed3cf922ab5ee348 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Sat, 2 Nov 2013 14:50:56 +0100 Subject: [PATCH] * refactored FormatDescriptor * reimplemented LoadBMP (everything except RLE compression is supported) --- glBitmap.pas | 2897 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 1800 insertions(+), 1097 deletions(-) diff --git a/glBitmap.pas b/glBitmap.pas index 12e84af..b2a1476 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -590,171 +590,115 @@ type EglBitmapUnsupportedFormatFormat = class(EglBitmapException); //////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapPixelDesc = packed record - RedRange: Cardinal; - RedShift: Shortint; - GreenRange: Cardinal; - GreenShift: Shortint; - BlueRange: Cardinal; - BlueShift: Shortint; - AlphaRange: Cardinal; - AlphaShift: Shortint; - end; - PglBitmapPixelDesc = ^TglBitmapPixelDesc; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapPixelData = packed record - Red: Cardinal; - Green: Cardinal; - Blue: Cardinal; - Alpha: Cardinal; - PixelDesc: TglBitmapPixelDesc; - end; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapFormatDesc = packed record - Format: Cardinal; - InternalFormat: Cardinal; - DataType: Cardinal; - end; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapPixelPositionFields = set of (ffX, ffY); - TglBitmapPixelPosition = record - Fields : TglBitmapPixelPositionFields; - X : Word; - Y : Word; - end; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmap = class; - TglBitmapFunctionRec = record - Sender: TglBitmap; - Size: TglBitmapPixelPosition; - Position: TglBitmapPixelPosition; - Source: TglBitmapPixelData; - Dest: TglBitmapPixelData; - Args: PtrInt; - end; - TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec); - -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapFileType = ( - {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} - {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} - ftDDS, - ftTGA, - ftBMP); - TglBitmapFileTypes = set of TglBitmapFileType; - - TglBitmapMipMap = ( - mmNone, - mmMipmap, - mmMipmapGlu); - - TglBitmapNormalMapFunc = ( - nm4Samples, - nmSobel, - nm3x3, - nm5x5); - TglBitmapFormat = ( tfEmpty = 0, - //TODO + //tfAlpha4, - //tfAlpha8, + tfAlpha8, //tfAlpha12, - //tfAlpha16, + tfAlpha16, //tfLuminance4, tfLuminance8, //tfLuminance12, - //tfLuminance16, - // - //tfuminance4Alpha4, - //tfLuminance6Alpha2, + tfLuminance16, + + tfLuminance4Alpha4, + tfLuminance6Alpha2, tfLuminance8Alpha8, - //tfLuminance12Alpha4, + tfLuminance12Alpha4, //tfLuminance12Alpha12, - //tfLuminance16Alpha16, + tfLuminance16Alpha16, - //tfR3G3B2, - //tfRGB4, + tfR3G3B2, + tfRGB4, + tfR5G6B5, tfRGB5, tfRGB8, - //tfRGB10, + tfRGB10, //tfRGB12, - //tfRGB16, + tfRGB16, - //tfRGBA2, - //tfRGBA4, + tfRGBA2, + tfRGBA4, tfRGB5A1, tfRGBA8, - //tfRGB10A2, + tfRGB10A2, //tfRGBA12, - //tfRGBA16, + tfRGBA16, - //tfBGR4, - //tfBGR5, + tfBGR4, + tfB5G6R5, + tfBGR5, tfBGR8, - //tfBGR10, + tfBGR10, //tfBGR12, - //tfBGR16, + tfBGR16, - //tfBGRA2, - //tfBGRA4, - //tfBGR5A1, - tfBGRA8 - //tfBGR10A2, + tfBGRA2, + tfBGRA4, + tfBGR5A1, + tfBGRA8, + tfBGR10A2, //tfBGRA12, - //tfBGRA16, + tfBGRA16 //tfDepth16, //tfDepth24, //tfDepth32 ); -//////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapGetPixel = procedure(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData) of object; - TglBitmapSetPixel = procedure(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData) of object; - - TglBitmapMapFunc = procedure(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); - TglBitmapUnMapFunc = procedure(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); + TglBitmapFileType = ( + {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} + {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} + ftDDS, + ftTGA, + ftBMP); + TglBitmapFileTypes = set of TglBitmapFileType; + + TglBitmapMipMap = ( + mmNone, + mmMipmap, + mmMipmapGlu); + + TglBitmapNormalMapFunc = ( + nm4Samples, + nmSobel, + nm3x3, + nm5x5); //////////////////////////////////////////////////////////////////////////////////////////////////// - TglBitmapFormatDescriptor = class(TObject) - public - //virtual abstract - class function GetFormat: TglBitmapFormat; virtual; abstract; - class function GetPixelDesc: TglBitmapPixelDesc; virtual; abstract; - class function GetFormatDesc: TglBitmapFormatDesc; virtual; abstract; - - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); virtual; abstract; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); virtual; abstract; - - //virtual - class function WithoutAlpha: TglBitmapFormat; virtual; - class function WithAlpha: TglBitmapFormat; virtual; - - class function GetSize: Single; virtual; overload; - class function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload; - class function GetColorCompCount: Integer; virtual; + TglBitmapColorRec = packed record + case Integer of + 0: (r, g, b, a: Cardinal); + 1: (arr: array[0..3] of Cardinal); + end; - class function IsEmpty: Boolean; virtual; - class function HasAlpha: Boolean; virtual; - class function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual; + TglBitmapPixelData = packed record + Data, Range: TglBitmapColorRec; + Format: TglBitmapFormat; + end; + PglBitmapPixelData = ^TglBitmapPixelData; - class procedure PreparePixel(var aPixel: TglBitmapPixelData); virtual; +//////////////////////////////////////////////////////////////////////////////////////////////////// + TglBitmapPixelPositionFields = set of (ffX, ffY); + TglBitmapPixelPosition = record + Fields : TglBitmapPixelPositionFields; + X : Word; + Y : Word; + end; - (* TODO - function FormatIsCompressed(Format: TglBitmapInternalFormat): boolean; - function FormatIsUncompressed(Format: TglBitmapInternalFormat): boolean; - function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean; - function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean; - function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean; - *) +//////////////////////////////////////////////////////////////////////////////////////////////////// + TglBitmap = class; + TglBitmapFunctionRec = record + Sender: TglBitmap; + Size: TglBitmapPixelPosition; + Position: TglBitmapPixelPosition; + Source: TglBitmapPixelData; + Dest: TglBitmapPixelData; + Args: PtrInt; end; - TglBitmapFormatDescClass = class of TglBitmapFormatDescriptor; + TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TglBitmap = class @@ -775,8 +719,6 @@ type // Mapping fPixelSize: Integer; fRowSize: Integer; - //TODO delete? fUnmapFunc: TglBitmapUnMapFunc; - //TODO delete? fMapFunc: TglBitmapMapFunc; // Filtering fFilterMin: Cardinal; @@ -787,9 +729,6 @@ type fWrapT: Cardinal; fWrapR: Cardinal; - //TODO delete? fGetPixelFunc: TglBitmapGetPixel; - //TODO delete? fSetPixelFunc: TglBitmapSetPixel; - // CustomData fFilename: String; fCustomName: String; @@ -1064,6 +1003,7 @@ procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal); procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal); function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition; +function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec; var glBitmapDefaultDeleteTextureOnFree: Boolean; @@ -1082,170 +1022,301 @@ function CreateGrayPalette: HPALETTE; implementation + + (* TODO + function FormatIsCompressed(Format: TglBitmapInternalFormat): boolean; + function FormatIsUncompressed(Format: TglBitmapInternalFormat): boolean; + function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean; + function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean; + function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean; + *) + uses - Math; + Math, syncobjs; type -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TBitfieldFormat = class(TObject) +//////////////////////////////////////////////////////////////////////////////////////////////////// + TShiftRec = packed record + case Integer of + 0: (r, g, b, a: Byte); + 1: (arr: array[0..3] of Byte); + end; + + TFormatDescriptor = class(TObject) private - fRedShift: ShortInt; - fGreenShift: ShortInt; - fBlueShift: ShortInt; - fAlphaShift: ShortInt; - - fRedRange: Cardinal; - fGreenRange: Cardinal; - fBlueRange: Cardinal; - fAlphaRange: Cardinal; - - fRedMask: UInt64; - fGreenMask: UInt64; - fBlueMask: UInt64; - fAlphaMask: UInt64; - function GetSize: Integer; - procedure SetAlphaMask(aValue: UInt64); - procedure SetAlphaRange(aValue: Cardinal); - procedure SetAlphaShift(aValue: ShortInt); - procedure SetBlueMask(aValue: UInt64); - procedure SetBlueRange(aValue: Cardinal); - procedure SetBlueShift(aValue: ShortInt); - procedure SetGreenMask(aValue: UInt64); - procedure SetGreenRange(aValue: Cardinal); - procedure SetGreenShift(aValue: ShortInt); - procedure SetRedMask(aValue: UInt64); - procedure SetRedRange(aValue: Cardinal); - procedure SetRedShift(aValue: ShortInt); - - procedure CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal; out aShift: ShortInt); + function GetRedMask: UInt64; + function GetGreenMask: UInt64; + function GetBlueMask: UInt64; + function GetAlphaMask: UInt64; + protected + fFormat: TglBitmapFormat; + fWithAlpha: TglBitmapFormat; + fWithoutAlpha: TglBitmapFormat; + fPixelSize: Single; + + fRange: TglBitmapColorRec; + fShift: TShiftRec; + + fglFormat: Cardinal; + fglInternalFormat: Cardinal; + fglDataFormat: Cardinal; + + function GetComponents: Integer; virtual; public - property RedShift: ShortInt read fRedShift write SetRedShift; - property GreenShift: ShortInt read fGreenShift write SetGreenShift; - property BlueShift: ShortInt read fBlueShift write SetBlueShift; - property AlphaShift: ShortInt read fAlphaShift write SetAlphaShift; + property Format: TglBitmapFormat read fFormat; + property WithAlpha: TglBitmapFormat read fWithAlpha; + property WithoutAlpha: TglBitmapFormat read fWithoutAlpha; + property Components: Integer read GetComponents; + property PixelSize: Single read fPixelSize; - property RedRange: Cardinal read fRedRange write SetRedRange; - property GreenRange: Cardinal read fGreenRange write SetGreenRange; - property BlueRange: Cardinal read fBlueRange write SetBlueRange; - property AlphaRange: Cardinal read fAlphaRange write SetAlphaRange; + property glFormat: Cardinal read fglFormat; + property glInternalFormat: Cardinal read fglInternalFormat; + property glDataFormat: Cardinal read fglDataFormat; - property RedMask: UInt64 read fRedMask write SetRedMask; - property GreenMask: UInt64 read fGreenMask write SetGreenMask; - property BlueMask: UInt64 read fBlueMask write SetBlueMask; - property AlphaMask: UInt64 read fAlphaMask write SetAlphaMask; + property Range: TglBitmapColorRec read fRange; + property Shift: TShiftRec read fShift; - property Size: Integer read GetSize; + property RedMask: UInt64 read GetRedMask; + property GreenMask: UInt64 read GetGreenMask; + property BlueMask: UInt64 read GetBlueMask; + property AlphaMask: UInt64 read GetAlphaMask; - procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); - procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); overload; - procedure Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData); overload; - end; + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdEmpty = class(TglBitmapFormatDescriptor) + function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload; + function GetSize(const aWidth, aHeight: Integer): Integer; virtual; overload; + + function CreateMappingData: Pointer; virtual; + procedure FreeMappingData(var aMappingData: Pointer); virtual; + + function IsEmpty: Boolean; virtual; + function HasAlpha: Boolean; virtual; + function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual; + + procedure PreparePixel(var aPixel: TglBitmapPixelData); virtual; + + constructor Create; virtual; public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; + class procedure Init; + class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor; + class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor; + class procedure Clear; + class procedure Finalize; + end; + TFormatDescriptorClass = class of TFormatDescriptor; + + TfdEmpty = class(TFormatDescriptor); - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdAlpha8 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdLuminance8 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithAlpha: TglBitmapFormat; override; + TfdAlpha16 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdLuminance8 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdLuminance8Alpha8 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithoutAlpha: TglBitmapFormat; override; + TfdLuminance16 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; - end; + TfdLuminance4Alpha4 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdRGB5 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithAlpha: TglBitmapFormat; override; + TfdLuminance6Alpha2 = class(TfdLuminance4Alpha4) + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdLuminance8Alpha8 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdRGB8 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithAlpha: TglBitmapFormat; override; + TfdLuminance12Alpha4 = class(TfdLuminance8Alpha8) + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdLuminance16Alpha16 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdRGB5A1 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithoutAlpha: TglBitmapFormat; override; + TfdR3G3B2 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdRGB4 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdRGBA8 = class(TglBitmapFormatDescriptor) - public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithoutAlpha: TglBitmapFormat; override; + TfdR5G6B5 = class(TfdRGB4) + constructor Create; override; + end; + + TfdRGB5 = class(TfdRGB4) + constructor Create; override; + end; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + TfdRGB8 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdRGB10 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdRGB16 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdRGBA2 = class(TfdR3G3B2) + constructor Create; override; + end; + + TfdRGBA4 = class(TfdRGB4) + constructor Create; override; + end; + + TfdRGB5A1 = class(TfdRGB5) + constructor Create; override; + end; + + TfdRGBA8 = class(TfdRGB8) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdRGB10A2 = class(TfdRGB10) + constructor Create; override; + end; + + TfdRGBA16 = class(TfdRGB16) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdBGR4 = class(TfdRGB4) + constructor Create; override; + end; + + TfdB5G6R5 = class(TfdRGB4) + constructor Create; override; + end; + + TfdBGR5 = class(TfdRGB5) + constructor Create; override; + end; + + TfdBGR8 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdBGR10 = class(TfdRGB10) + constructor Create; override; + end; + + TfdBGR16 = class(TFormatDescriptor) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdBGRA2 = class(TfdRGBA2) + constructor Create; override; + end; + + TfdBGRA4 = class(TfdRGBA4) + constructor Create; override; + end; + + TfdBGR5A1 = class(TfdRGB5A1) + constructor Create; override; + end; + + TfdBGRA8 = class(TfdBGR8) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; + end; + + TfdBGR10A2 = class(TfdRGB10A2) + constructor Create; override; + end; + + TfdBGRA16 = class(TfdBGR16) + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + constructor Create; override; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdBGR8 = class(TglBitmapFormatDescriptor) + TBitfieldFormat = class(TFormatDescriptor) + private + procedure SetRedMask (const aValue: UInt64); + procedure SetGreenMask(const aValue: UInt64); + procedure SetBlueMask (const aValue: UInt64); + procedure SetAlphaMask(const aValue: UInt64); + + procedure Update(aMask: UInt64; out aRange: Cardinal; out aShift: Byte); public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithAlpha: TglBitmapFormat; override; + property RedMask: UInt64 read GetRedMask write SetRedMask; + property GreenMask: UInt64 read GetGreenMask write SetGreenMask; + property BlueMask: UInt64 read GetBlueMask write SetBlueMask; + property AlphaMask: UInt64 read GetAlphaMask write SetAlphaMask; + + property PixelSize: Single read fPixelSize write fPixelSize; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TfdBGRA8 = class(TglBitmapFormatDescriptor) + TColorTableEnty = packed record + b, g, r, a: Byte; + end; + TColorTable = array of TColorTableEnty; + TColorTableFormat = class(TFormatDescriptor) + private + fColorTable: TColorTable; public - class function GetFormat: TglBitmapFormat; override; - class function GetPixelDesc: TglBitmapPixelDesc; override; - class function GetFormatDesc: TglBitmapFormatDesc; override; - class function WithoutAlpha: TglBitmapFormat; override; + property PixelSize: Single read fPixelSize write fPixelSize; + property ColorTable: TColorTable read fColorTable write fColorTable; + property Range: TglBitmapColorRec read fRange write fRange; - class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override; - class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override; + procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override; + procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override; + destructor Destroy; override; end; const @@ -1259,24 +1330,68 @@ const UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.'; - FORMAT_DESCRIPTORS: array[TglBitmapFormat] of TglBitmapFormatDescClass = ( + FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = ( TfdEmpty, + //TfdAlpha4, + TfdAlpha8, + //TfdAlpha12, + TfdAlpha16, + + //TfdLuminance4, TfdLuminance8, + //TfdLuminance12, + TfdLuminance16, + + TfdLuminance4Alpha4, + TfdLuminance6Alpha2, TfdLuminance8Alpha8, + TfdLuminance12Alpha4, + //TfdLuminance12Alpha12, + TfdLuminance16Alpha16, + TfdR3G3B2, + TfdRGB4, + TfdR5G6B5, TfdRGB5, TfdRGB8, + TfdRGB10, + //TfdRGB12, + TfdRGB16, + TfdRGBA2, + TfdRGBA4, TfdRGB5A1, TfdRGBA8, + TfdRGB10A2, + //TfdRGBA12, + TfdRGBA16, + TfdBGR4, + TfdB5G6R5, + TfdBGR5, TfdBGR8, - TfdBGRA8 + TfdBGR10, + //TfdBGR12, + TfdBGR16, + + TfdBGRA2, + TfdBGRA4, + TfdBGR5A1, + TfdBGRA8, + TfdBGR10A2, + //TfdBGRA12, + TfdBGRA16 + + //TfdDepth16, + //TfdDepth24, + //TfdDepth32 ); +var + FormatDescriptorCS: TCriticalSection; + FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor; -{$REGION Private Helper} ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition; begin @@ -1292,6 +1407,15 @@ begin end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec; +begin + result.r := r; + result.g := g; + result.b := b; + result.a := a; +end; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes; begin //TODO Supported File Formats! @@ -1359,7 +1483,15 @@ begin aBitSet := aBitSet shr 1; end; end; -{$ENDREGION} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal; +begin + result := Trunc( + LUMINANCE_WEIGHT_R * aPixel.Data.r + + LUMINANCE_WEIGHT_G * aPixel.Data.g + + LUMINANCE_WEIGHT_B * aPixel.Data.b); +end; //TODO check _ARB functions and constants @@ -1699,7 +1831,6 @@ begin end; *) -{$REGION default Setter and Gettter} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean); begin @@ -1777,857 +1908,1430 @@ begin T := glBitmapDefaultWrapT; R := glBitmapDefaultWrapR; end; -{$ENDREGION} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TCustomFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TglBitmapFormatDescriptor/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetAlphaMask(aValue: UInt64); +function TFormatDescriptor.GetRedMask: UInt64; begin - if fAlphaMask = aValue then Exit; - fAlphaMask := aValue; - CalcShiftAndRange(fAlphaMask, fAlphaRange, fAlphaShift); + result := fRange.r shl fShift.r; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function TBitfieldFormat.GetSize: Integer; -var - tmp: UInt64; +function TFormatDescriptor.GetGreenMask: UInt64; begin - tmp := - (fRedRange shl fRedShift) or - (fGreenRange shl fGreenShift) or - (fBlueRange shl fBlueShift) or - (fAlphaRange shl fAlphaShift); - result := Trunc(GetTopMostBit(tmp) / 8); + result := fRange.g shl fShift.g; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetAlphaRange(aValue: Cardinal); +function TFormatDescriptor.GetBlueMask: UInt64; begin - if fAlphaRange = aValue then Exit; - fAlphaRange := aValue; - fAlphaMask := fAlphaRange shl fAlphaShift; + result := fRange.b shl fShift.b; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetAlphaShift(aValue: ShortInt); +function TFormatDescriptor.GetAlphaMask: UInt64; begin - if fAlphaShift = aValue then Exit; - fAlphaShift := aValue; - fAlphaMask := fAlphaRange shl fAlphaShift; + result := fRange.a shl fShift.a; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetBlueMask(aValue: UInt64); +function TFormatDescriptor.GetComponents: Integer; +var + i: Integer; begin - if fBlueMask = aValue then Exit; - fBlueMask := aValue; - CalcShiftAndRange(fBlueMask, fBlueRange, fBlueShift); + result := 0; + for i := 0 to 3 do + if (fRange.arr[i] > 0) then + inc(result); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetBlueRange(aValue: Cardinal); +function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer; +var + w, h: Integer; begin - if fBlueRange = aValue then Exit; - fBlueRange := aValue; - fBlueMask := fBlueRange shl fBlueShift; + if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin + w := Max(1, aSize.X); + h := Max(1, aSize.Y); + result := GetSize(w, h); + end else + result := 0; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetBlueShift(aValue: ShortInt); +function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer; begin - if fBlueShift = aValue then Exit; - fBlueShift := aValue; - fBlueMask := fBlueRange shl fBlueShift; + result := 0; + if (aWidth <= 0) or (aHeight <= 0) then + exit; + result := Ceil(aWidth * aHeight * fPixelSize); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetGreenMask(aValue: UInt64); +function TFormatDescriptor.CreateMappingData: Pointer; begin - if fGreenMask = aValue then Exit; - fGreenMask := aValue; - CalcShiftAndRange(fGreenMask, fGreenRange, fGreenShift); + result := nil; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetGreenRange(aValue: Cardinal); +procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer); begin - if fGreenRange = aValue then Exit; - fGreenRange := aValue; - fGreenMask := fGreenRange shl fGreenShift; + //DUMMY end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetGreenShift(aValue: ShortInt); +function TFormatDescriptor.IsEmpty: Boolean; begin - if fGreenShift = aValue then Exit; - fGreenShift := aValue; - fGreenMask := fGreenRange shl fGreenShift; + result := (fFormat = tfEmpty); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetRedMask(aValue: UInt64); +function TFormatDescriptor.HasAlpha: Boolean; begin - if fRedMask = aValue then Exit; - fRedMask := aValue; - CalcShiftAndRange(fRedMask, fRedRange, fRedShift); + result := (fRange.a > 0); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetRedRange(aValue: Cardinal); +function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; begin - if fRedRange = aValue then Exit; - fRedRange := aValue; - fRedMask := fRedRange shl fRedShift; + result := false; + + if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then + raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0'); + + if (aRedMask <> RedMask) then + exit; + if (aGreenMask <> GreenMask) then + exit; + if (aBlueMask <> BlueMask) then + exit; + if (aAlphaMask <> AlphaMask) then + exit; + result := true; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.SetRedShift(aValue: ShortInt); +procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData); begin - if fRedShift = aValue then Exit; - fRedShift := aValue; - fRedMask := fRedRange shl fRedShift; + FillChar(aPixel, SizeOf(aPixel), 0); + aPixel.Data := fRange; + aPixel.Range := fRange; + aPixel.Format := fFormat; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal; - out aShift: ShortInt); +constructor TFormatDescriptor.Create; begin - aShift := 0; - aRange := 0; - if (aMask = 0) then - exit; - while (aMask > 0) and ((aMask and 1) = 0) do begin - inc(aShift); - aMask := aMask shr 1; - end; - aRange := 1; - while (aMask > 0) do begin - aRange := aRange shl 1; - aMask := aMask shr 1; - end; - dec(aRange); + inherited Create; + + fFormat := tfEmpty; + fWithAlpha := tfEmpty; + fWithoutAlpha := tfEmpty; + fPixelSize := 0.0; + + fglFormat := 0; + fglInternalFormat := 0; + fglDataFormat := 0; + + FillChar(fRange, 0, SizeOf(fRange)); + FillChar(fShift, 0, SizeOf(fShift)); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte); -var - data: UInt64; - s: Integer; -type - PUInt64 = ^UInt64; +//TfdAlpha8/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdAlpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - data := - ((aPixel.Red and fRedRange) shl fRedShift) or - ((aPixel.Green and fGreenRange) shl fGreenShift) or - ((aPixel.Blue and fBlueRange) shl fBlueShift) or - ((aPixel.Alpha and fAlphaRange) shl fAlphaShift); - s := Size; - case s of - 1: aData^ := data; - 2: PWord(aData)^ := data; - 4: PCardinal(aData)^ := data; - 8: PUInt64(aData)^ := data; - end; - inc(aData, s); + aData^ := aPixel.Data.a; + inc(aData); end; -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); -var - data: UInt64; - s: Integer; -type - PUInt64 = ^UInt64; +procedure TfdAlpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - s := Size; - case s of - 1: data := aData^; - 2: data := PWord(aData)^; - 4: data := PCardinal(aData)^; - 8: data := PUInt64(aData)^; - end; - Unmap(data, aPixel); - inc(aData, s); + aPixel.Data.r := 0; + aPixel.Data.g := 0; + aPixel.Data.b := 0; + aPixel.Data.a := aData^; + inc(aData^); end; +constructor TfdAlpha8.Create; +begin + inherited Create; + fPixelSize := 1.0; + fFormat := tfAlpha8; + fRange.a := $FF; + fglFormat := GL_ALPHA; + fglInternalFormat := GL_ALPHA8; + fglDataFormat := GL_UNSIGNED_BYTE; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TfdAlpha16////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure TBitfieldFormat.Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData); +procedure TfdAlpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +begin + PWord(aData)^ := aPixel.Data.a; + inc(aData, 2); +end; + +procedure TfdAlpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +begin + aPixel.Data.r := 0; + aPixel.Data.g := 0; + aPixel.Data.b := 0; + aPixel.Data.a := PWord(aData)^; + inc(aData, 2); +end; + +constructor TfdAlpha16.Create; begin - aPixel.Red := (aData shr fRedShift) and fRedRange; - aPixel.Green := (aData shr fGreenShift) and fGreenRange; - aPixel.Blue := (aData shr fBlueShift) and fBlueRange; - aPixel.Alpha := (aData shr fAlphaShift) and fAlphaRange; + inherited Create; + fPixelSize := 2.0; + fFormat := tfAlpha16; + fRange.a := $FFFF; + fglFormat := GL_ALPHA; + fglInternalFormat := GL_ALPHA16; + fglDataFormat := GL_UNSIGNED_SHORT; end; -{$REGION TglBitmapFormatDescriptor} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TglBitmapFormatDescriptor/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.WithoutAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - if not HasAlpha then - result := GetFormat - else - result := tfEmpty; + aData^ := LuminanceWeight(aPixel); + inc(aData); +end; + +procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +begin + aPixel.Data.r := aData^; + aPixel.Data.g := aData^; + aPixel.Data.b := aData^; + aPixel.Data.a := 0; + inc(aData); end; +constructor TfdLuminance8.Create; +begin + inherited Create; + fPixelSize := 1.0; + fFormat := tfLuminance8; + fWithAlpha := tfLuminance8Alpha8; + fWithoutAlpha := tfLuminance8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE8; + fglDataFormat := GL_UNSIGNED_BYTE; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.WithAlpha: TglBitmapFormat; +procedure TfdLuminance16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - if HasAlpha then - result := GetFormat - else - result := tfEmpty; + PWord(aData)^ := LuminanceWeight(aPixel); + inc(aData, 2); end; +procedure TfdLuminance16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +begin + aPixel.Data.r := PWord(aData)^; + aPixel.Data.g := PWord(aData)^; + aPixel.Data.b := PWord(aData)^; + aPixel.Data.a := 0; + inc(aData, 2); +end; + +constructor TfdLuminance16.Create; +begin + inherited Create; + fPixelSize := 2.0; + fFormat := tfLuminance16; + fWithAlpha := tfLuminance16Alpha16; + fWithoutAlpha := tfLuminance16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE16; + fglDataFormat := GL_UNSIGNED_SHORT; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.GetSize: Single; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdLuminance4Alpha4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +begin + aData^ := + ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or + ((aPixel.Data.a and fRange.a) shl fShift.a); + inc(aData); +end; + +procedure TfdLuminance4Alpha4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); var - tmp: UInt64; + i: Integer; begin - with GetPixelDesc do begin - tmp := - (RedRange shl RedShift) or - (GreenRange shl GreenShift) or - (BlueRange shl BlueShift) or - (AlphaRange shl AlphaShift); - end; - result := Trunc(GetTopMostBit(tmp) / 4) / 2; + for i := 0 to 3 do + aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData); +end; + +constructor TfdLuminance4Alpha4.Create; +begin + inherited Create; + fPixelSize := 1.0; + fFormat := tfLuminance4Alpha4; + fWithAlpha := tfLuminance4Alpha4; + fWithoutAlpha := tfLuminance8; + fRange.r := $F; + fRange.g := $F; + fRange.b := $F; + fRange.a := $F; + fShift.a := 4; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE4_ALPHA4; + fglDataFormat := GL_UNSIGNED_BYTE; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdLuminance6Alpha2.Create; +begin + inherited Create; + fFormat := tfLuminance6Alpha2; + fWithAlpha := tfLuminance6Alpha2; + fWithoutAlpha := tfLuminance8; + fRange.r := $3F; + fRange.g := $3F; + fRange.b := $3F; + fRange.a := $03; + fShift.a := 6; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE6_ALPHA2; + fglDataFormat := GL_UNSIGNED_BYTE; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +begin + PWord(aData)^ := + ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or + ((aPixel.Data.a and fRange.a) shl fShift.a); + inc(aData, 2); +end; + +procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); var - w, h: Integer; + i: Integer; begin - if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin - w := Max(1, aSize.X); - h := Max(1, aSize.Y); - result := Ceil(w * h * GetSize); - end else - result := 0; + for i := 0 to 3 do + aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData, 2); +end; + +constructor TfdLuminance8Alpha8.Create; +begin + inherited Create; + fPixelSize := 2.0; + fFormat := tfLuminance8Alpha8; + fWithAlpha := tfLuminance8Alpha8; + fWithoutAlpha := tfLuminance8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fRange.a := $FF; + fShift.a := 8; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE8_ALPHA8; + fglDataFormat := GL_UNSIGNED_SHORT; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.GetColorCompCount: Integer; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdLuminance12Alpha4.Create; begin - result := 0; - with GetPixelDesc do begin - if (RedRange > 0) then - inc(result); - if (GreenRange > 0) then - inc(result); - if (BlueRange > 0) then - inc(result); - if (AlphaRange > 0) then - inc(result); - end; + inherited Create; + fFormat := tfLuminance12Alpha4; + fWithAlpha := tfLuminance12Alpha4; + fWithoutAlpha := tfLuminance16; + fRange.r := $FFF; + fRange.g := $FFF; + fRange.b := $FFF; + fRange.a := $00F; + fShift.a := 12; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE12_ALPHA4; + fglDataFormat := GL_UNSIGNED_SHORT; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.IsEmpty: Boolean; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdLuminance16Alpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - result := (GetFormat = tfEmpty); + PCardinal(aData)^ := + ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or + ((aPixel.Data.a and fRange.a) shl fShift.a); + inc(aData, 4); end; +procedure TfdLuminance16Alpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +var + i: Integer; +begin + for i := 0 to 3 do + aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData, 4); +end; + +constructor TfdLuminance16Alpha16.Create; +begin + inherited Create; + fFormat := tfLuminance16Alpha16; + fWithAlpha := tfLuminance16Alpha16; + fWithoutAlpha := tfLuminance16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fRange.a := $FFFF; + fShift.a := 16; + fglFormat := GL_LUMINANCE; + fglInternalFormat := GL_LUMINANCE16_ALPHA16; + fglDataFormat := GL_UNSIGNED_INT; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.HasAlpha: Boolean; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdR3G3B2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +var + i: Integer; +begin + aData^ := 0; + for i := 0 to 3 do + if (fRange.arr[i] > 0) then + aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]); + inc(aData); +end; + +procedure TfdR3G3B2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +var + i: Integer; begin - result := (GetPixelDesc.AlphaRange > 0); + for i := 0 to 3 do + aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData); +end; + +constructor TfdR3G3B2.Create; +begin + inherited Create; + fPixelSize := 1.0; + fFormat := tfR3G3B2; + fWithAlpha := tfRGBA2; + fWithoutAlpha := tfR3G3B2; + fRange.r := $7; + fRange.g := $7; + fRange.b := $3; + fShift.r := 0; + fShift.g := 3; + fShift.b := 5; + fglFormat := GL_RGB; + fglInternalFormat := GL_R3_G3_B2; + fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TglBitmapFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); var - PixelDesc: TglBitmapPixelDesc; + i: Integer; begin - result := false; + PWord(aData)^ := 0; + for i := 0 to 3 do + if (fRange.arr[i] > 0) then + PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]); + inc(aData, 2); +end; - if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then - raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0'); +procedure TfdRGB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +var + i: Integer; +begin + for i := 0 to 3 do + aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData, 2); +end; - PixelDesc := GetPixelDesc; - with PixelDesc do begin - if (aRedMask <> 0) and (aRedMask <> (RedRange shl RedShift)) then - exit; - if (aGreenMask <> 0) and (aGreenMask <> (GreenRange shl GreenShift)) then - exit; - if (aBlueMask <> 0) and (aBlueMask <> (BlueRange shl BlueShift)) then - exit; - if (aAlphaMask <> 0) and (aAlphaMask <> (AlphaRange shl AlphaShift)) then - exit; - end; - result := true; +constructor TfdRGB4.Create; +begin + inherited Create; + fPixelSize := 2.0; + fFormat := tfRGB4; + fWithAlpha := tfRGBA4; + fWithoutAlpha := tfRGB4; + fRange.r := $F; + fRange.g := $F; + fRange.b := $F; + fShift.r := 0; + fShift.g := 4; + fShift.b := 8; + fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA + fglInternalFormat := GL_RGB4; + fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class procedure TglBitmapFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdR5G6B5.Create; begin - FillChar(aPixel, SizeOf(aPixel), 0); - aPixel.PixelDesc := GetPixelDesc; - with aPixel.PixelDesc do begin - aPixel.Red := RedRange; - aPixel.Green := GreenRange; - aPixel.Blue := BlueRange; - aPixel.Alpha := AlphaRange; - end; + inherited Create; + fPixelSize := 2.0; + fFormat := tfR5G6B5; + fWithAlpha := tfRGBA4; + fWithoutAlpha := tfR5G6B5; + fRange.r := $1F; + fRange.g := $3F; + fRange.b := $1F; + fShift.r := 0; + fShift.g := 5; + fShift.b := 11; + fglFormat := GL_RGB; + fglInternalFormat := GL_RGB8; + fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV; end; -{$ENDREGION} -{$REGION TfdEmpty} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdEmpty//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdEmpty.GetFormat: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdRGB5.Create; begin - result := tfEmpty; + inherited Create; + fPixelSize := 2.0; + fFormat := tfRGB5; + fWithAlpha := tfRGB5A1; + fWithoutAlpha := tfRGB5; + fRange.r := $1F; + fRange.g := $1F; + fRange.b := $1F; + fShift.r := 0; + fShift.g := 5; + fShift.b := 10; + fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA + fglInternalFormat := GL_RGB5; + fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV; end; -class function TfdEmpty.GetPixelDesc: TglBitmapPixelDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - with result do begin - RedRange := $00000000; RedShift := 0; - GreenRange := $00000000; GreenShift := 0; - BlueRange := $00000000; BlueShift := 0; - AlphaRange := $00000000; AlphaShift := 0; - end; + aData^ := aPixel.Data.r; + inc(aData); + aData^ := aPixel.Data.g; + inc(aData); + aData^ := aPixel.Data.b; + inc(aData); end; -class function TfdEmpty.GetFormatDesc: TglBitmapFormatDesc; +procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - with result do begin - Format := 0; - InternalFormat := 0; - DataType := 0; - end; + aPixel.Data.r := aData^; + inc(aData); + aPixel.Data.g := aData^; + inc(aData); + aPixel.Data.b := aData^; + inc(aData); + aPixel.Data.a := 0; end; -class procedure TfdEmpty.Map(const aPixel: TglBitmapPixelData; var aData: PByte ); +constructor TfdRGB8.Create; begin - raise EglBitmapException.Create('format does not support mapping'); + inherited Create; + fPixelSize := 3.0; + fFormat := tfRGB8; + fWithAlpha := tfRGBA8; + fWithoutAlpha := tfRGB8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fShift.r := 0; + fShift.g := 8; + fShift.b := 16; + fglFormat := GL_RGB; + fglInternalFormat := GL_RGB8; + fglDataFormat := GL_UNSIGNED_BYTE; end; -class procedure TfdEmpty.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGB10.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +var + i: Integer; +begin + PCardinal(aData)^ := 0; + for i := 0 to 3 do + if (fRange.arr[i] > 0) then + PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]); + inc(aData, 4); +end; + +procedure TfdRGB10.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +var + i: Integer; begin - raise EglBitmapException.Create('format does not support unmapping'); + for i := 0 to 3 do + aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i]; + inc(aData, 4); +end; + +constructor TfdRGB10.Create; +begin + inherited Create; + fPixelSize := 4.0; + fFormat := tfRGB10; + fWithAlpha := tfRGB10A2; + fWithoutAlpha := tfRGB10; + fRange.r := $3FF; + fRange.g := $3FF; + fRange.b := $3FF; + fShift.r := 0; + fShift.g := 10; + fShift.b := 20; + fglFormat := GL_RGB; + fglInternalFormat := GL_RGB10; + fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV; end; -{$ENDREGION} -{$REGION TfdLuminance8} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdLuminance8/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdLuminance8.GetFormat: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGB16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +begin + PWord(aData)^ := aPixel.Data.r; + inc(aData, 2); + PWord(aData)^ := aPixel.Data.g; + inc(aData, 2); + PWord(aData)^ := aPixel.Data.b; + inc(aData, 2); +end; + +procedure TfdRGB16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - result := tfEmpty; + aPixel.Data.r := PWord(aData)^; + inc(aData, 2); + aPixel.Data.g := PWord(aData)^; + inc(aData, 2); + aPixel.Data.b := PWord(aData)^; + inc(aData, 2); + aPixel.Data.a := 0; end; -class function TfdLuminance8.GetPixelDesc: TglBitmapPixelDesc; +constructor TfdRGB16.Create; begin - with result do begin - RedRange := $000000FF; RedShift := 0; - GreenRange := $000000FF; GreenShift := 0; - BlueRange := $000000FF; BlueShift := 0; - AlphaRange := $00000000; AlphaShift := 0; - end; + inherited Create; + fPixelSize := 6.0; + fFormat := tfRGB16; + fWithAlpha := tfRGBA16; + fWithoutAlpha := tfRGB16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fShift.r := 0; + fShift.g := 16; + fShift.b := 32; + fglFormat := GL_RGB; + fglInternalFormat := GL_RGB16; + fglDataFormat := GL_UNSIGNED_SHORT; end; -class function TfdLuminance8.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdRGBA2.Create; begin - with result do begin - Format := GL_LUMINANCE; - InternalFormat := GL_LUMINANCE8; - DataType := GL_UNSIGNED_BYTE; - end; + inherited Create; + fFormat := tfRGBA2; + fWithAlpha := tfRGBA2; + fWithoutAlpha := tfR3G3B2; + fRange.r := $3; + fRange.g := $3; + fRange.b := $3; + fRange.a := $3; + fShift.r := 0; + fShift.g := 2; + fShift.b := 4; + fShift.a := 6; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGBA2; + fglDataFormat := GL_UNSIGNED_BYTE; end; -class function TfdLuminance8.WithAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdRGBA4.Create; +begin + inherited Create; + fFormat := tfRGBA4; + fWithAlpha := tfRGBA4; + fWithoutAlpha := tfRGB4; + fRange.r := $F; + fRange.g := $F; + fRange.b := $F; + fRange.a := $F; + fShift.r := 0; + fShift.g := 4; + fShift.b := 8; + fShift.a := 12; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGBA4; + fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdRGB5A1.Create; begin - result := tfLuminance8Alpha8; + inherited Create; + fFormat := tfRGB5A1; + fWithAlpha := tfRGB5A1; + fWithoutAlpha := tfRGB5; + fRange.r := $1F; + fRange.g := $1F; + fRange.b := $1F; + fRange.a := $01; + fShift.r := 0; + fShift.g := 5; + fShift.b := 10; + fShift.a := 15; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGB5_A1; + fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV; end; -class procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - aData^ := Trunc( - aPixel.Red * LUMINANCE_WEIGHT_R + - aPixel.Green * LUMINANCE_WEIGHT_G + - aPixel.Blue * LUMINANCE_WEIGHT_B); + inherited Map(aPixel, aData, aMapData); + aData^ := aPixel.Data.a; inc(aData); end; -class procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - aPixel.Red := aData^; - aPixel.Green := aData^; - aPixel.Blue := aData^; - aPixel.Alpha := 0; + inherited Unmap(aData, aPixel, aMapData); + aPixel.Data.a := aData^; inc(aData); end; -{$ENDREGION} -{$REGION TfdLuminance8Alpha8} +constructor TfdRGBA8.Create; +begin + inherited Create; + fPixelSize := 4.0; + fFormat := tfRGBA8; + fWithAlpha := tfRGBA8; + fWithoutAlpha := tfRGB8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fRange.a := $FF; + fShift.r := 0; + fShift.g := 8; + fShift.b := 16; + fShift.a := 24; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGBA8; + fglDataFormat := GL_UNSIGNED_BYTE; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdLuminance8Alpha8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdLuminance8Alpha8.GetFormat: TglBitmapFormat; +constructor TfdRGB10A2.Create; begin - result := tfLuminance8Alpha8; + inherited Create; + fFormat := tfRGB10A2; + fWithAlpha := tfRGB10A2; + fWithoutAlpha := tfRGB10; + fRange.r := $3FF; + fRange.g := $3FF; + fRange.b := $3FF; + fRange.a := $003; + fShift.r := 0; + fShift.g := 10; + fShift.b := 20; + fShift.a := 30; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGB10_A2; + fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV; end; -class function TfdLuminance8Alpha8.GetPixelDesc: TglBitmapPixelDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdRGBA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - with result do begin - RedRange := $000000FF; RedShift := 0; - GreenRange := $000000FF; GreenShift := 0; - BlueRange := $000000FF; BlueShift := 0; - AlphaRange := $000000FF; AlphaShift := 8; - end; + inherited Map(aPixel, aData, aMapData); + PWord(aData)^ := aPixel.Data.a; + inc(aData, 2); end; -class function TfdLuminance8Alpha8.GetFormatDesc: TglBitmapFormatDesc; +procedure TfdRGBA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - with result do begin - Format := GL_LUMINANCE_ALPHA; - InternalFormat := GL_LUMINANCE8_ALPHA8; - DataType := GL_UNSIGNED_BYTE; - end; + inherited Unmap(aData, aPixel, aMapData); + aPixel.Data.a := PWord(aData)^; + inc(aData, 2); +end; + +constructor TfdRGBA16.Create; +begin + inherited Create; + fPixelSize := 8.0; + fFormat := tfRGBA16; + fWithAlpha := tfRGBA16; + fWithoutAlpha := tfRGB16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fRange.a := $FFFF; + fShift.r := 0; + fShift.g := 16; + fShift.b := 32; + fShift.a := 48; + fglFormat := GL_RGBA; + fglInternalFormat := GL_RGBA16; + fglDataFormat := GL_UNSIGNED_SHORT; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGR4.Create; +begin + inherited Create; + fPixelSize := 2.0; + fFormat := tfBGR4; + fWithAlpha := tfBGRA4; + fWithoutAlpha := tfBGR4; + fRange.r := $F; + fRange.g := $F; + fRange.b := $F; + fRange.a := $0; + fShift.r := 8; + fShift.g := 4; + fShift.b := 0; + fShift.a := 0; + fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA + fglInternalFormat := GL_RGB4; + fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV; +end; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdB5G6R5.Create; +begin + inherited Create; + fPixelSize := 2.0; + fFormat := tfB5G6R5; + fWithAlpha := tfBGRA4; + fWithoutAlpha := tfB5G6R5; + fRange.r := $1F; + fRange.g := $3F; + fRange.b := $1F; + fShift.r := 11; + fShift.g := 5; + fShift.b := 0; + fglFormat := GL_RGB; + fglInternalFormat := GL_RGB8; + fglDataFormat := GL_UNSIGNED_SHORT_5_6_5; end; -class function TfdLuminance8Alpha8.WithoutAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGR5.Create; begin - result := tfLuminance8; + inherited Create; + fPixelSize := 2.0; + fFormat := tfBGR5; + fWithAlpha := tfBGR5A1; + fWithoutAlpha := tfBGR5; + fRange.r := $1F; + fRange.g := $1F; + fRange.b := $1F; + fRange.a := $00; + fShift.r := 10; + fShift.g := 5; + fShift.b := 0; + fShift.a := 0; + fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA + fglInternalFormat := GL_RGB5; + fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV; end; -class procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - aData^ := Trunc( - aPixel.Red * LUMINANCE_WEIGHT_R + - aPixel.Green * LUMINANCE_WEIGHT_G + - aPixel.Blue * LUMINANCE_WEIGHT_B); + aData^ := aPixel.Data.b; inc(aData); - - aData^ := aPixel.Alpha; + aData^ := aPixel.Data.g; + inc(aData); + aData^ := aPixel.Data.r; inc(aData); end; -class procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - aPixel.Red := aData^; - aPixel.Green := aData^; - aPixel.Blue := aData^; + aPixel.Data.b := aData^; inc(aData); - - aPixel.Alpha := aData^; + aPixel.Data.g := aData^; inc(aData); -end; -{$ENDREGION} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdRGB5///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdRGB5.GetFormat: TglBitmapFormat; -begin - result := tfRGB5; + aPixel.Data.r := aData^; + inc(aData); + aPixel.Data.a := 0; end; -class function TfdRGB5.GetPixelDesc: TglBitmapPixelDesc; +constructor TfdBGR8.Create; begin - with result do begin - RedRange := $0000001F; RedShift := 0; - GreenRange := $0000001F; GreenShift := 5; - BlueRange := $0000001F; BlueShift := 10; - AlphaRange := $00000000; AlphaShift := 0; - end; + inherited Create; + fPixelSize := 3.0; + fFormat := tfBGR8; + fWithAlpha := tfBGRA8; + fWithoutAlpha := tfBGR8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fRange.a := $00; + fShift.r := 16; + fShift.g := 8; + fShift.b := 0; + fShift.a := 0; + fglFormat := GL_BGR; + fglInternalFormat := GL_RGB8; + fglDataFormat := GL_UNSIGNED_BYTE; end; -class function TfdRGB5.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGR10.Create; begin - with result do begin - Format := GL_RGB; - InternalFormat := GL_RGB5; - DataType := GL_UNSIGNED_SHORT_5_5_5_1; - end; + inherited Create; + fFormat := tfBGR10; + fWithAlpha := tfBGR10A2; + fWithoutAlpha := tfBGR10; + fRange.r := $3FF; + fRange.g := $3FF; + fRange.b := $3FF; + fRange.a := $000; + fShift.r := 20; + fShift.g := 10; + fShift.b := 0; + fShift.a := 0; + fglFormat := GL_BGR; + fglInternalFormat := GL_RGB10; + fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV; end; -class function TfdRGB5.WithAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdBGR16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - result := tfRGB5A1; + PWord(aData)^ := aPixel.Data.b; + inc(aData, 2); + PWord(aData)^ := aPixel.Data.g; + inc(aData, 2); + PWord(aData)^ := aPixel.Data.r; + inc(aData, 2); end; -class procedure TfdRGB5.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +procedure TfdBGR16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - PWord(aData)^ := - ((aPixel.Red and aPixel.PixelDesc.RedRange) shl aPixel.PixelDesc.RedShift) or - ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or - ((aPixel.Blue and aPixel.PixelDesc.BlueRange) shl aPixel.PixelDesc.BlueShift); + aPixel.Data.b := PWord(aData)^; + inc(aData, 2); + aPixel.Data.g := PWord(aData)^; inc(aData, 2); + aPixel.Data.r := PWord(aData)^; + inc(aData, 2); + aPixel.Data.a := 0; end; -class procedure TfdRGB5.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +constructor TfdBGR16.Create; begin - aPixel.Red := (PWord(aData)^ shr aPixel.PixelDesc.RedShift) and aPixel.PixelDesc.RedRange; - aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange; - aPixel.Blue := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift) and aPixel.PixelDesc.BlueRange; - aPixel.Alpha := 0; - inc(aData, 2); + inherited Create; + fPixelSize := 6.0; + fFormat := tfBGR16; + fWithAlpha := tfBGRA16; + fWithoutAlpha := tfBGR16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fRange.a := $0000; + fShift.r := 32; + fShift.g := 16; + fShift.b := 0; + fShift.a := 0; + fglFormat := GL_BGR; + fglInternalFormat := GL_RGB16; + fglDataFormat := GL_UNSIGNED_SHORT; end; -{$REGION TfdRGB8} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdRGB8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdRGB8.GetFormat: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGRA2.Create; begin - result := tfRGB8; + inherited Create; + fFormat := tfBGRA2; + fWithAlpha := tfBGRA4; + fWithoutAlpha := tfBGR4; + fRange.r := $3; + fRange.g := $3; + fRange.b := $3; + fRange.a := $3; + fShift.r := 4; + fShift.g := 2; + fShift.b := 0; + fShift.a := 6; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGBA2; + fglDataFormat := GL_UNSIGNED_BYTE; end; -class function TfdRGB8.GetPixelDesc: TglBitmapPixelDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGRA4.Create; begin - with result do begin - RedRange := $000000FF; RedShift := 0; - GreenRange := $000000FF; GreenShift := 8; - BlueRange := $000000FF; BlueShift := 16; - AlphaRange := $00000000; AlphaShift := 0; - end; + inherited Create; + fFormat := tfBGRA4; + fWithAlpha := tfBGRA4; + fWithoutAlpha := tfBGR4; + fRange.r := $F; + fRange.g := $F; + fRange.b := $F; + fRange.a := $F; + fShift.r := 8; + fShift.g := 4; + fShift.b := 0; + fShift.a := 12; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGBA4; + fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV; end; -class function TfdRGB8.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGR5A1.Create; begin - with result do begin - Format := GL_LUMINANCE; - InternalFormat := GL_LUMINANCE8; - DataType := GL_UNSIGNED_BYTE; - end; + inherited Create; + fFormat := tfBGR5A1; + fWithAlpha := tfBGR5A1; + fWithoutAlpha := tfBGR5; + fRange.r := $1F; + fRange.g := $1F; + fRange.b := $1F; + fRange.a := $01; + fShift.r := 10; + fShift.g := 5; + fShift.b := 0; + fShift.a := 15; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGB5_A1; + fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV; end; -class function TfdRGB8.WithAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////s +procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - result := tfRGBA8; + inherited Map(aPixel, aData, aMapData); + aData^ := aPixel.Data.a; + inc(aData); end; -class procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - aData^ := aPixel.Red; - inc(aData); - aData^ := aPixel.Green; - inc(aData); - aData^ := aPixel.Blue; + inherited Unmap(aData, aPixel, aMapData); + aPixel.Data.a := aData^; inc(aData); end; -class procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +constructor TfdBGRA8.Create; begin - aPixel.Red := aData^; - inc(aData); - aPixel.Green := aData^; - inc(aData); - aPixel.Blue := aData^; - inc(aData); - aPixel.Alpha := 0; + inherited Create; + fPixelSize := 4.0; + fFormat := tfBGRA8; + fWithAlpha := tfBGRA8; + fWithoutAlpha := tfBGR8; + fRange.r := $FF; + fRange.g := $FF; + fRange.b := $FF; + fRange.a := $FF; + fShift.r := 16; + fShift.g := 8; + fShift.b := 0; + fShift.a := 24; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGBA8; + fglDataFormat := GL_UNSIGNED_BYTE; end; -{$ENDREGION} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdRGB5A1/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdRGB5A1.GetFormat: TglBitmapFormat; -begin - result := tfRGB5A1; -end; - -class function TfdRGB5A1.GetPixelDesc: TglBitmapPixelDesc; -begin - with result do begin - RedRange := $0000001F; RedShift := 0; - GreenRange := $0000001F; GreenShift := 5; - BlueRange := $0000001F; BlueShift := 10; - AlphaRange := $00000001; AlphaShift := 15; - end; -end; - -class function TfdRGB5A1.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TfdBGR10A2.Create; begin - with result do begin - Format := GL_RGBA; - InternalFormat := GL_RGB5_A1; - DataType := GL_UNSIGNED_SHORT_5_5_5_1; - end; + inherited Create; + fFormat := tfBGR10A2; + fWithAlpha := tfBGR10A2; + fWithoutAlpha := tfBGR10; + fRange.r := $3FF; + fRange.g := $3FF; + fRange.b := $3FF; + fRange.a := $003; + fShift.r := 20; + fShift.g := 10; + fShift.b := 0; + fShift.a := 30; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGB10_A2; + fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV; end; -class function TfdRGB5A1.WithoutAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TfdBGRA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - //TODO result := tfRGB5; + inherited Map(aPixel, aData, aMapData); + PWord(aData)^ := aPixel.Data.a; + inc(aData, 2); end; -class procedure TfdRGB5A1.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +procedure TfdBGRA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); begin - PWord(aData)^ := - ((aPixel.Red and aPixel.PixelDesc.RedRange) shl aPixel.PixelDesc.RedShift) or - ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or - ((aPixel.Blue and aPixel.PixelDesc.BlueRange) shl aPixel.PixelDesc.BlueShift) or - ((aPixel.Alpha and aPixel.PixelDesc.AlphaRange) shl aPixel.PixelDesc.AlphaShift); + inherited Unmap(aData, aPixel, aMapData); + aPixel.Data.a := PWord(aData)^; inc(aData, 2); end; -class procedure TfdRGB5A1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +constructor TfdBGRA16.Create; begin - aPixel.Red := (PWord(aData)^ shr aPixel.PixelDesc.RedShift) and aPixel.PixelDesc.RedRange; - aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange; - aPixel.Blue := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift) and aPixel.PixelDesc.BlueRange; - aPixel.Alpha := (PWord(aData)^ shr aPixel.PixelDesc.AlphaShift) and aPixel.PixelDesc.AlphaRange; - inc(aData, 2); + inherited Create; + fPixelSize := 8.0; + fFormat := tfBGRA16; + fWithAlpha := tfBGRA16; + fWithoutAlpha := tfBGR16; + fRange.r := $FFFF; + fRange.g := $FFFF; + fRange.b := $FFFF; + fRange.a := $FFFF; + fShift.r := 32; + fShift.g := 16; + fShift.b := 0; + fShift.a := 48; + fglFormat := GL_BGRA; + fglInternalFormat := GL_RGBA16; + fglDataFormat := GL_UNSIGNED_SHORT; end; -{$REGION TfdRGBA8} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdRGBA8//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TFormatDescriptor/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdRGBA8.GetFormat: TglBitmapFormat; -begin - result := tfRGBA8; -end; - -class function TfdRGBA8.GetPixelDesc: TglBitmapPixelDesc; +class procedure TFormatDescriptor.Init; begin - with result do begin - RedRange := $000000FF; RedShift := 0; - GreenRange := $000000FF; GreenShift := 8; - BlueRange := $000000FF; BlueShift := 16; - AlphaRange := $000000FF; AlphaShift := 24; - end; + if not Assigned(FormatDescriptorCS) then + FormatDescriptorCS := TCriticalSection.Create; end; -class function TfdRGBA8.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor; begin - with result do begin - Format := GL_RGB; - InternalFormat := GL_RGB8; - DataType := GL_UNSIGNED_BYTE; + FormatDescriptorCS.Enter; + try + result := FormatDescriptors[aFormat]; + if not Assigned(result) then begin + result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create; + FormatDescriptors[aFormat] := result; + end; + finally + FormatDescriptorCS.Leave; end; end; -class function TfdRGBA8.WithoutAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor; begin - result := tfRGB8; + result := Get(Get(aFormat).WithAlpha); end; -class procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class procedure TFormatDescriptor.Clear; +var + f: TglBitmapFormat; begin - aData^ := aPixel.Red; - inc(aData); - aData^ := aPixel.Green; - inc(aData); - aData^ := aPixel.Blue; - inc(aData); - aData^ := aPixel.Alpha; - inc(aData); + FormatDescriptorCS.Enter; + try + for f := low(FormatDescriptors) to high(FormatDescriptors) do + FreeAndNil(FormatDescriptors[f]); + finally + FormatDescriptorCS.Leave; + end; end; -class procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +class procedure TFormatDescriptor.Finalize; begin - aPixel.Red := aData^; - inc(aData); - aPixel.Green := aData^; - inc(aData); - aPixel.Blue := aData^; - inc(aData); - aPixel.Alpha := aData^; - inc(aData); + Clear; + FreeAndNil(FormatDescriptorCS); end; -{$ENDREGION} -{$REGION TfdBGR8} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdBGR8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TBitfieldFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdBGR8.GetFormat: TglBitmapFormat; +procedure TBitfieldFormat.SetRedMask(const aValue: UInt64); begin - result := tfBGR8; + Update(aValue, fRange.r, fShift.r); end; -class function TfdBGR8.GetPixelDesc: TglBitmapPixelDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TBitfieldFormat.SetGreenMask(const aValue: UInt64); begin - with result do begin - RedRange := $000000FF; RedShift := 16; - GreenRange := $000000FF; GreenShift := 8; - BlueRange := $000000FF; BlueShift := 0; - AlphaRange := $00000000; AlphaShift := 0; - end; + Update(aValue, fRange.g, fShift.g); end; -class function TfdBGR8.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TBitfieldFormat.SetBlueMask(const aValue: UInt64); begin - with result do begin - Format := GL_BGR; - InternalFormat := GL_RGB8; - DataType := GL_UNSIGNED_BYTE; - end; + Update(aValue, fRange.b, fShift.b); end; -class function TfdBGR8.WithAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TBitfieldFormat.SetAlphaMask(const aValue: UInt64); begin - result := tfBGRA8; + Update(aValue, fRange.a, fShift.a); end; -class procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out + aShift: Byte); begin - aData^ := aPixel.Blue; - inc(aData); - aData^ := aPixel.Green; - inc(aData); - aData^ := aPixel.Red; - inc(aData); -end; + aShift := 0; + aRange := 0; + if (aMask = 0) then + exit; + while (aMask > 0) and ((aMask and 1) = 0) do begin + inc(aShift); + aMask := aMask shr 1; + end; + aRange := 1; + while (aMask > 0) do begin + aRange := aRange shl 1; + aMask := aMask shr 1; + end; + dec(aRange); -class procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); -begin - aPixel.Blue := aData^; - inc(aData); - aPixel.Green := aData^; - inc(aData); - aPixel.Red := aData^; - inc(aData); + fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8); end; -{$ENDREGION} -{$REGION TfdBGRA8} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TfdBGRA8//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class function TfdBGRA8.GetFormat: TglBitmapFormat; -begin - result := tfBGRA8; -end; - -class function TfdBGRA8.GetPixelDesc: TglBitmapPixelDesc; +procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); +var + data: UInt64; + s: Integer; +type + PUInt64 = ^UInt64; begin - with result do begin - RedRange := $000000FF; RedShift := 16; - GreenRange := $000000FF; GreenShift := 8; - BlueRange := $000000FF; BlueShift := 0; - AlphaRange := $000000FF; AlphaShift := 24; + data := + ((aPixel.Data.r and fRange.r) shl fShift.r) or + ((aPixel.Data.g and fRange.g) shl fShift.g) or + ((aPixel.Data.b and fRange.b) shl fShift.b) or + ((aPixel.Data.a and fRange.a) shl fShift.a); + s := Round(fPixelSize); + case s of + 1: aData^ := data; + 2: PWord(aData)^ := data; + 4: PCardinal(aData)^ := data; + 8: PUInt64(aData)^ := data; + else + raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]); end; + inc(aData, s); end; -class function TfdBGRA8.GetFormatDesc: TglBitmapFormatDesc; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +var + data: UInt64; + s, i: Integer; +type + PUInt64 = ^UInt64; begin - with result do begin - Format := GL_BGRA; - InternalFormat := GL_RGBA8; - DataType := GL_UNSIGNED_BYTE; + s := Round(fPixelSize); + case s of + 1: data := aData^; + 2: data := PWord(aData)^; + 4: data := PCardinal(aData)^; + 8: data := PUInt64(aData)^; + else + raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]); end; + for i := 0 to 3 do + aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i]; + inc(aData, s); end; -class function TfdBGRA8.WithoutAlpha: TglBitmapFormat; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TColorTableFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); begin - result := tfBGR8; + raise EglBitmapException.Create('mapping of color table formats is not supported'); end; -class procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte); +procedure TColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); +type + PUInt64 = ^UInt64; +var + idx: UInt64; + s: Integer; + bits: Byte; + f: Single; begin - aData^ := aPixel.Blue; - inc(aData); - aData^ := aPixel.Green; - inc(aData); - aData^ := aPixel.Red; - inc(aData); - aData^ := aPixel.Alpha; - inc(aData); + s := Trunc(fPixelSize); + f := fPixelSize - s; + bits := Round(8 * f); + case s of + 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1); + 1: idx := aData^; + 2: idx := PWord(aData)^; + 4: idx := PCardinal(aData)^; + 8: idx := PUInt64(aData)^; + else + raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]); + end; + if (idx >= Length(fColorTable)) then + raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]); + with fColorTable[idx] do begin + aPixel.Data.r := r; + aPixel.Data.g := g; + aPixel.Data.b := b; + aPixel.Data.a := a; + end; + inc(aMapData, bits); + if (PtrInt(aMapData) >= 8) then begin + inc(aData, 1); + dec(aMapData, 8); + end; + inc(aData, s); end; -class procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); +destructor TColorTableFormat.Destroy; begin - aPixel.Blue := aData^; - inc(aData); - aPixel.Green := aData^; - inc(aData); - aPixel.Red := aData^; - inc(aData); - aPixel.Alpha := aData^; - inc(aData); + SetLength(fColorTable, 0); + inherited Destroy; end; -{$ENDREGION} -{$REGION TglBitmap} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TglBitmap - Helper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec); begin with aFuncRec do begin - if (Source.PixelDesc.RedRange > 0) then - Dest.Red := Source.Red; - if (Source.PixelDesc.GreenRange > 0) then - Dest.Green := Source.Green; - if (Source.PixelDesc.BlueRange > 0) then - Dest.Blue := Source.Blue; - if (Source.PixelDesc.AlphaRange > 0) then - Dest.Alpha := Source.Alpha; + if (Source.Range.r > 0) then + Dest.Data.r := Source.Data.r; + if (Source.Range.g > 0) then + Dest.Data.g := Source.Data.g; + if (Source.Range.b > 0) then + Dest.Data.b := Source.Data.b; + if (Source.Range.a > 0) then + Dest.Data.a := Source.Data.a; end; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec); +var + i: Integer; begin with aFuncRec do begin - if (Source.PixelDesc.RedRange > 0) then - Dest.Red := Round(Dest.PixelDesc.RedRange * Source.Red / Source.PixelDesc.RedRange); - if (Source.PixelDesc.GreenRange > 0) then - Dest.Green := Round(Dest.PixelDesc.GreenRange * Source.Green / Source.PixelDesc.GreenRange); - if (Source.PixelDesc.BlueRange > 0) then - Dest.Blue := Round(Dest.PixelDesc.BlueRange * Source.Blue / Source.PixelDesc.BlueRange); - if (Source.PixelDesc.AlphaRange > 0) then - Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Source.Alpha / Source.PixelDesc.AlphaRange); + for i := 0 to 3 do + if (Source.Range.arr[i] > 0) then + Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]); end; end; +type + TShiftData = packed record + case Integer of + 0: (r, g, b, a: SmallInt); + 1: (arr: array[0..3] of SmallInt); + end; + PShiftData = ^TShiftData; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec); +var + i: Integer; begin with aFuncRec do - with PglBitmapPixelDesc(Args)^ do begin - if (Source.PixelDesc.RedRange > 0) then - Dest.Red := Source.Red shr RedShift; - if (Source.PixelDesc.GreenRange > 0) then - Dest.Green := Source.Green shr GreenShift; - if (Source.PixelDesc.BlueRange > 0) then - Dest.Blue := Source.Blue shr BlueShift; - if (Source.PixelDesc.AlphaRange > 0) then - Dest.Alpha := Source.Alpha shr AlphaShift; - end; + for i := 0 to 3 do + if (Source.Range.arr[i] > 0) then + Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i]; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec); begin with aFuncRec do begin - Dest.Red := Source.Red; - Dest.Green := Source.Green; - Dest.Blue := Source.Blue; - Dest.Alpha := Source.Alpha; + Dest.Data.r := Source.Data.r; + Dest.Data.g := Source.Data.g; + Dest.Data.b := Source.Data.b; + Dest.Data.a := Source.Data.a; if (Args and $1 > 0) then begin - Dest.Red := Dest.Red xor Dest.PixelDesc.RedRange; - Dest.Green := Dest.Green xor Dest.PixelDesc.GreenRange; - Dest.Blue := Dest.Blue xor Dest.PixelDesc.BlueRange; + Dest.Data.r := Dest.Data.r xor Dest.Range.r; + Dest.Data.g := Dest.Data.g xor Dest.Range.g; + Dest.Data.b := Dest.Data.b xor Dest.Range.b; end; if (Args and $2 > 0) then begin - Dest.Alpha := Dest.Alpha xor Dest.PixelDesc.AlphaRange; + Dest.Data.a := Dest.Data.a xor Dest.Range.a; end; end; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec); -type - PglBitmapPixelData = ^TglBitmapPixelData; +var + i: Integer; begin with aFuncRec do begin - Dest.Red := PglBitmapPixelData(Args)^.Red; - Dest.Green := PglBitmapPixelData(Args)^.Green; - Dest.Blue := PglBitmapPixelData(Args)^.Blue; - Dest.Alpha := PglBitmapPixelData(Args)^.Alpha; + for i := 0 to 3 do + Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i]; end; end; @@ -2639,12 +3343,12 @@ begin with FuncRec do begin if (FuncRec.Args = 0) then begin //source has no alpha Temp := - Source.Red / Source.PixelDesc.RedRange * ALPHA_WEIGHT_R + - Source.Green / Source.PixelDesc.GreenRange * ALPHA_WEIGHT_G + - Source.Blue / Source.PixelDesc.BlueRange * ALPHA_WEIGHT_B; - Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Temp); + Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R + + Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G + + Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B; + Dest.Data.a := Round(Dest.Range.a * Temp); end else - Dest.Alpha := Round(Source.Alpha / Source.PixelDesc.AlphaRange * Dest.PixelDesc.AlphaRange); + Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a); end; end; @@ -2654,17 +3358,17 @@ type PglBitmapPixelData = ^TglBitmapPixelData; begin with FuncRec do begin - Dest.Red := Source.Red; - Dest.Green := Source.Green; - Dest.Blue := Source.Blue; + Dest.Data.r := Source.Data.r; + Dest.Data.g := Source.Data.g; + Dest.Data.b := Source.Data.b; with PglBitmapPixelData(Args)^ do - if ((Dest.Red <= Red ) and (Dest.Red >= PixelDesc.RedRange ) and - (Dest.Green <= Green) and (Dest.Green >= PixelDesc.GreenRange) and - (Dest.Blue <= Blue ) and (Dest.Blue >= PixelDesc.BlueRange )) then - Dest.Alpha := 0 + if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and + (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and + (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then + Dest.Data.a := 0 else - Dest.Alpha := Dest.PixelDesc.AlphaRange; + Dest.Data.a := Dest.Range.a; end; end; @@ -2674,11 +3378,10 @@ type PglBitmapPixelData = ^TglBitmapPixelData; begin with FuncRec do begin - Dest.Red := Source.Red; - Dest.Green := Source.Green; - Dest.Blue := Source.Blue; - with PglBitmapPixelData(Args)^ do - Dest.Alpha := Alpha; + Dest.Data.r := Source.Data.r; + Dest.Data.g := Source.Data.g; + Dest.Data.b := Source.Data.b; + Dest.Data.a := PCardinal(Args)^; end; end; @@ -2706,7 +3409,6 @@ end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TglBitmap - PROTECTED/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -{$REGION Getter} function TglBitmap.GetWidth: Integer; begin if (ffX in fDimension.Fields) then @@ -2735,9 +3437,7 @@ function TglBitmap.GetFileHeight: Integer; begin result := Max(1, Height); end; -{$ENDREGION} -{$REGION Setter} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TglBitmap.SetCustomData(const aValue: Pointer); begin @@ -2775,7 +3475,7 @@ procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat); begin if fFormat = aValue then exit; - if (FORMAT_DESCRIPTORS[Format].GetSize <> FORMAT_DESCRIPTORS[aValue].GetSize) then + if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT); SetDataPointer(Data, aValue, Width, Height); end; @@ -2832,7 +3532,6 @@ begin end; end; end; -{$ENDREGION} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TglBitmap.CreateID; @@ -2891,7 +3590,7 @@ begin fDimension.Y := aHeight; end; - s := FORMAT_DESCRIPTORS[aFormat].GetSize; + s := TFormatDescriptor.Get(aFormat).PixelSize; fFormat := aFormat; fPixelSize := Ceil(s); fRowSize := Ceil(s * aWidth); @@ -2976,7 +3675,7 @@ var tmpData: PByte; size: Integer; begin - size := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize); + size := TFormatDescriptor.Get(aFormat).GetSize(aSize); GetMem(tmpData, size); try FillChar(tmpData^, size, #$FF); @@ -3069,7 +3768,8 @@ function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunct var DestData, TmpData, SourceData: pByte; TempHeight, TempWidth: Integer; - SourceFD, DestFD: TglBitmapFormatDescClass; + SourceFD, DestFD: TFormatDescriptor; + SourceMD, DestMD: Pointer; FuncRec: TglBitmapFunctionRec; begin @@ -3079,11 +3779,11 @@ begin result := false; if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin - SourceFD := FORMAT_DESCRIPTORS[aSource.Format]; - DestFD := FORMAT_DESCRIPTORS[aFormat]; + SourceFD := TFormatDescriptor.Get(aSource.Format); + DestFD := TFormatDescriptor.Get(aFormat); // inkompatible Formats so CreateTemp - if (SourceFD.GetSize <> DestFD.GetSize) then + if (SourceFD.PixelSize <> DestFD.PixelSize) then aCreateTemp := true; // Values @@ -3095,7 +3795,7 @@ begin TmpData := nil; if aCreateTemp then begin - GetMem(TmpData, Ceil(FORMAT_DESCRIPTORS[aFormat].GetSize * TempHeight * TempWidth)); + GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight)); DestData := TmpData; end else DestData := Data; @@ -3104,49 +3804,37 @@ begin SourceFD.PreparePixel(FuncRec.Source); DestFD.PreparePixel (FuncRec.Dest); + SourceMD := SourceFD.CreateMappingData; + DestMD := DestFD.CreateMappingData; + FuncRec.Size := aSource.Dimension; FuncRec.Position.Fields := FuncRec.Size.Fields; - if {FormatIsUncompressed(Source.InternalFormat)} true then begin + try SourceData := aSource.Data; FuncRec.Position.Y := 0; while FuncRec.Position.Y < TempHeight do begin FuncRec.Position.X := 0; while FuncRec.Position.X < TempWidth do begin - SourceFD.Unmap(SourceData, FuncRec.Source); + SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD); aFunc(FuncRec); - DestFD.Map(FuncRec.Dest, DestData); + DestFD.Map(FuncRec.Dest, DestData, DestMD); inc(FuncRec.Position.X); end; inc(FuncRec.Position.Y); end; - end else begin - (* TODO - // Compressed Images - FuncRec.Position.Y := 0; - while FuncRec.Position.Y < TempHeight do begin - FuncRec.Position.X := 0; - while FuncRec.Position.X < TempWidth do begin - // Get Data - fGetPixelFunc(FuncRec.Position, FuncRec.Source); - // Func - Func(FuncRec); - // Set Data - MapFunc(FuncRec.Dest, dest); - Inc(FuncRec.Position.X); - end; - Inc(FuncRec.Position.Y); - end; - *) - end; - // Updating Image or InternalFormat - if aCreateTemp then - SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) - else if (aFormat <> fFormat) then - Format := aFormat; + // Updating Image or InternalFormat + if aCreateTemp then + SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) + else if (aFormat <> fFormat) then + Format := aFormat; - result := true; + result := true; + finally + SourceFD.FreeMappingData(SourceMD); + DestFD.FreeMappingData(DestMD); + end; except if aCreateTemp then FreeMem(TmpData); @@ -3530,7 +4218,7 @@ begin if not FormatIsUncompressed(InternalFormat) then raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT); *) - result := AddFunc(Self, aFunc, false, FORMAT_DESCRIPTORS[Format].WithAlpha, aArgs); + result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3564,7 +4252,8 @@ function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitm var DestData, DestData2, SourceData: pByte; TempHeight, TempWidth: Integer; - SourceFD, DestFD: TglBitmapFormatDescClass; + SourceFD, DestFD: TFormatDescriptor; + SourceMD, DestMD, DestMD2: Pointer; FuncRec: TglBitmapFunctionRec; begin @@ -3575,12 +4264,12 @@ begin Assert(Assigned(aBitmap.Data)); if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin - result := ConvertTo(FORMAT_DESCRIPTORS[Format].WithAlpha); + result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha); if not Assigned(aFunc) then aFunc := glBitmapAlphaFunc; - SourceFD := FORMAT_DESCRIPTORS[aBitmap.Format]; - DestFD := FORMAT_DESCRIPTORS[Format]; + SourceFD := TFormatDescriptor.Get(aBitmap.Format); + DestFD := TFormatDescriptor.Get(Format); // Values TempHeight := aBitmap.FileHeight; @@ -3600,22 +4289,30 @@ begin SourceFD.PreparePixel(FuncRec.Source); DestFD.PreparePixel (FuncRec.Dest); - FuncRec.Position.Y := 0; - while FuncRec.Position.Y < TempHeight do begin - FuncRec.Position.X := 0; - while FuncRec.Position.X < TempWidth do begin - SourceFD.Unmap(SourceData, FuncRec.Source); - DestFD.Unmap (DestData, FuncRec.Dest); - aFunc(FuncRec); - DestFD.Map(FuncRec.Dest, DestData2); - inc(FuncRec.Position.X); + SourceMD := SourceFD.CreateMappingData; + DestMD := DestFD.CreateMappingData; + DestMD2 := DestFD.CreateMappingData; + try + FuncRec.Position.Y := 0; + while FuncRec.Position.Y < TempHeight do begin + FuncRec.Position.X := 0; + while FuncRec.Position.X < TempWidth do begin + SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD); + DestFD.Unmap (DestData, FuncRec.Dest, DestMD); + aFunc(FuncRec); + DestFD.Map(FuncRec.Dest, DestData2, DestMD2); + inc(FuncRec.Position.X); + end; + inc(FuncRec.Position.Y); end; - inc(FuncRec.Position.Y); + finally + SourceFD.FreeMappingData(SourceMD); + DestFD.FreeMappingData(DestMD); + DestFD.FreeMappingData(DestMD2); end; end; end; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean; begin @@ -3627,34 +4324,35 @@ function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal var PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData); + TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData); result := AddAlphaFromColorKeyFloat( - aRed / PixelData.PixelDesc.RedRange, - aGreen / PixelData.PixelDesc.GreenRange, - aBlue / PixelData.PixelDesc.BlueRange, - aDeviation / Max(PixelData.PixelDesc.RedRange, Max(PixelData.PixelDesc.GreenRange, PixelData.PixelDesc.BlueRange))); + aRed / PixelData.Range.r, + aGreen / PixelData.Range.g, + aBlue / PixelData.Range.b, + aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b))); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean; var - TempR, TempG, TempB: Cardinal; + values: array[0..2] of Single; + tmp: Cardinal; + i: Integer; PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData); - with PixelData.PixelDesc do begin - TempR := Trunc(RedRange * aDeviation); - TempG := Trunc(GreenRange * aDeviation); - TempB := Trunc(BlueRange * aDeviation); - - PixelData.Red := Min(RedRange, Trunc(RedRange * aRed) + TempR); - RedRange := Max(0, Trunc(RedRange * aRed) - TempR); - PixelData.Green := Min(GreenRange, Trunc(GreenRange * aGreen) + TempG); - GreenRange := Max(0, Trunc(GreenRange * aGreen) - TempG); - PixelData.Blue := Min(BlueRange, Trunc(BlueRange * aBlue) + TempB); - BlueRange := Max(0, Trunc(BlueRange * aBlue) - TempB); - PixelData.Alpha := 0; - AlphaRange := 0; + TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData); + with PixelData do begin + values[0] := aRed; + values[1] := aGreen; + values[2] := aBlue; + + for i := 0 to 2 do begin + tmp := Trunc(Range.arr[i] * aDeviation); + Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp)); + Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp)); + end; + Data.a := 0; + Range.a := 0; end; result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData)); end; @@ -3670,8 +4368,8 @@ function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean; var PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData); - result := AddAlphaFromValueFloat(aAlpha / PixelData.PixelDesc.AlphaRange); + TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData); + result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3679,19 +4377,19 @@ function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean; var PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData); - with PixelData.PixelDesc do - PixelData.Alpha := Min(AlphaRange, Max(0, Round(AlphaRange * aAlpha))); - result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData)); + TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData); + with PixelData do + Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha))); + result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a)); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TglBitmap.RemoveAlpha: Boolean; var - FormatDesc: TglBitmapFormatDescClass; + FormatDesc: TFormatDescriptor; begin result := false; - FormatDesc := FORMAT_DESCRIPTORS[Format]; + FormatDesc := TFormatDescriptor.Get(Format); if Assigned(Data) then begin if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT); @@ -3711,7 +4409,7 @@ begin try // copy texture data if assigned if Assigned(Data) then begin - Size := FORMAT_DESCRIPTORS[Format].GetSize(fDimension); + Size := TFormatDescriptor.Get(Format).GetSize(fDimension); GetMem(TempPtr, Size); try Move(Data^, TempPtr^, Size); @@ -3752,26 +4450,26 @@ end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean; var - SourceFD, DestFD: TglBitmapFormatDescClass; + SourceFD, DestFD: TFormatDescriptor; SourcePD, DestPD: TglBitmapPixelData; - PixelDesc: TglBitmapPixelDesc; + ShiftData: TShiftData; function CanCopyDirect: Boolean; begin result := - ((SourcePD.PixelDesc.RedRange = DestPD.PixelDesc.RedRange) or (SourcePD.PixelDesc.RedRange = 0) or (DestPD.PixelDesc.RedRange = 0)) and - ((SourcePD.PixelDesc.GreenRange = DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and - ((SourcePD.PixelDesc.BlueRange = DestPD.PixelDesc.BlueRange) or (SourcePD.PixelDesc.BlueRange = 0) or (DestPD.PixelDesc.BlueRange = 0)) and - ((SourcePD.PixelDesc.AlphaRange = DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0)); + ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and + ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and + ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and + ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0)); end; function CanShift: Boolean; begin result := - ((SourcePD.PixelDesc.RedRange >= DestPD.PixelDesc.RedRange ) or (SourcePD.PixelDesc.RedRange = 0) or (DestPD.PixelDesc.RedRange = 0)) and - ((SourcePD.PixelDesc.GreenRange >= DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and - ((SourcePD.PixelDesc.BlueRange >= DestPD.PixelDesc.BlueRange ) or (SourcePD.PixelDesc.BlueRange = 0) or (DestPD.PixelDesc.BlueRange = 0)) and - ((SourcePD.PixelDesc.AlphaRange >= DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0)); + ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and + ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and + ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and + ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0)); end; function GetShift(aSource, aDest: Cardinal) : ShortInt; @@ -3785,8 +4483,8 @@ var begin if aFormat <> fFormat then begin - SourceFD := FORMAT_DESCRIPTORS[Format]; - DestFD := FORMAT_DESCRIPTORS[aFormat]; + SourceFD := TFormatDescriptor.Get(Format); + DestFD := TFormatDescriptor.Get(aFormat); SourceFD.PreparePixel(SourcePD); DestFD.PreparePixel (DestPD); @@ -3794,11 +4492,11 @@ begin if CanCopyDirect then result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat) else if CanShift then begin - PixelDesc.RedShift := GetShift(SourcePD.PixelDesc.RedRange, DestPD.PixelDesc.RedRange); - PixelDesc.GreenShift := GetShift(SourcePD.PixelDesc.GreenRange, DestPD.PixelDesc.GreenRange); - PixelDesc.BlueShift := GetShift(SourcePD.PixelDesc.BlueRange, DestPD.PixelDesc.BlueRange); - PixelDesc.AlphaShift := GetShift(SourcePD.PixelDesc.AlphaRange, DestPD.PixelDesc.AlphaRange); - result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@PixelDesc)); + ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r); + ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g); + ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b); + ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a); + result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData)); end else result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat); end else @@ -3843,12 +4541,12 @@ procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; cons var PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData); + TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData); FillWithColorFloat( - aRed / PixelData.PixelDesc.RedRange, - aGreen / PixelData.PixelDesc.GreenRange, - aBlue / PixelData.PixelDesc.BlueRange, - aAlpha / PixelData.PixelDesc.AlphaRange); + aRed / PixelData.Range.r, + aGreen / PixelData.Range.g, + aBlue / PixelData.Range.b, + aAlpha / PixelData.Range.a); end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3856,11 +4554,13 @@ procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const var PixelData: TglBitmapPixelData; begin - FORMAT_DESCRIPTORS[Format].PreparePixel(PixelData); - PixelData.Red := Max(0, Min(PixelData.PixelDesc.RedRange, Trunc(PixelData.PixelDesc.RedRange * aRed))); - PixelData.Green := Max(0, Min(PixelData.PixelDesc.GreenRange, Trunc(PixelData.PixelDesc.GreenRange * aGreen))); - PixelData.Blue := Max(0, Min(PixelData.PixelDesc.BlueRange, Trunc(PixelData.PixelDesc.BlueRange * aBlue))); - PixelData.Alpha := Max(0, Min(PixelData.PixelDesc.AlphaRange, Trunc(PixelData.PixelDesc.AlphaRange * aAlpha))); + TFormatDescriptor.Get(Format).PreparePixel(PixelData); + with PixelData do begin + Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed))); + Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen))); + Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue))); + Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha))); + end; AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData)); end; @@ -4031,7 +4731,7 @@ var ImageSize: Integer; begin Create; - ImageSize := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize); + TFormatDescriptor.Get(aFormat).GetSize(aSize); GetMem(Image, ImageSize); try FillChar(Image^, ImageSize, #$FF); @@ -4957,6 +5657,7 @@ type biClrImportant: Cardinal; end; + (* TODO: delete? TBMPInfoOS = packed record biSize: Cardinal; biWidth: Longint; @@ -4964,201 +5665,203 @@ type biPlanes: Word; biBitCount: Word; end; - -// TBMPPalette = record -// case Boolean of -// true : (Colors: array[Byte] of TRGBQUAD); -// false: (redMask, greenMask, blueMask: Cardinal); -// end; + *) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TglBitmap.LoadBMP(const aStream: TStream): Boolean; -type - TMaskValues = packed record - Red: Cardinal; - Green: Cardinal; - Blue: Cardinal; - Alpha: Cardinal; - end; - -var - StartPos: Int64; ////////////////////////////////////////////////////////////////////////////////////////////////// - function ReadInfo(var aInfo: TBMPInfo; var aMask: TMaskValues): TglBitmapFormat; + function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat; begin result := tfEmpty; aStream.Read(aInfo, SizeOf(aInfo)); FillChar(aMask, SizeOf(aMask), 0); //Read Compression - if aInfo.biCompression <> BMP_COMP_RGB then begin - if aInfo.biCompression = BMP_COMP_BITFIELDS then begin - // Read Bitmasks for 16 or 32 Bit (24 Bit dosn't support Bitmasks!) + case aInfo.biCompression of + BMP_COMP_RLE4, + BMP_COMP_RLE8: begin + raise EglBitmapException.Create('RLE compression is not supported'); + end; + BMP_COMP_BITFIELDS: begin if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin - aStream.Read(aMask.Red, SizeOf(Cardinal)); - aStream.Read(aMask.Green, SizeOf(Cardinal)); - aStream.Read(aMask.Blue, SizeOf(Cardinal)); - aStream.Read(aMask.Alpha, SizeOf(Cardinal)); + aStream.Read(aMask.r, SizeOf(aMask.r)); + aStream.Read(aMask.g, SizeOf(aMask.g)); + aStream.Read(aMask.b, SizeOf(aMask.b)); + aStream.Read(aMask.a, SizeOf(aMask.a)); end else - raise EglBitmapException.Create('Bitmask is not supported for 24bit formats'); - end else begin - aStream.Position := StartPos; - raise EglBitmapException.Create('RLE compression is not supported'); + raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats'); end; end; //get suitable format case aInfo.biBitCount of 8: result := tfLuminance8; - 16: result := tfRGB5A1; + 16: result := tfBGR5; 24: result := tfBGR8; 32: result := tfBGRA8; end; end; + function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TColorTableFormat; + var + i, c: Integer; + ColorTable: TColorTable; + begin + result := nil; + if (aInfo.biBitCount >= 16) then + exit; + aFormat := tfLuminance8; + c := aInfo.biClrUsed; + if (c = 0) then + c := 1 shl aInfo.biBitCount; + SetLength(ColorTable, c); + for i := 0 to c-1 do begin + aStream.Read(ColorTable[i], SizeOf(TColorTableEnty)); + if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then + aFormat := tfRGB8; + end; + + result := TColorTableFormat.Create; + result.PixelSize := aInfo.biBitCount / 8; + result.ColorTable := ColorTable; + result.Range := glBitmapColorRec($FF, $FF, $FF, $00); + end; + ////////////////////////////////////////////////////////////////////////////////////////////////// - function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TMaskValues): TBitfieldFormat; + function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec; + const aInfo: TBMPInfo): TBitfieldFormat; var TmpFormat: TglBitmapFormat; - FormatDesc: TglBitmapFormatDescClass; + FormatDesc: TFormatDescriptor; begin result := nil; - if (aMask.Red <> 0) or (aMask.Green <> 0) or (aMask.Blue <> 0) or (aMask.Alpha <> 0) then begin - for TmpFormat := High(FORMAT_DESCRIPTORS) downto Low(FORMAT_DESCRIPTORS) do begin - FormatDesc := FORMAT_DESCRIPTORS[TmpFormat]; - if FormatDesc.MaskMatch(aMask.Red, aMask.Green, aMask.Blue, aMask.Alpha) then begin - aFormat := FormatDesc.GetFormat; + if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin + for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin + FormatDesc := TFormatDescriptor.Get(TmpFormat); + if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin + aFormat := FormatDesc.Format; exit; end; end; - if (aMask.Alpha = 0) then - aFormat := FORMAT_DESCRIPTORS[aFormat].WithoutAlpha; + if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then + aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha; + if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then + aFormat := TFormatDescriptor.Get(aFormat).WithAlpha; result := TBitfieldFormat.Create; - result.RedMask := aMask.Red; - result.GreenMask := aMask.Green; - result.BlueMask := aMask.Blue; - result.AlphaMask := aMask.Alpha; + result.PixelSize := aInfo.biBitCount / 8; + result.RedMask := aMask.r; + result.GreenMask := aMask.g; + result.BlueMask := aMask.b; + result.AlphaMask := aMask.a; end; end; var //simple types + StartPos: Int64; ImageSize, rbLineSize, wbLineSize, Padding, i: Integer; PaddingBuff: Cardinal; LineBuf, ImageData, TmpData: PByte; + SourceMD, DestMD: Pointer; BmpFormat: TglBitmapFormat; + ColorTable: TColorTable; //records - Mask: TMaskValues; + Mask: TglBitmapColorRec; Header: TBMPHeader; Info: TBMPInfo; //classes - BitfieldFormat: TBitfieldFormat; - FormatDesc: TglBitmapFormatDescClass; - - - Tick: QWord; -{ - - - ImageData, pData, pTmp, LineBuf, TmpData: PByte; - BitOffset: Byte; - BmpFormat: TglBitmapFormat; - LineSize, Padding, LineIdx, PixelIdx: Integer; - RedMask, GreenMask, BlueMask, AlphaMask, FormatSize: Cardinal; - - - Pixel: TglBitmapPixelData; - PaddingBuff: Cardinal; - - - - } + SpecialFormat: TFormatDescriptor; + FormatDesc: TFormatDescriptor; ////////////////////////////////////////////////////////////////////////////////////////////////// - procedure ReadBitfieldLine(aData: PByte; aLineBuf: PByte); + procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte); var - i: Integer; + i, j: Integer; Pixel: TglBitmapPixelData; - - //////////////////////////////////////////////////////////////////////////////////////////////// - procedure ChangeRange(var aValue: Cardinal; const aOldRange, aNewRange: Cardinal); - begin - if (aOldRange = aNewRange) then - exit; - if (aOldRange > 0) then - aValue := Round(aValue / aOldRange * aNewRange) - else - aValue := 0; - end; - begin aStream.Read(aLineBuf^, rbLineSize); + SpecialFormat.PreparePixel(Pixel); for i := 0 to Info.biWidth-1 do begin - BitfieldFormat.Unmap(PCardinal(aLineBuf)^, Pixel); //if is 16bit Bitfield only 2 last significant Bytes are taken from Cardinal - inc(aLineBuf, Info.biBitCount shr 3); - with FormatDesc.GetPixelDesc do begin - ChangeRange(Pixel.Red, BitfieldFormat.RedRange, RedRange); - ChangeRange(Pixel.Green, BitfieldFormat.GreenRange, GreenRange); - ChangeRange(Pixel.Blue, BitfieldFormat.BlueRange, BlueRange); - ChangeRange(Pixel.Alpha, BitfieldFormat.AlphaRange, AlphaRange); + SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD); + with FormatDesc do begin + //TODO: use convert function + for j := 0 to 3 do + if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin + if (SpecialFormat.Range.arr[j] > 0) then + Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j]) + else + Pixel.Data.arr[j] := 0; + end; end; - FormatDesc.Map(Pixel, aData); + FormatDesc.Map(Pixel, aData, DestMD); end; end; begin - result := false; - BmpFormat := tfEmpty; - BitfieldFormat := nil; - LineBuf := nil; + result := false; + BmpFormat := tfEmpty; + SpecialFormat := nil; + LineBuf := nil; + SourceMD := nil; + DestMD := nil; // Header StartPos := aStream.Position; aStream.Read(Header, SizeOf(Header)); if Header.bfType = BMP_MAGIC then begin - BmpFormat := ReadInfo(Info, Mask); - BitfieldFormat := CheckBitfields(BmpFormat, Mask); - try - if (Info.biBitCount < 16) then - aStream.Position := aStream.Position + Info.biClrUsed * 4; + try try + BmpFormat := ReadInfo(Info, Mask); + SpecialFormat := ReadColorTable(BmpFormat, Info); + if not Assigned(SpecialFormat) then + SpecialFormat := CheckBitfields(BmpFormat, Mask, Info); aStream.Position := StartPos + Header.bfOffBits; if (BmpFormat <> tfEmpty) then begin - FormatDesc := FORMAT_DESCRIPTORS[BmpFormat]; - rbLineSize := Info.biWidth * (Info.biBitCount shr 3); //ReadBuffer LineSize - wbLineSize := Trunc(Info.biWidth * FormatDesc.GetSize); + FormatDesc := TFormatDescriptor.Get(BmpFormat); + rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize + wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize); Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize; //get Memory - ImageSize := FormatDesc.GetSize(glBitmapPosition(Info.biWidth, Info.biHeight)); + DestMD := FormatDesc.CreateMappingData; + ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight)); GetMem(ImageData, ImageSize); - if Assigned(BitfieldFormat) then + if Assigned(SpecialFormat) then begin GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields + SourceMD := SpecialFormat.CreateMappingData; + end; //read Data try try FillChar(ImageData^, ImageSize, $FF); TmpData := ImageData; - Inc(TmpData, wbLineSize * (Info.biHeight -1)); - for i := 0 to Info.biHeight-1 do begin - if Assigned(BitfieldFormat) then - ReadBitfieldLine(TmpData, LineBuf) //if is bitfield format read and convert data + if (Info.biHeight > 0) then + Inc(TmpData, wbLineSize * (Info.biHeight-1)); + for i := 0 to Abs(Info.biHeight)-1 do begin + if Assigned(SpecialFormat) then + SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data else aStream.Read(TmpData^, wbLineSize); //else only read data - Dec(TmpData, wbLineSize); + if (Info.biHeight > 0) then + dec(TmpData, wbLineSize) + else + inc(TmpData, wbLineSize); aStream.Read(PaddingBuff, Padding); end; - SetDataPointer(ImageData, BmpFormat, Info.biWidth, Info.biHeight); + SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); result := true; finally if Assigned(LineBuf) then FreeMem(LineBuf); + if Assigned(SourceMD) then + SpecialFormat.FreeMappingData(SourceMD); + FormatDesc.FreeMappingData(DestMD); end; except FreeMem(ImageData); @@ -5166,8 +5869,12 @@ begin end; end else raise EglBitmapException.Create('LoadBMP - No suitable format found'); + except + aStream.Position := StartPos; + raise; + end; finally - FreeAndNil(BitfieldFormat); + FreeAndNil(SpecialFormat); end; end else aStream.Position := StartPos; @@ -5181,6 +5888,7 @@ var pData, pTemp: pByte; PixelFormat: TglBitmapPixelData; + FormatDesc: TFormatDescriptor; ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer; Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal; @@ -5195,7 +5903,7 @@ begin if not (ftBMP in FormatGetSupportedFiles(Format)) then raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT); - ImageSize := FORMAT_DESCRIPTORS[Format].GetSize(Dimension); + ImageSize := TFormatDescriptor.Get(Format).GetSize(Dimension); Header.bfType := BMP_MAGIC; Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize; @@ -5248,13 +5956,11 @@ begin Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal); Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal); - FORMAT_DESCRIPTORS[Format].PreparePixel(PixelFormat); - with PixelFormat.PixelDesc do begin - RedMask := RedRange shl RedShift; - GreenMask := GreenRange shl GreenShift; - BlueMask := BlueRange shl BlueShift; - AlphaMask := AlphaRange shl AlphaShift; - end; + FormatDesc := TFormatDescriptor.Get(Format); + RedMask := FormatDesc.RedMask; + GreenMask := FormatDesc.GreenMask; + BlueMask := FormatDesc.BlueMask; + AlphaMask := FormatDesc.AlphaMask; end; // headers @@ -5279,7 +5985,7 @@ begin end; // image data - LineSize := Trunc(Width * FORMAT_DESCRIPTORS[Format].GetSize); + LineSize := Trunc(Width * TFormatDescriptor.Get(Format).PixelSize); Padding := GetLineWidth - LineSize; PaddingBuff := 0; @@ -5527,7 +6233,7 @@ begin if Header.ImageID <> 0 then aStream.Position := aStream.Position + Header.ImageID; - PixelSize := Trunc(FORMAT_DESCRIPTORS[Format].GetSize); + PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1); LineSize := Trunc(Header.Width * PixelSize); GetMem(NewImage, LineSize * Header.Height); @@ -5569,7 +6275,7 @@ var Header: TTGAHeader; Size: Integer; pTemp: pByte; - FormatDesc: TglBitmapFormatDescClass; + FormatDesc: TFormatDescriptor; procedure ConvertData(pTemp: pByte); var @@ -5615,7 +6321,7 @@ begin Header.Width := Width; Header.Height := Height; Header.ImageDes := $20; - FormatDesc := FORMAT_DESCRIPTORS[Format]; + FormatDesc := TFormatDescriptor.Get(Format); if FormatDesc.HasAlpha then Header.ImageDes := Header.ImageDes or $08; @@ -5694,7 +6400,7 @@ type dwRBitMask: Cardinal; dwGBitMask: Cardinal; dwBBitMask: Cardinal; - dwAlphaBitMask: Cardinal; + dwABitMask: Cardinal; end; TDDSCaps = packed record @@ -5815,7 +6521,7 @@ begin end; ddsFormat := GetDDSFormat; - LineSize := Trunc(Header.dwWidth * FORMAT_DESCRIPTORS[ddsFormat].GetSize); + LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize); GetMem(NewImage, Header.dwHeight * LineSize); try pData := NewImage; @@ -5853,6 +6559,7 @@ procedure TglBitmap.SaveDDS(const aStream: TStream); var Header: TDDSHeader; Pix: TglBitmapPixelData; + FormatDesc: TFormatDescriptor; begin //if not FormatIsUncompressed(InternalFormat) then // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT); @@ -5860,7 +6567,7 @@ begin (* TODO if Format = tfAlpha8 then FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix); else *) - FORMAT_DESCRIPTORS[Format].PreparePixel(Pix); + TFormatDescriptor.Get(Format).PreparePixel(Pix); // Generell FillChar(Header, SizeOf(Header), 0); @@ -5893,16 +6600,16 @@ begin Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS; *) - Header.PixelFormat.dwRGBBitCount := Trunc(FORMAT_DESCRIPTORS[Format].GetSize * 8); - Header.PixelFormat.dwRBitMask := Pix.PixelDesc.RedRange shl Pix.PixelDesc.RedShift; - Header.PixelFormat.dwGBitMask := Pix.PixelDesc.GreenRange shl Pix.PixelDesc.GreenShift; - Header.PixelFormat.dwBBitMask := Pix.PixelDesc.BlueRange shl Pix.PixelDesc.BlueShift; - Header.PixelFormat.dwAlphaBitMask := Pix.PixelDesc.AlphaRange shl Pix.PixelDesc.AlphaShift; + FormatDesc := TFormatDescriptor.Get(Format); + Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8); + Header.PixelFormat.dwRBitMask := FormatDesc.RedMask; + Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask; + Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask; + Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask; aStream.Write(Header, SizeOf(Header)); - aStream.Write(Data^, FORMAT_DESCRIPTORS[Format].GetSize(Dimension)); + aStream.Write(Data^, FormatDesc.GetSize(Dimension)); end; -{$ENDREGION} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TglBitmap2D///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -5932,7 +6639,7 @@ begin // Assigning Data if Assigned(Data) then begin SetLength(fLines, GetHeight); - LineWidth := Trunc(GetWidth * FORMAT_DESCRIPTORS[Format].GetSize); + LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize); for Idx := 0 to GetHeight -1 do begin fLines[Idx] := Data; @@ -5963,8 +6670,7 @@ end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean); var - FormatDescriptor: TglBitmapFormatDescClass; - FormatDesc: TglBitmapFormatDesc; + FormatDesc: TFormatDescriptor; begin glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -5974,14 +6680,13 @@ begin else *) - FormatDescriptor := FORMAT_DESCRIPTORS[Format]; - FormatDesc := FormatDescriptor.GetFormatDesc; + FormatDesc := TFormatDescriptor.Get(Format); if aBuildWithGlu then - gluBuild2DMipmaps(aTarget, FormatDescriptor.GetColorCompCount, Width, Height, - FormatDesc.Format, FormatDesc.DataType, Data) + gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height, + FormatDesc.glFormat, FormatDesc.glDataFormat, Data) else - glTexImage2D(aTarget, 0, FormatDesc.InternalFormat, Width, Height, 0, - FormatDesc.Format, FormatDesc.DataType, Data); + glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, + FormatDesc.glFormat, FormatDesc.glDataFormat, Data); // Freigeben if (FreeDataAfterGenTexture) then @@ -6000,8 +6705,7 @@ procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; co var Temp: pByte; Size, w, h: Integer; - FormatDesc: TglBitmapFormatDescClass; - glFormatDesc: TglBitmapFormatDesc; + FormatDesc: TFormatDescriptor; begin (* TODO compression if not FormatIsUncompressed(Format) then @@ -6010,13 +6714,12 @@ begin w := aRight - aLeft; h := aBottom - aTop; - FormatDesc := FORMAT_DESCRIPTORS[Format]; - glFormatDesc := FormatDesc.GetFormatDesc; - Size := FormatDesc.GetSize(glBitmapPosition(w, h)); + FormatDesc := TFormatDescriptor.Get(Format); + Size := FormatDesc.GetSize(w, h); GetMem(Temp, Size); try glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(aLeft, aTop, w, h, glFormatDesc.Format, glFormatDesc.DataType, Temp); + glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp); SetDataPointer(Temp, Format, w, h); FlipVert; except @@ -6029,10 +6732,10 @@ end; procedure TglBitmap2D.GetDataFromTexture; var Temp: PByte; - TempWidth, TempHeight, RedSize, GreenSize, BlueSize, AlphaSize, LumSize: Integer; + TempWidth, TempHeight: Integer; TempType, TempIntFormat: Cardinal; - IntFormat: TglBitmapFormat; - FormatDesc: TglBitmapFormatDescClass; + IntFormat, f: TglBitmapFormat; + FormatDesc: TFormatDescriptor; begin Bind; @@ -6041,29 +6744,23 @@ begin glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight); glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat); - glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_RED_SIZE, @RedSize); - glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_GREEN_SIZE, @GreenSize); - glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_BLUE_SIZE, @BlueSize); - glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_ALPHA_SIZE, @AlphaSize); - glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_LUMINANCE_SIZE, @LumSize); - IntFormat := tfEmpty; - for FormatDesc in FORMAT_DESCRIPTORS do - if (FormatDesc.GetFormatDesc.InternalFormat = TempIntFormat) then begin - IntFormat := FormatDesc.GetFormat; + for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do + if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin + IntFormat := FormatDesc.Format; break; end; // Getting data from OpenGL - GetMem(Temp, FormatDesc.GetSize(glBitmapPosition(TempWidth, TempHeight))); + FormatDesc := TFormatDescriptor.Get(IntFormat); + GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight)); try (* TODO Compression if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then glGetCompressedTexImage(Target, 0, Temp) else *) - with FormatDesc.GetFormatDesc do - glGetTexImage(Target, 0, InternalFormat, DataType, Temp); + glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp); SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); except FreeMem(Temp); @@ -6176,7 +6873,7 @@ type end; const - oneover255 = 1 / 255; + ONE_OVER_255 = 1 / 255; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec); @@ -6184,8 +6881,11 @@ var Val: Single; begin with FuncRec do begin - Val := Source.Red * 0.3 + Source.Green * 0.59 + Source.Blue * 0.11; - PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * oneover255; + Val := + Source.Data.r * LUMINANCE_WEIGHT_R + + Source.Data.g * LUMINANCE_WEIGHT_G + + Source.Data.b * LUMINANCE_WEIGHT_B; + PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255; end; end; @@ -6193,7 +6893,7 @@ end; procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec); begin with FuncRec do - PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Alpha * oneover255; + PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255; end; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -6240,9 +6940,9 @@ begin end; // Farbe zuweisem - Dest.Red := Trunc((Vec[0] + 1) * 127.5); - Dest.Green := Trunc((Vec[1] + 1) * 127.5); - Dest.Blue := Trunc((Vec[2] + 1) * 127.5); + Dest.Data.r := Trunc((Vec[0] + 1) * 127.5); + Dest.Data.g := Trunc((Vec[1] + 1) * 127.5); + Dest.Data.b := Trunc((Vec[2] + 1) * 127.5); end; end; @@ -6370,7 +7070,7 @@ begin end; // Daten Sammeln - if aUseAlpha and FORMAT_DESCRIPTORS[Format].HasAlpha then + if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec)) else AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec)); @@ -6752,6 +7452,9 @@ initialization glBitmapSetDefaultFreeDataAfterGenTexture(true); glBitmapSetDefaultDeleteTextureOnFree (true); + TFormatDescriptor.Init; + finalization + TFormatDescriptor.Finalize; end. -- 2.1.4