Subversion Repositories spacemission

Rev

Rev 4 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4 Rev 16
Line 26... Line 26...
26
{$INCLUDE DelphiXcfg.inc}
26
{$INCLUDE DelphiXcfg.inc}
27
{$DEFINE USE_SCANLINE}
27
{$DEFINE USE_SCANLINE}
28
 
28
 
29
uses
29
uses
30
  Windows, SysUtils, Classes, Graphics, Controls,
30
  Windows, SysUtils, Classes, Graphics, Controls,
-
 
31
  {$IFDEF VER7UP} Types, {$ENDIF}
-
 
32
  {$IFDEF VER9UP} GraphUtil, {$ENDIF}
31
  {$IFDEF VER17UP} Types, UITypes,{$ENDIF}
33
  {$IFDEF VER17UP} UITypes,{$ENDIF}
32
  Math;
34
  Math;
33
 
35
 
34
type
36
type
35
  TColorLineStyle = (csSolid, csGradient, csRainbow);
37
  TColorLineStyle = (csSolid, csGradient, csRainbow);
36
  TColorLinePixelGeometry = (pgPoint, pgCircular, pgRectangular);
38
  TColorLinePixelGeometry = (pgPoint, pgCircular, pgRectangular);
37
  PRGBQuads = ^TRGBQuads;
39
  PRGBQuads = ^TRGBQuads;
38
  TRGBQuads = array[0..255] of TRGBQuad;
40
  TRGBQuads = array[0..255] of TRGBQuad;
39
 
41
 
40
  TPaletteEntries = array[0..255] of TPaletteEntry;
42
  TPaletteEntries = array[0..255] of TPaletteEntry;
41
 
43
 
-
 
44
  PBGRA = ^TBGRA;
-
 
45
  TBGRA = packed record
-
 
46
    B, G, R, A: Byte;
-
 
47
  end;
-
 
48
  TLinesA = array[0..0] of TBGRA;
-
 
49
  PLinesA = ^TLinesA;
-
 
50
 
42
  PBGR = ^TBGR;
51
  PBGR = ^TBGR;
43
  TBGR = packed record
52
  TBGR = packed record
44
    B, G, R: Byte;
53
    B, G, R: Byte;
45
  end;
54
  end;
46
 
55
 
Line 53... Line 62...
53
  TPBytes = array[0..0] of PBytes;
62
  TPBytes = array[0..0] of PBytes;
54
  PPBytes = ^TPBytes;
63
  PPBytes = ^TPBytes;
55
  {   End of type's   }
64
  {   End of type's   }
56
 
65
 
57
  PArrayBGR = ^TArrayBGR;
66
  PArrayBGR = ^TArrayBGR;
58
  TArrayBGR = array[0..10000] of TBGR;
67
  TArrayBGR = array[0..0] of TBGR;
59
 
68
 
60
  PArrayByte = ^TArrayByte;
69
  PArrayByte = ^TArrayByte;
61
  TArrayByte = array[0..10000] of Byte;
70
  TArrayByte = array[0..0] of Byte;
62
 
71
 
63
  PArrayWord = ^TArrayWord;
72
  PArrayWord = ^TArrayWord;
64
  TArrayWord = array[0..10000] of Word;
73
  TArrayWord = array[0..0] of Word;
65
 
74
 
66
  PArrayDWord = ^TArrayDWord;
75
  PArrayDWord = ^TArrayDWord;
67
  TArrayDWord = array[0..10000] of DWord;
76
  TArrayDWord = array[0..0] of DWord;
68
 
77
 
69
  {  TDIBPixelFormat  }
78
  {  TDIBPixelFormat  }
70
 
79
 
71
  TDIBPixelFormat = record
80
  TDIBPixelFormat = record
72
    RBitMask, GBitMask, BBitMask: DWORD;
81
    RBitMask, GBitMask, BBitMask: DWORD;
Line 212... Line 221...
212
    procedure ReadData(Stream: TStream); override;
221
    procedure ReadData(Stream: TStream); override;
213
    procedure SetHeight(Value: Integer); override;
222
    procedure SetHeight(Value: Integer); override;
214
    procedure SetPalette(Value: HPalette); override;
223
    procedure SetPalette(Value: HPalette); override;
215
    procedure SetWidth(Value: Integer); override;
224
    procedure SetWidth(Value: Integer); override;
216
    procedure WriteData(Stream: TStream); override;
225
    procedure WriteData(Stream: TStream); override;
-
 
226
    {$IFDEF VER16UP}
-
 
227
    function GetSupportsPartialTransparency: Boolean; override;
-
 
228
    {$ENDIF}
-
 
229
    function GetTransparent: Boolean; override;
217
  public
230
  public
218
    ColorTable: TRGBQuads;
231
    ColorTable: TRGBQuads;
219
    PixelFormat: TDIBPixelFormat;
232
    PixelFormat: TDIBPixelFormat;
220
    constructor Create; override;
233
    constructor Create; override;
221
    destructor Destroy; override;
234
    destructor Destroy; override;
Line 237... Line 250...
237
    procedure UpdatePalette;
250
    procedure UpdatePalette;
238
    {  Special effect  }
251
    {  Special effect  }
239
    procedure Blur(ABitCount: Integer; Radius: Integer);
252
    procedure Blur(ABitCount: Integer; Radius: Integer);
240
    procedure Greyscale(ABitCount: Integer);
253
    procedure Greyscale(ABitCount: Integer);
241
    procedure Mirror(MirrorX, MirrorY: Boolean);
254
    procedure Mirror(MirrorX, MirrorY: Boolean);
242
    procedure Negative;
255
    procedure Negative; {$IFDEF VER9UP}inline;{$ENDIF}
243
 
256
 
244
    {   Added New Special Effect   }
257
    {   Added New Special Effect   }
245
    procedure Spray(Amount: Integer);
258
    procedure Spray(Amount: Integer);
246
    procedure Emboss;
259
    procedure Emboss;
247
    procedure AddMonoNoise(Amount: Integer);
260
    procedure AddMonoNoise(Amount: Integer);
Line 304... Line 317...
304
    procedure DoResample(AmountX, AmountY: Integer; TypeResample: TFilterTypeResample);
317
    procedure DoResample(AmountX, AmountY: Integer; TypeResample: TFilterTypeResample);
305
    {rotate}
318
    {rotate}
306
    procedure DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended);
319
    procedure DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended);
307
    procedure DoColorize(ForeColor, BackColor: TColor);
320
    procedure DoColorize(ForeColor, BackColor: TColor);
308
    {Simple explosion spoke effect}
321
    {Simple explosion spoke effect}
309
    procedure DoNovaEffect(sr, sg, sb, cx, cy, radius,
322
    procedure DoNovaEffect(const sr, sg, sb, cx, cy, radius,
310
      nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent);
323
      nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent);
311
 
324
 
312
    {Simple Mandelbrot-set drawing}
325
    {Simple Mandelbrot-set drawing}
313
    procedure DrawMandelbrot(ao, au: Integer; bo, bu: Double);
326
    procedure DrawMandelbrot(ao, au: Integer; bo, bu: Double);
314
 
327
 
Line 377... Line 390...
377
    procedure InitLight(Count, Detail: Integer);
390
    procedure InitLight(Count, Detail: Integer);
378
    procedure DrawLights(FLight: TLightArray; AmbientLight: TColor);
391
    procedure DrawLights(FLight: TLightArray; AmbientLight: TColor);
379
    //
392
    //
380
    // effect for special purpose
393
    // effect for special purpose
381
    //
394
    //
382
    procedure FadeOut(DIB2: TDIB; Step: Byte);
395
    procedure FadeOut(DIB2: TDIB; Step: Byte); {$IFDEF VER9UP} inline; {$ENDIF}
383
    procedure DoZoom(DIB2: TDIB; ZoomRatio: Real);
396
    procedure DoZoom(DIB2: TDIB; ZoomRatio: Real);
384
    procedure DoBlur(DIB2: TDIB);
397
    procedure DoBlur(DIB2: TDIB);
385
    procedure FadeIn(DIB2: TDIB; Step: Byte);
398
    procedure FadeIn(DIB2: TDIB; Step: Byte); {$IFDEF VER9UP} inline; {$ENDIF}
386
    procedure FillDIB8(Color: Byte);
399
    procedure FillDIB8(Color: Byte);  {$IFDEF VER9UP} inline; {$ENDIF}
