+ if ((aDataObj.Width = Width) and (aDataObj.Height = Height)) then begin
+ result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
+
+ SourceFD := TFormatDescriptor.Get(aDataObj.Format);
+ DestFD := TFormatDescriptor.Get(Format);
+
+ if not Assigned(aFunc) then begin
+ aFunc := glBitmapAlphaFunc;
+ FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
+ end else
+ FuncRec.Args := aArgs;
+
+ // Values
+ TempWidth := aDataObj.Width;
+ TempHeight := aDataObj.Height;
+ if (TempWidth <= 0) or (TempHeight <= 0) then
+ exit;
+
+ FuncRec.Sender := Self;
+ FuncRec.Size := Dimension;
+ FuncRec.Position.Fields := FuncRec.Size.Fields;
+
+ DestData := Data;
+ DestData2 := Data;
+ SourceData := aDataObj.Data;
+
+ // Mapping
+ SourceFD.PreparePixel(FuncRec.Source);
+ DestFD.PreparePixel (FuncRec.Dest);
+
+ 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;
+ finally
+ SourceFD.FreeMappingData(SourceMD);
+ DestFD.FreeMappingData(DestMD);
+ DestFD.FreeMappingData(DestMD2);
+ end;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
+begin
+ result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ result := AddAlphaFromColorKeyFloat(
+ 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 TglBitmapData.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
+var
+ values: array[0..2] of Single;
+ tmp: Cardinal;
+ i: Integer;
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(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, @PixelData);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValue(const aAlpha: Byte): Boolean;
+begin
+ result := AddAlphaFromValueFloat(aAlpha / $FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ with PixelData do
+ Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
+ result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.RemoveAlpha: Boolean;
+var
+ FormatDesc: TFormatDescriptor;
+begin
+ result := false;
+ FormatDesc := TFormatDescriptor.Get(Format);
+ if Assigned(Data) then begin
+ if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
+ raise EglBitmapUnsupportedFormat.Create(Format);
+ result := ConvertTo(FormatDesc.WithoutAlpha);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColor(const aRed, aGreen, aBlue: Byte;
+ const aAlpha: Byte);
+begin
+ FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
+var
+ PixelData: TglBitmapPixelData;
+begin
+ TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
+ FillWithColorFloat(
+ aRed / PixelData.Range.r,
+ aGreen / PixelData.Range.g,
+ aBlue / PixelData.Range.b,
+ aAlpha / PixelData.Range.a);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
+var
+ PixelData: TglBitmapPixelData;
+begin
+ 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;
+ Convert(glBitmapFillWithColorFunc, false, @PixelData);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.SetData(const aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer; const aHeight: Integer);
+begin
+ if (Data <> aData) then begin
+ if (Assigned(Data)) then
+ FreeMem(Data);
+ fData := aData;
+ end;
+
+ if Assigned(fData) then begin
+ FillChar(fDimension, SizeOf(fDimension), 0);
+ if aWidth <> -1 then begin
+ fDimension.Fields := fDimension.Fields + [ffX];
+ fDimension.X := aWidth;
+ end;
+
+ if aHeight <> -1 then begin
+ fDimension.Fields := fDimension.Fields + [ffY];
+ fDimension.Y := aHeight;
+ end;
+
+ fFormat := aFormat;
+ end else
+ fFormat := tfEmpty;
+
+ UpdateScanlines;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmapData.Clone: TglBitmapData;
+var
+ Temp: TglBitmapData;
+ TempPtr: PByte;
+ Size: Integer;
+begin
+ result := nil;
+ Temp := (ClassType.Create as TglBitmapData);
+ try
+ // copy texture data if assigned
+ if Assigned(Data) then begin
+ Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
+ GetMem(TempPtr, Size);
+ try
+ Move(Data^, TempPtr^, Size);
+ Temp.SetData(TempPtr, Format, Width, Height);
+ except
+ if Assigned(TempPtr) then
+ FreeMem(TempPtr);
+ raise;
+ end;
+ end else begin
+ TempPtr := nil;
+ Temp.SetData(TempPtr, Format, Width, Height);
+ end;
+
+ // copy properties
+ Temp.fFormat := Format;
+ result := Temp;
+ except
+ FreeAndNil(Temp);
+ raise;
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
+var
+ mask: PtrInt;
+begin
+ mask :=
+ (Byte(aRed) and 1) or
+ ((Byte(aGreen) and 1) shl 1) or
+ ((Byte(aBlue) and 1) shl 2) or
+ ((Byte(aAlpha) and 1) shl 3);
+ if (mask > 0) then
+ Convert(glBitmapInvertFunc, false, {%H-}Pointer(mask));
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+type
+ TMatrixItem = record
+ X, Y: Integer;
+ W: Single;
+ end;
+
+ PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
+ TglBitmapToNormalMapRec = Record
+ Scale: Single;
+ Heights: array of Single;
+ MatrixU : array of TMatrixItem;
+ MatrixV : array of TMatrixItem;
+ end;
+
+const
+ ONE_OVER_255 = 1 / 255;
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
+var
+ Val: Single;
+begin
+ with FuncRec do begin
+ 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;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+begin
+ with FuncRec do
+ PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
+type
+ TVec = Array[0..2] of Single;
+var
+ Idx: Integer;
+ du, dv: Double;
+ Len: Single;
+ Vec: TVec;
+
+ function GetHeight(X, Y: Integer): Single;
+ begin
+ with FuncRec do begin
+ X := Max(0, Min(Size.X -1, X));
+ Y := Max(0, Min(Size.Y -1, Y));
+ result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
+ end;
+ end;
+
+begin
+ with FuncRec do begin
+ with PglBitmapToNormalMapRec(Args)^ do begin
+ du := 0;
+ for Idx := Low(MatrixU) to High(MatrixU) do
+ du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
+
+ dv := 0;
+ for Idx := Low(MatrixU) to High(MatrixU) do
+ dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
+
+ Vec[0] := -du * Scale;
+ Vec[1] := -dv * Scale;
+ Vec[2] := 1;
+ end;
+
+ // Normalize
+ Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
+ if Len <> 0 then begin
+ Vec[0] := Vec[0] * Len;
+ Vec[1] := Vec[1] * Len;
+ Vec[2] := Vec[2] * Len;
+ end;
+
+ // Farbe zuweisem
+ 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;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmapData.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
+var
+ Rec: TglBitmapToNormalMapRec;
+
+ procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
+ begin
+ if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
+ Matrix[Index].X := X;
+ Matrix[Index].Y := Y;
+ Matrix[Index].W := W;
+ end;
+ end;
+
+begin
+ if TFormatDescriptor.Get(Format).IsCompressed then
+ raise EglBitmapUnsupportedFormat.Create(Format);
+
+ if aScale > 100 then
+ Rec.Scale := 100
+ else if aScale < -100 then
+ Rec.Scale := -100
+ else
+ Rec.Scale := aScale;
+
+ SetLength(Rec.Heights, Width * Height);
+ try
+ case aFunc of
+ nm4Samples: begin
+ SetLength(Rec.MatrixU, 2);
+ SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
+ SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
+
+ SetLength(Rec.MatrixV, 2);
+ SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
+ SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
+ end;
+
+ nmSobel: begin
+ SetLength(Rec.MatrixU, 6);
+ SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
+ SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
+ SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
+ SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
+ SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
+ SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
+
+ SetLength(Rec.MatrixV, 6);
+ SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
+ SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
+ SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
+ SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
+ SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
+ SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
+ end;
+
+ nm3x3: begin
+ SetLength(Rec.MatrixU, 6);
+ SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
+ SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
+ SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
+ SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
+ SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
+ SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
+
+ SetLength(Rec.MatrixV, 6);
+ SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
+ SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
+ SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
+ SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
+ SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
+ SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
+ end;
+
+ nm5x5: begin
+ SetLength(Rec.MatrixU, 20);
+ SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
+ SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
+ SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
+ SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
+ SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
+ SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
+ SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
+ SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
+ SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
+ SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
+ SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
+ SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
+ SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
+ SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
+ SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
+ SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
+ SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
+ SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
+ SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
+ SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
+
+ SetLength(Rec.MatrixV, 20);
+ SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
+ SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
+ SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
+ SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
+ SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
+ SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
+ SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
+ SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
+ SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
+ SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
+ SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
+ SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
+ SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
+ SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
+ SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
+ SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
+ SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
+ SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
+ SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
+ SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
+ end;
+ end;
+
+ // Daten Sammeln
+ if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
+ Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
+ else
+ Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
+ Convert(glBitmapToNormalMapFunc, false, @Rec);
+ finally
+ SetLength(Rec.Heights, 0);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create;
+begin
+ inherited Create;
+ fFormat := glBitmapDefaultFormat;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aFileName: String);
+begin
+ Create;
+ LoadFromFile(aFileName);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aStream: TStream);
+begin
+ Create;
+ LoadFromStream(aStream);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
+var
+ ImageSize: Integer;
+begin
+ Create;
+ if not Assigned(aData) then begin
+ ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
+ GetMem(aData, ImageSize);
+ try
+ FillChar(aData^, ImageSize, #$FF);
+ SetData(aData, aFormat, aSize.X, aSize.Y);
+ except
+ if Assigned(aData) then
+ FreeMem(aData);
+ raise;
+ end;
+ end else begin
+ SetData(aData, aFormat, aSize.X, aSize.Y);
+ end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
+begin
+ Create;
+ LoadFromFunc(aSize, aFormat, aFunc, aArgs);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
+begin
+ Create;
+ LoadFromResource(aInstance, aResource, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmapData.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
+begin
+ Create;
+ LoadFromResourceID(aInstance, aResourceID, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TglBitmapData.Destroy;
+begin
+ SetData(nil, tfEmpty);
+ inherited Destroy;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetWidth: Integer;
+begin
+ if (ffX in fDimension.Fields) then
+ result := fDimension.X
+ else
+ result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetHeight: Integer;
+begin
+ if (ffY in fDimension.Fields) then
+ result := fDimension.Y
+ else
+ result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetCustomData(const aValue: Pointer);
+begin
+ if fCustomData = aValue then