Ignore:
Timestamp:
Dec 22, 2016, 8:49:19 PM (7 years ago)
Author:
chronos
Message:
  • Modified: Updated BGRABitmap package.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/Packages/bgrabitmap/bgrapalette.pas

    r472 r494  
    2424
    2525type
     26  TBGRAIndexedPaletteEntry = packed record
     27    Color: TBGRAPixel;
     28    Index: UInt32;
     29  end;
     30  PBGRAIndexedPaletteEntry = ^TBGRAIndexedPaletteEntry;
    2631  TBGRAWeightedPaletteEntry = packed record
    2732    Color: TBGRAPixel;
     
    3136  ArrayOfWeightedColor = array of TBGRAWeightedPaletteEntry;
    3237
     38  TBGRAPixelComparer = function (p1,p2 : PBGRAPixel): boolean;
     39
    3340  { TBGRACustomPalette }
    3441
    3542  TBGRACustomPalette = class
     43  private
     44    function GetDominantColor: TBGRAPixel;
    3645  protected
    3746    function GetCount: integer; virtual; abstract;
     
    4453    procedure AssignTo(AImage: TFPCustomImage); overload;
    4554    procedure AssignTo(APalette: TFPPalette); overload;
     55    property DominantColor: TBGRAPixel read GetDominantColor;
    4656    property Count: integer read GetCount;
    4757    property Color[AIndex: integer]: TBGRAPixel read GetColorByIndex;
     
    8696  public
    8797    constructor Create(ABitmap: TBGRACustomBitmap); virtual; overload;
     98    constructor Create(APalette: TBGRACustomPalette); virtual; overload;
     99    constructor Create(AColors: ArrayOfTBGRAPixel); virtual; overload;
     100    constructor Create(AColors: ArrayOfWeightedColor); virtual; overload;
    88101    function AddColor(AValue: TBGRAPixel): boolean; virtual;
     102    procedure AddColors(ABitmap: TBGRACustomBitmap); virtual; overload;
     103    procedure AddColors(APalette: TBGRACustomPalette); virtual; overload;
    89104    function RemoveColor(AValue: TBGRAPixel): boolean; virtual;
    90105    procedure LoadFromFile(AFilenameUTF8: string); virtual;
     
    97112  end;
    98113
     114  { TBGRAIndexedPalette }
     115
     116  TBGRAIndexedPalette = class(TBGRAPalette)
     117  private
     118    FCurrentIndex: UInt32;
     119  protected
     120    procedure NeedArray; override;
     121    function CreateEntry(AColor: TBGRAPixel): PBGRAPixel; override;
     122    procedure FreeEntry(AEntry: PBGRAPixel); override;
     123  public
     124    function RemoveColor({%H-}AValue: TBGRAPixel): boolean; override;
     125    function IndexOfColor(AValue: TBGRAPixel): integer; override;
     126    procedure Clear; override;
     127  end;
     128
    99129  { TBGRAWeightedPalette }
    100130
     
    107137    procedure IncludePixel(PPixel: PBGRAPixel); override;
    108138  public
     139    constructor Create(AColors: ArrayOfWeightedColor); override;
    109140    function GetAsArrayOfWeightedColor: ArrayOfWeightedColor; override;
    110141    function IncColor(AValue: TBGRAPixel; out NewWeight: UInt32): boolean;
     
    127158  TBGRACustomApproxPalette = class(TBGRACustomPalette)
    128159  private
    129     function FindNearestColorIgnoreAlpha(AValue: TBGRAPixel): TBGRAPixel;
     160    function FindNearestColorIgnoreAlpha(AValue: TBGRAPixel): TBGRAPixel; inline;
     161    function FindNearestColorIndexIgnoreAlpha(AValue: TBGRAPixel): integer; inline;
     162  protected
     163    function GetWeightByIndex({%H-}AIndex: Integer): UInt32; virtual;
    130164  public
    131165    function FindNearestColor(AValue: TBGRAPixel; AIgnoreAlpha: boolean): TBGRAPixel; overload;
    132     function FindNearestColor(AValue: TBGRAPixel): TBGRAPixel; virtual; abstract;
    133     function FindNearestColorIndex(AValue: TBGRAPixel): integer; virtual; abstract;
    134   end;
     166    function FindNearestColor(AValue: TBGRAPixel): TBGRAPixel; virtual; abstract; overload;
     167    function FindNearestColorIndex(AValue: TBGRAPixel; AIgnoreAlpha: boolean): integer; overload;
     168    function FindNearestColorIndex(AValue: TBGRAPixel): integer; virtual; abstract; overload;
     169    property Weight[AIndex: Integer]: UInt32 read GetWeightByIndex;
     170  end;
     171
     172  { TBGRA16BitPalette }
     173
     174  TBGRA16BitPalette = class(TBGRACustomApproxPalette)
     175  protected
     176    function GetCount: integer; override;
     177    function GetColorByIndex(AIndex: integer): TBGRAPixel; override;
     178  public
     179    function ContainsColor(AValue: TBGRAPixel): boolean; override;
     180    function IndexOfColor(AValue: TBGRAPixel): integer; override;
     181    function GetAsArrayOfColor: ArrayOfTBGRAPixel; override;
     182    function GetAsArrayOfWeightedColor: ArrayOfWeightedColor; override;
     183    function FindNearestColor(AValue: TBGRAPixel): TBGRAPixel; override;
     184    function FindNearestColorIndex(AValue: TBGRAPixel): integer; override;
     185  end;
     186
     187  { TBGRACustomColorQuantizer }
     188
     189  TBGRACustomColorQuantizer = class
     190  protected
     191    function GetDominantColor: TBGRAPixel; virtual;
     192    function GetPalette: TBGRACustomApproxPalette; virtual; abstract;
     193    function GetSourceColor(AIndex: integer): TBGRAPixel; virtual; abstract;
     194    function GetSourceColorCount: Integer; virtual; abstract;
     195    function GetReductionColorCount: integer; virtual; abstract;
     196    procedure SetReductionColorCount(AValue: Integer); virtual; abstract;
     197  public
     198    constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean); virtual; abstract; overload;
     199    constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); virtual; abstract; overload;
     200    constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean; AReductionColorCount: integer); virtual; abstract; overload;
     201    constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption; AReductionColorCount: integer); virtual; abstract; overload;
     202    procedure ApplyDitheringInplace(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect); virtual; abstract; overload;
     203    procedure ApplyDitheringInplace(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap); overload;
     204    function GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect): TBGRACustomBitmap; virtual; abstract; overload;
     205    function GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap): TBGRACustomBitmap; overload;
     206    procedure SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AFilenameUTF8: string); overload;
     207    procedure SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AFilenameUTF8: string; AFormat: TBGRAImageFormat); overload;
     208    procedure SaveBitmapToStream(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AStream: TStream; AFormat: TBGRAImageFormat); virtual; abstract;
     209    function GetDitheredBitmapIndexedData(ABitDepth: integer; AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; out AScanlineSize: PtrInt): Pointer; overload;
     210    function GetDitheredBitmapIndexedData(ABitDepth: integer; AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap): Pointer; overload;
     211    function GetDitheredBitmapIndexedData(ABitDepth: integer; AByteOrder: TRawImageByteOrder; AAlgorithm: TDitheringAlgorithm;
     212      ABitmap: TBGRACustomBitmap; out AScanlineSize: PtrInt): Pointer; virtual; abstract; overload;
     213    property SourceColorCount: Integer read GetSourceColorCount;
     214    property SourceColor[AIndex: integer]: TBGRAPixel read GetSourceColor;
     215    property ReductionColorCount: Integer read GetReductionColorCount write SetReductionColorCount;
     216    property ReducedPalette: TBGRACustomApproxPalette read GetPalette;
     217    property DominantColor: TBGRAPixel read GetDominantColor;
     218  end;
     219
     220  TBGRAColorQuantizerAny = class of TBGRACustomColorQuantizer;
     221
     222var
     223  BGRAColorQuantizerFactory: TBGRAColorQuantizerAny;
    135224
    136225function BGRARequiredBitDepth(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption): integer; overload;
     
    146235function BGRARegisteredPaletteFormatFilter(AAllSupportedDescription: string) : string;
    147236
     237procedure ArrayOfWeightedColor_QuickSort(AColors: ArrayOfWeightedColor; AMinIndex,
     238  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     239
     240procedure ArrayOfWeightedColor_InsertionSort(AColors: ArrayOfWeightedColor; AMinIndex,
     241  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     242
     243procedure ArrayOfTBGRAPixel_QuickSort(AColors: ArrayOfTBGRAPixel; AMinIndex,
     244  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     245
     246procedure ArrayOfTBGRAPixel_InsertionSort(AColors: ArrayOfTBGRAPixel; AMinIndex,
     247  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     248
    148249implementation
    149250
    150 uses lazutf8classes, bufstream;
     251uses BGRAUTF8, bufstream;
     252
     253function IsDWordGreater(p1, p2: PBGRAPixel): boolean;
     254begin
     255  result := DWord(p1^) > DWord(p2^);
     256end;
     257
     258const
     259  InsertionSortLimit = 10;
     260
     261procedure ArrayOfWeightedColor_InsertionSort(AColors: ArrayOfWeightedColor; AMinIndex,
     262  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     263var i,j,insertPos: NativeInt;
     264  compared: TBGRAWeightedPaletteEntry;
     265begin
     266  if AComparer = nil then AComparer := @IsDWordGreater;
     267  for i := AMinIndex+1 to AMaxIndex do
     268  begin
     269    insertPos := i;
     270    compared := AColors[i];
     271    while (insertPos > AMinIndex) and AComparer(@AColors[insertPos-1].Color,@compared.Color) do
     272      dec(insertPos);
     273    if insertPos <> i then
     274    begin
     275      for j := i downto insertPos+1 do
     276        AColors[j] := AColors[j-1];
     277      AColors[insertPos] := compared;
     278    end;
     279  end;
     280end;
     281
     282procedure ArrayOfWeightedColor_QuickSort(AColors: ArrayOfWeightedColor; AMinIndex,
     283  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     284var Pivot: TBGRAPixel;
     285  CurMin,CurMax,i : NativeInt;
     286
     287  procedure Swap(a,b: NativeInt);
     288  var Temp: TBGRAWeightedPaletteEntry;
     289  begin
     290    if a = b then exit;
     291    Temp := AColors[a];
     292    AColors[a] := AColors[b];
     293    AColors[b] := Temp;
     294  end;
     295begin
     296  if AComparer = nil then AComparer := @IsDWordGreater;
     297  if AMaxIndex-AMinIndex+1 <= InsertionSortLimit then
     298  begin
     299    ArrayOfWeightedColor_InsertionSort(AColors,AMinIndex,AMaxIndex,AComparer);
     300    exit;
     301  end;
     302  Pivot := AColors[(AMinIndex+AMaxIndex) shr 1].Color;
     303  CurMin := AMinIndex;
     304  CurMax := AMaxIndex;
     305  i := CurMin;
     306  while i < CurMax do
     307  begin
     308    if AComparer(@AColors[i].Color, @Pivot) then
     309    begin
     310      Swap(i, CurMax);
     311      dec(CurMax);
     312    end else
     313    begin
     314      if AComparer(@Pivot, @AColors[i].Color) then
     315      begin
     316        Swap(i, CurMin);
     317        inc(CurMin);
     318      end;
     319      inc(i);
     320    end;
     321  end;
     322  if AComparer(@Pivot, @AColors[i].Color) then
     323  begin
     324    Swap(i, CurMin);
     325    inc(CurMin);
     326  end;
     327  if CurMin > AMinIndex then ArrayOfWeightedColor_QuickSort(AColors,AMinIndex,CurMin,AComparer);
     328  if CurMax < AMaxIndex then ArrayOfWeightedColor_QuickSort(AColors,CurMax,AMaxIndex,AComparer);
     329end;
     330
     331procedure ArrayOfTBGRAPixel_InsertionSort(AColors: ArrayOfTBGRAPixel; AMinIndex,
     332  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     333var i,j,insertPos: NativeInt;
     334  compared: TBGRAPixel;
     335begin
     336  if AComparer = nil then AComparer := @IsDWordGreater;
     337  for i := AMinIndex+1 to AMaxIndex do
     338  begin
     339    insertPos := i;
     340    compared := AColors[i];
     341    while (insertPos > AMinIndex) and AComparer(@AColors[insertPos-1],@compared) do
     342      dec(insertPos);
     343    if insertPos <> i then
     344    begin
     345      for j := i downto insertPos+1 do
     346        AColors[j] := AColors[j-1];
     347      AColors[insertPos] := compared;
     348    end;
     349  end;
     350end;
     351
     352procedure ArrayOfTBGRAPixel_QuickSort(AColors: ArrayOfTBGRAPixel; AMinIndex,
     353  AMaxIndex: NativeInt; AComparer: TBGRAPixelComparer = nil);
     354var Pivot: TBGRAPixel;
     355  CurMin,CurMax,i : NativeInt;
     356
     357  procedure Swap(a,b: NativeInt);
     358  var Temp: TBGRAPixel;
     359  begin
     360    if a = b then exit;
     361    Temp := AColors[a];
     362    AColors[a] := AColors[b];
     363    AColors[b] := Temp;
     364  end;
     365begin
     366  if AComparer = nil then AComparer := @IsDWordGreater;
     367  if AMaxIndex-AMinIndex+1 <= InsertionSortLimit then
     368  begin
     369    ArrayOfTBGRAPixel_InsertionSort(AColors,AMinIndex,AMaxIndex,AComparer);
     370    exit;
     371  end;
     372  Pivot := AColors[(AMinIndex+AMaxIndex) shr 1];
     373  CurMin := AMinIndex;
     374  CurMax := AMaxIndex;
     375  i := CurMin;
     376  while i < CurMax do
     377  begin
     378    if AComparer(@AColors[i], @Pivot) then
     379    begin
     380      Swap(i, CurMax);
     381      dec(CurMax);
     382    end else
     383    begin
     384      if AComparer(@Pivot, @AColors[i]) then
     385      begin
     386        Swap(i, CurMin);
     387        inc(CurMin);
     388      end;
     389      inc(i);
     390    end;
     391  end;
     392  if AComparer(@Pivot, @AColors[i]) then
     393  begin
     394    Swap(i, CurMin);
     395    inc(CurMin);
     396  end;
     397  if CurMin > AMinIndex then ArrayOfTBGRAPixel_QuickSort(AColors,AMinIndex,CurMin,AComparer);
     398  if CurMax < AMaxIndex then ArrayOfTBGRAPixel_QuickSort(AColors,CurMax,AMaxIndex,AComparer);
     399end;
    151400
    152401{$i paletteformats.inc}
     
    233482end;
    234483
     484{ TBGRA16BitPalette }
     485
     486function TBGRA16BitPalette.GetCount: integer;
     487begin
     488  result := 65537;
     489end;
     490
     491function TBGRA16BitPalette.GetColorByIndex(AIndex: integer): TBGRAPixel;
     492begin
     493  if (AIndex >= 65536) or (AIndex < 0) then
     494    result := BGRAPixelTransparent
     495  else
     496    result := Color16BitToBGRA(AIndex);
     497end;
     498
     499function TBGRA16BitPalette.ContainsColor(AValue: TBGRAPixel): boolean;
     500begin
     501  if AValue.alpha = 0 then
     502    result := true
     503  else
     504    result := (AValue.alpha = 255) and (FindNearestColor(AValue)=AValue);
     505end;
     506
     507function TBGRA16BitPalette.IndexOfColor(AValue: TBGRAPixel): integer;
     508var idx: integer;
     509begin
     510  if AValue.Alpha = 0 then
     511    result := 65536
     512  else
     513  begin
     514    idx := BGRAToColor16Bit(AValue);
     515    if Color16BitToBGRA(idx)=AValue then
     516      result := idx
     517    else
     518      result := -1;
     519  end;
     520end;
     521
     522function TBGRA16BitPalette.GetAsArrayOfColor: ArrayOfTBGRAPixel;
     523begin
     524  result := nil;
     525  raise exception.Create('Palette too big');
     526end;
     527
     528function TBGRA16BitPalette.GetAsArrayOfWeightedColor: ArrayOfWeightedColor;
     529begin
     530  result := nil;
     531  raise exception.Create('Palette too big');
     532end;
     533
     534function TBGRA16BitPalette.FindNearestColor(AValue: TBGRAPixel): TBGRAPixel;
     535begin
     536  if AValue.alpha = 0 then result := BGRAPixelTransparent
     537  else
     538    result := GetColorByIndex(BGRAToColor16Bit(AValue));
     539end;
     540
     541function TBGRA16BitPalette.FindNearestColorIndex(AValue: TBGRAPixel): integer;
     542begin
     543  result := BGRAToColor16Bit(AValue);
     544end;
     545
     546{ TBGRAIndexedPalette }
     547
     548procedure TBGRAIndexedPalette.NeedArray;
     549var Node: TAvgLvlTreeNode;
     550  n: UInt32;
     551begin
     552  n := Count;
     553  if UInt32(length(FArray)) <> n then
     554  begin
     555    setLength(FArray,n);
     556    for Node in FTree do
     557    with PBGRAIndexedPaletteEntry(Node.Data)^ do
     558    begin
     559      if Index < n then //index is unsigned so always >= 0
     560        FArray[Index] := @Color;
     561    end;
     562  end;
     563end;
     564
     565function TBGRAIndexedPalette.CreateEntry(AColor: TBGRAPixel): PBGRAPixel;
     566begin
     567  result := PBGRAPixel(GetMem(sizeOf(TBGRAIndexedPaletteEntry)));
     568  result^ := AColor;
     569  PBGRAIndexedPaletteEntry(result)^.Index := FCurrentIndex;
     570  Inc(FCurrentIndex);
     571end;
     572
     573procedure TBGRAIndexedPalette.FreeEntry(AEntry: PBGRAPixel);
     574begin
     575  FreeMem(AEntry);
     576end;
     577
     578function TBGRAIndexedPalette.RemoveColor(AValue: TBGRAPixel): boolean;
     579begin
     580  Result:= false;
     581  raise exception.Create('It is not possible to remove a color from an indexed palette');
     582end;
     583
     584function TBGRAIndexedPalette.IndexOfColor(AValue: TBGRAPixel): integer;
     585Var Node: TAvgLvlTreeNode;
     586begin
     587  Node := FTree.Find(@AValue);
     588  if Assigned(Node) then
     589    result := PBGRAIndexedPaletteEntry(Node.Data)^.Index
     590  else
     591    result := -1;
     592end;
     593
     594procedure TBGRAIndexedPalette.Clear;
     595begin
     596  inherited Clear;
     597  FCurrentIndex := 0;
     598end;
     599
     600{ TBGRACustomColorQuantizer }
     601
     602function TBGRACustomColorQuantizer.GetDominantColor: TBGRAPixel;
     603begin
     604  result := ReducedPalette.DominantColor;
     605end;
     606
     607procedure TBGRACustomColorQuantizer.ApplyDitheringInplace(
     608  AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap);
     609begin
     610  ApplyDitheringInplace(AAlgorithm, ABitmap, rect(0,0,ABitmap.Width,ABitmap.Height));
     611end;
     612
     613function TBGRACustomColorQuantizer.GetDitheredBitmap(
     614  AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap
     615  ): TBGRACustomBitmap;
     616begin
     617  result := GetDitheredBitmap(AAlgorithm, ABitmap, rect(0,0,ABitmap.Width,ABitmap.Height));
     618end;
     619
     620procedure TBGRACustomColorQuantizer.SaveBitmapToFile(
     621  AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap;
     622  AFilenameUTF8: string);
     623begin
     624  SaveBitmapToFile(AAlgorithm, ABitmap, AFilenameUTF8, SuggestImageFormat(AFilenameUTF8));
     625end;
     626
     627procedure TBGRACustomColorQuantizer.SaveBitmapToFile(
     628  AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap;
     629  AFilenameUTF8: string; AFormat: TBGRAImageFormat);
     630var
     631  stream: TFileStreamUTF8;
     632begin
     633   stream := TFileStreamUTF8.Create(AFilenameUTF8,fmCreate);
     634   try
     635     SaveBitmapToStream(AAlgorithm, ABitmap, stream, AFormat);
     636   finally
     637     stream.Free;
     638   end;
     639end;
     640
     641function TBGRACustomColorQuantizer.GetDitheredBitmapIndexedData(
     642  ABitDepth: integer; AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap;
     643  out AScanlineSize: PtrInt): Pointer;
     644begin
     645  result := GetDitheredBitmapIndexedData(ABitDepth,
     646  {$IFDEF ENDIAN_LITTLE}riboLSBFirst{$ELSE}riboMSBFirst{$endif},
     647  AAlgorithm, ABitmap, AScanlineSize);
     648end;
     649
     650function TBGRACustomColorQuantizer.GetDitheredBitmapIndexedData(
     651  ABitDepth: integer; AAlgorithm: TDitheringAlgorithm;
     652  ABitmap: TBGRACustomBitmap): Pointer;
     653var dummy: PtrInt;
     654begin
     655  result := GetDitheredBitmapIndexedData(ABitDepth, AAlgorithm, ABitmap, dummy);
     656end;
     657
    235658{ TBGRACustomPalette }
     659
     660function TBGRACustomPalette.GetDominantColor: TBGRAPixel;
     661var
     662  w: ArrayOfWeightedColor;
     663  i: Integer;
     664  maxWeight, totalWeight: UInt32;
     665begin
     666  result := BGRAWhite;
     667  maxWeight := 0;
     668  w := GetAsArrayOfWeightedColor;
     669  totalWeight:= 0;
     670  for i := 0 to high(w) do
     671    inc(totalWeight, w[i].Weight);
     672  for i := 0 to high(w) do
     673    if (w[i].Weight > maxWeight) and (BGRAToGSBA(w[i].Color).saturation > 16000) then
     674    begin
     675      maxWeight:= w[i].Weight;
     676      result := w[i].Color;
     677    end;
     678  if maxWeight > totalWeight div 20 then exit;
     679  for i := 0 to high(w) do
     680    if (w[i].Weight > maxWeight) and (BGRAToGSBA(w[i].Color).lightness < 56000) and (BGRAToGSBA(w[i].Color).lightness > 16000) then
     681    begin
     682      maxWeight:= w[i].Weight;
     683      result := w[i].Color;
     684    end;
     685  if maxWeight > 0 then exit;
     686  for i := 0 to high(w) do
     687    if (w[i].Weight > maxWeight) then
     688    begin
     689      maxWeight:= w[i].Weight;
     690      result := w[i].Color;
     691    end;
     692end;
    236693
    237694procedure TBGRACustomPalette.AssignTo(AImage: TFPCustomImage);
     
    265722end;
    266723
     724function TBGRACustomApproxPalette.FindNearestColorIndexIgnoreAlpha(
     725  AValue: TBGRAPixel): integer;
     726const AlphaMask : DWord = {$IFDEF ENDIAN_LITTLE}$ff000000{$ELSE}$000000ff{$endif};
     727begin
     728  if AValue.alpha = 0 then
     729    result := -1
     730  else
     731  begin
     732    result := FindNearestColorIndex(TBGRAPixel(DWord(AValue) or AlphaMask));
     733  end;
     734end;
     735
     736function TBGRACustomApproxPalette.GetWeightByIndex(AIndex: Integer): UInt32;
     737begin
     738  result := 1;
     739end;
     740
    267741function TBGRACustomApproxPalette.FindNearestColor(AValue: TBGRAPixel; AIgnoreAlpha: boolean): TBGRAPixel;
    268742begin
     
    273747end;
    274748
     749function TBGRACustomApproxPalette.FindNearestColorIndex(AValue: TBGRAPixel;
     750  AIgnoreAlpha: boolean): integer;
     751begin
     752  if AIgnoreAlpha then
     753    result := FindNearestColorIndexIgnoreAlpha(AValue)
     754  else
     755    result := FindNearestColorIndex(AValue);
     756end;
     757
    275758{ TBGRAWeightedPalette }
    276759
    277 function TBGRAWeightedPalette.GetWeightByIndex(AIndex: integer): UInt32;
     760function TBGRAWeightedPalette.GetWeightByIndex(AIndex: Integer): UInt32;
    278761begin
    279762  NeedArray;
     
    288771begin
    289772  IncColor(PPixel^,dummy);
     773end;
     774
     775constructor TBGRAWeightedPalette.Create(AColors: ArrayOfWeightedColor);
     776var
     777  i: Integer;
     778begin
     779  inherited Create;
     780  for i := 0 to high(AColors) do
     781    with AColors[i] do IncColor(Color,Weight);
    290782end;
    291783
     
    6451137end;
    6461138
     1139constructor TBGRAPalette.Create(APalette: TBGRACustomPalette);
     1140begin
     1141  inherited Create;
     1142  AddColors(APalette);
     1143end;
     1144
     1145constructor TBGRAPalette.Create(AColors: ArrayOfTBGRAPixel);
     1146var
     1147  i: Integer;
     1148begin
     1149  inherited Create;
     1150  for i := 0 to high(AColors) do
     1151    AddColor(AColors[i]);
     1152end;
     1153
     1154constructor TBGRAPalette.Create(AColors: ArrayOfWeightedColor);
     1155var
     1156  i: Integer;
     1157begin
     1158  inherited Create;
     1159  for i := 0 to high(AColors) do
     1160    AddColor(AColors[i].Color);
     1161end;
     1162
    6471163function TBGRAPalette.AddColor(AValue: TBGRAPixel): boolean;
    6481164Var Node: TAvgLvlTreeNode;
     
    6681184    AddLastColor(Entry);
    6691185  end;
     1186end;
     1187
     1188procedure TBGRAPalette.AddColors(ABitmap: TBGRACustomBitmap);
     1189var p: PBGRAPixel;
     1190  n: integer;
     1191begin
     1192  n := ABitmap.NbPixels;
     1193  p := ABitmap.Data;
     1194  while n > 0 do
     1195  begin
     1196    AddColor(p^);
     1197    inc(p);
     1198    dec(n);
     1199  end;
     1200end;
     1201
     1202procedure TBGRAPalette.AddColors(APalette: TBGRACustomPalette);
     1203var i: NativeInt;
     1204begin
     1205  for i := 0 to APalette.Count- 1 do
     1206    AddColor(APalette.Color[i]);
    6701207end;
    6711208
Note: See TracChangeset for help on using the changeset viewer.