387
    procedure DoRotate(DIB1: TDIB; cX, cY, Angle: Integer);
400
    procedure DoRotate(DIB1: TDIB; cX, cY, Angle: Integer);
388
    procedure Distort(DIB1: TDIB; dt: TDistortType; cX, cY, Angle: Integer; Factor: Real);
401
    procedure Distort(DIB1: TDIB; dt: TDistortType; cX, cY, Angle: Integer; Factor: Real);
389
    function Ink(DIB: TDIB; const SprayInit: Boolean; const AmountSpray: Integer): Boolean;
402
    function Ink(DIB: TDIB; const SprayInit: Boolean; const AmountSpray: Integer): Boolean;
390
    // lines
403
    // lines
391
    procedure AntialiasedLine(x1, y1, x2, y2: Integer; color: TColor); {$IFDEF VER9UP} inline; {$ENDIF}
404
    procedure AntialiasedLine(x1, y1, x2, y2: Integer; color: TColor); {$IFDEF VER9UP} inline; {$ENDIF}
Line 563... Line 576...
563
{Proportionaly scale of size, for recountin image sizes}
576
{Proportionaly scale of size, for recountin image sizes}
564
function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single; {$IFDEF VER9UP}inline;{$ENDIF}
577
function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single; {$IFDEF VER9UP}inline;{$ENDIF}
565
 
578
 
566
procedure MakeDib(out DIB: TDIB; const iWidth, iHeight, iBitCount: Integer; iFillColor: TColor{$IFDEF VER4UP} = clBlack{$ENDIF}); {$IFDEF VER4UP}overload; {$ENDIF}
579
procedure MakeDib(out DIB: TDIB; const iWidth, iHeight, iBitCount: Integer; iFillColor: TColor{$IFDEF VER4UP} = clBlack{$ENDIF}); {$IFDEF VER4UP}overload; {$ENDIF}
567
procedure{$IFDEF VER4UP}MakeDib{$ELSE}MakeDIB2{$ENDIF}(out DIB: TDIB; iBitmap: TBitmap); {$IFDEF VER4UP}overload; {$ENDIF}
580
procedure{$IFDEF VER4UP}MakeDib{$ELSE}MakeDIB2{$ENDIF}(out DIB: TDIB; iBitmap: TBitmap); {$IFDEF VER4UP}overload; {$ENDIF}
-
 
581
procedure MakeDIB32MaskByColor(var D: TDIB; const MaskColor: TColor{$IFDEF VER4UP} = clWhite{$ENDIF});
-
 
582
 
-
 
583
function BGR(B, G, R: Byte): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
568
 
584
 
569
implementation
585
implementation
570
 
586
 
571
uses DXConsts, {$IFDEF PNG_GRAPHICS}pngimage,{$ENDIF} jpeg;
587
uses DXConsts, {$IFDEF PNG_GRAPHICS}pngimage,{$ENDIF} jpeg;
572
 
588
 
-
 
589
function BGR(B, G, R: Byte): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
-
 
590
begin
-
 
591
  Result := (B shl 16) or (G shl 8) or R;
-
 
592
end;
-
 
593
 
-
 
594
procedure MakeDIB32MaskByColor(var D: TDIB; const MaskColor: TColor{$IFDEF VER4UP} = clWhite{$ENDIF});
-
 
595
type
-
 
596
  PRGBA = ^TRGBA;
-
 
597
  TRGBA = array[0..0] of Windows.TRGBQuad;
-
 
598
var
-
 
599
  p: PRGBA;
-
 
600
  y: Integer;
-
 
601
  x: Integer;
-
 
602
  B: TDIB;
-
 
603
begin
-
 
604
  MakeDib(B, D.Width, D.Height, 32, $FFFFFF);
-
 
605
  B.RGBChannel := D.RGBChannel;
-
 
606
  if B.BitCount = 32 then
-
 
607
    for Y := 0 to B.Height - 1 do
-
 
608
    begin
-
 
609
      p := B.ScanLine[Y];
-
 
610
      for X := 0 to B.Width - 1 do
-
 
611
      begin
-
 
612
        if (p[X].rgbBlue = GetBValue(MaskColor)) and (p[X].rgbGreen = GetGValue(MaskColor)) and (p[X].rgbRed = GetRValue(MaskColor)) then
-
 
613
          p[X].rgbReserved := 0
-
 
614
        else
-
 
615
          p[X].rgbReserved := $FF
-
 
616
      end
-
 
617
    end;
-
 
618
  d.Assign(B);
-
 
619
end;
-
 
620
 
573
function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single;
621
function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single;
574
var
622
var
575
  XScale, YScale: Single;
623
  XScale, YScale: Single;
576
begin
624
begin
577
  XScale := 1;
625
  XScale := 1;
Line 983... Line 1031...
983
    biBitCount := FBitCount;
1031
    biBitCount := FBitCount;
984
    if UsePixelFormat then
1032
    if UsePixelFormat then
985
      biCompression := BI_BITFIELDS
1033
      biCompression := BI_BITFIELDS
986
    else
1034
    else
987
    begin
1035
    begin
-
 
1036
      biCompression := 0; //none
988
      if (FBitCount = 4) and (Compressed) then
1037
      if (FBitCount = 4) and (Compressed) then
989
        biCompression := BI_RLE4
1038
        biCompression := BI_RLE4
990
      else if (FBitCount = 8) and (Compressed) then
1039
      else if (FBitCount = 8) and (Compressed) then
991
        biCompression := BI_RLE8
1040
        biCompression := BI_RLE8
992
      else
1041
      else
-
 
1042
        if FBitCount = 24 then
993
        biCompression := BI_RGB;
1043
          biCompression := BI_RGB;
994
    end;
1044
    end;
995
    biSizeImage := FSize;
1045
    biSizeImage := FSize;
996
    biXPelsPerMeter := 0;
1046
    biXPelsPerMeter := 0;
997
    biYPelsPerMeter := 0;
1047
    biYPelsPerMeter := 0;
Line 1710... Line 1760...
1710
 
1760
 
1711
  while FFreeList.Count > 0 do
1761
  while FFreeList.Count > 0 do
1712
  try
1762
  try
1713
    D := TDIB(FFreeList[0]);
1763
    D := TDIB(FFreeList[0]);
1714
    FFreeList.Remove(D);
1764
    FFreeList.Remove(D);
-
 
1765
    if (D <> nil) and (D.Height > 0) and (D.Width > 0) then //is really pointed to image?
1715
    D.Free;
1766
      D.Free;
1716
  except
1767
  except
-
 
1768
    // it is silent exception, but it can through outer (abstract) exception
1717
  end;
1769
  end;
1718
  FFreeList.Free;
1770
  FFreeList.Free;
1719
 
1771
 
1720
  inherited Destroy;
1772
  inherited Destroy;
1721
end;
1773
end;
Line 2131... Line 2183...
2131
  p0: PRGBA;
2183
  p0: PRGBA;
2132
  pB: PArrayByte;
2184
  pB: PArrayByte;
2133
  X, Y: Integer;
2185
  X, Y: Integer;
2134
begin
2186
begin
2135
  oDIB := nil;
2187
  oDIB := nil;
2136
  if not HasAlphaChannel then exit;
2188
  if not HasAlphaChannel then Exit;
2137
  oDIB := TDIB.Create;
2189
  oDIB := TDIB.Create;
2138
  oDIB.SetSize(Width, Height, 8);
2190
  oDIB.SetSize(Width, Height, 8);
2139
  for Y := 0 to Height - 1 do
2191
  for Y := 0 to Height - 1 do
2140
  begin
2192
  begin
2141
    p0 := ScanLine[Y];
2193
    p0 := ScanLine[Y];
Line 2231... Line 2283...
2231
  if not FImage.FMemoryImage then
2283
  if not FImage.FMemoryImage then
2232
    GDIFlush;
2284
    GDIFlush;
2233
  Result := Pointer(Integer(FTopPBits) + Y * FNextLine);
2285
  Result := Pointer(Integer(FTopPBits) + Y * FNextLine);
2234
end;
2286
end;
2235
 
2287
 
-
 
2288
{$IFDEF VER16UP}
-
 
2289
function TDIB.GetSupportsPartialTransparency: Boolean;
-
 
2290
begin
-
 
2291
  Result := (FBitCount = 32) and HasAlphaChannel;
-
 
2292
end;
-
 
2293
{$ENDIF}
-
 
2294
 
