Changeset 522 for GraphicTest/Packages/Graphics32/GR32_OrdinalMaps.pas
- Timestamp:
- Apr 17, 2019, 10:42:18 AM (5 years ago)
- Location:
- GraphicTest/Packages/Graphics32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/Graphics32
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
GraphicTest/Packages/Graphics32/GR32_OrdinalMaps.pas
r450 r522 54 54 ctWeightedRGB); 55 55 56 {$IFDEF FPC} 57 PInteger = ^Integer; 58 {$ENDIF} 59 56 60 TBooleanMap = class(TCustomMap) 57 61 private 58 FBits: TArrayOfByte;59 62 function GetValue(X, Y: Integer): Boolean; 60 63 procedure SetValue(X, Y: Integer; const Value: Boolean); 61 function GetBits: PByteArray;62 64 protected 65 FBits: PByteArray; 63 66 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 64 67 public 68 constructor Create; overload; override; 65 69 destructor Destroy; override; 70 66 71 function Empty: Boolean; override; 67 72 procedure Clear(FillValue: Byte); 68 73 procedure ToggleBit(X, Y: Integer); 74 69 75 property Value[X, Y: Integer]: Boolean read GetValue write SetValue; default; 70 property Bits: PByteArray read GetBits;76 property Bits: PByteArray read FBits; 71 77 end; 72 78 73 79 TByteMap = class(TCustomMap) 74 80 private 75 FBits: TArrayOfByte;76 81 function GetValue(X, Y: Integer): Byte; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 77 82 function GetValPtr(X, Y: Integer): PByte; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 78 83 procedure SetValue(X, Y: Integer; Value: Byte); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 79 function Get Bits: PByteArray;84 function GetScanline(Y: Integer): PByteArray; 80 85 protected 86 FBits: PByteArray; 81 87 procedure AssignTo(Dst: TPersistent); override; 82 88 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 83 89 public 90 constructor Create; overload; override; 84 91 destructor Destroy; override; 92 85 93 procedure Assign(Source: TPersistent); override; 86 function 94 function Empty: Boolean; override; 87 95 procedure Clear(FillValue: Byte); 96 97 procedure Multiply(Value: Byte); 98 procedure Add(Value: Byte); 99 procedure Sub(Value: Byte); 100 88 101 procedure ReadFrom(Source: TCustomBitmap32; Conversion: TConversionType); 89 102 procedure WriteTo(Dest: TCustomBitmap32; Conversion: TConversionType); overload; 90 103 procedure WriteTo(Dest: TCustomBitmap32; const Palette: TPalette32); overload; 91 property Bits: PByteArray read GetBits; 104 105 procedure DrawTo(Dest: TCustomBitmap32; X, Y: Integer; Color: TColor32); overload; 106 procedure DrawTo(Dest: TCustomBitmap32; Rect: TRect; Color: TColor32); overload; 107 108 procedure Downsample(Factor: Byte); overload; 109 procedure Downsample(Dest: TByteMap; Factor: Byte); overload; 110 111 procedure FlipHorz(Dst: TByteMap = nil); 112 procedure FlipVert(Dst: TByteMap = nil); 113 procedure Rotate90(Dst: TByteMap = nil); 114 procedure Rotate180(Dst: TByteMap = nil); 115 procedure Rotate270(Dst: TByteMap = nil); 116 117 property Bits: PByteArray read FBits; 118 property Scanline[Y: Integer]: PByteArray read GetScanline; 92 119 property ValPtr[X, Y: Integer]: PByte read GetValPtr; 93 120 property Value[X, Y: Integer]: Byte read GetValue write SetValue; default; 94 121 end; 95 122 123 { TWordMap } 124 96 125 TWordMap = class(TCustomMap) 97 126 private 98 FBits: TArrayOfWord;99 127 function GetValPtr(X, Y: Integer): PWord; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 100 128 function GetValue(X, Y: Integer): Word; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 101 129 procedure SetValue(X, Y: Integer; const Value: Word); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 102 function Get Bits: PWordArray;130 function GetScanline(Y: Integer): PWordArray; 103 131 protected 132 FBits: PWordArray; 104 133 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 105 134 public 135 constructor Create; overload; override; 106 136 destructor Destroy; override; 137 138 procedure Assign(Source: TPersistent); override; 107 139 function Empty: Boolean; override; 108 140 procedure Clear(FillValue: Word); 141 109 142 property ValPtr[X, Y: Integer]: PWord read GetValPtr; 110 143 property Value[X, Y: Integer]: Word read GetValue write SetValue; default; 111 property Bits: PWordArray read GetBits; 112 end; 144 property Bits: PWordArray read FBits; 145 property Scanline[Y: Integer]: PWordArray read GetScanline; 146 end; 147 148 { TIntegerMap } 113 149 114 150 TIntegerMap = class(TCustomMap) 115 151 private 116 FBits: TArrayOfInteger;117 152 function GetValPtr(X, Y: Integer): PInteger; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 118 153 function GetValue(X, Y: Integer): Integer; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 119 154 procedure SetValue(X, Y: Integer; const Value: Integer); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 120 function Get Bits: PIntegerArray;155 function GetScanline(Y: Integer): PIntegerArray; 121 156 protected 157 FBits: PIntegerArray; 122 158 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 123 159 public 160 constructor Create; overload; override; 124 161 destructor Destroy; override; 162 163 procedure Assign(Source: TPersistent); override; 125 164 function Empty: Boolean; override; 126 procedure Clear(FillValue: Integer); 165 procedure Clear(FillValue: Integer = 0); 166 127 167 property ValPtr[X, Y: Integer]: PInteger read GetValPtr; 128 168 property Value[X, Y: Integer]: Integer read GetValue write SetValue; default; 129 property Bits: PIntegerArray read GetBits; 130 end; 169 property Bits: PIntegerArray read FBits; 170 property Scanline[Y: Integer]: PIntegerArray read GetScanline; 171 end; 172 173 { TCardinalMap } 174 175 TCardinalMap = class(TCustomMap) 176 private 177 function GetValPtr(X, Y: Cardinal): PCardinal; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 178 function GetValue(X, Y: Cardinal): Cardinal; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 179 procedure SetValue(X, Y: Cardinal; const Value: Cardinal); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 180 function GetScanline(Y: Integer): PCardinalArray; 181 protected 182 FBits: PCardinalArray; 183 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 184 public 185 constructor Create; overload; override; 186 destructor Destroy; override; 187 188 procedure Assign(Source: TPersistent); override; 189 function Empty: Boolean; override; 190 procedure Clear(FillValue: Cardinal = 0); 191 192 property ValPtr[X, Y: Cardinal]: PCardinal read GetValPtr; 193 property Value[X, Y: Cardinal]: Cardinal read GetValue write SetValue; default; 194 property Bits: PCardinalArray read FBits; 195 property Scanline[Y: Integer]: PCardinalArray read GetScanline; 196 end; 197 198 { TFloatMap } 131 199 132 200 TFloatMap = class(TCustomMap) 133 201 private 134 FBits: TArrayOfFloat; 135 function GetValPtr(X, Y: Integer): PFloat; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 202 function GetValPtr(X, Y: Integer): GR32.PFloat; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 136 203 function GetValue(X, Y: Integer): TFloat; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 137 204 procedure SetValue(X, Y: Integer; const Value: TFloat); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 138 function Get Bits: PFloatArray;205 function GetScanline(Y: Integer): PFloatArray; 139 206 protected 207 FBits: PFloatArray; 140 208 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 141 209 public 210 constructor Create; overload; override; 142 211 destructor Destroy; override; 212 213 procedure Assign(Source: TPersistent); override; 143 214 function Empty: Boolean; override; 144 215 procedure Clear; overload; 145 216 procedure Clear(FillValue: TFloat); overload; 217 146 218 property ValPtr[X, Y: Integer]: PFloat read GetValPtr; 147 219 property Value[X, Y: Integer]: TFloat read GetValue write SetValue; default; 148 property Bits: PFloatArray read GetBits; 149 end; 220 property Bits: PFloatArray read FBits; 221 property Scanline[Y: Integer]: PFloatArray read GetScanline; 222 end; 223 224 {$IFDEF COMPILER2010} 225 226 { TGenericMap<T> } 227 228 TGenericMap<T> = class(TCustomMap) 229 private 230 function GetValue(X, Y: Integer): T; {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 231 procedure SetValue(X, Y: Integer; const Value: T); {$IFDEF INLININGSUPPORTED} inline; {$ENDIF} 232 protected 233 FBits: Pointer; 234 procedure ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); override; 235 public 236 constructor Create; overload; override; 237 destructor Destroy; override; 238 239 procedure Assign(Source: TPersistent); override; 240 function Empty: Boolean; override; 241 procedure Clear; overload; 242 procedure Clear(FillValue: T); overload; 243 244 property Value[X, Y: Integer]: T read GetValue write SetValue; default; 245 property Bits: Pointer read FBits; 246 end; 247 248 {$ENDIF} 150 249 151 250 implementation 152 251 153 252 uses 154 GR32_LowLevel; 253 Math, GR32_LowLevel, GR32_Blend, GR32_Resamplers; 254 255 function Bytes(Bits: Integer): Integer; 256 begin 257 Result := (Bits - 1) shr 3 + 1; 258 end; 155 259 156 260 { TBooleanMap } 157 261 158 function Bytes(Bits: Integer): Integer; 159 begin 160 Result := (Bits - 1) shr 3 + 1; 262 constructor TBooleanMap.Create; 263 begin 264 FreeMem(FBits); 265 inherited Create; 161 266 end; 162 267 … … 164 269 NewHeight: Integer); 165 270 begin 166 SetLength(FBits, Bytes(NewWidth * NewHeight));271 ReallocMem(FBits, Bytes(NewWidth * NewHeight)); 167 272 Width := NewWidth; 168 273 Height := NewHeight; … … 171 276 procedure TBooleanMap.Clear(FillValue: Byte); 172 277 begin 173 FillChar(FBits [0], Bytes(Width * Height), FillValue);278 FillChar(FBits^, Bytes(Width * Height), FillValue); 174 279 end; 175 280 … … 185 290 end; 186 291 187 function TBooleanMap.GetBits: PByteArray;188 begin189 Result := @FBits[0];190 end;191 192 292 function TBooleanMap.GetValue(X, Y: Integer): Boolean; 193 293 begin 194 294 X := X + Y * Width; 195 Result := FBits [X shr 3] and (1 shl (X and 7)) <> 0; //Boolean(FBits[X shr 3] and (1 shl (X and 7)));295 Result := FBits^[X shr 3] and (1 shl (X and 7)) <> 0; //Boolean(FBits^[X shr 3] and (1 shl (X and 7))); 196 296 end; 197 297 … … 200 300 X := Y * Width + X; 201 301 if Value then 202 FBits [X shr 3] := FBits[X shr 3] or (1 shl (X and 7))302 FBits^[X shr 3] := FBits^[X shr 3] or (1 shl (X and 7)) 203 303 else 204 FBits [X shr 3] := FBits[X shr 3] and ((1 shl (X and 7)) xor $FF);304 FBits^[X shr 3] := FBits^[X shr 3] and ((1 shl (X and 7)) xor $FF); 205 305 end; 206 306 … … 208 308 begin 209 309 X := Y * Width + X; 210 FBits [X shr 3] := FBits[X shr 3] xor (1 shl (X and 7));310 FBits^[X shr 3] := FBits^[X shr 3] xor (1 shl (X and 7)); 211 311 end; 212 312 213 313 { TByteMap } 314 315 constructor TByteMap.Create; 316 begin 317 FBits := nil; 318 inherited Create; 319 end; 320 321 destructor TByteMap.Destroy; 322 begin 323 FreeMem(FBits); 324 inherited; 325 end; 326 327 procedure TByteMap.Downsample(Factor: Byte); 328 begin 329 // downsample inplace 330 case Factor of 331 2: 332 DownsampleByteMap2x(Self, Self); 333 3: 334 DownsampleByteMap3x(Self, Self); 335 4: 336 DownsampleByteMap4x(Self, Self); 337 6: 338 begin 339 DownsampleByteMap3x(Self, Self); 340 DownsampleByteMap2x(Self, Self); 341 end; 342 8: 343 begin 344 DownsampleByteMap4x(Self, Self); 345 DownsampleByteMap2x(Self, Self); 346 end; 347 9: 348 begin 349 DownsampleByteMap3x(Self, Self); 350 DownsampleByteMap3x(Self, Self); 351 end; 352 12: 353 begin 354 DownsampleByteMap4x(Self, Self); 355 DownsampleByteMap3x(Self, Self); 356 end; 357 16: 358 begin 359 DownsampleByteMap4x(Self, Self); 360 DownsampleByteMap4x(Self, Self); 361 end; 362 18: 363 begin 364 DownsampleByteMap3x(Self, Self); 365 DownsampleByteMap3x(Self, Self); 366 DownsampleByteMap2x(Self, Self); 367 end; 368 24: 369 begin 370 DownsampleByteMap4x(Self, Self); 371 DownsampleByteMap3x(Self, Self); 372 DownsampleByteMap2x(Self, Self); 373 end; 374 27: 375 begin 376 DownsampleByteMap3x(Self, Self); 377 DownsampleByteMap3x(Self, Self); 378 DownsampleByteMap3x(Self, Self); 379 end; 380 32: 381 begin 382 DownsampleByteMap4x(Self, Self); 383 DownsampleByteMap4x(Self, Self); 384 DownsampleByteMap2x(Self, Self); 385 end; 386 end; 387 end; 388 389 procedure TByteMap.Downsample(Dest: TByteMap; Factor: Byte); 390 391 procedure DownsampleAndMove; 392 var 393 Temp: TByteMap; 394 Y: Integer; 395 begin 396 // clone destination and downsample inplace 397 Temp := TByteMap.Create; 398 Temp.Assign(Self); 399 Temp.Downsample(Factor); 400 401 // copy downsampled result 402 Dest.SetSize(Width div Factor, Height div Factor); 403 for Y := 0 to Dest.Height - 1 do 404 Move(Temp.Scanline[Y]^, Dest.Scanline[Y]^, Dest.Width); 405 end; 406 407 begin 408 // downsample directly 409 if (Dest = Self) or not (Factor in [2, 3, 4]) then 410 begin 411 DownsampleAndMove; 412 Exit; 413 end; 414 415 case Factor of 416 2: 417 begin 418 Dest.SetSize(Width div 2, Height div 2); 419 DownsampleByteMap2x(Self, Dest); 420 end; 421 3: 422 begin 423 // downsample directly 424 Dest.SetSize(Width div 3, Height div 3); 425 DownsampleByteMap3x(Self, Dest); 426 end; 427 4: 428 begin 429 // downsample directly 430 Dest.SetSize(Width div 4, Height div 4); 431 DownsampleByteMap4x(Self, Dest); 432 end; 433 end; 434 end; 214 435 215 436 procedure TByteMap.Assign(Source: TPersistent); … … 240 461 procedure TByteMap.ChangeSize(var Width, Height: Integer; NewWidth, NewHeight: Integer); 241 462 begin 242 SetLength(FBits, NewWidth * NewHeight);463 ReallocMem(FBits, NewWidth * NewHeight); 243 464 Width := NewWidth; 244 465 Height := NewHeight; … … 247 468 procedure TByteMap.Clear(FillValue: Byte); 248 469 begin 249 FillChar(Bits [0], Width * Height, FillValue);470 FillChar(Bits^, Width * Height, FillValue); 250 471 Changed; 251 end;252 253 destructor TByteMap.Destroy;254 begin255 FBits := nil;256 inherited;257 472 end; 258 473 … … 263 478 end; 264 479 265 function TByteMap.GetBits: PByteArray; 266 begin 267 Result := @FBits[0]; 480 procedure TByteMap.FlipHorz(Dst: TByteMap); 481 var 482 i, j: Integer; 483 P1, P2: PByte; 484 tmp: Byte; 485 W, W2: Integer; 486 begin 487 W := Width; 488 if (Dst = nil) or (Dst = Self) then 489 begin 490 { In-place flipping } 491 P1 := PByte(Bits); 492 P2 := P1; 493 Inc(P2, Width - 1); 494 W2 := Width shr 1; 495 for J := 0 to Height - 1 do 496 begin 497 for I := 0 to W2 - 1 do 498 begin 499 tmp := P1^; 500 P1^ := P2^; 501 P2^ := tmp; 502 Inc(P1); 503 Dec(P2); 504 end; 505 Inc(P1, W - W2); 506 Inc(P2, W + W2); 507 end; 508 Changed; 509 end 510 else 511 begin 512 { Flip to Dst } 513 Dst.BeginUpdate; 514 Dst.SetSize(W, Height); 515 P1 := PByte(Bits); 516 P2 := PByte(Dst.Bits); 517 Inc(P2, W - 1); 518 for J := 0 to Height - 1 do 519 begin 520 for I := 0 to W - 1 do 521 begin 522 P2^ := P1^; 523 Inc(P1); 524 Dec(P2); 525 end; 526 Inc(P2, W shl 1); 527 end; 528 Dst.EndUpdate; 529 Dst.Changed; 530 end; 531 end; 532 533 procedure TByteMap.FlipVert(Dst: TByteMap); 534 var 535 J, J2: Integer; 536 Buffer: PByteArray; 537 P1, P2: PByte; 538 begin 539 if (Dst = nil) or (Dst = Self) then 540 begin 541 { in-place } 542 J2 := Height - 1; 543 GetMem(Buffer, Width); 544 for J := 0 to Height div 2 - 1 do 545 begin 546 P1 := PByte(ScanLine[J]); 547 P2 := PByte(ScanLine[J2]); 548 Move(P1^, Buffer^, Width); 549 Move(P2^, P1^, Width); 550 Move(Buffer^, P2^, Width); 551 Dec(J2); 552 end; 553 FreeMem(Buffer); 554 Changed; 555 end 556 else 557 begin 558 Dst.SetSize(Width, Height); 559 J2 := Height - 1; 560 for J := 0 to Height - 1 do 561 begin 562 Move(ScanLine[J]^, Dst.ScanLine[J2]^, Width); 563 Dec(J2); 564 end; 565 Dst.Changed; 566 end; 567 end; 568 569 function TByteMap.GetScanline(Y: Integer): PByteArray; 570 begin 571 Result := @FBits^[Y * Width]; 268 572 end; 269 573 270 574 function TByteMap.GetValPtr(X, Y: Integer): PByte; 271 575 begin 272 Result := @FBits [X + Y * Width];576 Result := @FBits^[X + Y * Width]; 273 577 end; 274 578 275 579 function TByteMap.GetValue(X, Y: Integer): Byte; 276 580 begin 277 Result := FBits[X + Y * Width]; 581 Result := FBits^[X + Y * Width]; 582 end; 583 584 procedure TByteMap.Multiply(Value: Byte); 585 var 586 Index: Integer; 587 begin 588 for Index := 0 to FWidth * FHeight - 1 do 589 FBits^[Index] := ((FBits^[Index] * Value + $80) shr 8); 590 end; 591 592 procedure TByteMap.Add(Value: Byte); 593 var 594 Index: Integer; 595 begin 596 for Index := 0 to FWidth * FHeight - 1 do 597 FBits^[Index] := Min(FBits^[Index] + Value, 255); 598 end; 599 600 procedure TByteMap.Sub(Value: Byte); 601 var 602 Index: Integer; 603 begin 604 for Index := 0 to FWidth * FHeight - 1 do 605 FBits^[Index] := Max(FBits^[Index] + Value, 0); 278 606 end; 279 607 … … 295 623 SrcC := Source.PixelPtr[0, 0]; 296 624 SrcB := Pointer(SrcC); 297 DstB := @FBits [0];625 DstB := @FBits^; 298 626 case Conversion of 299 627 … … 371 699 end; 372 700 701 procedure TByteMap.Rotate180(Dst: TByteMap); 702 var 703 Src: PByteArray; 704 S, D: PByte; 705 X, Y: Integer; 706 T: Byte; 707 begin 708 if (Dst = nil) or (Dst = Self) then 709 begin 710 for Y := 0 to FHeight - 1 do 711 begin 712 Src := Scanline[Y]; 713 for X := 0 to (FWidth div 2) - 1 do 714 begin 715 T := Src^[X]; 716 Src^[X] := Src^[Width - 1 - X]; 717 Src^[Width - 1 - X] := T; 718 end; 719 end; 720 end 721 else 722 begin 723 S := PByte(FBits); 724 D := PByte(@Dst.Bits[FHeight * FWidth - 1]); 725 for X := 0 to FHeight * FWidth - 1 do 726 begin 727 D^ := S^; 728 Dec(D); 729 Inc(S); 730 end; 731 end; 732 end; 733 734 procedure TByteMap.Rotate270(Dst: TByteMap); 735 var 736 Src: PByteArray; 737 Current: PByte; 738 X, Y, W, H: Integer; 739 begin 740 if (Dst = nil) or (Dst = Self) then 741 begin 742 W := FWidth; 743 H := FHeight; 744 745 // inplace replace 746 GetMem(Src, W * H); 747 748 // copy bits 749 Move(Bits^, Src^, W * H); 750 751 SetSize(H, W); 752 753 Current := PByte(Src); 754 for Y := 0 to H - 1 do 755 for X := 0 to W - 1 do 756 begin 757 Bits^[(W - 1 - X) * H + Y] := Current^; 758 Inc(Current); 759 end; 760 761 // dispose old data pointer 762 FreeMem(Src); 763 end 764 else 765 begin 766 // exchange dimensions 767 Dst.SetSize(Height, Width); 768 769 for Y := 0 to FHeight - 1 do 770 begin 771 Src := Scanline[Y]; 772 for X := 0 to FWidth - 1 do 773 Dst.Bits^[X * FHeight + FHeight - 1 - Y] := Src^[X]; 774 end; 775 end; 776 end; 777 778 procedure TByteMap.Rotate90(Dst: TByteMap); 779 var 780 Src: PByteArray; 781 Current: PByte; 782 X, Y, W, H: Integer; 783 begin 784 if (Dst = nil) or (Dst = Self) then 785 begin 786 W := FWidth; 787 H := FHeight; 788 789 // inplace replace 790 GetMem(Src, W * H); 791 792 // copy bits 793 Move(Bits^, Src^, W * H); 794 795 SetSize(H, W); 796 797 Current := PByte(Src); 798 for Y := 0 to H - 1 do 799 for X := 0 to W - 1 do 800 begin 801 Bits^[X * H + (H - 1 - Y)] := Current^; 802 Inc(Current); 803 end; 804 805 // dispose old data pointer 806 FreeMem(Src); 807 end 808 else 809 begin 810 // exchange dimensions 811 Dst.SetSize(Height, Width); 812 813 for Y := 0 to FHeight - 1 do 814 begin 815 Src := Scanline[Y]; 816 for X := 0 to FWidth - 1 do 817 Dst.Bits^[(FWidth - 1 - X) * FHeight + Y] := Src^[X]; 818 end; 819 end; 820 end; 821 373 822 procedure TByteMap.SetValue(X, Y: Integer; Value: Byte); 374 823 begin 375 FBits [X + Y * Width] := Value;824 FBits^[X + Y * Width] := Value; 376 825 end; 377 826 … … 394 843 DstC := Dest.PixelPtr[0, 0]; 395 844 DstB := Pointer(DstC); 396 SrcB := @FBits [0];845 SrcB := @FBits^; 397 846 case Conversion of 398 847 … … 472 921 N := W * H - 1; 473 922 DstC := Dest.PixelPtr[0, 0]; 474 SrcB := @FBits [0];923 SrcB := @FBits^; 475 924 476 925 for I := 0 to N do … … 485 934 end; 486 935 end; 487 936 937 procedure TByteMap.DrawTo(Dest: TCustomBitmap32; X, Y: Integer; Color: TColor32); 938 var 939 ClipRect: TRect; 940 IX, IY: Integer; 941 RGB: Cardinal; 942 NewColor: TColor32; 943 ScnLn: PColor32Array; 944 ByteLine: PByteArray; 945 Alpha: Byte; 946 begin 947 with ClipRect do 948 begin 949 Left := X; 950 if Left < 0 then 951 Left := 0; 952 Top := Y; 953 if Top < 0 then 954 Top := 0; 955 Right := X + Self.Width; 956 if Right > Self.Width then 957 Right := Self.Width; 958 Bottom := Y + Self.Height; 959 if Bottom > Self.Height then 960 Bottom := Self.Height; 961 962 // split RGB and alpha 963 RGB := Color and $FFFFFF; 964 Alpha := Color shr 24; 965 966 // blend scanlines 967 for IY := Top to Bottom - 1 do 968 begin 969 ScnLn := Dest.ScanLine[IY]; 970 ByteLine := Self.ScanLine[IY - Y]; 971 for IX := Left to Right - 1 do 972 begin 973 NewColor := (((ByteLine^[IX - X] * Alpha) shl 16) and $FF000000) or RGB; 974 MergeMem(NewColor, ScnLn^[IX]); 975 end; 976 end; 977 EMMS; 978 end; 979 end; 980 981 procedure TByteMap.DrawTo(Dest: TCustomBitmap32; Rect: TRect; Color: TColor32); 982 var 983 ClipRect: TRect; 984 IX, IY: Integer; 985 RGB: Cardinal; 986 NewColor: TColor32; 987 ScnLn: PColor32Array; 988 ByteLine: PByteArray; 989 Alpha: Byte; 990 begin 991 with ClipRect do 992 begin 993 Left := Rect.Left; 994 if Left < 0 then 995 Left := 0; 996 Top := Rect.Top; 997 if Top < 0 then 998 Top := 0; 999 Right := Math.Min(Rect.Left + Self.Width, Rect.Right); 1000 Bottom := Math.Min(Rect.Top + Self.Height, Rect.Bottom); 1001 1002 // split RGB and alpha 1003 RGB := Color and $FFFFFF; 1004 Alpha := Color shr 24; 1005 1006 // blend scanlines 1007 for IY := Top to Bottom - 1 do 1008 begin 1009 ScnLn := Dest.ScanLine[IY]; 1010 ByteLine := Self.ScanLine[IY - Rect.Top]; 1011 for IX := Left to Right - 1 do 1012 begin 1013 NewColor := (((ByteLine^[IX - Rect.Left] * Alpha) shl 16) and $FF000000) or RGB; 1014 MergeMem(NewColor, ScnLn^[IX]); 1015 end; 1016 end; 1017 EMMS; 1018 end; 1019 end; 1020 1021 488 1022 { TWordMap } 1023 1024 constructor TWordMap.Create; 1025 begin 1026 FBits := nil; 1027 inherited Create; 1028 end; 1029 1030 destructor TWordMap.Destroy; 1031 begin 1032 FreeMem(FBits); 1033 inherited; 1034 end; 489 1035 490 1036 procedure TWordMap.ChangeSize(var Width, Height: Integer; NewWidth, 491 1037 NewHeight: Integer); 492 1038 begin 493 SetLength(FBits, NewWidth * NewHeight);1039 ReallocMem(FBits, NewWidth * NewHeight * SizeOf(Word)); 494 1040 Width := NewWidth; 495 1041 Height := NewHeight; … … 498 1044 procedure TWordMap.Clear(FillValue: Word); 499 1045 begin 500 FillWord(FBits [0], Width * Height, FillValue);1046 FillWord(FBits^, Width * Height, FillValue); 501 1047 Changed; 502 1048 end; 503 1049 504 destructor TWordMap.Destroy; 1050 procedure TWordMap.Assign(Source: TPersistent); 1051 begin 1052 BeginUpdate; 1053 try 1054 if Source is TWordMap then 1055 begin 1056 inherited SetSize(TWordMap(Source).Width, TWordMap(Source).Height); 1057 Move(TWordMap(Source).Bits[0], Bits[0], Width * Height * SizeOf(Word)); 1058 end 1059 //else if Source is TBitmap32 then 1060 // ReadFrom(TBitmap32(Source), ctWeightedRGB) 1061 else 1062 inherited; 1063 finally 1064 EndUpdate; 1065 Changed; 1066 end; 1067 end; 1068 1069 function TWordMap.Empty: Boolean; 1070 begin 1071 Result := not Assigned(FBits); 1072 end; 1073 1074 function TWordMap.GetScanline(Y: Integer): PWordArray; 1075 begin 1076 Result := @FBits^[Y * Width]; 1077 end; 1078 1079 function TWordMap.GetValPtr(X, Y: Integer): PWord; 1080 begin 1081 Result := @FBits^[X + Y * Width]; 1082 end; 1083 1084 function TWordMap.GetValue(X, Y: Integer): Word; 1085 begin 1086 Result := FBits^[X + Y * Width]; 1087 end; 1088 1089 procedure TWordMap.SetValue(X, Y: Integer; const Value: Word); 1090 begin 1091 FBits^[X + Y * Width] := Value; 1092 end; 1093 1094 1095 { TIntegerMap } 1096 1097 constructor TIntegerMap.Create; 505 1098 begin 506 1099 FBits := nil; 1100 inherited Create; 1101 end; 1102 1103 destructor TIntegerMap.Destroy; 1104 begin 1105 FreeMem(FBits); 507 1106 inherited; 508 1107 end; 509 510 function TWordMap.Empty: Boolean;511 begin512 Result := not Assigned(FBits);513 end;514 515 function TWordMap.GetBits: PWordArray;516 begin517 Result := @FBits[0];518 end;519 520 function TWordMap.GetValPtr(X, Y: Integer): PWord;521 begin522 Result := @FBits[X + Y * Width];523 end;524 525 function TWordMap.GetValue(X, Y: Integer): Word;526 begin527 Result := FBits[X + Y * Width];528 end;529 530 procedure TWordMap.SetValue(X, Y: Integer; const Value: Word);531 begin532 FBits[X + Y * Width] := Value;533 end;534 535 { TIntegerMap }536 1108 537 1109 procedure TIntegerMap.ChangeSize(var Width, Height: Integer; NewWidth, 538 1110 NewHeight: Integer); 539 1111 begin 540 SetLength(FBits, NewWidth * NewHeight);1112 ReallocMem(FBits, NewWidth * NewHeight * SizeOf(Integer)); 541 1113 Width := NewWidth; 542 1114 Height := NewHeight; … … 545 1117 procedure TIntegerMap.Clear(FillValue: Integer); 546 1118 begin 547 FillLongword(FBits [0], Width * Height, FillValue);1119 FillLongword(FBits^, Width * Height, FillValue); 548 1120 Changed; 549 1121 end; 550 1122 551 destructor TIntegerMap.Destroy; 1123 procedure TIntegerMap.Assign(Source: TPersistent); 1124 begin 1125 BeginUpdate; 1126 try 1127 if Source is TIntegerMap then 1128 begin 1129 inherited SetSize(TIntegerMap(Source).Width, TIntegerMap(Source).Height); 1130 Move(TIntegerMap(Source).Bits[0], Bits[0], Width * Height * SizeOf(Integer)); 1131 end 1132 //else if Source is TBitmap32 then 1133 // ReadFrom(TBitmap32(Source), ctWeightedRGB) 1134 else 1135 inherited; 1136 finally 1137 EndUpdate; 1138 Changed; 1139 end; 1140 end; 1141 1142 function TIntegerMap.Empty: Boolean; 1143 begin 1144 Result := not Assigned(FBits); 1145 end; 1146 1147 function TIntegerMap.GetScanline(Y: Integer): PIntegerArray; 1148 begin 1149 Result := @FBits^[Y * Width]; 1150 end; 1151 1152 function TIntegerMap.GetValPtr(X, Y: Integer): PInteger; 1153 begin 1154 Result := @FBits^[X + Y * Width]; 1155 end; 1156 1157 function TIntegerMap.GetValue(X, Y: Integer): Integer; 1158 begin 1159 Result := FBits^[X + Y * Width]; 1160 end; 1161 1162 procedure TIntegerMap.SetValue(X, Y: Integer; const Value: Integer); 1163 begin 1164 FBits^[X + Y * Width] := Value; 1165 end; 1166 1167 1168 { TCardinalMap } 1169 1170 constructor TCardinalMap.Create; 552 1171 begin 553 1172 FBits := nil; 1173 inherited Create; 1174 end; 1175 1176 destructor TCardinalMap.Destroy; 1177 begin 1178 FreeMem(FBits); 554 1179 inherited; 555 1180 end; 556 1181 557 function TIntegerMap.Empty: Boolean; 1182 procedure TCardinalMap.Assign(Source: TPersistent); 1183 begin 1184 BeginUpdate; 1185 try 1186 if Source is TCardinalMap then 1187 begin 1188 inherited SetSize(TCardinalMap(Source).Width, TCardinalMap(Source).Height); 1189 Move(TCardinalMap(Source).Bits[0], Bits[0], Width * Height * SizeOf(Cardinal)); 1190 end 1191 //else if Source is TBitmap32 then 1192 // ReadFrom(TBitmap32(Source), ctWeightedRGB) 1193 else 1194 inherited; 1195 finally 1196 EndUpdate; 1197 Changed; 1198 end; 1199 end; 1200 1201 procedure TCardinalMap.ChangeSize(var Width, Height: Integer; NewWidth, 1202 NewHeight: Integer); 1203 begin 1204 ReallocMem(FBits, NewWidth * NewHeight * SizeOf(Cardinal)); 1205 Width := NewWidth; 1206 Height := NewHeight; 1207 end; 1208 1209 procedure TCardinalMap.Clear(FillValue: Cardinal); 1210 begin 1211 FillLongword(FBits^, Width * Height, FillValue); 1212 Changed; 1213 end; 1214 1215 function TCardinalMap.Empty: Boolean; 558 1216 begin 559 1217 Result := not Assigned(FBits); 560 1218 end; 561 1219 562 function TIntegerMap.GetBits: PIntegerArray; 563 begin 564 Result := @FBits[0]; 565 end; 566 567 function TIntegerMap.GetValPtr(X, Y: Integer): PInteger; 568 begin 569 Result := @FBits[X + Y * Width]; 570 end; 571 572 function TIntegerMap.GetValue(X, Y: Integer): Integer; 573 begin 574 Result := FBits[X + Y * Width]; 575 end; 576 577 procedure TIntegerMap.SetValue(X, Y: Integer; const Value: Integer); 578 begin 579 FBits[X + Y * Width] := Value; 580 end; 1220 function TCardinalMap.GetScanline(Y: Integer): PCardinalArray; 1221 begin 1222 Result := @FBits^[Y * Width]; 1223 end; 1224 1225 function TCardinalMap.GetValPtr(X, Y: Cardinal): PCardinal; 1226 begin 1227 Result := @FBits^[X + Y * Cardinal(Width)]; 1228 end; 1229 1230 function TCardinalMap.GetValue(X, Y: Cardinal): Cardinal; 1231 begin 1232 Result := FBits^[X + Y * Cardinal(Width)]; 1233 end; 1234 1235 procedure TCardinalMap.SetValue(X, Y: Cardinal; const Value: Cardinal); 1236 begin 1237 FBits^[X + Y * Cardinal(Width)] := Value; 1238 end; 1239 581 1240 582 1241 { TFloatMap } 1242 1243 constructor TFloatMap.Create; 1244 begin 1245 FBits := nil; 1246 inherited Create; 1247 end; 1248 1249 destructor TFloatMap.Destroy; 1250 begin 1251 FreeMem(FBits); 1252 inherited; 1253 end; 1254 1255 procedure TFloatMap.Assign(Source: TPersistent); 1256 begin 1257 BeginUpdate; 1258 try 1259 if Source is TFloatMap then 1260 begin 1261 inherited SetSize(TFloatMap(Source).Width, TFloatMap(Source).Height); 1262 Move(TFloatMap(Source).Bits[0], Bits[0], Width * Height * SizeOf(TFloat)); 1263 end 1264 //else if Source is TBitmap32 then 1265 // ReadFrom(TBitmap32(Source), ctWeightedRGB) 1266 else 1267 inherited; 1268 finally 1269 EndUpdate; 1270 Changed; 1271 end; 1272 end; 583 1273 584 1274 procedure TFloatMap.ChangeSize(var Width, Height: Integer; NewWidth, 585 1275 NewHeight: Integer); 586 1276 begin 587 SetLength(FBits, NewWidth * NewHeight);1277 ReallocMem(FBits, NewWidth * NewHeight * SizeOf(TFloat)); 588 1278 Width := NewWidth; 589 1279 Height := NewHeight; … … 592 1282 procedure TFloatMap.Clear; 593 1283 begin 594 FillChar(FBits [0], Width * Height * SizeOf(TFloat), 0);1284 FillChar(FBits^, Width * Height * SizeOf(TFloat), 0); 595 1285 Changed; 596 1286 end; … … 601 1291 begin 602 1292 for Index := 0 to Width * Height - 1 do 603 FBits [Index] := FillValue;1293 FBits^[Index] := FillValue; 604 1294 Changed; 605 1295 end; 606 1296 607 destructor TFloatMap.Destroy; 1297 function TFloatMap.Empty: Boolean; 1298 begin 1299 Result := not Assigned(FBits); 1300 end; 1301 1302 function TFloatMap.GetScanline(Y: Integer): PFloatArray; 1303 begin 1304 Result := @FBits^[Y * Width]; 1305 end; 1306 1307 function TFloatMap.GetValPtr(X, Y: Integer): GR32.PFloat; 1308 begin 1309 Result := @FBits^[X + Y * Width]; 1310 end; 1311 1312 function TFloatMap.GetValue(X, Y: Integer): TFloat; 1313 begin 1314 Result := FBits^[X + Y * Width]; 1315 end; 1316 1317 procedure TFloatMap.SetValue(X, Y: Integer; const Value: TFloat); 1318 begin 1319 FBits^[X + Y * Width] := Value; 1320 end; 1321 1322 1323 {$IFDEF COMPILER2010} 1324 1325 { TGenericMap<T> } 1326 1327 constructor TGenericMap<T>.Create; 608 1328 begin 609 1329 FBits := nil; 1330 inherited Create; 1331 end; 1332 1333 destructor TGenericMap<T>.Destroy; 1334 begin 1335 FreeMem(FBits); 610 1336 inherited; 611 1337 end; 612 1338 613 function TFloatMap.Empty: Boolean; 1339 procedure TGenericMap<T>.Assign(Source: TPersistent); 1340 begin 1341 BeginUpdate; 1342 try 1343 (* 1344 if Source is TFloatMap then 1345 begin 1346 inherited SetSize(TFloatMap(Source).Width, TFloatMap(Source).Height); 1347 Move(TFloatMap(Source).Bits[0], Bits[0], Width * Height * SizeOf(TFloat)); 1348 end 1349 //else if Source is TBitmap32 then 1350 // ReadFrom(TBitmap32(Source), ctWeightedRGB) 1351 else 1352 inherited; 1353 *) 1354 finally 1355 EndUpdate; 1356 Changed; 1357 end; 1358 end; 1359 1360 procedure TGenericMap<T>.ChangeSize(var Width, Height: Integer; NewWidth, 1361 NewHeight: Integer); 1362 begin 1363 ReallocMem(FBits, NewWidth * NewHeight * SizeOf(T)); 1364 Width := NewWidth; 1365 Height := NewHeight; 1366 end; 1367 1368 procedure TGenericMap<T>.Clear(FillValue: T); 1369 var 1370 Index: Integer; 1371 begin 1372 for Index := 0 to Width * Height - 1 do 1373 Move(FillValue, PByte(FBits)[Index], SizeOf(T)); 1374 Changed; 1375 end; 1376 1377 procedure TGenericMap<T>.Clear; 1378 begin 1379 FillChar(FBits^, Width * Height * SizeOf(T), 0); 1380 Changed; 1381 end; 1382 1383 function TGenericMap<T>.Empty: Boolean; 614 1384 begin 615 1385 Result := not Assigned(FBits); 616 1386 end; 617 1387 618 function TFloatMap.GetBits: PFloatArray; 619 begin 620 Result := @FBits[0]; 621 end; 622 623 function TFloatMap.GetValPtr(X, Y: Integer): PFloat; 624 begin 625 Result := @FBits[X + Y * Width]; 626 end; 627 628 function TFloatMap.GetValue(X, Y: Integer): TFloat; 629 begin 630 Result := FBits[X + Y * Width]; 631 end; 632 633 procedure TFloatMap.SetValue(X, Y: Integer; const Value: TFloat); 634 begin 635 FBits[X + Y * Width] := Value; 636 end; 1388 function TGenericMap<T>.GetValue(X, Y: Integer): T; 1389 begin 1390 Move(PByte(FBits)[(X + Y * Width) * SizeOf(T)], Result, SizeOf(T)); 1391 end; 1392 1393 procedure TGenericMap<T>.SetValue(X, Y: Integer; const Value: T); 1394 begin 1395 Move(Value, PByte(FBits)[(X + Y * Width) * SizeOf(T)], SizeOf(T)); 1396 end; 1397 1398 {$ENDIF} 637 1399 638 1400 end.
Note:
See TracChangeset
for help on using the changeset viewer.