Changeset 494 for GraphicTest/Packages/bgrabitmap/bgracolorquantization.pas
- Timestamp:
- Dec 22, 2016, 8:49:19 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgracolorquantization.pas
r472 r494 33 33 { TBGRAColorQuantizer } 34 34 35 TBGRAColorQuantizer = class 35 TBGRAColorQuantizer = class(TBGRACustomColorQuantizer) 36 36 private 37 37 FColors: ArrayOfWeightedColor; … … 40 40 FReductionKeepContrast: boolean; 41 41 FSeparateAlphaChannel: boolean; 42 function GetPalette: TBGRAApproxPalette;43 function GetSourceColor(AIndex: integer): TBGRAPixel;44 function GetSourceColorCount: Integer;45 42 procedure Init(ABox: TBGRAColorBox); 46 procedure SetReductionColorCount(AValue: Integer);47 43 procedure NormalizeArrayOfColors(AColors: ArrayOfTBGRAPixel; ARedBounds, AGreenBounds, ABlueBounds, AAlphaBounds: TDimensionMinMax; AUniform: boolean); 48 44 procedure NormalizeArrayOfColors(AColors: ArrayOfTBGRAPixel; AColorBounds, AAlphaBounds: TDimensionMinMax); 45 protected 46 function GetPalette: TBGRACustomApproxPalette; override; 47 function GetSourceColor(AIndex: integer): TBGRAPixel; override; 48 function GetSourceColorCount: Integer; override; 49 function GetReductionColorCount: integer; override; 50 procedure SetReductionColorCount(AValue: Integer); override; 49 51 public 50 constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean); over load;51 constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); over load;52 constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean; AReductionColorCount: integer); over load;53 constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption; AReductionColorCount: integer); over load;52 constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean); override; 53 constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); override; 54 constructor Create(APalette: TBGRACustomPalette; ASeparateAlphaChannel: boolean; AReductionColorCount: integer); override; 55 constructor Create(ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption; AReductionColorCount: integer); override; 54 56 destructor Destroy; override; 55 procedure ApplyDitheringInplace(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect); 56 procedure ApplyDitheringInplace(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap); 57 function GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect): TBGRACustomBitmap; 58 function GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap): TBGRACustomBitmap; 59 procedure SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AFilenameUTF8: string); 60 procedure SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AFilenameUTF8: string; AFormat: TBGRAImageFormat); 61 procedure SaveBitmapToStream(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; AStream: TStream; AFormat: TBGRAImageFormat); 62 property SourceColorCount: Integer read GetSourceColorCount; 63 property SourceColor[AIndex: integer]: TBGRAPixel read GetSourceColor; 64 property ReductionColorCount: Integer read FReductionColorCount write SetReductionColorCount; 65 property ReducedPalette: TBGRAApproxPalette read GetPalette; 57 procedure ApplyDitheringInplace(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect); override; 58 function GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; ABounds: TRect): TBGRACustomBitmap; override; 59 function GetDitheredBitmapIndexedData(ABitDepth: integer; AByteOrder: TRawImageByteOrder; AAlgorithm: TDitheringAlgorithm; 60 ABitmap: TBGRACustomBitmap; out AScanlineSize: PtrInt): Pointer; override; 61 procedure SaveBitmapToStream(AAlgorithm: TDitheringAlgorithm; 62 ABitmap: TBGRACustomBitmap; AStream: TStream; AFormat: TBGRAImageFormat); override; 66 63 end; 67 64 … … 71 68 private 72 69 FTree: TBGRAColorTree; 73 FColors: ArrayOf TBGRAPixel;70 FColors: ArrayOfWeightedColor; 74 71 protected 75 72 function GetCount: integer; override; 76 73 function GetColorByIndex(AIndex: integer): TBGRAPixel; override; 74 function GetWeightByIndex(AIndex: Integer): UInt32; override; 77 75 procedure Init(const AColors: ArrayOfTBGRAPixel); 78 76 public … … 99 97 end; 100 98 FLargerOwned: boolean; 99 FTransparentColorIndex: integer; 101 100 protected 102 101 function FindNearestLargerColorIndex(AValue: TBGRAPixel): integer; virtual; … … 107 106 function FindNearestColor(AValue: TBGRAPixel): TBGRAPixel; override; 108 107 function FindNearestColorIndex(AValue: TBGRAPixel): integer; override; 109 end; 110 111 TIsChannelStrictlyGreaterFunc = function (p1,p2 : PBGRAPixel): boolean; 108 function GetAsArrayOfWeightedColor: ArrayOfWeightedColor; override; 109 end; 110 111 TIsChannelStrictlyGreaterFunc = TBGRAPixelComparer; 112 112 TIsChannelGreaterThanOrEqualToValueFunc = function (p : PBGRAPixel; v: UInt32): boolean; 113 113 … … 122 122 FColors: ArrayOfWeightedColor; 123 123 FDimensions: TColorDimensions; 124 F HasPureTransparentColor: boolean;124 FPureTransparentColorCount: integer; 125 125 function GetApparentInterval(ADimension: TColorDimension): UInt32; 126 126 function GetAverageColor: TBGRAPixel; … … 128 128 function GetBounds(ADimension: TColorDimension): TDimensionMinMax; 129 129 function GetColorCount(ACountPureTransparent: boolean): integer; 130 function GetHasPureTransparentColor: boolean; 130 131 function GetInferiorColor: TBGRAPixel; 131 132 function GetLargestApparentDimension: TColorDimension; … … 135 136 procedure Init(AColors: ArrayOfWeightedColor; AOwner: boolean); 136 137 procedure SortBy(ADimension: TColorDimension); 137 procedure InsertionSort(AComparer: TIsChannelStrictlyGreaterFunc; AMinIndex, AMaxIndex: NativeInt);138 procedure QuickSort(AComparer: TIsChannelStrictlyGreaterFunc; AMinIndex, AMaxIndex: NativeInt);139 138 function GetMedianIndex(ADimension : TColorDimension; AMinValue, AMaxValue: UInt32): integer; 140 139 public 141 140 constructor Create(ADimensions: TColorDimensions; AColors: ArrayOfWeightedColor; AOwner: boolean); overload; 142 constructor Create(ADimensions: TColorDimensions; AColors: ArrayOfTBGRAPixel); overload;141 constructor Create(ADimensions: TColorDimensions; const AColors: ArrayOfTBGRAPixel; AAlpha: TAlphaChannelPaletteOption = acFullChannelInPalette); overload; 143 142 constructor Create(ADimensions: TColorDimensions; ABounds: TColorBoxBounds); overload; 144 143 constructor Create(ADimensions: TColorDimensions; APalette: TBGRACustomPalette); overload; 145 144 constructor Create(ADimensions: TColorDimensions; ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); overload; 145 constructor Create(ADimensions: TColorDimensions; AColors: PBGRAPixel; ANbPixels: integer; AAlpha: TAlphaChannelPaletteOption); overload; 146 146 function BoundsContain(AColor: TBGRAPixel): boolean; 147 147 function MedianCut(ADimension: TColorDimension; out SuperiorMiddle: UInt32): TBGRAColorBox; … … 159 159 property TotalWeight: UInt32 read FTotalWeight; 160 160 property ColorCount[ACountPureTransparent: boolean]: integer read GetColorCount; 161 property HasPureTransparentColor: boolean read FHasPureTransparentColor; 161 property HasPureTransparentColor: boolean read GetHasPureTransparentColor; 162 property PureTransparentColorCount: integer read FPureTransparentColorCount; 162 163 end; 163 164 … … 180 181 FAverageColor: TBGRAPixel; 181 182 182 F HasPureTransparentColor: boolean;183 FPureTransparentColorCount: integer; 183 184 FPureTransparentColorIndex: integer; 184 185 FDimension: TColorDimension; … … 187 188 FInferiorBranch, FSuperiorBranch: TBGRAColorTree; 188 189 function GetApproximatedColorCount: integer; 190 function GetHasPureTransparentColor: boolean; 189 191 function GetLeafCount: integer; 190 192 procedure Init(ALeaf: TBGRAColorBox; AOwned: boolean); … … 206 208 function ApproximateColorIndex(AColor: TBGRAPixel): integer; 207 209 function GetAsArrayOfApproximatedColors: ArrayOfTBGRAPixel; 210 function GetAsArrayOfWeightedColors: ArrayOfWeightedColor; 208 211 procedure SplitIntoPalette(ACount: integer; AMethod: TBiggestLeafMethod; 209 212 ALeafColor: TBGRALeafColorMode); … … 212 215 property LeafCount: integer read GetLeafCount; 213 216 property ApproximatedColorCount: integer read GetApproximatedColorCount; 214 property HasPureTransparentColor: boolean read FHasPureTransparentColor; 217 property HasPureTransparentColor: boolean read GetHasPureTransparentColor; 218 property PureTransparentColorCount: integer read FPureTransparentColorCount; 215 219 end; 216 220 … … 224 228 implementation 225 229 226 uses BGRADithering, lazutf8classes, FPimage, FPWriteBMP, FPWritePNG;230 uses BGRADithering, FPimage, FPWriteBMP, BGRAWritePNG; 227 231 228 232 const MedianMinPercentage = 0.2; … … 533 537 534 538 const 535 InsertionSortLimit = 10;536 539 ApproxPaletteDimensions = [cdAlpha,cdRInvG,cdGInvB,cdRInvB,cdRInvGB,cdGInvRB,cdBInvRG,cdRGB]; 537 540 … … 551 554 if AValue.alpha = 0 then 552 555 begin 553 result := -1;556 result := FTransparentColorIndex; 554 557 exit; 555 558 end; 556 diff := BGRAWordDiff(AValue, FColors[0] );559 diff := BGRAWordDiff(AValue, FColors[0].Color); 557 560 result := 0; 558 561 for i := 0 to high(FColors) do 559 562 begin 560 curDiff := BGRAWordDiff(AValue, FColors[i] );563 curDiff := BGRAWordDiff(AValue, FColors[i].Color); 561 564 if curDiff < diff then 562 565 begin … … 570 573 const AColors: ArrayOfTBGRAPixel; ALarger: TBGRACustomApproxPalette; ALargerOwned: boolean); 571 574 var i: integer; 575 largeWeighted: ArrayOfWeightedColor; 572 576 begin 573 577 inherited Create(AColors); 578 FTransparentColorIndex:= -1; 579 for i := 0 to high(FColors) do 580 begin 581 FColors[i].Weight := 0; 582 if FColors[i].Color.alpha = 0 then FTransparentColorIndex:= i; 583 end; 574 584 FLarger := ALarger; 575 585 FLargerOwned := ALargerOwned; 576 setlength(FLargerColors, FLarger.Count); 586 largeWeighted := FLarger.GetAsArrayOfWeightedColor; 587 setlength(FLargerColors, length(largeWeighted)); 577 588 for i := 0 to high(FLargerColors) do 578 589 with FLargerColors[i] do 579 590 begin 580 approxColorIndex := SlowFindNearestColorIndex( FLarger.Color[i]);591 approxColorIndex := SlowFindNearestColorIndex(largeWeighted[i].Color); 581 592 if approxColorIndex = -1 then 582 593 approxColor := BGRAPixelTransparent 583 594 else 584 approxColor := FColors[approxColorIndex]; 595 begin 596 approxColor := FColors[approxColorIndex].Color; 597 inc(FColors[approxColorIndex].Weight, largeWeighted[i].Weight); 598 end; 585 599 end; 586 600 end; … … 614 628 end; 615 629 630 function TBGRAApproxPaletteViaLargerPalette.GetAsArrayOfWeightedColor: ArrayOfWeightedColor; 631 var 632 i: Integer; 633 begin 634 setlength(result, length(FColors)); 635 for i := 0 to high(FColors) do 636 result[i] := FColors[i]; 637 end; 638 616 639 { TBGRAApproxPalette } 617 640 … … 625 648 if (AIndex < 0) or (AIndex >= length(FColors)) then 626 649 raise ERangeError.Create('Index out of bounds'); 627 result := FColors[AIndex]; 650 result := FColors[AIndex].Color; 651 end; 652 653 function TBGRAApproxPalette.GetWeightByIndex(AIndex: Integer): UInt32; 654 begin 655 if (AIndex < 0) or (AIndex >= length(FColors)) then 656 raise ERangeError.Create('Index out of bounds'); 657 result := FColors[AIndex].Weight; 628 658 end; 629 659 … … 643 673 FTree.SplitIntoPalette(length(AColors),blApparentInterval,lcAverage); 644 674 645 FColors := FTree.GetAsArrayOf ApproximatedColors;675 FColors := FTree.GetAsArrayOfWeightedColors; 646 676 end; 647 677 … … 656 686 FTree.SplitIntoPalette(length(AColors),blApparentInterval,lcAverage); 657 687 658 FColors := FTree.GetAsArrayOf ApproximatedColors;688 FColors := FTree.GetAsArrayOfWeightedColors; 659 689 end; 660 690 … … 662 692 begin 663 693 FTree := AOwnedSplitTree; 664 FColors := FTree.GetAsArrayOf ApproximatedColors;694 FColors := FTree.GetAsArrayOfWeightedColors; 665 695 end; 666 696 … … 679 709 begin 680 710 result := FTree.ApproximateColorIndex(AValue); 681 if (result <> -1) and not (DWord(FColors[result] ) = DWord(AValue)) then result := -1;711 if (result <> -1) and not (DWord(FColors[result].Color) = DWord(AValue)) then result := -1; 682 712 end; 683 713 … … 698 728 setlength(result, length(FColors)); 699 729 for i := 0 to high(result) do 700 result[i] := FColors[i] ;730 result[i] := FColors[i].Color; 701 731 end; 702 732 … … 705 735 i: NativeInt; 706 736 begin 707 setlength(result, length(FColors)); 708 for i := 0 to high(result) do 709 with result[i] do 710 begin 711 Color := FColors[i]; 712 Weight:= 1; 737 if Assigned(FTree) then 738 result := FTree.GetAsArrayOfWeightedColors 739 else 740 begin 741 setlength(result, length(FColors)); 742 for i := 0 to high(result) do 743 result[i] := FColors[i]; 713 744 end; 714 745 end; … … 719 750 begin 720 751 FColors := ABox.FColors; 721 if ABox. FHasPureTransparentColor then752 if ABox.HasPureTransparentColor then 722 753 begin 723 754 setlength(FColors,length(FColors)+1); … … 725 756 begin 726 757 Color := BGRAPixelTransparent; 727 Weight:= 1;758 Weight:= ABox.PureTransparentColorCount; 728 759 end; 729 760 end; … … 853 884 end; 854 885 855 function TBGRAColorQuantizer.GetPalette: TBGRAApproxPalette; 886 function TBGRAColorQuantizer.GetReductionColorCount: integer; 887 begin 888 result := FReductionColorCount; 889 end; 890 891 function TBGRAColorQuantizer.GetPalette: TBGRACustomApproxPalette; 856 892 var 857 893 tree: TBGRAColorTree; 858 894 859 895 procedure MakeTreeErrorDiffusionFriendly; 860 var moreColors: ArrayOf TBGRAPixel;896 var moreColors: ArrayOfWeightedColor; 861 897 box: TBGRAColorBox; 862 898 begin 863 moreColors := tree.GetAsArrayOf ApproximatedColors;899 moreColors := tree.GetAsArrayOfWeightedColors; 864 900 tree.free; 865 box := TBGRAColorBox.Create([cdRed,cdGreen,cdBlue,cdAlpha],moreColors );901 box := TBGRAColorBox.Create([cdRed,cdGreen,cdBlue,cdAlpha],moreColors,True); 866 902 tree := TBGRAColorTree.Create(box,True); 867 903 tree.SplitIntoPalette(box.ColorCount[true], blApparentInterval, lcAverage); … … 889 925 bounds[cdBlue] := originalBox.Bounds[cdBlue]; 890 926 bounds[cdAlpha] := originalBox.Bounds[cdAlpha]; 891 if originalBox. FHasPureTransparentColor then bounds[cdAlpha].Minimum := 0;927 if originalBox.HasPureTransparentColor then bounds[cdAlpha].Minimum := 0; 892 928 if FReductionColorCount = 1 then 893 929 begin … … 971 1007 end; 972 1008 973 procedure TBGRAColorQuantizer.ApplyDitheringInplace(974 AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap);975 begin976 ApplyDitheringInplace(AAlgorithm, ABitmap, rect(0,0,ABitmap.Width,ABitmap.Height));977 end;978 979 1009 function TBGRAColorQuantizer.GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; 980 1010 ABitmap: TBGRACustomBitmap; ABounds: TRect): TBGRACustomBitmap; … … 986 1016 end; 987 1017 988 function TBGRAColorQuantizer.GetDitheredBitmap(AAlgorithm: TDitheringAlgorithm; 989 ABitmap: TBGRACustomBitmap): TBGRACustomBitmap; 990 var task: TDitheringTask; 991 begin 992 task := CreateDitheringTask(AAlgorithm, ABitmap, ReducedPalette, FSeparateAlphaChannel); 993 result := task.Execute; 994 task.Free; 995 end; 996 997 procedure TBGRAColorQuantizer.SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; 998 AFilenameUTF8: string); 999 begin 1000 SaveBitmapToFile(AAlgorithm, ABitmap, AFilenameUTF8, SuggestImageFormat(AFilenameUTF8)); 1001 end; 1002 1003 procedure TBGRAColorQuantizer.SaveBitmapToFile(AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; 1004 AFilenameUTF8: string; AFormat: TBGRAImageFormat); 1018 function TBGRAColorQuantizer.GetDitheredBitmapIndexedData( 1019 ABitDepth: integer; AByteOrder: TRawImageByteOrder; AAlgorithm: TDitheringAlgorithm; ABitmap: TBGRACustomBitmap; 1020 out AScanlineSize: PtrInt): Pointer; 1005 1021 var 1006 stream: TFileStreamUTF8; 1007 begin 1008 stream := TFileStreamUTF8.Create(AFilenameUTF8,fmCreate); 1009 try 1010 SaveBitmapToStream(AAlgorithm, ABitmap, stream, AFormat); 1011 finally 1012 stream.Free; 1013 end; 1022 indexer: TDitheringToIndexedImage; 1023 begin 1024 indexer := TDitheringToIndexedImage.Create(ReducedPalette, FSeparateAlphaChannel, ABitDepth, AByteOrder); 1025 indexer.DefaultTransparentColorIndex := ReducedPalette.IndexOfColor(BGRAPixelTransparent); 1026 AScanlineSize:= indexer.ComputeMinimumScanlineSize(ABitmap.Width); 1027 result := indexer.DitherImage(AAlgorithm, ABitmap, AScanlineSize); 1028 indexer.Free; 1014 1029 end; 1015 1030 … … 1028 1043 writer := CreateBGRAImageWriter(AFormat, hasTransp); 1029 1044 try 1030 if writer is T FPWriterPNG then TFPWriterPNG(writer).Indexed := true else1045 if writer is TBGRAWriterPNG then TBGRAWriterPNG(writer).Indexed := true else 1031 1046 if writer is TFPWriterBMP then 1032 1047 begin … … 1092 1107 begin 1093 1108 index := 0; 1094 if FHasPureTransparentColor then1109 if HasPureTransparentColor then 1095 1110 begin 1096 1111 FPureTransparentColorIndex:= index; … … 1229 1244 begin 1230 1245 CheckColorComputed; 1231 setlength(result,1+byte( FHasPureTransparentColor));1246 setlength(result,1+byte(HasPureTransparentColor)); 1232 1247 idx := 0; 1233 if FHasPureTransparentColor then1248 if HasPureTransparentColor then 1234 1249 begin 1235 1250 result[idx] := BGRAPixelTransparent; … … 1241 1256 a := FInferiorBranch.GetAsArrayOfApproximatedColors; 1242 1257 b := FSuperiorBranch.GetAsArrayOfApproximatedColors; 1243 setlength(result, length(a)+length(b)+byte( FHasPureTransparentColor));1258 setlength(result, length(a)+length(b)+byte(HasPureTransparentColor)); 1244 1259 idx := 0; 1245 if FHasPureTransparentColor then1260 if HasPureTransparentColor then 1246 1261 begin 1247 1262 result[idx] := BGRAPixelTransparent; 1263 inc(idx); 1264 end; 1265 for i := 0 to high(a) do 1266 begin 1267 result[idx] := a[i]; 1268 inc(idx); 1269 end; 1270 for i := 0 to high(b) do 1271 begin 1272 result[idx] := b[i]; 1273 inc(idx); 1274 end; 1275 end; 1276 end; 1277 1278 function TBGRAColorTree.GetAsArrayOfWeightedColors: ArrayOfWeightedColor; 1279 var a,b: ArrayOfWeightedColor; 1280 idx,i: integer; 1281 begin 1282 if IsLeaf then 1283 begin 1284 CheckColorComputed; 1285 setlength(result,1+byte(HasPureTransparentColor)); 1286 idx := 0; 1287 if HasPureTransparentColor then 1288 begin 1289 result[idx].Color := BGRAPixelTransparent; 1290 result[idx].Weight := PureTransparentColorCount; 1291 inc(idx); 1292 end; 1293 result[idx].Color := FLeafColor; 1294 result[idx].Weight := Weight; 1295 end else 1296 begin 1297 a := FInferiorBranch.GetAsArrayOfWeightedColors; 1298 b := FSuperiorBranch.GetAsArrayOfWeightedColors; 1299 setlength(result, length(a)+length(b)+byte(HasPureTransparentColor)); 1300 idx := 0; 1301 if HasPureTransparentColor then 1302 begin 1303 result[idx].Color := BGRAPixelTransparent; 1304 result[idx].Weight := PureTransparentColorCount; 1248 1305 inc(idx); 1249 1306 end; … … 1328 1385 if Assigned(FSuperiorBranch) then result += FSuperiorBranch.ApproximatedColorCount; 1329 1386 end; 1330 if FHasPureTransparentColor then inc(result); 1387 if HasPureTransparentColor then inc(result); 1388 end; 1389 1390 function TBGRAColorTree.GetHasPureTransparentColor: boolean; 1391 begin 1392 result := FPureTransparentColorCount > 0; 1331 1393 end; 1332 1394 … … 1347 1409 FMaxBorder[c] := true; 1348 1410 end; 1349 F HasPureTransparentColor:= FLeaf.HasPureTransparentColor;1411 FPureTransparentColorCount:= FLeaf.PureTransparentColorCount; 1350 1412 FPureTransparentColorIndex:= -1; 1351 1413 end; … … 1406 1468 else 1407 1469 result := supLeaf; 1408 blMix:1470 else{blMix:} 1409 1471 if (sqrt(infLeaf.Weight/FWeight)*(infLeaf.LargestApparentInterval/LargestApparentInterval) >= 1410 1472 sqrt(supLeaf.Weight/FWeight)*(supLeaf.LargestApparentInterval/LargestApparentInterval) ) then … … 1533 1595 begin 1534 1596 result := length(FColors); 1535 if ACountPureTransparent and FHasPureTransparentColor then inc(result); 1597 if ACountPureTransparent and HasPureTransparentColor then inc(result); 1598 end; 1599 1600 function TBGRAColorBox.GetHasPureTransparentColor: boolean; 1601 begin 1602 result := FPureTransparentColorCount > 0; 1536 1603 end; 1537 1604 … … 1667 1734 c: TColorDimension; 1668 1735 begin 1669 F HasPureTransparentColor:= false;1736 FPureTransparentColorCount:= 0; 1670 1737 FTotalWeight:= 0; 1671 1738 for c := low(TColorDimension) to high(TColorDimension) do … … 1697 1764 inc(idx); 1698 1765 end else 1699 FHasPureTransparentColor:= true;1766 inc(FPureTransparentColorCount, Weight); 1700 1767 end; 1701 1768 setlength(FColors,idx); … … 1707 1774 comparer := GetPixelStrictComparer(ADimension); 1708 1775 if comparer = nil then exit; 1709 if Length(FColors) > InsertionSortLimit then 1710 QuickSort(comparer,0,high(FColors)) 1711 else 1712 InsertionSort(comparer,0,high(FColors)); 1713 end; 1714 1715 procedure TBGRAColorBox.InsertionSort(AComparer: TIsChannelStrictlyGreaterFunc; AMinIndex, 1716 AMaxIndex: NativeInt); 1717 var i,j,insertPos: NativeInt; 1718 compared: TBGRAWeightedPaletteEntry; 1719 begin 1720 for i := AMinIndex+1 to AMaxIndex do 1721 begin 1722 insertPos := i; 1723 compared := FColors[i]; 1724 while (insertPos > AMinIndex) and AComparer(@FColors[insertPos-1].Color,@compared.Color) do 1725 dec(insertPos); 1726 if insertPos <> i then 1727 begin 1728 for j := i downto insertPos+1 do 1729 FColors[j] := FColors[j-1]; 1730 FColors[insertPos] := compared; 1731 end; 1732 end; 1733 end; 1734 1735 procedure TBGRAColorBox.QuickSort(AComparer: TIsChannelStrictlyGreaterFunc; AMinIndex, 1736 AMaxIndex: NativeInt); 1737 var Pivot: TBGRAPixel; 1738 CurMin,CurMax,i : NativeInt; 1739 1740 procedure Swap(a,b: NativeInt); 1741 var Temp: TBGRAWeightedPaletteEntry; 1742 begin 1743 if a = b then exit; 1744 Temp := FColors[a]; 1745 FColors[a] := FColors[b]; 1746 FColors[b] := Temp; 1747 end; 1748 begin 1749 if AMaxIndex-AMinIndex+1 <= InsertionSortLimit then 1750 begin 1751 InsertionSort(AComparer,AMinIndex,AMaxIndex); 1752 exit; 1753 end; 1754 Pivot := FColors[(AMinIndex+AMaxIndex) shr 1].Color; 1755 CurMin := AMinIndex; 1756 CurMax := AMaxIndex; 1757 i := CurMin; 1758 while i < CurMax do 1759 begin 1760 if AComparer(@FColors[i].Color, @Pivot) then 1761 begin 1762 Swap(i, CurMax); 1763 dec(CurMax); 1764 end else 1765 begin 1766 if AComparer(@Pivot, @FColors[i].Color) then 1767 begin 1768 Swap(i, CurMin); 1769 inc(CurMin); 1770 end; 1771 inc(i); 1772 end; 1773 end; 1774 if AComparer(@Pivot, @FColors[i].Color) then 1775 begin 1776 Swap(i, CurMin); 1777 inc(CurMin); 1778 end; 1779 if CurMin > AMinIndex then QuickSort(AComparer,AMinIndex,CurMin); 1780 if CurMax < AMaxIndex then QuickSort(AComparer,CurMax,AMaxIndex); 1776 ArrayOfWeightedColor_QuickSort(FColors,0,high(FColors),comparer) 1781 1777 end; 1782 1778 … … 1842 1838 1843 1839 constructor TBGRAColorBox.Create(ADimensions: TColorDimensions; 1844 AColors: ArrayOfTBGRAPixel);1840 const AColors: ArrayOfTBGRAPixel; AAlpha: TAlphaChannelPaletteOption = acFullChannelInPalette); 1845 1841 var weightedColors: ArrayOfWeightedColor; 1846 1842 i: Integer; 1847 1843 begin 1848 FDimensions:= ADimensions; 1849 setlength(weightedColors, length(AColors)); 1850 for i := 0 to high(weightedColors) do 1851 with weightedColors[i] do 1852 begin 1853 color := AColors[i]; 1854 Weight:= 1; 1855 end; 1856 Init(weightedColors,True); 1844 if AAlpha = acFullChannelInPalette then 1845 begin 1846 FDimensions:= ADimensions; 1847 setlength(weightedColors, length(AColors)); 1848 for i := 0 to high(weightedColors) do 1849 with weightedColors[i] do 1850 begin 1851 color := AColors[i]; 1852 Weight:= 1; 1853 end; 1854 Init(weightedColors,True); 1855 end else 1856 Create(ADimensions, @AColors[0], length(AColors), AAlpha); 1857 1857 end; 1858 1858 … … 1862 1862 FBounds := ABounds; 1863 1863 FTotalWeight:= 0; 1864 F HasPureTransparentColor:= false;1864 FPureTransparentColorCount:= 0; 1865 1865 end; 1866 1866 … … 1871 1871 end; 1872 1872 1873 constructor TBGRAColorBox.Create(ADimensions: TColorDimensions; ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); 1873 constructor TBGRAColorBox.Create(ADimensions: TColorDimensions; 1874 ABitmap: TBGRACustomBitmap; AAlpha: TAlphaChannelPaletteOption); 1875 begin 1876 Create(ADimensions, ABitmap.Data, ABitmap.NbPixels, AAlpha); 1877 end; 1878 1879 constructor TBGRAColorBox.Create(ADimensions: TColorDimensions; AColors: PBGRAPixel; ANbPixels: integer; AAlpha: TAlphaChannelPaletteOption); 1874 1880 var i,j,prev,idx: integer; 1875 1881 p: PBGRAPixel; 1876 1882 skip: boolean; 1877 1883 alphaMask: DWord; 1878 transp : boolean;1884 transpIndex: integer; 1879 1885 begin 1880 1886 if AAlpha <> acFullChannelInPalette then … … 1883 1889 alphaMask := 0; 1884 1890 FDimensions:= ADimensions; 1885 transp := false;1886 SetLength(FColors,A Bitmap.NbPixels);1891 transpIndex := -1; 1892 SetLength(FColors,ANbPixels); 1887 1893 if length(FColors)>0 then 1888 1894 begin 1889 p := A Bitmap.Data;1895 p := AColors; 1890 1896 idx := 0; 1891 for i := 0 to A Bitmap.NbPixels-1 do1897 for i := 0 to ANbPixels-1 do 1892 1898 begin 1893 1899 if (p^.alpha = 0) or ((AAlpha = acTransparentEntry) and (p^.alpha < 128)) then 1894 1900 begin 1895 1901 skip := true; 1896 if not transp and not(AAlpha = acIgnore) then1902 if not (AAlpha = acIgnore) then 1897 1903 begin 1898 with FColors[idx] do1904 if (transpIndex=-1) then 1899 1905 begin 1900 Color := BGRAPixelTransparent; 1901 Weight:= 1; 1902 end; 1903 transp := true; 1904 inc(idx); 1906 transpIndex := idx; 1907 with FColors[idx] do 1908 begin 1909 Color := BGRAPixelTransparent; 1910 Weight:= 1; 1911 end; 1912 inc(idx); 1913 end else 1914 inc(FColors[transpIndex].Weight); 1905 1915 end; 1906 1916 if (p^.alpha = 0) then … … 1938 1948 setLength(FColors, idx); 1939 1949 1940 QuickSort(@IsDWordGreater,0,high(FColors));1950 ArrayOfWeightedColor_QuickSort(FColors,0,high(FColors),@IsDWordGreater); 1941 1951 prev := 0; 1942 1952 for i := 1 to high(FColors) do … … 2006 2016 var i,idx: integer; 2007 2017 begin 2008 if AIncludePureTransparent and FHasPureTransparentColor then2018 if AIncludePureTransparent and HasPureTransparentColor then 2009 2019 begin 2010 2020 setlength(result, length(FColors)+1);
Note:
See TracChangeset
for help on using the changeset viewer.