2236
function TDIB.GetTopPBits: Pointer;
2295
function TDIB.GetTopPBits: Pointer;
2237
begin
2296
begin
2238
  Changing(True);
2297
  Changing(True);
2239
 
2298
 
2240
  if not FImage.FMemoryImage then
2299
  if not FImage.FMemoryImage then
Line 2247... Line 2306...
2247
  if not FImage.FMemoryImage then
2306
  if not FImage.FMemoryImage then
2248
    GDIFlush;
2307
    GDIFlush;
2249
  Result := FTopPBits;
2308
  Result := FTopPBits;
2250
end;
2309
end;
2251
 
2310
 
-
 
2311
function TDIB.GetTransparent: Boolean;
-
 
2312
begin
-
 
2313
  Result := (FBitCount = 32) and HasAlphaChannel;
-
 
2314
end;
-
 
2315
 
2252
function TDIB.GetWidth: Integer;
2316
function TDIB.GetWidth: Integer;
2253
begin
2317
begin
2254
  Result := FWidth;
2318
  Result := FWidth;
2255
end;
2319
end;
2256
 
2320
 
Line 2481... Line 2545...
2481
    bfType := BitmapFileType;
2545
    bfType := BitmapFileType;
2482
    bfOffBits := SizeOf(TBitmapFileHeader) + BitmapInfoSize;
2546
    bfOffBits := SizeOf(TBitmapFileHeader) + BitmapInfoSize;
2483
    bfSize := bfOffBits + FImage.FBitmapInfo^.bmiHeader.biSizeImage;
2547
    bfSize := bfOffBits + FImage.FBitmapInfo^.bmiHeader.biSizeImage;
2484
    bfReserved1 := 0;
2548
    bfReserved1 := 0;
2485
    bfReserved2 := 0;
2549
    bfReserved2 := 0;
-
 
2550
    if (FBitCount = 32) and (FImage.FBitmapInfo^.bmiHeader.biCompression <> 0) then FImage.FBitmapInfo^.bmiHeader.biCompression := 0; //corrext RGB error to RGBA
2486
  end;
2551
  end;
-
 
2552
 
2487
  Stream.WriteBuffer(BF, SizeOf(TBitmapFileHeader));
2553
  Stream.WriteBuffer(BF, SizeOf(TBitmapFileHeader));
2488
 
2554
 
2489
  WriteData(Stream);
2555
  WriteData(Stream);
2490
end;
2556
end;
2491
 
2557
 
Line 3543... Line 3609...
3543
    end;
3609
    end;
3544
  finally
3610
  finally
3545
    EndProgress;
3611
    EndProgress;
3546
  end;
3612
  end;
3547
end;
3613
end;
3548
 
3614
(*
3549
procedure TDIB.Negative;
3615
procedure TDIB.Negative;
3550
var
3616
var
3551
  i, i2: Integer;
3617
  i, i2: Integer;
3552
  P: Pointer;
3618
  P: Pointer;
3553
begin
3619
begin
Line 3601... Line 3667...
3601
 
3667
 
3602
    @@byte_skip:
3668
    @@byte_skip:
3603
    end;
3669
    end;
3604
  end;
3670
  end;
3605
end;
3671
end;
-
 
3672
*)
-
 
3673
procedure TDIB.Negative;
-
 
3674
var
-
 
3675
  i: Integer;
-
 
3676
  P: Pointer;
-
 
3677
  i2: Integer;
-
 
3678
begin
-
 
3679
  if Empty then Exit;
-
 
3680
 
-
 
3681
  if BitCount <= 8 then
-
 
3682
  begin
-
 
3683
    for i := 0 to 255 do
-
 
3684
      with ColorTable[i] do
-
 
3685
      begin
-
 
3686
        rgbRed := 255 - rgbRed;
-
 
3687
        rgbGreen := 255 - rgbGreen;
-
 
3688
        rgbBlue := 255 - rgbBlue;
-
 
3689
      end;
-
 
3690
    UpdatePalette;
-
 
3691
  end
-
 
3692
  else
-
 
3693
  begin
-
 
3694
    P := PBits;
-
 
3695
    i2 := Size;
-
 
3696
    for i := 0 to i2-1 do
-
 
3697
    begin
-
 
3698
      PByteArray(P)^[i] := not PByteArray(P)^[i];
-
 
3699
    end;
-
 
3700
  end;
-
 
3701
end;
3606
 
3702
 
3607
procedure TDIB.Greyscale(ABitCount: Integer);
3703
procedure TDIB.Greyscale(ABitCount: Integer);
3608
var
3704
var
3609
  YTblR, YTblG, YTblB: array[0..255] of Byte;
3705
  YTblR, YTblG, YTblB: array[0..255] of Byte;
3610
  i, j, x, y: Integer;
3706
  i, j, x, y: Integer;
Line 4761... Line 4857...
4761
  weight, xmid, ymid, fx, fy, r1, r2, dx, dy, rmax: Double;
4857
  weight, xmid, ymid, fx, fy, r1, r2, dx, dy, rmax: Double;
4762
  Amount, ifx, ify, ty, tx, new_red, new_green, new_blue, ix, iy: Integer;
4858
  Amount, ifx, ify, ty, tx, new_red, new_green, new_blue, ix, iy: Integer;
4763
  weight_x, weight_y: array[0..1] of Double;
4859
  weight_x, weight_y: array[0..1] of Double;
4764
  total_red, total_green, total_blue: Double;
4860
  total_red, total_green, total_blue: Double;
4765
  sli, slo: PLines;
4861
  sli, slo: PLines;
4766
  D: Pointer;
4862
  //D: Pointer;
4767
begin
4863
begin
4768
  Result := True;
4864
  Result := True;
4769
  case BitCount of
4865
  case BitCount of
4770
    32, 16, 8, 4, 1:
4866
    32, 16, 8, 4, 1:
4771
      begin
4867
      begin
Line 5280... Line 5376...
5280
// Please, work to implement 32,16,8,4,2 BitCount's DIB                                           //
5376
// Please, work to implement 32,16,8,4,2 BitCount's DIB                                           //
5281
// Have fun - Mickey - Good job                                                                   //
5377
// Have fun - Mickey - Good job                                                                   //
5282
//--------------------------------------------------------------------------------------------------
5378
//--------------------------------------------------------------------------------------------------
5283
 
5379
 
5284
function TDIB.GetAlphaChannel: TDIB;
5380
function TDIB.GetAlphaChannel: TDIB;
-
 
5381
var
-
 
5382
  I: Integer;
5285
begin
5383
begin
5286
  RetAlphaChannel(Result);
5384
  RetAlphaChannel(Result);
-
 
5385
  if Result = nil then Exit;
-
 
5386
 
-
 
5387
  if FFreeList.Count > 0 then
-
 
5388
    for I := 0 to FFreeList.Count - 1 do
-
 
5389
      if FFreeList[I] = Result then Exit;
5287
 
5390
 
5288
  FFreeList.Add(Result);
5391
  FFreeList.Add(Result);
5289
end;
5392
end;
5290
 
5393
 
5291
procedure TDIB.SetAlphaChannel(const Value: TDIB);
5394
procedure TDIB.SetAlphaChannel(const Value: TDIB);
Line 5293... Line 5396...
5293
  if not AssignAlphaChannel(Value{$IFNDEF VER4UP}, False{$ENDIF}) then
5396
  if not AssignAlphaChannel(Value{$IFNDEF VER4UP}, False{$ENDIF}) then
5294
    Exception.Create('Cannot set alphachannel from DIB.');
5397
    Exception.Create('Cannot set alphachannel from DIB.');
5295
end;
5398
end;
5296
 
5399
 
5297
procedure TDIB.Fill(aColor: TColor);
5400
procedure TDIB.Fill(aColor: TColor);
-
 
5401
var
-
 
5402
  p: PRGBA;
-
 
5403
  y: Integer;
-
 
5404
  x: Integer;
5298
begin
5405
begin
5299
  Canvas.Brush.Color := aColor;
5406
  Canvas.Brush.Color := aColor;
5300
  Canvas.FillRect(ClientRect);
5407
  Canvas.FillRect(ClientRect);
-
 
5408
  if Self.BitCount = 32 then
-
 
5409
  begin
-
 
5410
    //fill alpha chanell too with $FF
-
 
5411
    for Y := 0 to Self.Height - 1 do
-
 
5412
    begin
-
 
5413
      p := Self.ScanLine[Y];
-
 
