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; |