5414
      for X := 0 to Self.Width - 1 do
-
 
5415
      begin
-
 
5416
        p[X].rgbReserved := $FF
-
 
5417
      end;
-
 
5418
    end;
-
 
5419
  end;
5301
end;
5420
end;
5302
 
5421
 
5303
function TDIB.GetClientRect: TRect;
5422
function TDIB.GetClientRect: TRect;
5304
begin
5423
begin
5305
  Result := Bounds(0, 0, Width, Height);
5424
  Result := Bounds(0, 0, Width, Height);
Line 5525... Line 5644...
5525
end;
5644
end;
5526
 
5645
 
5527
procedure TDIB.CreateDIBFromBitmap(const Bitmap: TBitmap);
5646
procedure TDIB.CreateDIBFromBitmap(const Bitmap: TBitmap);
5528
var
5647
var
5529
  pf: Integer;
5648
  pf: Integer;
-
 
5649
  X, Y: Integer;
-
 
5650
  P: PLinesA;
-
 
5651
  q: PRGBA;
5530
begin
5652
begin
5531
  if Bitmap.PixelFormat = pf32bit then pf := 32 else pf := 24;
5653
  if Bitmap.PixelFormat = pf32bit then pf := 32 else pf := 24;
5532
  SetSize(Bitmap.Width, Bitmap.Height, pf); {always >=24}
5654
  SetSize(Bitmap.Width, Bitmap.Height, pf); {always >=24}
-
 
5655
  Canvas.Brush.Color := clWhite;
-
 
5656
  Canvas.FillRect(Bounds(0, 0, Width, Height));
5533
  Canvas.Draw(0, 0, Bitmap);
5657
  Canvas.Draw(0, 0, Bitmap);
-
 
5658
  //Note. Transparent background from bitmap is not drawed when is alphalayer active
-
 
5659
  if (pf = 32) {and (Bitmap.AlphaFormat <> afIgnored)} then
-
 
5660
  begin
-
 
5661
    for y := 0 to Bitmap.Height-1 do
-
 
5662
    begin
-
 
5663
      p := Bitmap.ScanLine[y]; //BGRA
-
 
5664
      q := Self.ScanLine[y]; //ARGB
-
 
5665
      for x := 0 to Width-1 do //copy only alphachannel
-
 
5666
        q[x].rgbReserved := P[x].A;
-
 
5667
    end;
-
 
5668
  end;
5534
end;
5669
end;
5535
 
5670
 
5536
function TDIB.CreateBitmapFromDIB: TBitmap;
5671
function TDIB.CreateBitmapFromDIB: TBitmap;
5537
//var
5672
var
-
 
5673
  ach: Boolean;
5538
//  X, Y: Integer;
5674
  X, Y: Integer;
-
 
5675
  P: PLinesA;
-
 
5676
  q: PRGBA;
5539
begin
5677
begin
-
 
5678
  ach := False;
5540
  Result := TBitmap.Create;
5679
  Result := TBitmap.Create;
5541
  if BitCount = 32 then
5680
  case BitCount of
5542
    Result.PixelFormat := pf32bit
5681
    32:
5543
  else if BitCount = 24 then
5682
      begin
5544
    Result.PixelFormat := pf24bit
5683
        Result.PixelFormat := pf32bit;
5545
  else if BitCount = 16 then
5684
        ach := HasAlphaChannel;
-
 
5685
      end;
5546
    Result.PixelFormat := pf16bit
5686
    24: Result.PixelFormat := pf24bit;
5547
  else if BitCount = 8 then
5687
    15: Result.PixelFormat := pf16bit;
5548
    Result.PixelFormat := pf8bit
5688
     8: Result.PixelFormat := pf8bit;
-
 
5689
  else
5549
  else Result.PixelFormat := pf24bit;
5690
    Result.PixelFormat := pf24bit;
-
 
5691
  end;
-
 
5692
 
5550
  Result.Width := Width;
5693
  Result.Width := Width;
5551
  Result.Height := Height;
5694
  Result.Height := Height;
5552
  Result.Canvas.Draw(0, 0, Self);
5695
  Result.Canvas.Draw(0, 0, Self);
-
 
5696
  if (BitCount = 32)  then
-
 
5697
  begin
-
 
5698
    if ach then
-
 
5699
    begin
-
 
5700
      {$IFDEF VER16UP}
-
 
5701
      Result.AlphaFormat := afDefined;
-
 
5702
      {$ENDIF}
5553
//  for Y := 0 to Height - 1 do
5703
      for y := 0 to Height-1 do
-
 
5704
      begin
-
 
5705
        p := Result.ScanLine[y]; //BGRA
-
 
5706
        q := Self.ScanLine[y]; //ARGB
5554
//    for X := 0 to Width - 1 do
5707
        for x := 0 to Width-1 do //copy only alphachannel
5555
//      Result.Canvas.Pixels[X, Y] := Canvas.Pixels[X, Y];
5708
          P[x].A := q[x].rgbReserved;
-
 
5709
      end;
-
 
5710
    end;
-
 
5711
  end;
5556
end;
5712
end;
5557
 
5713
 
5558
procedure TDIB.DrawTo(SrcDIB: TDIB; X, Y, Width, Height,
5714
procedure TDIB.DrawTo(SrcDIB: TDIB; X, Y, Width, Height,
5559
  SourceX, SourceY: Integer);
5715
  SourceX, SourceY: Integer);
5560
begin
5716
begin
Line 6502... Line 6658...
6502
  else Result := i;
6658
  else Result := i;
6503
end;
6659
end;
6504
 
6660
 
6505
procedure TDIB.DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended);
6661
procedure TDIB.DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended);
6506
var
6662
var
6507
  Top, Bottom, Left, Right, eww, nsw, fx, fy, wx, wy: Extended;
6663
  Top, Bottom, eww, nsw, fx, fy: Extended;
6508
  cAngle, sAngle: Double;
6664
  cAngle, sAngle: Double;
6509
  xDiff, yDiff, ifx, ify, px, py, ix, iy, x, y: Integer;
6665
  xDiff, yDiff, ifx, ify, px, py, ix, iy, x, y: Integer;
6510
  nw, ne, sw, se: TBGR;
6666
  nw, ne, sw, se: TBGR;
6511
  P1, P2, P3: Pbytearray;
6667
  P1, P2, P3: Pbytearray;
6512
begin
6668
begin
Line 7724... Line 7880...
7724
  //                    Filter functions
7880
  //                    Filter functions
7725
  //
7881
  //
7726
  // -----------------------------------------------------------------------------
7882
  // -----------------------------------------------------------------------------
7727
 
7883
 
7728
  // Hermite filter
7884
  // Hermite filter
7729
    function HermiteFilter(Value: Single): Single;
7885
    function HermiteFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7730
    begin
7886
    begin
7731
    // f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1
7887
    // f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1
7732
      if (Value < 0.0) then
7888
      if (Value < 0.0) then
7733
        Value := -Value;
7889
        Value := -Value;
7734
      if (Value < 1.0) then
7890
      if (Value < 1.0) then
Line 7739... Line 7895...
7739
 
7895
 
7740
    // Box filter
7896
    // Box filter
7741
    // a.k.a. "Nearest Neighbour" filter
7897
    // a.k.a. "Nearest Neighbour" filter
7742
    // anme: I have not been able to get acceptable
7898
    // anme: I have not been able to get acceptable
7743
    //       results with this filter for subsampling.
7899
    //       results with this filter for subsampling.
7744
    function BoxFilter(Value: Single): Single;
7900
    function BoxFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7745
    begin
7901
    begin
7746
      if (Value > -0.5) and (Value <= 0.5) then
7902
      if (Value > -0.5) and (Value <= 0.5) then
7747
        Result := 1.0
7903
        Result := 1.0
7748
      else
7904
      else
7749
        Result := 0.0;
7905
        Result := 0.0;
7750
    end;
7906
    end;
7751
 
7907
 
7752
    // Triangle filter
7908
    // Triangle filter
7753
    // a.k.a. "Linear" or "Bilinear" filter
7909
    // a.k.a. "Linear" or "Bilinear" filter
7754
    function TriangleFilter(Value: Single): Single;
7910
    function TriangleFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7755
    begin
7911
    begin
7756
      if (Value < 0.0) then
7912
      if (Value < 0.0) then
7757
        Value := -Value;
7913
        Value := -Value;
7758
      if (Value < 1.0) then
7914
      if (Value < 1.0) then
7759
        Result := 1.0 - Value
7915
        Result := 1.0 - Value
7760
      else
7916
      else
7761
        Result := 0.0;
7917
        Result := 0.0;
7762
    end;
7918
    end;
7763
 
7919
 
7764
    // Bell filter
7920
    // Bell filter
7765
    function BellFilter(Value: Single): Single;
7921
    function BellFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7766
    begin
7922
    begin
7767
      if (Value < 0.0) then
7923
      if (Value < 0.0) then
7768
        Value := -Value;
7924
        Value := -Value;
7769
      if (Value < 0.5) then
7925
      if (Value < 0.5) then
7770
        Result := 0.75 - Sqr(Value)
7926
        Result := 0.75 - Sqr(Value)
Line 7777... Line 7933...
7777
        else
7933
        else
7778
          Result := 0.0;
7934
          Result := 0.0;
7779
    end;
7935
    end;
7780
 
7936
 
7781
    // B-spline filter
7937
    // B-spline filter
7782
    function SplineFilter(Value: Single): Single;
7938
    function SplineFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7783
    var
7939
    var
7784
      tt: single;
7940
      tt: single;
7785
    begin
7941
    begin
7786
      if (Value < 0.0) then
7942
      if (Value < 0.0) then
7787
        Value := -Value;
7943
        Value := -Value;
Line 7800... Line 7956...
7800
          Result := 0.0;
7956
          Result := 0.0;
7801
    end;
7957
    end;
7802
 
7958
 
7803
    // Lanczos3 filter
7959
    // Lanczos3 filter
7804
    function Lanczos3Filter(Value: Single): Single;
7960
    function Lanczos3Filter(Value: Single): Single;
7805
      function SinC(Value: Single): Single;
7961
      function SinC(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7806
      begin
7962
      begin
7807
        if (Value <> 0.0) then
7963
        if (Value <> 0.0) then
7808
        begin
7964
        begin
7809
          Value := Value * Pi;
7965
          Value := Value * Pi;
7810
          Result := sin(Value) / Value
7966
          Result := sin(Value) / Value
Line 7819... Line 7975...
7819
        Result := SinC(Value) * SinC(Value / 3.0)
7975
        Result := SinC(Value) * SinC(Value / 3.0)
7820
      else
7976
      else
7821
        Result := 0.0;
7977
        Result := 0.0;
7822
    end;
7978
    end;
7823
 
7979
 
7824
    function MitchellFilter(Value: Single): Single;
7980
    function MitchellFilter(Value: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF}
7825
    const
7981
    const
7826
      B = (1.0 / 3.0);
7982
      B = (1.0 / 3.0);
7827
      C = (1.0 / 3.0);
7983
      C = (1.0 / 3.0);
7828
    var
7984
    var
7829
      tt: single;
7985
      tt: single;
Line 7856... Line 8012...
7856
  //                    Interpolator
8012
  //                    Interpolator
7857
  //
8013
  //
7858
  // -----------------------------------------------------------------------------
8014
  // -----------------------------------------------------------------------------
7859
  type
8015
  type
7860
    // Contributor for a pixel
8016
    // Contributor for a pixel
7861
    TContributor = record
8017
    TContributor = packed record
7862
      pixel: Integer; // Source pixel
8018
      pixel: Integer; // Source pixel
7863
      weight: single; // Pixel weight
8019
      weight: single; // Pixel weight
7864
    end;
8020
    end;
7865
 
8021
 
7866
    TContributorList = array[0..0] of TContributor;
8022
    TContributorList = array[0..0] of TContributor;
7867
    PContributorList = ^TContributorList;
8023
    PContributorList = ^TContributorList;
7868
 
8024
 
7869
    // List of source pixels contributing to a destination pixel
8025
    // List of source pixels contributing to a destination pixel
7870
    TCList = record
8026
    TCList = packed record
7871
      n: Integer;
8027
      n: Integer;
7872
      p: PContributorList;
8028
      p: PContributorList;
7873
    end;
8029
    end;
7874
 
8030
 
7875
    TCListList = array[0..0] of TCList;
8031
    TCListList = array[0..0] of TCList;
Line 7901... Line 8057...
7901
    rgb: TRGB;
8057
    rgb: TRGB;
7902
    color: TColorRGB;
8058
    color: TColorRGB;
7903
  {$IFDEF USE_SCANLINE}
8059
  {$IFDEF USE_SCANLINE}
7904
    SourceLine,
8060
    SourceLine,
7905
      DestLine: PRGBList;
8061
      DestLine: PRGBList;
7906
    SourcePixel,
8062
    //SourcePixel,
7907
      DestPixel: PColorRGB;
8063
      DestPixel: PColorRGB;
7908
    Delta,
8064
    Delta,
7909
      DestDelta: Integer;
8065
      DestDelta: Integer;
7910
  {$ENDIF}
8066
  {$ENDIF}
7911
    SrcWidth,
8067
    SrcWidth,
7912
      SrcHeight,
8068
      SrcHeight,
7913
      DstWidth,
8069
      DstWidth,
7914
      DstHeight: Integer;
8070
      DstHeight: Integer;
7915
 
8071
 
7916
    function Color2RGB(Color: TColor): TColorRGB;
8072
    function Color2RGB(Color: TColor): TColorRGB; {$IFDEF VER9UP}inline;{$ENDIF}
7917
    begin
8073
    begin
7918
      Result.r := Color and $000000FF;
8074
      Result.r := Color and $000000FF;
7919
      Result.g := (Color and $0000FF00) shr 8;
8075
      Result.g := (Color and $0000FF00) shr 8;
7920
      Result.b := (Color and $00FF0000) shr 16;
8076
      Result.b := (Color and $00FF0000) shr 16;
7921
    end;
8077
    end;
7922
 
8078
 
7923
    function RGB2Color(Color: TColorRGB): TColor;
8079
    function RGB2Color(Color: TColorRGB): TColor; {$IFDEF VER9UP}inline;{$ENDIF}
7924
    begin
8080
    begin
7925
      Result := Color.r or (Color.g shl 8) or (Color.b shl 16);
8081
      Result := Color.r or (Color.g shl 8) or (Color.b shl 16);
7926
    end;
8082
    end;
7927
 
8083
 
7928
  begin
8084
  begin
Line 8226... Line 8382...
8226
          rgb.b := 0;
8382
          rgb.b := 0;
8227
          // weight := 0.0;
8383
          // weight := 0.0;
8228
          for j := 0 to contrib^[i].n - 1 do
8384
          for j := 0 to contrib^[i].n - 1 do
8229
          begin
8385
          begin
8230
           {$IFDEF USE_SCANLINE}
8386
           {$IFDEF USE_SCANLINE}
8231
            color := PColorRGB(Integer(SourceLine) + contrib^[i].p^[j].pixel * Delta)^;
8387
            //color := PColorRGB(PByte(SourceLine) + contrib^[i].p^[j].pixel * Delta)^;
-
 
8388
            Move(Pointer(Integer(SourceLine) + contrib^[i].p^[j].pixel * Delta)^, Color, SizeOf(Color));
8232
           {$ELSE}
8389
           {$ELSE}
8233
            color := Color2RGB(Work.Canvas.Pixels[k, contrib^[i].p^[j].pixel]);
8390
            color := Color2RGB(Work.Canvas.Pixels[k, contrib^[i].p^[j].pixel]);
8234
           {$ENDIF}
8391
           {$ENDIF}
8235
            weight := contrib^[i].p^[j].weight;
8392
            weight := contrib^[i].p^[j].weight;
8236
            if (weight = 0.0) then
8393
            if (weight = 0.0) then
Line 8257... Line 8414...
8257
            color.b := 0
8414
            color.b := 0
8258
          else
8415
          else
8259
            color.b := round(rgb.b);
8416
            color.b := round(rgb.b);
8260
         {$IFDEF USE_SCANLINE}
8417
         {$IFDEF USE_SCANLINE}
8261
          DestPixel^ := color;
8418
          DestPixel^ := color;
-
 
8419
          {$IFDEF WIN64}
-
 
8420
          inc(PByte(DestPixel), DestDelta);
-
 
8421
          {$ELSE}
8262
          inc(Integer(DestPixel), DestDelta);
8422
          inc(Integer(DestPixel), DestDelta);
-
 
8423
          {$ENDIF}
8263
         {$ELSE}
8424
         {$ELSE}
8264
          Dst.Canvas.Pixels[k, i] := RGB2Color(color);
8425
          Dst.Canvas.Pixels[k, i] := RGB2Color(color);
8265
         {$ENDIF}
8426
         {$ENDIF}
8266
        end;
8427
        end;
8267
       {$IFDEF USE_SCANLINE}
8428
       {$IFDEF USE_SCANLINE}
Line 8398... Line 8559...
8398
  BB1.Free;
8559
  BB1.Free;
8399
  BB2.Free;
8560
  BB2.Free;
8400
end;
8561
end;
8401
 
8562
 
8402
{ procedure for special purpose }
8563
{ procedure for special purpose }
8403
 
8564
(*
8404
procedure TDIB.FadeOut(DIB2: TDIB; Step: Byte);
8565
procedure TDIB.FadeOut(DIB2: TDIB; Step: Byte);
8405
var
8566
var
8406
  P1, P2: PByteArray;
8567
  P1, P2: PByteArray;
8407
  W, H: Integer;
8568
  W, H: Integer;
8408
begin
8569
begin
Line 8433... Line 8594...
8433
    JNZ @@1
8594
    JNZ @@1
8434
    POP EDI
8595
    POP EDI
8435
    POP ESI
8596
    POP ESI
8436
  end;
8597
  end;
8437
end;
8598
end;
-
 
8599
*)
-
 
8600
procedure TDIB.FadeOut(DIB2: TDIB; Step: Byte);
-
 
8601
var
-
 
8602
  P1, P2: PByteArray;
-
 
8603
  W, H, i: Integer;
-
 
8604
begin
-
 
8605
  P1 := ScanLine[DIB2.Height - 1];
-
 
8606
  P2 := DIB2.ScanLine[DIB2.Height - 1];
-
 
8607
  W := WidthBytes;
-
 
8608
  H := Height;
-
 
8609
  for i := 0 to W * H - 1 do
-
 
8610
  begin
-
 
8611
    if P1[i] < Step then P2[i] := P1[i]
-
 
8612
    else P2[i] := Step;
-
 
8613
  end;
-
 
8614
end;
8438
 
8615
 
8439
procedure TDIB.DoZoom(DIB2: TDIB; ZoomRatio: Real);
8616
procedure TDIB.DoZoom(DIB2: TDIB; ZoomRatio: Real);
8440
var
8617
var
8441
  P1, P2: PByteArray;
8618
  P1, P2: PByteArray;
8442
  W, H: Integer;
8619
  W, H: Integer;
Line 8499... Line 8676...
8499
    begin
8676
    begin
8500
      P2[x] := (P1[x] + P1[x - 1] + P1[x + 1] + P1[x + W] + P1[x - W]) div 5;
8677
      P2[x] := (P1[x] + P1[x - 1] + P1[x + 1] + P1[x + W] + P1[x - W]) div 5;
8501
    end;
8678
    end;
8502
  end;
8679
  end;
8503
end;
8680
end;
8504
 
8681
(*
8505
procedure TDIB.FadeIn(DIB2: TDIB; Step: Byte);
8682
procedure TDIB.FadeIn(DIB2: TDIB; Step: Byte);
8506
var
8683
var
8507
  P1, P2: PByteArray;
8684
  P1, P2: PByteArray;
8508
  W, H: Integer;
8685
  W, H: Integer;
8509
begin
8686
begin
Line 8534... Line 8711...
8534
    JNZ @@1
8711
    JNZ @@1
8535
    POP EDI
8712
    POP EDI
8536
    POP ESI
8713
    POP ESI
8537
  end;
8714
  end;
8538
end;
8715
end;
-
 
8716
*)
-
 
8717
procedure TDIB.FadeIn(DIB2: TDIB; Step: Byte);
-
 
8718
var
-
 
8719
  P1, P2: PByteArray;
-
 
8720
  W, H, i: Integer;
-
 
8721
begin
-
 
8722
  P1 := ScanLine[DIB2.Height - 1];
-
 
8723
  P2 := DIB2.ScanLine[DIB2.Height - 1];
-
 
8724
  W := WidthBytes;
-
 
8725
  H := Height;
-
 
8726
  for i := 0 to W * H - 1 do
-
 
8727
  begin
-
 
8728
    if P1[i] > Step then P2[i] := P1[i]
-
 
8729
    else P2[i] := Step;
-
 
8730
  end;
-
 
8731
end;
8539
 
8732
 
-
 
8733
(*
8540
procedure TDIB.FillDIB8(Color: Byte);
8734
procedure TDIB.FillDIB8(Color: Byte);
8541
var
8735
var
8542
  P: PByteArray;
8736
  P: PByteArray;
8543
  W, H: Integer;
8737
  W, H: Integer;
8544
begin
8738
begin
Line 8559... Line 8753...
8559
    DEC ECX
8753
    DEC ECX
8560
    JNZ @@1
8754
    JNZ @@1
8561
    POP ESI
8755
    POP ESI
8562
  end;
8756
  end;
8563
end;
8757
end;
-
 
8758
*)
-
 
8759
 
-
 
8760
procedure TDIB.FillDIB8(Color: Byte);
-
 
8761
var
-
 
8762
  P: PByteArray;
-
 
8763
  W, H, I: Integer;
-
 
8764
begin
-
 
8765
  P := ScanLine[Height - 1];
-
 
8766
  W := WidthBytes;
-
 
8767
  H := Height;
-
 
8768
  for I := 0 to W * H - 1 do
-
 
8769
    P[I] := Color;
-
 
8770
end;
-
 
8771
 
8564
 
8772
 
8565
procedure TDIB.DoRotate(DIB1: TDIB; cX, cY, Angle: Integer);
8773
procedure TDIB.DoRotate(DIB1: TDIB; cX, cY, Angle: Integer);
8566
type
8774
type
8567
  T3Byte = array[0..2] of Byte;
8775
  T3Byte = array[0..2] of Byte;
8568
  P3ByteArray = ^T3ByteArray;
8776
  P3ByteArray = ^T3ByteArray;
Line 9184... Line 9392...
9184
      P^[X].R := (R * LM + P^[X].R * LR) shr 16;
9392
      P^[X].R := (R * LM + P^[X].R * LR) shr 16;
9185
      Inc(dxi, dydxi); // next point
9393
      Inc(dxi, dydxi); // next point
9186
    end;
9394
    end;
9187
  end;
9395
  end;
9188
end;
9396
end;
9189
 
9397
(*
9190
function TDIB.GetColorBetween(StartColor, EndColor: TColor; Pointvalue,
9398
function TDIB.GetColorBetween(StartColor, EndColor: TColor; Pointvalue,
9191
  FromPoint, ToPoint: Extended): TColor;
9399
  FromPoint, ToPoint: Extended): TColor;
9192
var F: Extended; r1, r2, r3, g1, g2, g3, b1, b2, b3: Byte;
9400
var F: Extended; r1, r2, r3, g1, g2, g3, b1, b2, b3: Byte;
9193
  function CalcColorBytes(fb1, fb2: Byte): Byte;
9401
  function CalcColorBytes(fb1, fb2: Byte): Byte;
9194
  begin
9402
  begin
Line 9249... Line 9457...
9249
    mov AL, R3
9457
    mov AL, R3
9250
  @@Exit:
9458
  @@Exit:
9251
    mov @result, EAX
9459
    mov @result, EAX
9252
  end;
9460
  end;
9253
end;
9461
end;
-
 
9462
*)
-
 
9463
function TDIB.GetColorBetween(StartColor, EndColor: TColor; Pointvalue, FromPoint, ToPoint: Extended): TColor;
-
 
9464
var
-
 
9465
  F: Extended;
-
 
9466
  r1, g1, b1, r2, g2, b2, r3, g3, b3: Byte;
-
 
9467
 
-
 
9468
  function CalcColorBytes(const factor: Extended; const fb1, fb2: Byte): Byte; {$IFDEF VER9UP}inline;{$ENDIF}
-
 
9469
  begin
-
 
9470
    Result := fb1;
-
 
9471
    if fb1 < fb2 then Result := fb1 + Trunc(factor * (fb2 - fb1));
-
 
9472
    if fb1 > fb2 then Result := fb1 - Trunc(factor * (fb1 - fb2));
-
 
9473
  end;
-
 
9474
 
-
 
9475
  procedure GetRGB(const AColor: TColor; var R, G, B: Byte); {$IFDEF VER9UP}inline;{$ENDIF}
-
 
9476
  begin
-
 
9477
    R := AColor and $FF;
-
 
9478
    G := (AColor shr 8) and $FF;
-
 
9479
    B := (AColor shr 16) and $FF;
-
 
9480
  end;
-
 
9481
 
-
 
9482
begin
-
 
9483
  if Pointvalue <= FromPoint then
-
 
9484
  begin
-
 
9485
    Result := StartColor;
-
 
9486
    Exit;
-
 
9487
  end;
-
 
9488
  if Pointvalue >= ToPoint then
-
 
9489
  begin
-
 
9490
    Result := EndColor;
-
 
9491
    Exit;
-
 
9492
  end;
-
 
9493
 
-
 
9494
  F := (Pointvalue - FromPoint) / (ToPoint - FromPoint);
-
 
9495
 
-
 
9496
  GetRGB(StartColor, r1, g1, b1);
-
 
9497
//  r1 := StartColor and $FF;
-
 
9498
//  g1 := (StartColor shr 8) and $FF;
-
 
9499
//  b1 := (StartColor shr 16) and $FF;
-
 
9500
  GetRGB(StartColor, r2, g2, b2);
-
 
9501
//  r2 := EndColor and $FF;
-
 
9502
//  g2 := (EndColor shr 8) and $FF;
-
 
9503
//  b2 := (EndColor shr 16) and $FF;
-
 
9504
 
-
 
9505
  r3 := CalcColorBytes(F, r1, r2);
-
 
9506
  g3 := CalcColorBytes(F, g1, g2);
-
 
9507
  b3 := CalcColorBytes(F, b1, b2);
-
 
9508
 
-
 
9509
  Result := (b3 shl 16) or (g3 shl 8) or r3;
-
 
9510
end;
9254
 
9511
 
9255
procedure TDIB.ColoredLine(const iStart, iEnd: TPoint; iColorStyle: TColorLineStyle;
9512
procedure TDIB.ColoredLine(const iStart, iEnd: TPoint; iColorStyle: TColorLineStyle;
9256
  iGradientFrom, iGradientTo: TColor; iPixelGeometry: TColorLinePixelGeometry; iRadius: Word);
9513
  iGradientFrom, iGradientTo: TColor; iPixelGeometry: TColorLinePixelGeometry; iRadius: Word);
9257
var
9514
var
9258
  tempColor: TColor;
9515
  tempColor: TColor;
Line 9457... Line 9714...
9457
      Inc(d, diag_inc);
9714
      Inc(d, diag_inc);
9458
    end
9715
    end
9459
  end
9716
  end
9460
end {Line};
9717
end {Line};
9461
 
9718
 
9462
procedure TDIB.DoNovaEffect(sr, sg, sb, cx, cy, radius,
9719
procedure TDIB.DoNovaEffect(const sr, sg, sb, cx, cy, radius,
9463
  nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent);
9720
  nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent);
9464
// Copyright (c) 2000 by Keith Murray (kmurray@hotfreeware.com)
9721
// Copyright (c) 2000 by Keith Murray (kmurray@hotfreeware.com)
9465
// All rights reserved.
9722
// All rights reserved.
9466
// Adapted for DIB by JB.
9723
// Adapted for DIB by JB.
9467
type
9724
type
9468
  PByteArray = ^TByteArray;
9725
  PByteArray = ^TByteArray;
9469
  TByteArray = array[0..32767] of Byte;
9726
  TByteArray = array[0..32767] of Byte;
9470
  PDoubleArray = ^TDoubleArray;
9727
  PDoubleArray = ^TDoubleArray;
9471
  TDoubleArray = array[0..32767] of Double;
9728
  TDoubleArray = array[0..0] of Double;
9472
  PIntegerArray = ^TIntegerArray;
9729
  PIntegerArray = ^TIntegerArray;
9473
  TIntegerArray = array[0..32767] of Integer;
9730
  TIntegerArray = array[0..0] of Integer;
9474
type
9731
type
9475
  TProgressEvent = procedure(progress: Integer; message: string;
9732
  TProgressEvent = procedure(progress: Integer; message: string;
9476
    var cancel: Boolean) of object;
9733
    var cancel: Boolean) of object;
9477
const
9734
const
9478
  M_PI = 3.14159265358979323846;
9735
  M_PI = 3.14159265358979323846;
9479
  RAND_MAX = 2147483647;
9736
  RAND_MAX = 2147483647;
9480
 
9737
 
9481
  function Gauss: double;
9738
  function Gauss(const randgauss: Integer): double; {$IFDEF VER9UP}inline;{$ENDIF}
9482
  const magnitude = 6;
9739
  const magnitude = 6;
9483
  var
9740
  var
9484
    sum: double;
9741
    sum: double;
9485
    i: Integer;
9742
    i: Integer;
9486
  begin
9743
  begin
Line 9488... Line 9745...
9488
    for i := 1 to magnitude do
9745
    for i := 1 to magnitude do
9489
      sum := sum + (randgauss / 2147483647);
9746
      sum := sum + (randgauss / 2147483647);
9490
    result := sum / magnitude;
9747
    result := sum / magnitude;
9491
  end;
9748
  end;
9492
 
9749
 
9493
  function Clamp(i, l, h: double): double; {$IFDEF VER9UP}inline;{$ENDIF}
9750
  function Clamp(const i, l, h: double): double; {$IFDEF VER9UP}inline;{$ENDIF}
9494
  begin
9751
  begin
9495
    if i < l then
9752
    if i < l then
9496
      result := l
9753
      result := l
9497
    else
9754
    else
9498
      if i > h then
9755
      if i > h then
9499
        result := h
9756
        result := h
9500
      else
9757
      else
9501
        result := i;
9758
        result := i;
9502
  end;
9759
  end;
9503
 
9760
 
9504
  function IClamp(i, l, h: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
9761
  function IClamp(const i, l, h: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
9505
  begin
9762
  begin
9506
    if i < l then
9763
    if i < l then
9507
      result := l
9764
      result := l
9508
    else if i > h then
9765
    else if i > h then
9509
      result := h
9766
      result := h
9510
    else result := i;
9767
    else result := i;
9511
  end;
9768
  end;
9512
 
-
 
-
 
9769
  {$IFNDEF VER9UP}
9513
  procedure rgb_to_hsl(r, g, b: Double; var h, s, l: Double); {$IFDEF VER9UP}inline;{$ENDIF}
9770
  procedure rgb_to_hsl(const r, g, b: Double; var h, s, l: Double); {$IFDEF VER9UP}inline;{$ENDIF}
9514
  {$IFNDEF VER4UP}
9771
  {$IFNDEF VER4UP}
9515
    function Max(a, b: Double): Double;
9772
    function Max(a, b: Double): Double;
9516
    begin
9773
    begin
9517
      Result := a; if b > a then Result := b;
9774
      Result := a; if b > a then Result := b;
9518
    end;
9775
    end;
Line 9620... Line 9877...
9620
            r := v; g := m; b := mid2;
9877
            r := v; g := m; b := mid2;
9621
          end;
9878
          end;
9622
      end;
9879
      end;
9623
    end;
9880
    end;
9624
  end;
9881
  end;
-
 
9882
  {$ELSE}
-
 
9883
  procedure rgb_to_hsl(const r, g, b: Double; var h, s, l: Double); {$IFDEF VER9UP}inline;{$ENDIF}
-
 
9884
  var
-
 
9885
    h0, s0, l0: Word;
-
 
9886
  begin  //procedure ColorRGBToHLS(clrRGB: TColorRef; var Hue, Luminance, Saturation: Word);
-
 
9887
    GraphUtil.ColorRGBToHLS(RGB(Trunc(r),Trunc(g),Trunc(b)), h0, s0, l0);
-
 
9888
    h := h0;
-
 
9889
    s := s0;
-
 
9890
    l := l0;
-
 
9891
  end;
-
 
9892
 
-
 
9893
  procedure hsl_to_rgb(h, sl, l: Double; var r, g, b: Double); {$IFDEF VER9UP}inline;{$ENDIF}
-
 
9894
  var X: TColorRef;
-
 
9895
  begin //function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef;
-
 
9896
    X := GraphUtil.ColorHLSToRGB(Trunc(h), Trunc(l), Trunc(sl));
-
 
9897
    r := GetRValue(X);
-
 
9898
    g := GetGValue(X);
-
 
9899
    b := GetBValue(X);
-
 
9900
  end;
-
 
9901
  {$ENDIF}
9625
 
9902
 
9626
var
9903
var
9627
  src_row, dest_row: PByte;
9904
  src_row, dest_row: PByte;
9628
  src, dest: PByteArray;
9905
  src, dest: PByteArray;
9629
  color, colors: array[0..3] of Integer;
9906
  color, colors: array[0..3] of Integer;
9630
  SpokeColor: PIntegerArray;
9907
  SpokeColor: PIntegerArray;
9631
  spoke: PDoubleArray;
9908
  spoke: PDoubleArray;
9632
  x1, y1, x2, y2, row, col, x, y, alpha, has_alpha, bpp, progress, max_progress, xc, yc, i, j: Integer;
9909
  x2, row, col, x, y, alpha, has_alpha, bpp, xc, yc, i, j: Integer;
9633
  u, v, l, l0, w, w1, c, nova_alpha, src_alpha, new_alpha, compl_ratio, ratio, r, g, b, h, s, lu, SpokeCol: Double;
9910
  u, v, l, l0, w, w1, c, nova_alpha, new_alpha, compl_ratio, ratio, r, g, b, h, s, lu, SpokeCol: Double;
9634
  dstDIB: TDIB;
9911
  dstDIB: TDIB;
9635
begin
9912
begin
9636
  colors[0] := sr;
9913
  colors[0] := sr;
9637
  colors[1] := sg;
9914
  colors[1] := sg;
9638
  colors[2] := sb;
9915
  colors[2] := sb;
9639
  new_alpha := 0;
9916
  new_alpha := 0;
9640
 
9917
 
9641
  GetMem(spoke, NSpokes * sizeof(Double));
9918
  GetMem(spoke, NSpokes * sizeof(Double));
9642
  GetMem(spokecolor, NSpokes * sizeof(Integer) * 3);
9919
  GetMem(spokecolor, NSpokes * sizeof(Integer) * 3);
9643
  dstDIB := TDIB.Create;
9920
  dstDIB := TDIB.Create;
-
 
9921
  try
9644
  dstDIB.Assign(Self);
9922
    dstDIB.Assign(Self);
9645
  dstDIB.Canvas.Brush.Color := clBlack;
9923
    dstDIB.Canvas.Brush.Color := clBlack;
9646
  dstDIB.Canvas.FillRect(dstDIB.Canvas.ClipRect);
9924
    dstDIB.Canvas.FillRect(dstDIB.Canvas.ClipRect);
9647
  try
-
 
-
 
9925
    //         R                  G                  B
9648
    rgb_to_hsl(colors[0] / 255.0, colors[1] / 255.0, colors[2] / 255.0, h, s, lu);
9926
    rgb_to_hsl(colors[0] / 255.0, colors[1] / 255.0, colors[2] / 255.0, h, s, lu);
9649
 
9927
 
9650
    for i := 0 to NSpokes - 1 do
9928
    for i := 0 to NSpokes - 1 do
9651
    begin
9929
    begin
9652
      spoke[i] := gauss;
9930
      spoke[i] := gauss(randgauss);
9653
      h := h + randomhue / 360.0 * ({Random(RAND_MAX)}RandomSpok / RAND_MAX - 0.5);
9931
      h := h + randomhue / 360.0 * ({Random(RAND_MAX)}RandomSpok / RAND_MAX - 0.5);
9654
      if h < 0 then
9932
      if h < 0 then
9655
        h := h + 1.0
9933
        h := h + 1.0
9656
      else if h > 1.0 then
9934
      else if h > 1.0 then
9657
        h := h - 1.0;
9935
        h := h - 1.0;
Line 9666... Line 9944...
9666
    l0 := (x2 - xc) / 4 + 1;
9944
    l0 := (x2 - xc) / 4 + 1;
9667
    bpp := Self.BitCount div 8;
9945
    bpp := Self.BitCount div 8;
9668
    has_alpha := 0;
9946
    has_alpha := 0;
9669
    alpha := bpp;
9947
    alpha := bpp;
9670
    y := 0;
9948
    y := 0;
9671
    for row := 0 to Self.Height - 1 do begin
9949
    for row := 0 to Self.Height - 1 do
-
 
9950
    begin
9672
      src_row := Self.ScanLine[row];
9951
      src_row := Self.ScanLine[row];
9673
      dest_row := dstDIB.ScanLine[row];
9952
      dest_row := dstDIB.ScanLine[row];
9674
      src := Pointer(src_row);
9953
      src := Pointer(src_row);
9675
      dest := Pointer(dest_row);
9954
      dest := Pointer(dest_row);
9676
      x := 0;
9955
      x := 0;
9677
      for col := 0 to Self.Width - 1 do begin
9956
      for col := 0 to Self.Width - 1 do
-
 
9957
      begin
9678
        u := (x - xc) / radius;
9958
        u := (x - xc) / radius;
9679
        v := (y - yc) / radius;
9959
        v := (y - yc) / radius;
9680
        l := sqrt((u * u) + (v * v));
9960
        l := sqrt(sqr(u) + sqr(v));
9681
        c := (arctan2(u, v) / (2 * M_PI) + 0.51) * NSpokes;
9961
        c := (arctan2(u, v) / (2 * M_PI) + 0.51) * NSpokes;
9682
        i := floor(c);
9962
        i := floor(c);
9683
        c := c - i;
9963
        c := c - i;
9684
        i := i mod NSpokes;
9964
        i := i mod NSpokes;
9685
        w1 := spoke[i] * (1 - c) + spoke[(i + 1) mod NSpokes] * c;
9965
        w1 := spoke[i] * (1 - c) + spoke[(i + 1) mod NSpokes] * c;
Line 9696... Line 9976...
9696
          else
9976
          else
9697
            color[j] := Trunc(src[j] * compl_ratio + spokecol * ratio);
9977
            color[j] := Trunc(src[j] * compl_ratio + spokecol * ratio);
9698
          color[j] := Trunc(color[j] + 255 * Clamp(w1 * w, 0.0, 1.0));
9978
          color[j] := Trunc(color[j] + 255 * Clamp(w1 * w, 0.0, 1.0));
9699
          dest[j] := IClamp(color[j], 0, 255);
9979
          dest[j] := IClamp(color[j], 0, 255);
9700
        end;
9980
        end;
-
 
9981
        {$IFDEF WIN64}
-
 
9982
        Inc(PByte(src), bpp);
-
 
9983
        Inc(PBYTE(dest), bpp);
-
 
9984
        {$ELSE}
9701
        inc(Integer(src), bpp);
9985
        Inc(Integer(src), bpp);
9702
        inc(Integer(dest), bpp);
9986
        Inc(Integer(dest), bpp);
-
 
9987
        {$ENDIF}
9703
        inc(x);
9988
        Inc(x);
9704
      end;
9989
      end;
9705
      inc(y);
9990
      Inc(y);
9706
    end;
9991
    end;
9707
  finally
-
 
9708
    Self.Assign(dstDIB);
9992
    Self.Assign(dstDIB);
-
 
9993
  finally
9709
    dstDIB.Free;
9994
    dstDIB.Free;
9710
    FreeMem(Spoke);
9995
    FreeMem(Spoke);
9711
    FreeMem(SpokeColor);
9996
    FreeMem(SpokeColor);
9712
  end;
9997
  end;
9713
end;
9998
end;
Line 9764... Line 10049...
9764
end;
10049
end;
9765
 
10050
 
9766
procedure TDIB.SephiaEffect(Depth: Integer{$IFDEF VER4UP} = 20{$ENDIF});
10051
procedure TDIB.SephiaEffect(Depth: Integer{$IFDEF VER4UP} = 20{$ENDIF});
9767
{Note: when depth parameter set to 0 will produce black and white picture only}
10052
{Note: when depth parameter set to 0 will produce black and white picture only}
9768
var
10053
var
9769
  color, color2: longint;
10054
  color, color2: LongInt;
9770
  r, g, b, rr, gg: byte;
10055
  r, g, b, rr, gg: byte;
9771
  h, w: Integer;
10056
  h, w: Integer;
9772
  p0: pbytearray;
10057
  p0: PByteArray;
9773
  x, y: Integer;
10058
  x, y: Integer;
9774
begin
10059
begin
9775
  if Self.BitCount = 24 then
10060
  if Self.BitCount = 24 then
9776
  begin
10061
  begin
9777
    Self.DoGrayScale;
10062
    Self.DoGrayScale;