Rev 1 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1 | Rev 4 | ||
---|---|---|---|
Line -... | Line 1... | ||
- | 1 | {*******************************************************} |
|
- | 2 | { } |
|
- | 3 | { DIB and PAINTBOX componets } |
|
- | 4 | { } |
|
- | 5 | { Copyright (C) 1997-2000 Hiroyuki Hori } |
|
- | 6 | { base components and effects } |
|
- | 7 | { Copyright (C) 2000 Keith Murray } |
|
- | 8 | { supernova effect } |
|
- | 9 | { Copyright (C) 2000 Michel Hibon } |
|
- | 10 | { new special effects added for DIB } |
|
- | 11 | { Copyright (C) 2001 Joakim Back } |
|
- | 12 | { conFusion effects (as DxFusion) } |
|
- | 13 | { Copyright (C) 2003 Babak Sateli } |
|
- | 14 | { 24-bit DIB effect as supplement ones } |
|
- | 15 | { Copyright (C) 2004-2012 Jaro Benes } |
|
- | 16 | { 32-bit DIB effect with alphachannel } |
|
- | 17 | { direct works with texture buffer } |
|
- | 18 | { modified and adapted all adopted functions } |
|
- | 19 | { } |
|
- | 20 | {*******************************************************} |
|
- | 21 | ||
1 | unit DIB; |
22 | unit DIB; |
2 | 23 | ||
3 | interface |
24 | interface |
4 | 25 | ||
5 | {$INCLUDE DelphiXcfg.inc} |
26 | {$INCLUDE DelphiXcfg.inc} |
- | 27 | {$DEFINE USE_SCANLINE} |
|
6 | 28 | ||
7 | uses |
29 | uses |
8 | Windows, SysUtils, Classes, Graphics, Controls; |
30 | Windows, SysUtils, Classes, Graphics, Controls, |
- | 31 | {$IFDEF VER17UP} Types, UITypes,{$ENDIF} |
|
- | 32 | Math; |
|
9 | 33 | ||
10 | type |
34 | type |
- | 35 | TColorLineStyle = (csSolid, csGradient, csRainbow); |
|
- | 36 | TColorLinePixelGeometry = (pgPoint, pgCircular, pgRectangular); |
|
- | 37 | PRGBQuads = ^TRGBQuads; |
|
11 | TRGBQuads = array[0..255] of TRGBQuad; |
38 | TRGBQuads = array[0..255] of TRGBQuad; |
12 | 39 | ||
13 | TPaletteEntries = array[0..255] of TPaletteEntry; |
40 | TPaletteEntries = array[0..255] of TPaletteEntry; |
14 | 41 | ||
15 | PBGR = ^TBGR; |
42 | PBGR = ^TBGR; |
16 | TBGR = packed record |
43 | TBGR = packed record |
17 | B, G, R: Byte; |
44 | B, G, R: Byte; |
18 | end; |
45 | end; |
19 | 46 | ||
- | 47 | { Added this type for New SPecial Effect } |
|
- | 48 | TFilter = array[0..2, 0..2] of SmallInt; |
|
- | 49 | TLines = array[0..0] of TBGR; |
|
- | 50 | PLines = ^TLines; |
|
- | 51 | TBytes = array[0..0] of Byte; |
|
- | 52 | PBytes = ^TBytes; |
|
- | 53 | TPBytes = array[0..0] of PBytes; |
|
- | 54 | PPBytes = ^TPBytes; |
|
- | 55 | { End of type's } |
|
- | 56 | ||
20 | PArrayBGR = ^TArrayBGR; |
57 | PArrayBGR = ^TArrayBGR; |
21 | TArrayBGR = array[0..10000] of TBGR; |
58 | TArrayBGR = array[0..10000] of TBGR; |
22 | 59 | ||
23 | PArrayByte = ^TArrayByte; |
60 | PArrayByte = ^TArrayByte; |
24 | TArrayByte = array[0..10000] of Byte; |
61 | TArrayByte = array[0..10000] of Byte; |
Line 27... | Line 64... | ||
27 | TArrayWord = array[0..10000] of Word; |
64 | TArrayWord = array[0..10000] of Word; |
28 | 65 | ||
29 | PArrayDWord = ^TArrayDWord; |
66 | PArrayDWord = ^TArrayDWord; |
30 | TArrayDWord = array[0..10000] of DWord; |
67 | TArrayDWord = array[0..10000] of DWord; |
31 | 68 | ||
32 | { TDIB } |
69 | { TDIBPixelFormat } |
33 | 70 | ||
34 | TDIBPixelFormat = record |
71 | TDIBPixelFormat = record |
35 | RBitMask, GBitMask, BBitMask: DWORD; |
72 | RBitMask, GBitMask, BBitMask: DWORD; |
36 | RBitCount, GBitCount, BBitCount: DWORD; |
73 | RBitCount, GBitCount, BBitCount: DWORD; |
37 | RShift, GShift, BShift: DWORD; |
74 | RShift, GShift, BShift: DWORD; |
38 | RBitCount2, GBitCount2, BBitCount2: DWORD; |
75 | RBitCount2, GBitCount2, BBitCount2: DWORD; |
39 | end; |
76 | end; |
40 | 77 | ||
- | 78 | { TDIBSharedImage } |
|
- | 79 | ||
41 | TDIBSharedImage = class(TSharedImage) |
80 | TDIBSharedImage = class(TSharedImage) |
42 | private |
81 | private |
43 | FBitCount: Integer; |
82 | FBitCount: Integer; |
44 | FBitmapInfo: PBitmapInfo; |
83 | FBitmapInfo: PBitmapInfo; |
45 | FBitmapInfoSize: Integer; |
84 | FBitmapInfoSize: Integer; |
Line 62... | Line 101... | ||
62 | FWidth: Integer; |
101 | FWidth: Integer; |
63 | FWidthBytes: Integer; |
102 | FWidthBytes: Integer; |
64 | constructor Create; |
103 | constructor Create; |
65 | procedure NewImage(AWidth, AHeight, ABitCount: Integer; |
104 | procedure NewImage(AWidth, AHeight, ABitCount: Integer; |
66 | const PixelFormat: TDIBPixelFormat; const ColorTable: TRGBQuads; MemoryImage, Compressed: Boolean); |
105 | const PixelFormat: TDIBPixelFormat; const ColorTable: TRGBQuads; MemoryImage, Compressed: Boolean); |
67 | procedure Duplicate(Source: TDIBSharedImage; MemoryImage: Boolean); |
106 | procedure Duplicate(Source: TDIBSharedImage; MemoryImage: Boolean); {$IFDEF VER9UP}inline;{$ENDIF} |
68 | procedure Compress(Source: TDIBSharedImage); |
107 | procedure Compress(Source: TDIBSharedImage); |
69 | procedure Decompress(Source: TDIBSharedImage; MemoryImage: Boolean); |
108 | procedure Decompress(Source: TDIBSharedImage; MemoryImage: Boolean); |
70 | procedure ReadData(Stream: TStream; MemoryImage: Boolean); |
109 | procedure ReadData(Stream: TStream; MemoryImage: Boolean); |
71 | function GetPalette: THandle; |
110 | function GetPalette: THandle; |
72 | procedure SetColorTable(const Value: TRGBQuads); |
111 | procedure SetColorTable(const Value: TRGBQuads); |
Line 74... | Line 113... | ||
74 | procedure FreeHandle; override; |
113 | procedure FreeHandle; override; |
75 | public |
114 | public |
76 | destructor Destroy; override; |
115 | destructor Destroy; override; |
77 | end; |
116 | end; |
78 | 117 | ||
- | 118 | { TFilterTypeResample } |
|
- | 119 | ||
- | 120 | TFilterTypeResample = (ftrBox, ftrTriangle, ftrHermite, ftrBell, ftrBSpline, |
|
- | 121 | ftrLanczos3, ftrMitchell); |
|
- | 122 | ||
- | 123 | TDistortType = (dtFast, dtSlow); |
|
- | 124 | {DXFusion effect type} |
|
- | 125 | TFilterMode = (fmNormal, fmMix50, fmMix25, fmMix75); |
|
- | 126 | ||
- | 127 | { TLightSource } |
|
- | 128 | ||
- | 129 | TLightSource = record |
|
- | 130 | X, Y: Integer; |
|
- | 131 | Size1, Size2: Integer; |
|
- | 132 | Color: TColor; |
|
- | 133 | end; |
|
- | 134 | ||
- | 135 | { TLightArray } |
|
- | 136 | ||
- | 137 | TLightArray = array{$IFNDEF VER4UP} [0..0]{$ENDIF} of TLightsource; |
|
- | 138 | ||
- | 139 | { TMatrixSetting } |
|
- | 140 | ||
- | 141 | TMatrixSetting = array[0..9] of Integer; |
|
- | 142 | ||
- | 143 | { TDIB } |
|
- | 144 | ||
79 | TDIB = class(TGraphic) |
145 | TDIB = class(TGraphic) |
80 | private |
146 | private |
81 | FCanvas: TCanvas; |
147 | FCanvas: TCanvas; |
82 | FImage: TDIBSharedImage; |
148 | FImage: TDIBSharedImage; |
83 | 149 | ||
Line 94... | Line 160... | ||
94 | FPBits: Pointer; |
160 | FPBits: Pointer; |
95 | FSize: Integer; |
161 | FSize: Integer; |
96 | FTopPBits: Pointer; |
162 | FTopPBits: Pointer; |
97 | FWidth: Integer; |
163 | FWidth: Integer; |
98 | FWidthBytes: Integer; |
164 | FWidthBytes: Integer; |
- | 165 | FLUTDist: array[0..255, 0..255] of Integer; |
|
- | 166 | LG_COUNT: Integer; |
|
- | 167 | LG_DETAIL: Integer; |
|
- | 168 | FFreeList: TList; |
|
99 | procedure AllocHandle; |
169 | procedure AllocHandle; |
100 | procedure CanvasChanging(Sender: TObject); |
170 | procedure CanvasChanging(Sender: TObject); |
101 | procedure Changing(MemoryImage: Boolean); |
171 | procedure Changing(MemoryImage: Boolean); |
102 | procedure ConvertBitCount(ABitCount: Integer); |
172 | procedure ConvertBitCount(ABitCount: Integer); |
103 | function GetBitmapInfo: PBitmapInfo; |
173 | function GetBitmapInfo: PBitmapInfo; |
Line 111... | Line 181... | ||
111 | function GetScanLine(Y: Integer): Pointer; |
181 | function GetScanLine(Y: Integer): Pointer; |
112 | function GetScanLineReadOnly(Y: Integer): Pointer; |
182 | function GetScanLineReadOnly(Y: Integer): Pointer; |
113 | function GetTopPBits: Pointer; |
183 | function GetTopPBits: Pointer; |
114 | function GetTopPBitsReadOnly: Pointer; |
184 | function GetTopPBitsReadOnly: Pointer; |
115 | procedure SetBitCount(Value: Integer); |
185 | procedure SetBitCount(Value: Integer); |
116 | procedure SetImage(Value: TDIBSharedImage); |
186 | procedure SetImage(Value: TDIBSharedImage); {$IFDEF VER9UP}inline;{$ENDIF} |
117 | procedure SetNowPixelFormat(const Value: TDIBPixelFormat); |
187 | procedure SetNowPixelFormat(const Value: TDIBPixelFormat); |
118 | procedure SetPixel(X, Y: Integer; Value: DWORD); |
188 | procedure SetPixel(X, Y: Integer; Value: DWORD); |
119 | procedure StartProgress(const Name: string); |
189 | procedure StartProgress(const Name: string); |
120 | procedure EndProgress; |
190 | procedure EndProgress; |
121 | procedure UpdateProgress(PercentY: Integer); |
191 | procedure UpdateProgress(PercentY: Integer); |
- | 192 | ||
- | 193 | { Added these 3 functions for New Specials Effects } |
|
- | 194 | function Interval(iMin, iMax, iValue: Integer; iMark: Boolean): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 195 | function IntToByte(i: Integer): Byte; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 196 | function TrimInt(i, Min, Max: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 197 | { End of 3 functions for New Special Effect } |
|
- | 198 | ||
- | 199 | procedure Darkness(Amount: Integer); |
|
- | 200 | function GetAlphaChannel: TDIB; |
|
- | 201 | procedure SetAlphaChannel(const Value: TDIB); |
|
- | 202 | function GetClientRect: TRect; |
|
- | 203 | function GetRGBChannel: TDIB; |
|
- | 204 | procedure SetRGBChannel(const Value: TDIB); |
|
122 | protected |
205 | protected |
123 | procedure DefineProperties(Filer: TFiler); override; |
206 | procedure DefineProperties(Filer: TFiler); override; |
124 | procedure Draw(ACanvas: TCanvas; const Rect: TRect); override; |
207 | procedure Draw(ACanvas: TCanvas; const ARect: TRect); override; |
125 | function GetEmpty: Boolean; override; |
208 | function GetEmpty: Boolean; override; |
126 | function GetHeight: Integer; override; |
209 | function GetHeight: Integer; override; |
127 | function GetPalette: HPalette; override; |
210 | function GetPalette: HPalette; override; |
128 | function GetWidth: Integer; override; |
211 | function GetWidth: Integer; override; |
129 | procedure ReadData(Stream: TStream); override; |
212 | procedure ReadData(Stream: TStream); override; |
Line 139... | Line 222... | ||
139 | procedure Assign(Source: TPersistent); override; |
222 | procedure Assign(Source: TPersistent); override; |
140 | procedure Clear; |
223 | procedure Clear; |
141 | procedure Compress; |
224 | procedure Compress; |
142 | procedure Decompress; |
225 | procedure Decompress; |
143 | procedure FreeHandle; |
226 | procedure FreeHandle; |
- | 227 | function HasAlphaChannel: Boolean; |
|
- | 228 | function AssignAlphaChannel(ALPHA: TDIB; ForceResize: Boolean{$IFDEF VER4UP} = False{$ENDIF}): Boolean; |
|
- | 229 | procedure RetAlphaChannel(out oDIB: TDIB); |
|
144 | procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; |
230 | procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; |
145 | APalette: HPALETTE); override; |
231 | APalette: HPALETTE); override; |
146 | procedure LoadFromStream(Stream: TStream); override; |
232 | procedure LoadFromStream(Stream: TStream); override; |
147 | procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; |
233 | procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; |
148 | var APalette: HPALETTE); override; |
234 | var APalette: HPALETTE); override; |
149 | procedure SaveToStream(Stream: TStream); override; |
235 | procedure SaveToStream(Stream: TStream); override; |
150 | procedure SetSize(AWidth, AHeight, ABitCount: Integer); |
236 | procedure SetSize(AWidth, AHeight, ABitCount: Integer); {$IFDEF VER5UP}reintroduce;{$ENDIF} //{$IFDEF VER9UP} overload;{$ENDIF} |
151 | procedure UpdatePalette; |
237 | procedure UpdatePalette; |
152 | { Special effect } |
238 | { Special effect } |
153 | procedure Blur(ABitCount: Integer; Radius: Integer); |
239 | procedure Blur(ABitCount: Integer; Radius: Integer); |
154 | procedure Greyscale(ABitCount: Integer); |
240 | procedure Greyscale(ABitCount: Integer); |
155 | procedure Mirror(MirrorX, MirrorY: Boolean); |
241 | procedure Mirror(MirrorX, MirrorY: Boolean); |
156 | procedure Negative; |
242 | procedure Negative; |
157 | 243 | ||
- | 244 | { Added New Special Effect } |
|
- | 245 | procedure Spray(Amount: Integer); |
|
- | 246 | procedure Emboss; |
|
- | 247 | procedure AddMonoNoise(Amount: Integer); |
|
- | 248 | procedure AddGradiantNoise(Amount: byte); |
|
- | 249 | function Twist(bmp: TDIB; Amount: byte): Boolean; |
|
- | 250 | function FishEye(bmp: TDIB): Boolean; |
|
- | 251 | function SmoothRotateWrap(Bmp: TDIB; cx, cy: Integer; Degree: Extended): Boolean; |
|
- | 252 | procedure Lightness(Amount: Integer); |
|
- | 253 | procedure Saturation(Amount: Integer); |
|
- | 254 | procedure Contrast(Amount: Integer); |
|
- | 255 | procedure AddRGB(aR, aG, aB: Byte); |
|
- | 256 | function Filter(Dest: TDIB; Filter: TFilter): Boolean; |
|
- | 257 | procedure Sharpen(Amount: Integer); |
|
- | 258 | function IntToColor(i: Integer): TBGR; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 259 | function Rotate(Dst: TDIB; cx, cy: Integer; Angle: Double): Boolean; |
|
- | 260 | procedure SplitBlur(Amount: Integer); |
|
- | 261 | procedure GaussianBlur(Bmp: TDIB; Amount: Integer); |
|
- | 262 | { End of New Special Effect } |
|
- | 263 | { |
|
- | 264 | New effect for TDIB |
|
- | 265 | with Some Effects like AntiAlias, Contrast, |
|
- | 266 | Lightness, Saturation, GaussianBlur, Mosaic, |
|
- | 267 | Twist, Splitlight, Trace, Emboss, etc. |
|
- | 268 | Works with 24bit color DIBs. |
|
- | 269 | ||
- | 270 | This component is based on TProEffectImage component version 1.0 by |
|
- | 271 | Written By Babak Sateli (babak_sateli@yahoo.com, http://raveland.netfirms.com) |
|
- | 272 | ||
- | 273 | and modified by (c) 2004 Jaro Benes |
|
- | 274 | for DelphiX use. |
|
- | 275 | ||
- | 276 | Demo was modified into DXForm with function like original |
|
- | 277 | ||
- | 278 | DISCLAIMER |
|
- | 279 | This component is provided AS-IS without any warranty of any kind, either express or |
|
- | 280 | implied. This component is freeware and can be used in any software product. |
|
- | 281 | } |
|
- | 282 | procedure DoInvert; |
|
- | 283 | procedure DoAddColorNoise(Amount: Integer); |
|
- | 284 | procedure DoAddMonoNoise(Amount: Integer); |
|
- | 285 | procedure DoAntiAlias; |
|
- | 286 | procedure DoContrast(Amount: Integer); |
|
- | 287 | procedure DoFishEye(Amount: Integer); |
|
- | 288 | procedure DoGrayScale; |
|
- | 289 | procedure DoLightness(Amount: Integer); |
|
- | 290 | procedure DoDarkness(Amount: Integer); |
|
- | 291 | procedure DoSaturation(Amount: Integer); |
|
- | 292 | procedure DoSplitBlur(Amount: Integer); |
|
- | 293 | procedure DoGaussianBlur(Amount: Integer); |
|
- | 294 | procedure DoMosaic(Size: Integer); |
|
- | 295 | procedure DoTwist(Amount: Integer); |
|
- | 296 | procedure DoSplitlight(Amount: Integer); |
|
- | 297 | procedure DoTile(Amount: Integer); |
|
- | 298 | procedure DoSpotLight(Amount: Integer; Spot: TRect); |
|
- | 299 | procedure DoTrace(Amount: Integer); |
|
- | 300 | procedure DoEmboss; |
|
- | 301 | procedure DoSolorize(Amount: Integer); |
|
- | 302 | procedure DoPosterize(Amount: Integer); |
|
- | 303 | procedure DoBrightness(Amount: Integer); |
|
- | 304 | procedure DoResample(AmountX, AmountY: Integer; TypeResample: TFilterTypeResample); |
|
- | 305 | {rotate} |
|
- | 306 | procedure DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended); |
|
- | 307 | procedure DoColorize(ForeColor, BackColor: TColor); |
|
- | 308 | {Simple explosion spoke effect} |
|
- | 309 | procedure DoNovaEffect(sr, sg, sb, cx, cy, radius, |
|
- | 310 | nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent); |
|
- | 311 | ||
- | 312 | {Simple Mandelbrot-set drawing} |
|
- | 313 | procedure DrawMandelbrot(ao, au: Integer; bo, bu: Double); |
|
- | 314 | ||
- | 315 | {Sephia effect} |
|
- | 316 | procedure SephiaEffect(Depth: Integer{$IFDEF VER4UP} = 20{$ENDIF}); |
|
- | 317 | ||
- | 318 | {Simple blend pixel} |
|
- | 319 | procedure BlendPixel(const X, Y: Integer; aColor: Cardinal; Alpha: Byte); {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 320 | {Line in polar system} |
|
- | 321 | procedure LinePolar(x, y: Integer; AngleInDegree, Length: extended; |
|
- | 322 | Color: cardinal); |
|
- | 323 | ||
- | 324 | {special version Dark/Light procedure in percent} |
|
- | 325 | procedure Darker(Percent: Integer); |
|
- | 326 | procedure Lighter(Percent: Integer); |
|
- | 327 | ||
- | 328 | {Simple graphical crypt} |
|
- | 329 | procedure EncryptDecrypt(const Key: Integer); |
|
- | 330 | ||
- | 331 | { Standalone DXFusion } |
|
- | 332 | {--- c o n F u s i o n ---} |
|
- | 333 | {By Joakim Back, www.back.mine.nu} |
|
- | 334 | {Huge thanks to Ilkka Tuomioja for helping out with the project.} |
|
- | 335 | ||
- | 336 | { |
|
- | 337 | modified by (c) 2005 Jaro Benes for DelphiX use. |
|
- | 338 | } |
|
- | 339 | ||
- | 340 | procedure CreateDIBFromBitmap(const Bitmap: TBitmap); |
|
- | 341 | {Drawing Methods.} |
|
- | 342 | procedure DrawOn(Dest: TRect; DestCanvas: TCanvas; |
|
- | 343 | Xsrc, Ysrc: Integer); |
|
- | 344 | procedure DrawTo(SrcDIB: TDIB; X, Y, Width, Height, SourceX, |
|
- | 345 | SourceY: Integer); |
|
- | 346 | procedure DrawTransparent(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 347 | SourceX, SourceY: Integer; const Color: TColor); {$IFDEF VER5UP} reintroduce;{$ENDIF} //{$IFDEF VER9UP} overload;{$ENDIF} |
|
- | 348 | procedure DrawShadow(SrcDIB: TDIB; X, Y, Width, Height, Frame: Integer; |
|
- | 349 | FilterMode: TFilterMode); |
|
- | 350 | procedure DrawShadows(SrcDIB: TDIB; X, Y, Width, Height, Frame: Integer; |
|
- | 351 | Alpha: Byte); |
|
- | 352 | procedure DrawDarken(SrcDIB: TDIB; X, Y, Width, Height, |
|
- | 353 | Frame: Integer); |
|
- | 354 | procedure DrawAdditive(SrcDIB: TDIB; X, Y, Width, Height: Integer; Alpha: Integer{$IFDEF VER4UP} = 255{$ENDIF}; |
|
- | 355 | Frame: Integer{$IFDEF VER4UP} = 0{$ENDIF}); |
|
- | 356 | procedure DrawQuickAlpha(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 357 | SourceX, SourceY: Integer; const Color: TColor; |
|
- | 358 | FilterMode: TFilterMode); |
|
- | 359 | procedure DrawTranslucent(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 360 | SourceX, SourceY: Integer; const Color: TColor); |
|
- | 361 | procedure DrawMorphed(SrcDIB: TDIB; const X, Y, Width, Height, SourceX, |
|
- | 362 | SourceY: Integer; const Color: TColor); |
|
- | 363 | procedure DrawAlpha(SrcDIB: TDIB; const X, Y, Width, Height, SourceX, |
|
- | 364 | SourceY, Alpha: Integer; const Color: TColor); |
|
- | 365 | procedure DrawAlphaMask(SrcDIB, MaskDIB: TDIB; const X, Y, Width, |
|
- | 366 | Height, SourceX, SourceY: Integer); |
|
- | 367 | procedure DrawAntialias(SrcDIB: TDIB); |
|
- | 368 | procedure Draw3x3Matrix(SrcDIB: TDIB; Setting: TMatrixSetting); |
|
- | 369 | procedure DrawMono(SrcDIB: TDIB; const X, Y, Width, Height, SourceX, |
|
- | 370 | SourceY: Integer; const TransColor, ForeColor, BackColor: TColor); |
|
- | 371 | {One-color Filters.} |
|
- | 372 | procedure FilterLine(X1, Y1, X2, Y2: Integer; Color: TColor; |
|
- | 373 | FilterMode: TFilterMode); {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 374 | procedure FilterRect(X, Y, Width, Height: Integer; Color: TColor; |
|
- | 375 | FilterMode: TFilterMode); {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 376 | { Lightsource. } |
|
- | 377 | procedure InitLight(Count, Detail: Integer); |
|
- | 378 | procedure DrawLights(FLight: TLightArray; AmbientLight: TColor); |
|
- | 379 | // |
|
- | 380 | // effect for special purpose |
|
- | 381 | // |
|
- | 382 | procedure FadeOut(DIB2: TDIB; Step: Byte); |
|
- | 383 | procedure DoZoom(DIB2: TDIB; ZoomRatio: Real); |
|
- | 384 | procedure DoBlur(DIB2: TDIB); |
|
- | 385 | procedure FadeIn(DIB2: TDIB; Step: Byte); |
|
- | 386 | procedure FillDIB8(Color: Byte); |
|
- | 387 | procedure DoRotate(DIB1: TDIB; cX, cY, Angle: Integer); |
|
- | 388 | procedure Distort(DIB1: TDIB; dt: TDistortType; cX, cY, Angle: Integer; Factor: Real); |
|
- | 389 | function Ink(DIB: TDIB; const SprayInit: Boolean; const AmountSpray: Integer): Boolean; |
|
- | 390 | // lines |
|
- | 391 | procedure AntialiasedLine(x1, y1, x2, y2: Integer; color: TColor); {$IFDEF VER9UP} inline; {$ENDIF} |
|
- | 392 | function GetColorBetween(StartColor, EndColor: TColor; Pointvalue, |
|
- | 393 | FromPoint, ToPoint: Extended): TColor; |
|
- | 394 | procedure ColoredLine(const iStart, iEnd: TPoint; iColorStyle: TColorLineStyle; |
|
- | 395 | iGradientFrom, iGradientTo: TColor; iPixelGeometry: TColorLinePixelGeometry; |
|
- | 396 | iRadius: WORD); |
|
- | 397 | // standard property |
|
158 | property BitCount: Integer read FBitCount write SetBitCount; |
398 | property BitCount: Integer read FBitCount write SetBitCount; |
159 | property BitmapInfo: PBitmapInfo read GetBitmapInfo; |
399 | property BitmapInfo: PBitmapInfo read GetBitmapInfo; |
160 | property BitmapInfoSize: Integer read GetBitmapInfoSize; |
400 | property BitmapInfoSize: Integer read GetBitmapInfoSize; |
161 | property Canvas: TCanvas read GetCanvas; |
401 | property Canvas: TCanvas read GetCanvas; |
162 | property Handle: THandle read GetHandle; |
402 | property Handle: THandle read GetHandle; |
Line 172... | Line 412... | ||
172 | property Size: Integer read FSize; |
412 | property Size: Integer read FSize; |
173 | property TopPBits: Pointer read GetTopPBits; |
413 | property TopPBits: Pointer read GetTopPBits; |
174 | property TopPBitsReadOnly: Pointer read GetTopPBitsReadOnly; |
414 | property TopPBitsReadOnly: Pointer read GetTopPBitsReadOnly; |
175 | property Width: Integer read FWidth write SetWidth; |
415 | property Width: Integer read FWidth write SetWidth; |
176 | property WidthBytes: Integer read FWidthBytes; |
416 | property WidthBytes: Integer read FWidthBytes; |
- | 417 | property AlphaChannel: TDIB read GetAlphaChannel write SetAlphaChannel; |
|
- | 418 | property RGBChannel: TDIB read GetRGBChannel write SetRGBChannel; |
|
- | 419 | function CreateBitmapFromDIB: TBitmap; |
|
- | 420 | procedure Fill(aColor: TColor); |
|
- | 421 | property ClientRect: TRect read GetClientRect; |
|
177 | end; |
422 | end; |
178 | 423 | ||
- | 424 | { TDIBitmap } |
|
- | 425 | ||
179 | TDIBitmap = class(TDIB) end; |
426 | TDIBitmap = class(TDIB) end; |
180 | 427 | ||
181 | { TCustomDXDIB } |
428 | { TCustomDXDIB } |
182 | 429 | ||
183 | TCustomDXDIB = class(TComponent) |
430 | TCustomDXDIB = class(TComponent) |
Line 233... | Line 480... | ||
233 | 480 | ||
234 | { TDXPaintBox } |
481 | { TDXPaintBox } |
235 | 482 | ||
236 | TDXPaintBox = class(TCustomDXPaintBox) |
483 | TDXPaintBox = class(TCustomDXPaintBox) |
237 | published |
484 | published |
238 | {$IFDEF DelphiX_Spt4}property Anchors;{$ENDIF} |
485 | {$IFDEF VER4UP}property Anchors; {$ENDIF} |
239 | property AutoStretch; |
486 | property AutoStretch; |
240 | property Center; |
487 | property Center; |
241 | {$IFDEF DelphiX_Spt4}property Constraints;{$ENDIF} |
488 | {$IFDEF VER4UP}property Constraints; {$ENDIF} |
242 | property DIB; |
489 | property DIB; |
243 | property KeepAspect; |
490 | property KeepAspect; |
244 | property Stretch; |
491 | property Stretch; |
245 | property ViewWidth; |
492 | property ViewWidth; |
246 | property ViewHeight; |
493 | property ViewHeight; |
Line 259... | Line 506... | ||
259 | property OnDragOver; |
506 | property OnDragOver; |
260 | property OnEndDrag; |
507 | property OnEndDrag; |
261 | property OnMouseDown; |
508 | property OnMouseDown; |
262 | property OnMouseMove; |
509 | property OnMouseMove; |
263 | property OnMouseUp; |
510 | property OnMouseUp; |
- | 511 | {$IFDEF VER9UP}property OnMouseWheel; {$ENDIF} |
|
- | 512 | {$IFDEF VER9UP}property OnResize; {$ENDIF} |
|
- | 513 | {$IFDEF VER9UP}property OnCanResize; {$ENDIF} |
|
- | 514 | {$IFDEF VER9UP}property OnContextPopup; {$ENDIF} |
|
264 | property OnStartDrag; |
515 | property OnStartDrag; |
265 | end; |
516 | end; |
266 | 517 | ||
- | 518 | const |
|
- | 519 | DefaultFilterRadius: array[TFilterTypeResample] of Single = (0.5, 1, 1, 1.5, 2, 3, 2); |
|
- | 520 | ||
267 | function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat; |
521 | function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat; {$IFDEF VER9UP}inline;{$ENDIF} |
268 | function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat; |
522 | function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat; {$IFDEF VER9UP}inline;{$ENDIF} |
269 | function pfRGB(const PixelFormat: TDIBPixelFormat; R, G, B: Byte): DWORD; |
523 | function pfRGB(const PixelFormat: TDIBPixelFormat; R, G, B: Byte): DWORD; {$IFDEF VER9UP}inline;{$ENDIF} |
270 | procedure pfGetRGB(const PixelFormat: TDIBPixelFormat; Color: DWORD; var R, G, B: Byte); |
524 | procedure pfGetRGB(const PixelFormat: TDIBPixelFormat; Color: DWORD; var R, G, B: Byte); {$IFDEF VER9UP}inline;{$ENDIF} |
271 | function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
525 | function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; {$IFDEF VER9UP}inline;{$ENDIF} |
272 | function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
526 | function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; {$IFDEF VER9UP}inline;{$ENDIF} |
273 | function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
527 | function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; {$IFDEF VER9UP}inline;{$ENDIF} |
274 | 528 | ||
275 | function GreyscaleColorTable: TRGBQuads; |
529 | function GreyscaleColorTable: TRGBQuads; |
276 | 530 | ||
277 | function RGBQuad(R, G, B: Byte): TRGBQuad; |
531 | function RGBQuad(R, G, B: Byte): TRGBQuad; {$IFDEF VER9UP}inline;{$ENDIF} |
278 | function PaletteEntryToRGBQuad(const Entry: TPaletteEntry): TRGBQuad; |
532 | function PaletteEntryToRGBQuad(const Entry: TPaletteEntry): TRGBQuad; {$IFDEF VER9UP}inline;{$ENDIF} |
279 | function PaletteEntriesToRGBQuads(const Entries: TPaletteEntries): TRGBQuads; |
533 | function PaletteEntriesToRGBQuads(const Entries: TPaletteEntries): TRGBQuads; {$IFDEF VER9UP}inline;{$ENDIF} |
280 | function RGBQuadToPaletteEntry(const RGBQuad: TRGBQuad): TPaletteEntry; |
534 | function RGBQuadToPaletteEntry(const RGBQuad: TRGBQuad): TPaletteEntry; {$IFDEF VER9UP}inline;{$ENDIF} |
281 | function RGBQuadsToPaletteEntries(const RGBQuads: TRGBQuads): TPaletteEntries; |
535 | function RGBQuadsToPaletteEntries(const RGBQuads: TRGBQuads): TPaletteEntries; {$IFDEF VER9UP}inline;{$ENDIF} |
- | 536 | ||
- | 537 | function PosValue(Value: Integer): Integer; |
|
- | 538 | ||
- | 539 | type |
|
- | 540 | TOC = 0..511; |
|
- | 541 | function DSin(const C: TOC): Single; {$IFDEF VER9UP}inline; {$ENDIF} |
|
- | 542 | function DCos(const C: TOC): Single; {$IFDEF VER9UP}inline; {$ENDIF} |
|
- | 543 | ||
- | 544 | { Added Constants for TFilter Type } |
|
- | 545 | const |
|
- | 546 | EdgeFilter: TFilter = ((-1, -1, -1), (-1, 8, -1), (-1, -1, -1)); |
|
- | 547 | StrongOutlineFilter: TFilter = ((-100, 0, 0), (0, 0, 0), (0, 0, 100)); |
|
- | 548 | Enhance3DFilter: TFilter = ((-100, 5, 5), (5, 5, 5), (5, 5, 100)); |
|
- | 549 | LinearFilter: TFilter = ((-40, -40, -40), (-40, 255, -40), (-40, -40, -40)); |
|
- | 550 | GranularFilter: TFilter = ((-20, 5, 20), (5, -10, 5), (100, 5, -100)); |
|
- | 551 | SharpFilter: TFilter = ((-2, -2, -2), (-2, 20, -2), (-2, -2, -2)); |
|
- | 552 | { End of constants } |
|
- | 553 | ||
- | 554 | { Added Constants for DXFusion Type } |
|
- | 555 | const |
|
- | 556 | { 3x3 Matrix Presets. } |
|
- | 557 | msEmboss: TMatrixSetting = (-1, -1, 0, -1, 6, 1, 0, 1, 1, 6); |
|
- | 558 | msHardEmboss: TMatrixSetting = (-4, -2, -1, -2, 10, 2, -1, 2, 4, 8); |
|
- | 559 | msBlur: TMatrixSetting = (1, 2, 1, 2, 4, 2, 1, 2, 1, 16); |
|
- | 560 | msSharpen: TMatrixSetting = (-1, -1, -1, -1, 15, -1, -1, -1, -1, 7); |
|
- | 561 | msEdgeDetect: TMatrixSetting = (-1, -1, -1, -1, 8, -1, -1, -1, -1, 1); |
|
- | 562 | ||
- | 563 | {Proportionaly scale of size, for recountin image sizes} |
|
- | 564 | function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 565 | ||
- | 566 | 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} |
|
282 | 568 | ||
283 | implementation |
569 | implementation |
284 | 570 | ||
- | 571 | uses DXConsts, {$IFDEF PNG_GRAPHICS}pngimage,{$ENDIF} jpeg; |
|
- | 572 | ||
- | 573 | function GetScale(SourceWidth, SourceHeight, TargetWidth, TargetHeight: Integer): Single; |
|
- | 574 | var |
|
- | 575 | XScale, YScale: Single; |
|
- | 576 | begin |
|
- | 577 | XScale := 1; |
|
- | 578 | YScale := 1; |
|
- | 579 | if TargetWidth < SourceWidth then |
|
- | 580 | XScale := TargetWidth / SourceWidth; |
|
- | 581 | if TargetHeight < SourceHeight then |
|
- | 582 | YScale := TargetHeight / SourceHeight; |
|
285 | uses DXConsts; |
583 | Result := XScale; |
- | 584 | if YScale < Result then |
|
- | 585 | Result := YScale; |
|
- | 586 | end; |
|
286 | 587 | ||
- | 588 | {$IFNDEF VER4UP} |
|
287 | function Max(B1, B2: Integer): Integer; |
589 | function Max(B1, B2: Integer): Integer; |
288 | begin |
590 | begin |
289 | if B1>=B2 then Result := B1 else Result := B2; |
591 | if B1 >= B2 then Result := B1 else Result := B2; |
290 | end; |
592 | end; |
291 | 593 | ||
- | 594 | function Min(B1, B2: Integer): Integer; |
|
- | 595 | begin |
|
- | 596 | if B1 <= B2 then Result := B1 else Result := B2; |
|
- | 597 | end; |
|
- | 598 | {$ENDIF} |
|
- | 599 | ||
- | 600 | function DSin(const C: TOC): Single; {$IFDEF VER9UP}inline; {$ENDIF} |
|
- | 601 | begin |
|
- | 602 | Result := sin(((c * 360) / 511) * Pi / 180); |
|
- | 603 | end; |
|
- | 604 | ||
- | 605 | function DCos(const C: TOC): Single; {$IFDEF VER9UP}inline; {$ENDIF} |
|
- | 606 | begin |
|
- | 607 | Result := cos(((c * 360) / 511) * Pi / 180); |
|
- | 608 | end; |
|
- | 609 | ||
292 | function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat; |
610 | function MakeDIBPixelFormat(RBitCount, GBitCount, BBitCount: Integer): TDIBPixelFormat; |
293 | begin |
611 | begin |
294 | Result.RBitMask := ((1 shl RBitCount)-1) shl (GBitCount+BBitCount); |
612 | Result.RBitMask := ((1 shl RBitCount) - 1) shl (GBitCount + BBitCount); |
295 | Result.GBitMask := ((1 shl GBitCount)-1) shl (BBitCount); |
613 | Result.GBitMask := ((1 shl GBitCount) - 1) shl (BBitCount); |
296 | Result.BBitMask := (1 shl BBitCount)-1; |
614 | Result.BBitMask := (1 shl BBitCount) - 1; |
Line 303... | Line 621... | ||
303 | Result.RShift := (GBitCount+BBitCount)-(8-RBitCount); |
621 | Result.RShift := (GBitCount + BBitCount) - (8 - RBitCount); |
304 | Result.GShift := BBitCount-(8-GBitCount); |
622 | Result.GShift := BBitCount - (8 - GBitCount); |
305 | Result.BShift := 8-BBitCount; |
623 | Result.BShift := 8 - BBitCount; |
306 | end; |
624 | end; |
307 | 625 | ||
308 | function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat; |
- | |
309 | - | ||
310 | function GetBitCount(b: Integer): Integer; |
626 | function GetBitCount(b: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
311 | var |
627 | var |
312 | i: Integer; |
628 | i: Integer; |
313 | begin |
629 | begin |
314 | i := 0; |
630 | i := 0; |
315 | while (i<31) and (((1 shl i) and b)=0) do Inc(i); |
631 | while (i < 31) and (((1 shl i) and b) = 0) do Inc(i); |
Line 320... | Line 636... | ||
320 | Inc(i); |
636 | Inc(i); |
321 | Inc(Result); |
637 | Inc(Result); |
322 | end; |
638 | end; |
323 | end; |
639 | end; |
324 | 640 | ||
- | 641 | function MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask: Integer): TDIBPixelFormat; |
|
325 | begin |
642 | begin |
326 | Result := MakeDIBPixelFormat(GetBitCount(RBitMask), GetBitCount(GBitMask), |
643 | Result := MakeDIBPixelFormat(GetBitCount(RBitMask), GetBitCount(GBitMask), |
327 | GetBitCount(BBitMask)); |
644 | GetBitCount(BBitMask)); |
328 | end; |
645 | end; |
329 | 646 | ||
Line 350... | Line 667... | ||
350 | function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
667 | function pfGetRValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
351 | begin |
668 | begin |
352 | with PixelFormat do |
669 | with PixelFormat do |
353 | begin |
670 | begin |
354 | Result := (Color and RBitMask) shr RShift; |
671 | Result := (Color and RBitMask) shr RShift; |
355 | Result := Result or (Result shr RBitCount); |
672 | Result := Result or (Result shr RBitCount2); |
356 | end; |
673 | end; |
357 | end; |
674 | end; |
358 | 675 | ||
359 | function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
676 | function pfGetGValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
360 | begin |
677 | begin |
361 | with PixelFormat do |
678 | with PixelFormat do |
362 | begin |
679 | begin |
363 | Result := (Color and GBitMask) shr GShift; |
680 | Result := (Color and GBitMask) shr GShift; |
364 | Result := Result or (Result shr GBitCount); |
681 | Result := Result or (Result shr GBitCount2); |
365 | end; |
682 | end; |
366 | end; |
683 | end; |
367 | 684 | ||
368 | function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
685 | function pfGetBValue(const PixelFormat: TDIBPixelFormat; Color: DWORD): Byte; |
369 | begin |
686 | begin |
370 | with PixelFormat do |
687 | with PixelFormat do |
371 | begin |
688 | begin |
372 | Result := (Color and BBitMask) shl BShift; |
689 | Result := (Color and BBitMask) shl BShift; |
373 | Result := Result or (Result shr BBitCount); |
690 | Result := Result or (Result shr BBitCount2); |
374 | end; |
691 | end; |
375 | end; |
692 | end; |
376 | 693 | ||
377 | function GreyscaleColorTable: TRGBQuads; |
694 | function GreyscaleColorTable: TRGBQuads; |
378 | var |
695 | var |
Line 445... | Line 762... | ||
445 | PLocalDIBPixelFormat = ^TLocalDIBPixelFormat; |
762 | PLocalDIBPixelFormat = ^TLocalDIBPixelFormat; |
446 | TLocalDIBPixelFormat = packed record |
763 | TLocalDIBPixelFormat = packed record |
447 | RBitMask, GBitMask, BBitMask: DWORD; |
764 | RBitMask, GBitMask, BBitMask: DWORD; |
448 | end; |
765 | end; |
449 | 766 | ||
- | 767 | { TPaletteItem } |
|
- | 768 | ||
450 | TPaletteItem = class(TCollectionItem) |
769 | TPaletteItem = class(TCollectionItem) |
451 | private |
770 | private |
452 | ID: Integer; |
771 | ID: Integer; |
453 | Palette: HPalette; |
772 | Palette: HPalette; |
454 | RefCount: Integer; |
773 | RefCount: Integer; |
455 | ColorTable: TRGBQuads; |
774 | ColorTable: TRGBQuads; |
456 | ColorTableCount: Integer; |
775 | ColorTableCount: Integer; |
457 | destructor Destroy; override; |
776 | destructor Destroy; override; |
458 | procedure AddRef; |
777 | procedure AddRef; |
459 | procedure Release; |
778 | procedure Release; {$IFDEF VER17UP}reintroduce;{$ENDIF} |
460 | end; |
779 | end; |
461 | 780 | ||
- | 781 | { TPaletteManager } |
|
- | 782 | ||
462 | TPaletteManager = class |
783 | TPaletteManager = class |
463 | private |
784 | private |
464 | FList: TCollection; |
785 | FList: TCollection; |
465 | constructor Create; |
786 | constructor Create; |
466 | destructor Destroy; override; |
787 | destructor Destroy; override; |
467 | function CreatePalette(const ColorTable: TRGBQuads; ColorTableCount: Integer): HPalette; |
788 | function CreatePalette(const ColorTable: TRGBQuads; ColorTableCount: Integer): HPalette; |
468 | procedure DeletePalette(var Palette: HPalette); |
789 | procedure DeletePalette(var Palette: HPalette); |
469 | end; |
790 | end; |
470 | 791 | ||
- | 792 | { TPaletteItem } |
|
- | 793 | ||
471 | destructor TPaletteItem.Destroy; |
794 | destructor TPaletteItem.Destroy; |
472 | begin |
795 | begin |
473 | DeleteObject(Palette); |
796 | DeleteObject(Palette); |
474 | inherited Destroy; |
797 | inherited Destroy; |
475 | end; |
798 | end; |
Line 483... | Line 806... | ||
483 | begin |
806 | begin |
484 | Dec(RefCount); |
807 | Dec(RefCount); |
485 | if RefCount<=0 then Free; |
808 | if RefCount <= 0 then Free; |
486 | end; |
809 | end; |
487 | 810 | ||
- | 811 | { TPaletteManager } |
|
- | 812 | ||
488 | constructor TPaletteManager.Create; |
813 | constructor TPaletteManager.Create; |
489 | begin |
814 | begin |
490 | inherited Create; |
815 | inherited Create; |
491 | FList := TCollection.Create(TPaletteItem); |
816 | FList := TCollection.Create(TPaletteItem); |
492 | end; |
817 | end; |
Line 575... | Line 900... | ||
575 | if FPaletteManager=nil then |
900 | if FPaletteManager = nil then |
576 | FPaletteManager := TPaletteManager.Create; |
901 | FPaletteManager := TPaletteManager.Create; |
577 | Result := FPaletteManager; |
902 | Result := FPaletteManager; |
578 | end; |
903 | end; |
579 | 904 | ||
- | 905 | { TDIBSharedImage } |
|
- | 906 | ||
580 | constructor TDIBSharedImage.Create; |
907 | constructor TDIBSharedImage.Create; |
581 | begin |
908 | begin |
582 | inherited Create; |
909 | inherited Create; |
583 | FMemoryImage := True; |
910 | FMemoryImage := True; |
584 | SetColorTable(GreyscaleColorTable); |
911 | SetColorTable(GreyscaleColorTable); |
Line 590... | Line 917... | ||
590 | const PixelFormat: TDIBPixelFormat; const ColorTable: TRGBQuads; MemoryImage, Compressed: Boolean); |
917 | const PixelFormat: TDIBPixelFormat; const ColorTable: TRGBQuads; MemoryImage, Compressed: Boolean); |
591 | var |
918 | var |
592 | InfoOfs: Integer; |
919 | InfoOfs: Integer; |
593 | UsePixelFormat: Boolean; |
920 | UsePixelFormat: Boolean; |
594 | begin |
921 | begin |
- | 922 | {$IFNDEF D17UP} |
|
- | 923 | {self recreation is not allowed here} |
|
595 | Create; |
924 | Create; |
596 | 925 | {$ENDIF} |
|
597 | { Pixel format check } |
926 | { Pixel format check } |
598 | case ABitCount of |
927 | case ABitCount of |
599 | 1 : if not ((PixelFormat.RBitMask=$FF0000) and (PixelFormat.GBitMask=$00FF00) and (PixelFormat.BBitMask=$0000FF)) then |
928 | 1: if not ((PixelFormat.RBitMask = $FF0000) and (PixelFormat.GBitMask = $00FF00) and (PixelFormat.BBitMask = $0000FF)) then |
600 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
929 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
601 | 4 : if not ((PixelFormat.RBitMask=$FF0000) and (PixelFormat.GBitMask=$00FF00) and (PixelFormat.BBitMask=$0000FF)) then |
930 | 4: if not ((PixelFormat.RBitMask = $FF0000) and (PixelFormat.GBitMask = $00FF00) and (PixelFormat.BBitMask = $0000FF)) then |
602 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
931 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
603 | 8 : if not ((PixelFormat.RBitMask=$FF0000) and (PixelFormat.GBitMask=$00FF00) and (PixelFormat.BBitMask=$0000FF)) then |
932 | 8: if not ((PixelFormat.RBitMask = $FF0000) and (PixelFormat.GBitMask = $00FF00) and (PixelFormat.BBitMask = $0000FF)) then |
604 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
933 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
- | 934 | 16: |
|
605 | 16: begin |
935 | begin |
606 | if not (((PixelFormat.RBitMask=$7C00) and (PixelFormat.GBitMask=$03E0) and (PixelFormat.BBitMask=$001F)) or |
936 | if not (((PixelFormat.RBitMask = $7C00) and (PixelFormat.GBitMask = $03E0) and (PixelFormat.BBitMask = $001F)) or |
607 | ((PixelFormat.RBitMask=$F800) and (PixelFormat.GBitMask=$07E0) and (PixelFormat.BBitMask=$001F))) then |
937 | ((PixelFormat.RBitMask = $F800) and (PixelFormat.GBitMask = $07E0) and (PixelFormat.BBitMask = $001F))) then |
608 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
938 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
609 | end; |
939 | end; |
- | 940 | 24: |
|
610 | 24: begin |
941 | begin |
611 | if not ((PixelFormat.RBitMask=$FF0000) and (PixelFormat.GBitMask=$00FF00) and (PixelFormat.BBitMask=$0000FF)) then |
942 | if not ((PixelFormat.RBitMask = $FF0000) and (PixelFormat.GBitMask = $00FF00) and (PixelFormat.BBitMask = $0000FF)) then |
612 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
943 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
613 | end; |
944 | end; |
- | 945 | 32: |
|
614 | 32: begin |
946 | begin |
615 | if not ((PixelFormat.RBitMask=$FF0000) and (PixelFormat.GBitMask=$00FF00) and (PixelFormat.BBitMask=$0000FF)) then |
947 | if not ((PixelFormat.RBitMask = $FF0000) and (PixelFormat.GBitMask = $00FF00) and (PixelFormat.BBitMask = $0000FF)) then |
616 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
948 | raise EInvalidGraphicOperation.Create(SInvalidDIBPixelFormat); |
617 | end; |
949 | end; |
618 | else |
950 | else |
619 | raise EInvalidGraphicOperation.CreateFmt(SInvalidDIBBitCount, [ABitCount]); |
951 | raise EInvalidGraphicOperation.CreateFmt(SInvalidDIBBitCount, [ABitCount]); |
Line 694... | Line 1026... | ||
694 | if MemoryImage then |
1026 | if MemoryImage then |
695 | begin |
1027 | begin |
696 | FPBits := Pointer(GlobalAlloc(GMEM_FIXED, FSize)); |
1028 | FPBits := Pointer(GlobalAlloc(GMEM_FIXED, FSize)); |
697 | if FPBits=nil then |
1029 | if FPBits = nil then |
698 | OutOfMemoryError; |
1030 | OutOfMemoryError; |
- | 1031 | end |
|
699 | end else |
1032 | else |
700 | begin |
1033 | begin |
701 | FDC := CreateCompatibleDC(0); |
1034 | FDC := CreateCompatibleDC(0); |
702 | 1035 | ||
703 | FHandle := CreateDIBSection(FDC, FBitmapInfo^, DIB_RGB_COLORS, FPBits, 0, 0); |
1036 | FHandle := CreateDIBSection(FDC, FBitmapInfo^, DIB_RGB_COLORS, FPBits, 0, 0); |
704 | if FHandle=0 then |
1037 | if FHandle = 0 then |
Line 711... | Line 1044... | ||
711 | FTopPBits := Pointer(Integer(FPBits)+(FHeight-1)*FWidthBytes); |
1044 | FTopPBits := Pointer(Integer(FPBits) + (FHeight - 1) * FWidthBytes); |
712 | end; |
1045 | end; |
713 | 1046 | ||
714 | procedure TDIBSharedImage.Duplicate(Source: TDIBSharedImage; MemoryImage: Boolean); |
1047 | procedure TDIBSharedImage.Duplicate(Source: TDIBSharedImage; MemoryImage: Boolean); |
715 | begin |
1048 | begin |
- | 1049 | if Source = nil then Exit; //no source |
|
- | 1050 | ||
716 | if Source.FSize=0 then |
1051 | if Source.FSize = 0 then |
717 | begin |
1052 | begin |
- | 1053 | {$IFNDEF D17UP} |
|
- | 1054 | {self recreation is not allowed here} |
|
718 | Create; |
1055 | Create; |
- | 1056 | {$ENDIF} |
|
719 | FMemoryImage := MemoryImage; |
1057 | FMemoryImage := MemoryImage; |
- | 1058 | end |
|
720 | end else |
1059 | else |
721 | begin |
1060 | begin |
722 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
1061 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
723 | Source.FPixelFormat, Source.FColorTable, MemoryImage, Source.FCompressed); |
1062 | Source.FPixelFormat, Source.FColorTable, MemoryImage, Source.FCompressed); |
724 | if FCompressed then |
1063 | if FCompressed then |
725 | begin |
1064 | begin |
726 | FBitmapInfo.bmiHeader.biSizeImage := Source.FBitmapInfo.bmiHeader.biSizeImage; |
1065 | FBitmapInfo.bmiHeader.biSizeImage := Source.FBitmapInfo.bmiHeader.biSizeImage; |
727 | GetMem(FPBits, FBitmapInfo.bmiHeader.biSizeImage); |
1066 | GetMem(FPBits, FBitmapInfo.bmiHeader.biSizeImage); |
728 | Move(Source.FPBits^, FPBits^, FBitmapInfo.bmiHeader.biSizeImage); |
1067 | Move(Source.FPBits^, FPBits^, FBitmapInfo.bmiHeader.biSizeImage); |
- | 1068 | end |
|
729 | end else |
1069 | else |
730 | begin |
1070 | begin |
731 | Move(Source.FPBits^, FPBits^, FBitmapInfo.bmiHeader.biSizeImage); |
1071 | Move(Source.FPBits^, FPBits^, FBitmapInfo.bmiHeader.biSizeImage); |
732 | end; |
1072 | end; |
733 | end; |
1073 | end; |
734 | end; |
1074 | end; |
Line 787... | Line 1127... | ||
787 | C := (C shr 4) or (C shl 4); |
1127 | C := (C shr 4) or (C shl 4); |
788 | end; |
1128 | end; |
789 | 1129 | ||
790 | AllocByte^ := B1; |
1130 | AllocByte^ := B1; |
791 | AllocByte^ := B2; |
1131 | AllocByte^ := B2; |
- | 1132 | end |
|
792 | end else |
1133 | else |
793 | if (Source.FWidth-x>5) and ((GetPixel(x)<>GetPixel(x+2)) or (GetPixel(x+1)<>GetPixel(x+3))) and |
1134 | if (Source.FWidth - x > 5) and ((GetPixel(x) <> GetPixel(x + 2)) or (GetPixel(x + 1) <> GetPixel(x + 3))) and |
794 | ((GetPixel(x+2)=GetPixel(x+4)) and (GetPixel(x+3)=GetPixel(x+5))) then |
1135 | ((GetPixel(x + 2) = GetPixel(x + 4)) and (GetPixel(x + 3) = GetPixel(x + 5))) then |
795 | begin |
1136 | begin |
796 | { Encoding mode } |
1137 | { Encoding mode } |
797 | AllocByte^ := 2; |
1138 | AllocByte^ := 2; |
798 | AllocByte^ := (GetPixel(x) shl 4) or GetPixel(x+1); |
1139 | AllocByte^ := (GetPixel(x) shl 4) or GetPixel(x + 1); |
799 | Inc(x, 2); |
1140 | Inc(x, 2); |
- | 1141 | end |
|
800 | end else |
1142 | else |
801 | begin |
1143 | begin |
802 | if (Source.FWidth-x<4) then |
1144 | if (Source.FWidth - x < 4) then |
803 | begin |
1145 | begin |
804 | { Encoding mode } |
1146 | { Encoding mode } |
805 | while Source.FWidth-x>=2 do |
1147 | while Source.FWidth - x >= 2 do |
Line 813... | Line 1155... | ||
813 | begin |
1155 | begin |
814 | AllocByte^ := 1; |
1156 | AllocByte^ := 1; |
815 | AllocByte^ := GetPixel(x) shl 4; |
1157 | AllocByte^ := GetPixel(x) shl 4; |
816 | Inc(x); |
1158 | Inc(x); |
817 | end; |
1159 | end; |
- | 1160 | end |
|
818 | end else |
1161 | else |
819 | begin |
1162 | begin |
820 | { Absolute mode } |
1163 | { Absolute mode } |
821 | PB1 := Size; AllocByte; |
1164 | PB1 := Size; AllocByte; |
822 | PB2 := Size; AllocByte; |
1165 | PB2 := Size; AllocByte; |
823 | 1166 | ||
Line 902... | Line 1245... | ||
902 | Inc(Src); |
1245 | Inc(Src); |
903 | end; |
1246 | end; |
904 | 1247 | ||
905 | AllocByte^ := B1; |
1248 | AllocByte^ := B1; |
906 | AllocByte^ := B2; |
1249 | AllocByte^ := B2; |
- | 1250 | end |
|
907 | end else |
1251 | else |
908 | if (Source.FWidth-x>2) and (Src^<>PByte(Integer(Src)+1)^) and (PByte(Integer(Src)+1)^=PByte(Integer(Src)+2)^) then |
1252 | if (Source.FWidth - x > 2) and (Src^ <> PByte(Integer(Src) + 1)^) and (PByte(Integer(Src) + 1)^ = PByte(Integer(Src) + 2)^) then |
909 | begin |
1253 | begin |
910 | { Encoding mode } |
1254 | { Encoding mode } |
911 | AllocByte^ := 1; |
1255 | AllocByte^ := 1; |
912 | AllocByte^ := Src^; Inc(Src); |
1256 | AllocByte^ := Src^; Inc(Src); |
913 | Inc(x); |
1257 | Inc(x); |
- | 1258 | end |
|
914 | end else |
1259 | else |
915 | begin |
1260 | begin |
916 | if (Source.FWidth-x<4) then |
1261 | if (Source.FWidth - x < 4) then |
917 | begin |
1262 | begin |
918 | { Encoding mode } |
1263 | { Encoding mode } |
919 | if Source.FWidth-x=2 then |
1264 | if Source.FWidth - x = 2 then |
Line 922... | Line 1267... | ||
922 | AllocByte^ := Src^; Inc(Src); |
1267 | AllocByte^ := Src^; Inc(Src); |
923 | 1268 | ||
924 | AllocByte^ := 1; |
1269 | AllocByte^ := 1; |
925 | AllocByte^ := Src^; Inc(Src); |
1270 | AllocByte^ := Src^; Inc(Src); |
926 | Inc(x, 2); |
1271 | Inc(x, 2); |
- | 1272 | end |
|
927 | end else |
1273 | else |
928 | begin |
1274 | begin |
929 | AllocByte^ := 1; |
1275 | AllocByte^ := 1; |
930 | AllocByte^ := Src^; Inc(Src); |
1276 | AllocByte^ := Src^; Inc(Src); |
931 | Inc(x); |
1277 | Inc(x); |
932 | end; |
1278 | end; |
- | 1279 | end |
|
933 | end else |
1280 | else |
934 | begin |
1281 | begin |
935 | { Absolute mode } |
1282 | { Absolute mode } |
936 | PB1 := Size; AllocByte; |
1283 | PB1 := Size; AllocByte; |
937 | PB2 := Size; AllocByte; |
1284 | PB2 := Size; AllocByte; |
938 | 1285 | ||
Line 977... | Line 1324... | ||
977 | end; |
1324 | end; |
978 | 1325 | ||
979 | begin |
1326 | begin |
980 | if Source.FCompressed then |
1327 | if Source.FCompressed then |
981 | Duplicate(Source, Source.FMemoryImage) |
1328 | Duplicate(Source, Source.FMemoryImage) |
- | 1329 | else |
|
982 | else begin |
1330 | begin |
983 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
1331 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
984 | Source.FPixelFormat, Source.FColorTable, True, True); |
1332 | Source.FPixelFormat, Source.FColorTable, True, True); |
985 | case FBitmapInfo.bmiHeader.biCompression of |
1333 | case FBitmapInfo.bmiHeader.biCompression of |
986 | BI_RLE4: EncodeRLE4; |
1334 | BI_RLE4: EncodeRLE4; |
987 | BI_RLE8: EncodeRLE8; |
1335 | BI_RLE8: EncodeRLE8; |
Line 1028... | Line 1376... | ||
1028 | for i:=0 to B2-1 do |
1376 | for i := 0 to B2 - 1 do |
1029 | begin |
1377 | begin |
1030 | if i and 1=0 then |
1378 | if i and 1 = 0 then |
1031 | begin |
1379 | begin |
1032 | C := Src^; Inc(Src); |
1380 | C := Src^; Inc(Src); |
- | 1381 | end |
|
1033 | end else |
1382 | else |
1034 | begin |
1383 | begin |
1035 | C := C shl 4; |
1384 | C := C shl 4; |
1036 | end; |
1385 | end; |
1037 | 1386 | ||
1038 | P := Pointer(Integer(Dest)+X shr 1); |
1387 | P := Pointer(Integer(Dest) + X shr 1); |
Line 1042... | Line 1391... | ||
1042 | P^ := (P^ and $F0) or ((C and $F0) shr 4); |
1391 | P^ := (P^ and $F0) or ((C and $F0) shr 4); |
1043 | 1392 | ||
1044 | Inc(X); |
1393 | Inc(X); |
1045 | end; |
1394 | end; |
1046 | end; |
1395 | end; |
- | 1396 | end |
|
1047 | end else |
1397 | else |
1048 | begin |
1398 | begin |
1049 | { Encoding mode } |
1399 | { Encoding mode } |
1050 | Dest := Pointer(Longint(FPBits)+Y*FWidthBytes); |
1400 | Dest := Pointer(Longint(FPBits) + Y * FWidthBytes); |
1051 | 1401 | ||
1052 | for i:=0 to B1-1 do |
1402 | for i := 0 to B1 - 1 do |
Line 1099... | Line 1449... | ||
1099 | end; |
1449 | end; |
1100 | else |
1450 | else |
1101 | { Absolute mode } |
1451 | { Absolute mode } |
1102 | Move(Src^, Dest^, B2); Inc(Dest, B2); Inc(Src, B2); |
1452 | Move(Src^, Dest^, B2); Inc(Dest, B2); Inc(Src, B2); |
1103 | end; |
1453 | end; |
- | 1454 | end |
|
1104 | end else |
1455 | else |
1105 | begin |
1456 | begin |
1106 | { Encoding mode } |
1457 | { Encoding mode } |
1107 | FillChar(Dest^, B1, B2); Inc(Dest, B1); |
1458 | FillChar(Dest^, B1, B2); Inc(Dest, B1); |
1108 | end; |
1459 | end; |
1109 | 1460 | ||
Line 1113... | Line 1464... | ||
1113 | end; |
1464 | end; |
1114 | 1465 | ||
1115 | begin |
1466 | begin |
1116 | if not Source.FCompressed then |
1467 | if not Source.FCompressed then |
1117 | Duplicate(Source, MemoryImage) |
1468 | Duplicate(Source, MemoryImage) |
- | 1469 | else |
|
1118 | else begin |
1470 | begin |
1119 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
1471 | NewImage(Source.FWidth, Source.FHeight, Source.FBitCount, |
1120 | Source.FPixelFormat, Source.FColorTable, MemoryImage, False); |
1472 | Source.FPixelFormat, Source.FColorTable, MemoryImage, False); |
1121 | case Source.FBitmapInfo.bmiHeader.biCompression of |
1473 | case Source.FBitmapInfo.bmiHeader.biCompression of |
1122 | BI_RLE4: DecodeRLE4; |
1474 | BI_RLE4: DecodeRLE4; |
1123 | BI_RLE8: DecodeRLE8; |
1475 | BI_RLE8: DecodeRLE8; |
Line 1134... | Line 1486... | ||
1134 | BCRGB: array[0..255] of TRGBTriple; |
1486 | BCRGB: array[0..255] of TRGBTriple; |
1135 | 1487 | ||
1136 | procedure LoadRLE4; |
1488 | procedure LoadRLE4; |
1137 | begin |
1489 | begin |
1138 | FSize := BI.biSizeImage; |
1490 | FSize := BI.biSizeImage; |
- | 1491 | //GetMem(FPBits, FSize); |
|
1139 | FPBits := GlobalAllocPtr(GMEM_FIXED, FSize); |
1492 | FPBits := GlobalAllocPtr(GMEM_FIXED, FSize); |
1140 | FBitmapInfo.bmiHeader.biSizeImage := FSize; |
1493 | FBitmapInfo.bmiHeader.biSizeImage := FSize; |
1141 | Stream.ReadBuffer(FPBits^, FSize); |
1494 | Stream.ReadBuffer(FPBits^, FSize); |
1142 | end; |
1495 | end; |
1143 | 1496 | ||
1144 | procedure LoadRLE8; |
1497 | procedure LoadRLE8; |
1145 | begin |
1498 | begin |
1146 | FSize := BI.biSizeImage; |
1499 | FSize := BI.biSizeImage; |
- | 1500 | //GetMem(FPBits, FSize); |
|
1147 | FPBits := GlobalAllocPtr(GMEM_FIXED, FSize); |
1501 | FPBits := GlobalAllocPtr(GMEM_FIXED, FSize); |
1148 | FBitmapInfo.bmiHeader.biSizeImage := FSize; |
1502 | FBitmapInfo.bmiHeader.biSizeImage := FSize; |
1149 | Stream.ReadBuffer(FPBits^, FSize); |
1503 | Stream.ReadBuffer(FPBits^, FSize); |
1150 | end; |
1504 | end; |
1151 | 1505 | ||
Line 1155... | Line 1509... | ||
1155 | begin |
1509 | begin |
1156 | if BI.biHeight<0 then |
1510 | if BI.biHeight < 0 then |
1157 | begin |
1511 | begin |
1158 | for y:=0 to Abs(BI.biHeight)-1 do |
1512 | for y := 0 to Abs(BI.biHeight) - 1 do |
1159 | Stream.ReadBuffer(Pointer(Integer(FTopPBits)+y*FNextLine)^, FWidthBytes); |
1513 | Stream.ReadBuffer(Pointer(Integer(FTopPBits) + y * FNextLine)^, FWidthBytes); |
- | 1514 | end |
|
1160 | end else |
1515 | else |
1161 | begin |
1516 | begin |
1162 | Stream.ReadBuffer(FPBits^, FSize); |
1517 | Stream.ReadBuffer(FPBits^, FSize); |
1163 | end; |
1518 | end; |
1164 | end; |
1519 | end; |
1165 | 1520 | ||
Line 1168... | Line 1523... | ||
1168 | OS2: Boolean; |
1523 | OS2: Boolean; |
1169 | Localpf: TLocalDIBPixelFormat; |
1524 | Localpf: TLocalDIBPixelFormat; |
1170 | AColorTable: TRGBQuads; |
1525 | AColorTable: TRGBQuads; |
1171 | APixelFormat: TDIBPixelFormat; |
1526 | APixelFormat: TDIBPixelFormat; |
1172 | begin |
1527 | begin |
- | 1528 | if not Assigned(Stream) then Exit; |
|
- | 1529 | ||
1173 | { Header size reading } |
1530 | { Header size reading } |
1174 | i := Stream.Read(BI.biSize, 4); |
1531 | i := Stream.Read(BI.biSize, 4); |
1175 | 1532 | ||
1176 | if i=0 then |
1533 | if i = 0 then |
1177 | begin |
1534 | begin |
- | 1535 | {$IFNDEF D17UP} |
|
- | 1536 | {self recreation is not allowed here} |
|
1178 | Create; |
1537 | Create; |
- | 1538 | {$ENDIF} |
|
1179 | Exit; |
1539 | Exit; |
1180 | end; |
1540 | end; |
1181 | if i<>4 then |
1541 | if i <> 4 then |
1182 | raise EInvalidGraphic.Create(SInvalidDIB); |
1542 | raise EInvalidGraphic.Create(SInvalidDIB); |
1183 | 1543 | ||
Line 1214... | Line 1574... | ||
1214 | if BI.biCompression = BI_BITFIELDS then |
1574 | if BI.biCompression = BI_BITFIELDS then |
1215 | begin |
1575 | begin |
1216 | Stream.ReadBuffer(Localpf, SizeOf(Localpf)); |
1576 | Stream.ReadBuffer(Localpf, SizeOf(Localpf)); |
1217 | with Localpf do |
1577 | with Localpf do |
1218 | APixelFormat := MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask); |
1578 | APixelFormat := MakeDIBPixelFormatMask(RBitMask, GBitMask, BBitMask); |
- | 1579 | end |
|
1219 | end else |
1580 | else |
1220 | begin |
1581 | begin |
1221 | if BI.biBitCount=16 then |
1582 | if BI.biBitCount = 16 then |
1222 | APixelFormat := MakeDIBPixelFormat(5, 5, 5) |
1583 | APixelFormat := MakeDIBPixelFormat(5, 5, 5) |
1223 | else if BI.biBitCount=32 then |
1584 | else if BI.biBitCount = 32 then |
1224 | APixelFormat := MakeDIBPixelFormat(8, 8, 8) |
1585 | APixelFormat := MakeDIBPixelFormat(8, 8, 8) |
Line 1241... | Line 1602... | ||
1241 | for i:=0 to PalCount-1 do |
1602 | for i := 0 to PalCount - 1 do |
1242 | begin |
1603 | begin |
1243 | with BCRGB[i] do |
1604 | with BCRGB[i] do |
1244 | AColorTable[i] := RGBQuad(rgbtRed, rgbtGreen, rgbtBlue); |
1605 | AColorTable[i] := RGBQuad(rgbtRed, rgbtGreen, rgbtBlue); |
1245 | end; |
1606 | end; |
- | 1607 | end |
|
1246 | end else |
1608 | else |
1247 | begin |
1609 | begin |
1248 | { Windows type } |
1610 | { Windows type } |
1249 | Stream.ReadBuffer(AColorTable, SizeOf(TRGBQuad)*PalCount); |
1611 | Stream.ReadBuffer(AColorTable, SizeOf(TRGBQuad) * PalCount); |
1250 | end; |
1612 | end; |
1251 | 1613 | ||
1252 | { DIB ì¬ } |
1614 | { DIB compilation } |
1253 | NewImage(BI.biWidth, Abs(BI.biHeight), BI.biBitCount, APixelFormat, AColorTable, |
1615 | NewImage(BI.biWidth, Abs(BI.biHeight), BI.biBitCount, APixelFormat, AColorTable, |
1254 | MemoryImage, BI.biCompression in [BI_RLE4, BI_RLE8]); |
1616 | MemoryImage, BI.biCompression in [BI_RLE4, BI_RLE8]); |
1255 | 1617 | ||
1256 | { Pixel data reading } |
1618 | { Pixel data reading } |
1257 | case BI.biCompression of |
1619 | case BI.biCompression of |
Line 1268... | Line 1630... | ||
1268 | begin |
1630 | begin |
1269 | if FHandle<>0 then |
1631 | if FHandle <> 0 then |
1270 | begin |
1632 | begin |
1271 | if FOldHandle<>0 then SelectObject(FDC, FOldHandle); |
1633 | if FOldHandle <> 0 then SelectObject(FDC, FOldHandle); |
1272 | DeleteObject(FHandle); |
1634 | DeleteObject(FHandle); |
- | 1635 | end |
|
1273 | end else |
1636 | else |
- | 1637 | // GlobalFree(THandle(FPBits)); |
|
1274 | begin |
1638 | begin |
1275 | if FPBits<>nil then |
1639 | if FPBits <> nil then |
1276 | GlobalFreePtr(FPBits); |
1640 | GlobalFreePtr(FPBits); |
1277 | end; |
1641 | end; |
1278 | 1642 | ||
Line 1331... | Line 1695... | ||
1331 | 1695 | ||
1332 | constructor TDIB.Create; |
1696 | constructor TDIB.Create; |
1333 | begin |
1697 | begin |
1334 | inherited Create; |
1698 | inherited Create; |
1335 | SetImage(EmptyDIBImage); |
1699 | SetImage(EmptyDIBImage); |
- | 1700 | ||
- | 1701 | FFreeList := TList.Create; |
|
1336 | end; |
1702 | end; |
1337 | 1703 | ||
1338 | destructor TDIB.Destroy; |
1704 | destructor TDIB.Destroy; |
- | 1705 | var |
|
- | 1706 | D: TDIB; |
|
1339 | begin |
1707 | begin |
1340 | SetImage(EmptyDIBImage); |
1708 | SetImage(EmptyDIBImage); |
1341 | FCanvas.Free; |
1709 | FCanvas.Free; |
- | 1710 | ||
- | 1711 | while FFreeList.Count > 0 do |
|
- | 1712 | try |
|
- | 1713 | D := TDIB(FFreeList[0]); |
|
- | 1714 | FFreeList.Remove(D); |
|
- | 1715 | D.Free; |
|
- | 1716 | except |
|
- | 1717 | end; |
|
- | 1718 | FFreeList.Free; |
|
- | 1719 | ||
1342 | inherited Destroy; |
1720 | inherited Destroy; |
1343 | end; |
1721 | end; |
1344 | 1722 | ||
1345 | procedure TDIB.Assign(Source: TPersistent); |
1723 | procedure TDIB.Assign(Source: TPersistent); |
1346 | 1724 | ||
Line 1370... | Line 1748... | ||
1370 | begin |
1748 | begin |
1371 | DIBSectionRec := @Data; |
1749 | DIBSectionRec := @Data; |
1372 | if DIBSectionRec^.dsBm.bmBitsPixel>=24 then |
1750 | if DIBSectionRec^.dsBm.bmBitsPixel >= 24 then |
1373 | begin |
1751 | begin |
1374 | PixelFormat := MakeDIBPixelFormat(8, 8, 8); |
1752 | PixelFormat := MakeDIBPixelFormat(8, 8, 8); |
- | 1753 | end |
|
1375 | end else |
1754 | else |
1376 | if DIBSectionRec^.dsBm.bmBitsPixel>8 then |
1755 | if DIBSectionRec^.dsBm.bmBitsPixel > 8 then |
1377 | begin |
1756 | begin |
1378 | PixelFormat := MakeDIBPixelFormat(DIBSectionRec^.dsBitfields[0], |
1757 | PixelFormat := MakeDIBPixelFormatMask(DIBSectionRec^.dsBitfields[0], //correct I.Ceneff, thanks |
1379 | DIBSectionRec^.dsBitfields[1], DIBSectionRec^.dsBitfields[2]); |
1758 | DIBSectionRec^.dsBitfields[1], DIBSectionRec^.dsBitfields[2]); |
- | 1759 | end |
|
1380 | end else |
1760 | else |
1381 | begin |
1761 | begin |
1382 | PixelFormat := MakeDIBPixelFormat(8, 8, 8); |
1762 | PixelFormat := MakeDIBPixelFormat(8, 8, 8); |
1383 | end; |
1763 | end; |
1384 | SetSize(DIBSectionRec^.dsBm.bmWidth, DIBSectionRec^.dsBm.bmHeight, |
1764 | SetSize(DIBSectionRec^.dsBm.bmWidth, DIBSectionRec^.dsBm.bmHeight, |
1385 | DIBSectionRec^.dsBm.bmBitsPixel); |
1765 | DIBSectionRec^.dsBm.bmBitsPixel); |
Line 1391... | Line 1771... | ||
1391 | FillChar(PBits^, Size, 0); |
1771 | FillChar(PBits^, Size, 0); |
1392 | Canvas.Draw(0, 0, Source); |
1772 | Canvas.Draw(0, 0, Source); |
1393 | end; |
1773 | end; |
1394 | 1774 | ||
1395 | procedure AssignGraphic(Source: TGraphic); |
1775 | procedure AssignGraphic(Source: TGraphic); |
- | 1776 | {$IFDEF PNG_GRAPHICS} |
|
- | 1777 | var |
|
- | 1778 | alpha: TDIB; |
|
- | 1779 | png: {$IFDEF VER12UP}TPngImage{$ELSE}TPNGObject{$ENDIF}; |
|
- | 1780 | i, j: Integer; |
|
- | 1781 | q: pByteArray; |
|
- | 1782 | {$ENDIF} |
|
- | 1783 | begin |
|
- | 1784 | {$IFDEF PNG_GRAPHICS} |
|
- | 1785 | if Source is {$IFDEF VER12UP}TPngImage{$ELSE}TPNGObject{$ENDIF} then |
|
- | 1786 | begin |
|
- | 1787 | alpha := TDIB.Create; |
|
- | 1788 | try |
|
- | 1789 | {png image} |
|
- | 1790 | png := {$IFDEF VER12UP}TPngImage{$ELSE}TPNGObject{$ENDIF}.Create; |
|
- | 1791 | try |
|
- | 1792 | png.Assign(Source); |
|
- | 1793 | if png.TransparencyMode = ptmPartial then |
|
1396 | begin |
1794 | begin |
- | 1795 | Alpha.SetSize(png.Width, png.Height, 8); |
|
- | 1796 | {separate alpha} |
|
- | 1797 | for i := 0 to png.Height - 1 do |
|
- | 1798 | begin |
|
- | 1799 | q := png.AlphaScanline[i]; |
|
- | 1800 | for j := 0 to png.Width - 1 do |
|
- | 1801 | alpha.Pixels[j,i] := q[j]; |
|
- | 1802 | end; |
|
- | 1803 | end; |
|
- | 1804 | SetSize(png.Width, png.Height, 32); |
|
- | 1805 | FillChar(PBits^, Size, 0); |
|
- | 1806 | Canvas.Draw(0, 0, png); |
|
- | 1807 | Transparent := png.Transparent; |
|
- | 1808 | finally |
|
- | 1809 | png.Free; |
|
- | 1810 | end; |
|
- | 1811 | if not alpha.Empty then |
|
- | 1812 | AssignAlphaChannel(alpha); |
|
- | 1813 | finally |
|
- | 1814 | alpha.Free; |
|
- | 1815 | end; |
|
- | 1816 | end |
|
- | 1817 | else |
|
- | 1818 | {$ENDIF} |
|
1397 | if Source is TBitmap then |
1819 | if Source is TBitmap then |
1398 | AssignBitmap(TBitmap(Source)) |
1820 | AssignBitmap(TBitmap(Source)) |
1399 | else |
1821 | else |
1400 | begin |
1822 | begin |
- | 1823 | SetSize(Source.Width, Source.Height, 32); |
|
- | 1824 | FillChar(PBits^, Size, 0); |
|
- | 1825 | Canvas.Draw(0, 0, Source); |
|
- | 1826 | Transparent := Source.Transparent; |
|
- | 1827 | if not HasAlphaChannel then |
|
- | 1828 | begin |
|
1401 | SetSize(Source.Width, Source.Height, 24); |
1829 | SetSize(Source.Width, Source.Height, 24); |
1402 | FillChar(PBits^, Size, 0); |
1830 | FillChar(PBits^, Size, 0); |
1403 | Canvas.Draw(0, 0, Source); |
1831 | Canvas.Draw(0, 0, Source); |
- | 1832 | Transparent := Source.Transparent; |
|
- | 1833 | end |
|
1404 | end; |
1834 | end; |
1405 | end; |
1835 | end; |
1406 | 1836 | ||
1407 | begin |
1837 | begin |
1408 | if Source=nil then |
1838 | if Source = nil then |
Line 1423... | Line 1853... | ||
1423 | Clear; |
1853 | Clear; |
1424 | end else |
1854 | end else |
1425 | inherited Assign(Source); |
1855 | inherited Assign(Source); |
1426 | end; |
1856 | end; |
1427 | 1857 | ||
1428 | procedure TDIB.Draw(ACanvas: TCanvas; const Rect: TRect); |
1858 | procedure TDIB.Draw(ACanvas: TCanvas; const ARect: TRect); |
1429 | var |
1859 | var |
1430 | OldPalette: HPalette; |
1860 | OldPalette: HPalette; |
1431 | OldMode: Integer; |
1861 | OldMode: Integer; |
1432 | begin |
1862 | begin |
1433 | if Size>0 then |
1863 | if Size > 0 then |
1434 | begin |
1864 | begin |
1435 | if PaletteCount>0 then |
1865 | if PaletteCount > 0 then |
1436 | begin |
1866 | begin |
1437 | OldPalette := SelectPalette(ACanvas.Handle, Palette, False); |
1867 | OldPalette := SelectPalette(ACanvas.Handle, Palette, False); |
1438 | RealizePalette(ACanvas.Handle); |
1868 | RealizePalette(ACanvas.Handle); |
- | 1869 | end |
|
1439 | end else |
1870 | else |
1440 | OldPalette := 0; |
1871 | OldPalette := 0; |
1441 | try |
1872 | try |
1442 | OldMode := SetStretchBltMode(ACanvas.Handle, COLORONCOLOR); |
1873 | OldMode := SetStretchBltMode(ACanvas.Handle, COLORONCOLOR); |
1443 | try |
1874 | try |
1444 | GdiFlush; |
1875 | GdiFlush; |
1445 | if FImage.FMemoryImage then |
1876 | if FImage.FMemoryImage then |
1446 | begin |
1877 | begin |
1447 | with Rect do |
1878 | with ARect do |
- | 1879 | begin |
|
1448 | StretchDIBits(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, |
1880 | if StretchDIBits(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, |
1449 | 0, 0, Width, Height, FImage.FPBits, FImage.FBitmapInfo^, DIB_RGB_COLORS , ACanvas.CopyMode); |
1881 | 0, 0, Self.Width, Self.Height, FImage.FPBits, FImage.FBitmapInfo^, DIB_RGB_COLORS, ACanvas.CopyMode) = 0 then |
- | 1882 | MessageBeep(1); |
|
- | 1883 | end; |
|
- | 1884 | end |
|
1450 | end else |
1885 | else |
1451 | begin |
1886 | begin |
1452 | with Rect do |
1887 | with ARect do |
1453 | StretchBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, |
1888 | StretchBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, |
1454 | FImage.FDC, 0, 0, Width, Height, ACanvas.CopyMode); |
1889 | FImage.FDC, 0, 0, Self.Width, Self.Height, ACanvas.CopyMode); |
1455 | end; |
1890 | end; |
1456 | finally |
1891 | finally |
1457 | SetStretchBltMode(ACanvas.Handle, OldMode); |
1892 | SetStretchBltMode(ACanvas.Handle, OldMode); |
1458 | end; |
1893 | end; |
1459 | finally |
1894 | finally |
Line 1555... | Line 1990... | ||
1555 | end; |
1990 | end; |
1556 | SetImage(TempImage); |
1991 | SetImage(TempImage); |
1557 | end; |
1992 | end; |
1558 | end; |
1993 | end; |
1559 | 1994 | ||
- | 1995 | type |
|
- | 1996 | PRGBA = ^TRGBA; |
|
- | 1997 | TRGBA = array[0..0] of Windows.TRGBQuad; |
|
- | 1998 | ||
- | 1999 | function TDIB.HasAlphaChannel: Boolean; |
|
- | 2000 | {give that DIB contain the alphachannel} |
|
- | 2001 | var |
|
- | 2002 | p: PRGBA; |
|
- | 2003 | X, Y: Integer; |
|
- | 2004 | begin |
|
- | 2005 | Result := True; |
|
- | 2006 | if BitCount = 32 then |
|
- | 2007 | for Y := 0 to Height - 1 do |
|
- | 2008 | begin |
|
- | 2009 | p := ScanLine[Y]; |
|
- | 2010 | for X := 0 to Width - 1 do |
|
- | 2011 | begin |
|
- | 2012 | if p[X].rgbReserved <> $0 then Exit; |
|
- | 2013 | end |
|
- | 2014 | end; |
|
- | 2015 | Result := False; |
|
- | 2016 | end; |
|
- | 2017 | ||
- | 2018 | function TDIB.AssignAlphaChannel(ALPHA: TDIB; ForceResize: Boolean{$IFDEF VER4UP} = False{$ENDIF}): Boolean; |
|
- | 2019 | {copy alphachannel from other DIB or add from DIB8} |
|
- | 2020 | var |
|
- | 2021 | p32_0, p32_1: PRGBA; |
|
- | 2022 | p24: Pointer; |
|
- | 2023 | pB: PArrayByte; |
|
- | 2024 | X, Y: Integer; |
|
- | 2025 | tmpDIB, qAlpha: TDIB; |
|
- | 2026 | begin |
|
- | 2027 | Result := False; |
|
- | 2028 | if GetEmpty then Exit; |
|
- | 2029 | {Alphachannel can be copy into 32bit DIB only!} |
|
- | 2030 | if BitCount <> 32 then |
|
- | 2031 | begin |
|
- | 2032 | tmpDIB := TDIB.Create; |
|
- | 2033 | try |
|
- | 2034 | tmpDIB.Assign(Self); |
|
- | 2035 | Clear; |
|
- | 2036 | SetSize(tmpDIB.Width, tmpDIB.Height, 32); |
|
- | 2037 | Canvas.Draw(0, 0, tmpDIB); |
|
- | 2038 | finally |
|
- | 2039 | tmpDIB.Free; |
|
- | 2040 | end; |
|
- | 2041 | end; |
|
- | 2042 | qAlpha := TDIB.Create; |
|
- | 2043 | try |
|
- | 2044 | if not Assigned(Alpha) then Exit; |
|
- | 2045 | if ForceResize then |
|
- | 2046 | begin |
|
- | 2047 | {create temp} |
|
- | 2048 | tmpDIB := TDIB.Create; |
|
- | 2049 | try |
|
- | 2050 | {picture} |
|
- | 2051 | tmpDIB.Assign(ALPHA); |
|
- | 2052 | {resample size} |
|
- | 2053 | tmpDIB.DoResample(Width, Height, ftrBSpline); |
|
- | 2054 | {convert to greyscale} |
|
- | 2055 | tmpDIB.Greyscale(8); |
|
- | 2056 | {return picture to qAlpha} |
|
- | 2057 | qAlpha.Assign(tmpDIB); |
|
- | 2058 | finally |
|
- | 2059 | tmpDIB.Free; |
|
- | 2060 | end; |
|
- | 2061 | end |
|
- | 2062 | else |
|
- | 2063 | {Must be the same size!} |
|
- | 2064 | if not ((Width = ALPHA.Width) and (Height = ALPHA.Height)) then Exit |
|
- | 2065 | else qAlpha.Assign(ALPHA); |
|
- | 2066 | {It works now with qAlpha only} |
|
- | 2067 | case qAlpha.BitCount of |
|
- | 2068 | 24: |
|
- | 2069 | begin |
|
- | 2070 | for Y := 0 to Height - 1 do |
|
- | 2071 | begin |
|
- | 2072 | p32_0 := ScanLine[Y]; |
|
- | 2073 | p24 := qAlpha.ScanLine[Y]; |
|
- | 2074 | for X := 0 to Width - 1 do with PBGR(p24)^ do |
|
- | 2075 | begin |
|
- | 2076 | p32_0[X].rgbReserved := Round(0.30 * R + 0.59 * G + 0.11 * B); |
|
- | 2077 | end |
|
- | 2078 | end; |
|
- | 2079 | end; |
|
- | 2080 | 32: |
|
- | 2081 | begin |
|
- | 2082 | for Y := 0 to Height - 1 do |
|
- | 2083 | begin |
|
- | 2084 | p32_0 := ScanLine[Y]; |
|
- | 2085 | p32_1 := qAlpha.ScanLine[Y]; |
|
- | 2086 | for X := 0 to Width - 1 do |
|
- | 2087 | begin |
|
- | 2088 | p32_0[X].rgbReserved := p32_1[X].rgbReserved; |
|
- | 2089 | end |
|
- | 2090 | end; |
|
- | 2091 | end; |
|
- | 2092 | 8: |
|
- | 2093 | begin |
|
- | 2094 | for Y := 0 to Height - 1 do |
|
- | 2095 | begin |
|
- | 2096 | p32_0 := ScanLine[Y]; |
|
- | 2097 | pB := qAlpha.ScanLine[Y]; |
|
- | 2098 | for X := 0 to Width - 1 do |
|
- | 2099 | begin |
|
- | 2100 | p32_0[X].rgbReserved := pB[X]; |
|
- | 2101 | end |
|
- | 2102 | end; |
|
- | 2103 | end; |
|
- | 2104 | 1: |
|
- | 2105 | begin |
|
- | 2106 | for Y := 0 to Height - 1 do |
|
- | 2107 | begin |
|
- | 2108 | p32_0 := ScanLine[Y]; |
|
- | 2109 | pB := qAlpha.ScanLine[Y]; |
|
- | 2110 | for X := 0 to Width - 1 do |
|
- | 2111 | begin |
|
- | 2112 | if pB[X] = 0 then |
|
- | 2113 | p32_0[X].rgbReserved := $FF |
|
- | 2114 | else |
|
- | 2115 | p32_0[X].rgbReserved := 0 |
|
- | 2116 | end |
|
- | 2117 | end; |
|
- | 2118 | end; |
|
- | 2119 | else |
|
- | 2120 | Exit; |
|
- | 2121 | end; |
|
- | 2122 | Result := True; |
|
- | 2123 | finally |
|
- | 2124 | qAlpha.Free; |
|
- | 2125 | end; |
|
- | 2126 | end; |
|
- | 2127 | ||
- | 2128 | procedure TDIB.RetAlphaChannel(out oDIB: TDIB); |
|
- | 2129 | {Store alphachannel information into DIB8} |
|
- | 2130 | var |
|
- | 2131 | p0: PRGBA; |
|
- | 2132 | pB: PArrayByte; |
|
- | 2133 | X, Y: Integer; |
|
- | 2134 | begin |
|
- | 2135 | oDIB := nil; |
|
- | 2136 | if not HasAlphaChannel then exit; |
|
- | 2137 | oDIB := TDIB.Create; |
|
- | 2138 | oDIB.SetSize(Width, Height, 8); |
|
- | 2139 | for Y := 0 to Height - 1 do |
|
- | 2140 | begin |
|
- | 2141 | p0 := ScanLine[Y]; |
|
- | 2142 | pB := oDIB.ScanLine[Y]; |
|
- | 2143 | for X := 0 to Width - 1 do |
|
- | 2144 | begin |
|
- | 2145 | pB[X] := p0[X].rgbReserved; |
|
- | 2146 | end |
|
- | 2147 | end; |
|
- | 2148 | end; |
|
- | 2149 | ||
1560 | function TDIB.GetBitmapInfo: PBitmapInfo; |
2150 | function TDIB.GetBitmapInfo: PBitmapInfo; |
1561 | begin |
2151 | begin |
1562 | Result := FImage.FBitmapInfo; |
2152 | Result := FImage.FBitmapInfo; |
1563 | end; |
2153 | end; |
1564 | 2154 | ||
Line 1681... | Line 2271... | ||
1681 | Result := 0; |
2271 | Result := 0; |
1682 | if (X>=0) and (X<FWidth) and (Y>=0) and (Y<FHeight) then |
2272 | if (X >= 0) and (X < FWidth) and (Y >= 0) and (Y < FHeight) then |
1683 | begin |
2273 | begin |
1684 | case FBitCount of |
2274 | case FBitCount of |
1685 | 1 : Result := (PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]; |
2275 | 1: Result := (PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]; |
1686 | 4 : Result := (PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]; |
2276 | 4: Result := ((PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]); |
1687 | 8 : Result := PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X]; |
2277 | 8: Result := PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X]; |
1688 | 16: Result := PArrayWord(Integer(FTopPBits)+Y*FNextLine)[X]; |
2278 | 16: Result := PArrayWord(Integer(FTopPBits) + Y * FNextLine)[X]; |
1689 | 24: with PArrayBGR(Integer(FTopPBits)+Y*FNextLine)[X] do |
2279 | 24: with PArrayBGR(Integer(FTopPBits) + Y * FNextLine)[X] do |
1690 | Result := R or (G shl 8) or (B shl 16); |
2280 | Result := R or (G shl 8) or (B shl 16); |
1691 | 32: Result := PArrayDWord(Integer(FTopPBits)+Y*FNextLine)[X]; |
2281 | 32: Result := PArrayDWord(Integer(FTopPBits) + Y * FNextLine)[X]; |
1692 | end; |
2282 | end; |
1693 | end; |
2283 | end; |
1694 | end; |
2284 | end; |
1695 | 2285 | ||
- | 2286 | function TDIB.GetRGBChannel: TDIB; |
|
- | 2287 | {Store RGB channel information into DIB24} |
|
- | 2288 | begin |
|
- | 2289 | Result := nil; |
|
- | 2290 | if Self.Empty then Exit; |
|
- | 2291 | Result := TDIB.Create; |
|
- | 2292 | Result.SetSize(Width, Height, 24); |
|
- | 2293 | Self.DrawOn(Bounds(0,0, Self.Width, Self.Height), Result.Canvas, 0, 0); |
|
- | 2294 | FFreeList.Add(Result); |
|
- | 2295 | end; |
|
- | 2296 | ||
1696 | procedure TDIB.SetPixel(X, Y: Integer; Value: DWORD); |
2297 | procedure TDIB.SetPixel(X, Y: Integer; Value: DWORD); |
1697 | var |
2298 | var |
1698 | P: PByte; |
2299 | P: PByte; |
1699 | begin |
2300 | begin |
1700 | Changing(True); |
2301 | Changing(True); |
Line 1705... | Line 2306... | ||
1705 | 1 : begin |
2306 | 1: begin |
1706 | P := @PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X shr 3]; |
2307 | P := @PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X shr 3]; |
1707 | P^ := (P^ and Mask1n[X and 7]) or ((Value and 1) shl Shift1[X and 7]); |
2308 | P^ := (P^ and Mask1n[X and 7]) or ((Value and 1) shl Shift1[X and 7]); |
1708 | end; |
2309 | end; |
1709 | 4 : begin |
2310 | 4: begin |
1710 | P := @PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X shr 3]; |
2311 | P := (@PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X shr 3]); |
1711 | P^ := (P^ and Mask4n[X and 1]) or ((Value and 15) shl Shift4[X and 1]); |
2312 | P^ := ((P^ and Mask4n[X and 1]) or ((Value and 15) shl Shift4[X and 1])); |
1712 | end; |
2313 | end; |
1713 | 8 : PArrayByte(Integer(FTopPBits)+Y*FNextLine)[X] := Value; |
2314 | 8: PArrayByte(Integer(FTopPBits) + Y * FNextLine)[X] := Value; |
1714 | 16: PArrayWord(Integer(FTopPBits)+Y*FNextLine)[X] := Value; |
2315 | 16: PArrayWord(Integer(FTopPBits) + Y * FNextLine)[X] := Value; |
1715 | 24: with PArrayBGR(Integer(FTopPBits)+Y*FNextLine)[X] do |
2316 | 24: with PArrayBGR(Integer(FTopPBits) + Y * FNextLine)[X] do |
1716 | begin |
2317 | begin |
Line 1721... | Line 2322... | ||
1721 | 32: PArrayDWord(Integer(FTopPBits)+Y*FNextLine)[X] := Value; |
2322 | 32: PArrayDWord(Integer(FTopPBits) + Y * FNextLine)[X] := Value; |
1722 | end; |
2323 | end; |
1723 | end; |
2324 | end; |
1724 | end; |
2325 | end; |
1725 | 2326 | ||
- | 2327 | procedure TDIB.SetRGBChannel(const Value: TDIB); |
|
- | 2328 | var |
|
- | 2329 | alpha: TDIB; |
|
- | 2330 | begin |
|
- | 2331 | if Self.HasAlphaChannel then |
|
- | 2332 | try |
|
- | 2333 | RetAlphaChannel(alpha); |
|
- | 2334 | Self.SetSize(Value.Width, Value.Height, 32); |
|
- | 2335 | Value.DrawOn(Bounds(0,0,Value.Width, Value.Height), Self.Canvas, 0, 0); |
|
- | 2336 | Self.AssignAlphaChannel(alpha, True); |
|
- | 2337 | finally |
|
- | 2338 | alpha.Free; |
|
- | 2339 | end |
|
- | 2340 | else |
|
- | 2341 | Self.Assign(Value); |
|
- | 2342 | end; |
|
- | 2343 | ||
1726 | procedure TDIB.DefineProperties(Filer: TFiler); |
2344 | procedure TDIB.DefineProperties(Filer: TFiler); |
1727 | begin |
2345 | begin |
1728 | inherited DefineProperties(Filer); |
2346 | inherited DefineProperties(Filer); |
1729 | { For interchangeability with an old version. } |
2347 | { For interchangeability with an old version. } |
1730 | Filer.DefineBinaryProperty('DIB', LoadFromStream, nil, False); |
2348 | Filer.DefineBinaryProperty('DIB', LoadFromStream, nil, False); |
1731 | end; |
2349 | end; |
1732 | 2350 | ||
1733 | type |
2351 | type |
- | 2352 | { TGlobalMemoryStream } |
|
- | 2353 | ||
1734 | TGlobalMemoryStream = class(TMemoryStream) |
2354 | TGlobalMemoryStream = class(TMemoryStream) |
1735 | private |
2355 | private |
1736 | FHandle: THandle; |
2356 | FHandle: THandle; |
1737 | public |
2357 | public |
1738 | constructor Create(AHandle: THandle); |
2358 | constructor Create(AHandle: THandle); |
Line 1771... | Line 2391... | ||
1771 | 2391 | ||
1772 | procedure TDIB.LoadFromStream(Stream: TStream); |
2392 | procedure TDIB.LoadFromStream(Stream: TStream); |
1773 | var |
2393 | var |
1774 | BF: TBitmapFileHeader; |
2394 | BF: TBitmapFileHeader; |
1775 | i: Integer; |
2395 | i: Integer; |
- | 2396 | ImageJPEG: TJPEGImage; |
|
1776 | begin |
2397 | begin |
1777 | { File header reading } |
2398 | { File header reading } |
1778 | i := Stream.Read(BF, SizeOf(TBitmapFileHeader)); |
2399 | i := Stream.Read(BF, SizeOf(TBitmapFileHeader)); |
1779 | if i=0 then Exit; |
2400 | if i = 0 then Exit; |
1780 | if i<>SizeOf(TBitmapFileHeader) then |
2401 | if i <> SizeOf(TBitmapFileHeader) then |
1781 | raise EInvalidGraphic.Create(SInvalidDIB); |
2402 | raise EInvalidGraphic.Create(SInvalidDIB); |
1782 | 2403 | ||
- | 2404 | { Is the head jpeg ?} |
|
- | 2405 | ||
- | 2406 | if BF.bfType = $D8FF then |
|
- | 2407 | begin |
|
- | 2408 | ImageJPEG := TJPEGImage.Create; |
|
- | 2409 | try |
|
- | 2410 | try |
|
- | 2411 | Stream.Position := 0; |
|
- | 2412 | ImageJPEG.LoadFromStream(Stream); |
|
- | 2413 | except |
|
- | 2414 | on EInvalidGraphic do ImageJPEG := nil; |
|
- | 2415 | end; |
|
- | 2416 | if ImageJPEG <> nil then |
|
- | 2417 | begin |
|
- | 2418 | {set size and bitcount in natural units of jpeg} |
|
- | 2419 | SetSize(ImageJPEG.Width, ImageJPEG.Height, 24); |
|
- | 2420 | Canvas.Draw(0, 0, ImageJPEG); |
|
- | 2421 | Exit |
|
- | 2422 | end; |
|
- | 2423 | finally |
|
- | 2424 | ImageJPEG.Free; |
|
- | 2425 | end; |
|
- | 2426 | end |
|
- | 2427 | else |
|
1783 | { Is the head 'BM'? } |
2428 | { Is the head 'BM'? } |
1784 | if BF.bfType<>BitmapFileType then |
2429 | if BF.bfType <> BitmapFileType then |
1785 | raise EInvalidGraphic.Create(SInvalidDIB); |
2430 | raise EInvalidGraphic.Create(SInvalidDIB); |
1786 | 2431 | ||
1787 | ReadData(Stream); |
2432 | ReadData(Stream); |
Line 1862... | Line 2507... | ||
1862 | else |
2507 | else |
1863 | begin |
2508 | begin |
1864 | if Empty then |
2509 | if Empty then |
1865 | begin |
2510 | begin |
1866 | SetSize(Max(Width, 1), Max(Height, 1), Value) |
2511 | SetSize(Max(Width, 1), Max(Height, 1), Value) |
- | 2512 | end |
|
1867 | end else |
2513 | else |
1868 | begin |
2514 | begin |
1869 | ConvertBitCount(Value); |
2515 | ConvertBitCount(Value); |
1870 | end; |
2516 | end; |
1871 | end; |
2517 | end; |
1872 | end; |
2518 | end; |
Line 2029... | Line 2675... | ||
2029 | DestP := ScanLine[y]; |
2675 | DestP := ScanLine[y]; |
2030 | 2676 | ||
2031 | for x:=0 to Width-1 do |
2677 | for x := 0 to Width - 1 do |
2032 | begin |
2678 | begin |
2033 | case Temp.BitCount of |
2679 | case Temp.BitCount of |
- | 2680 | 1: |
|
2034 | 1 : begin |
2681 | begin |
2035 | i := (PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]; |
2682 | i := (PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]; |
2036 | end; |
2683 | end; |
- | 2684 | 4: |
|
2037 | 4 : begin |
2685 | begin |
2038 | i := (PArrayByte(SrcP)[X and 1] and Mask4[X and 1]) shr Shift4[X and 1]; |
2686 | i := (PArrayByte(SrcP)[X and 1] and Mask4[X and 1]) shr Shift4[X and 1]; |
2039 | end; |
2687 | end; |
- | 2688 | 8: |
|
2040 | 8 : begin |
2689 | begin |
2041 | i := PByte(SrcP)^; |
2690 | i := PByte(SrcP)^; |
2042 | Inc(PByte(SrcP)); |
2691 | Inc(PByte(SrcP)); |
2043 | end; |
2692 | end; |
2044 | end; |
2693 | end; |
2045 | 2694 | ||
2046 | case BitCount of |
2695 | case BitCount of |
- | 2696 | 1: |
|
2047 | 1 : begin |
2697 | begin |
2048 | P := @PArrayByte(DestP)[X shr 3]; |
2698 | P := @PArrayByte(DestP)[X shr 3]; |
2049 | P^ := (P^ and Mask1n[X and 7]) or (i shl Shift1[X shr 3]); |
2699 | P^ := (P^ and Mask1n[X and 7]) or (i shl Shift1[X shr 3]); |
2050 | end; |
2700 | end; |
- | 2701 | 4: |
|
2051 | 4 : begin |
2702 | begin |
2052 | P := @PArrayByte(DestP)[X shr 1]; |
2703 | P := @PArrayByte(DestP)[X shr 1]; |
2053 | P^ := (P^ and Mask4n[X and 1]) or (i shl Shift4[X and 1]); |
2704 | P^ := (P^ and Mask4n[X and 1]) or (i shl Shift4[X and 1]); |
2054 | end; |
2705 | end; |
- | 2706 | 8: |
|
2055 | 8 : begin |
2707 | begin |
2056 | PByte(DestP)^ := i; |
2708 | PByte(DestP)^ := i; |
2057 | Inc(PByte(DestP)); |
2709 | Inc(PByte(DestP)); |
2058 | end; |
2710 | end; |
2059 | end; |
2711 | end; |
2060 | end; |
2712 | end; |
Line 2077... | Line 2729... | ||
2077 | DestP := ScanLine[y]; |
2729 | DestP := ScanLine[y]; |
2078 | 2730 | ||
2079 | for x:=0 to Width-1 do |
2731 | for x := 0 to Width - 1 do |
2080 | begin |
2732 | begin |
2081 | case Temp.BitCount of |
2733 | case Temp.BitCount of |
- | 2734 | 1: |
|
2082 | 1 : begin |
2735 | begin |
2083 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]] do |
2736 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]] do |
2084 | begin |
2737 | begin |
2085 | cR := rgbRed; |
2738 | cR := rgbRed; |
2086 | cG := rgbGreen; |
2739 | cG := rgbGreen; |
2087 | cB := rgbBlue; |
2740 | cB := rgbBlue; |
2088 | end; |
2741 | end; |
2089 | end; |
2742 | end; |
- | 2743 | 4: |
|
2090 | 4 : begin |
2744 | begin |
2091 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]] do |
2745 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]] do |
2092 | begin |
2746 | begin |
2093 | cR := rgbRed; |
2747 | cR := rgbRed; |
2094 | cG := rgbGreen; |
2748 | cG := rgbGreen; |
2095 | cB := rgbBlue; |
2749 | cB := rgbBlue; |
2096 | end; |
2750 | end; |
2097 | end; |
2751 | end; |
- | 2752 | 8: |
|
2098 | 8 : begin |
2753 | begin |
2099 | with Temp.ColorTable[PByte(SrcP)^] do |
2754 | with Temp.ColorTable[PByte(SrcP)^] do |
2100 | begin |
2755 | begin |
2101 | cR := rgbRed; |
2756 | cR := rgbRed; |
2102 | cG := rgbGreen; |
2757 | cG := rgbGreen; |
2103 | cB := rgbBlue; |
2758 | cB := rgbBlue; |
2104 | end; |
2759 | end; |
2105 | Inc(PByte(SrcP)); |
2760 | Inc(PByte(SrcP)); |
2106 | end; |
2761 | end; |
- | 2762 | 16: |
|
2107 | 16: begin |
2763 | begin |
2108 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, cR, cG, cB); |
2764 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, cR, cG, cB); |
2109 | Inc(PWord(SrcP)); |
2765 | Inc(PWord(SrcP)); |
2110 | end; |
2766 | end; |
- | 2767 | 24: |
|
2111 | 24: begin |
2768 | begin |
2112 | with PBGR(SrcP)^ do |
2769 | with PBGR(SrcP)^ do |
2113 | begin |
2770 | begin |
2114 | cR := R; |
2771 | cR := R; |
2115 | cG := G; |
2772 | cG := G; |
2116 | cB := B; |
2773 | cB := B; |
2117 | end; |
2774 | end; |
2118 | 2775 | ||
2119 | Inc(PBGR(SrcP)); |
2776 | Inc(PBGR(SrcP)); |
2120 | end; |
2777 | end; |
- | 2778 | 32: |
|
2121 | 32: begin |
2779 | begin |
2122 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, cR, cG, cB); |
2780 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, cR, cG, cB); |
2123 | Inc(PDWORD(SrcP)); |
2781 | Inc(PDWORD(SrcP)); |
2124 | end; |
2782 | end; |
2125 | end; |
2783 | end; |
2126 | 2784 | ||
2127 | case BitCount of |
2785 | case BitCount of |
- | 2786 | 16: |
|
2128 | 16: begin |
2787 | begin |
2129 | PWord(DestP)^ := pfRGB(NowPixelFormat, cR, cG, cB); |
2788 | PWord(DestP)^ := pfRGB(NowPixelFormat, cR, cG, cB); |
2130 | Inc(PWord(DestP)); |
2789 | Inc(PWord(DestP)); |
2131 | end; |
2790 | end; |
- | 2791 | 24: |
|
2132 | 24: begin |
2792 | begin |
2133 | with PBGR(DestP)^ do |
2793 | with PBGR(DestP)^ do |
2134 | begin |
2794 | begin |
2135 | R := cR; |
2795 | R := cR; |
2136 | G := cG; |
2796 | G := cG; |
2137 | B := cB; |
2797 | B := cB; |
2138 | end; |
2798 | end; |
2139 | Inc(PBGR(DestP)); |
2799 | Inc(PBGR(DestP)); |
2140 | end; |
2800 | end; |
- | 2801 | 32: |
|
2141 | 32: begin |
2802 | begin |
2142 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, cR, cG, cB); |
2803 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, cR, cG, cB); |
2143 | Inc(PDWORD(DestP)); |
2804 | Inc(PDWORD(DestP)); |
2144 | end; |
2805 | end; |
2145 | end; |
2806 | end; |
2146 | end; |
2807 | end; |
Line 2161... | Line 2822... | ||
2161 | begin |
2822 | begin |
2162 | { The image is converted from the palette color image into the palette color image. } |
2823 | { The image is converted from the palette color image into the palette color image. } |
2163 | if Temp.BitCount<=BitCount then |
2824 | if Temp.BitCount <= BitCount then |
2164 | begin |
2825 | begin |
2165 | PaletteToPalette_Inc; |
2826 | PaletteToPalette_Inc; |
- | 2827 | end |
|
2166 | end else |
2828 | else |
2167 | begin |
2829 | begin |
2168 | case BitCount of |
2830 | case BitCount of |
2169 | 1: begin |
2831 | 1: begin |
2170 | ColorTable[0] := RGBQuad(0, 0, 0); |
2832 | ColorTable[0] := RGBQuad(0, 0, 0); |
2171 | ColorTable[1] := RGBQuad(255, 255, 255); |
2833 | ColorTable[1] := RGBQuad(255, 255, 255); |
Line 2175... | Line 2837... | ||
2175 | end; |
2837 | end; |
2176 | UpdatePalette; |
2838 | UpdatePalette; |
2177 | 2839 | ||
2178 | Canvas.Draw(0, 0, Temp); |
2840 | Canvas.Draw(0, 0, Temp); |
2179 | end; |
2841 | end; |
- | 2842 | end |
|
2180 | end else |
2843 | else |
2181 | if (Temp.BitCount<=8) and (BitCount>8) then |
2844 | if (Temp.BitCount <= 8) and (BitCount > 8) then |
2182 | begin |
2845 | begin |
2183 | { The image is converted from the palette color image into the rgb color image. } |
2846 | { The image is converted from the palette color image into the rgb color image. } |
2184 | PaletteToRGB_or_RGBToRGB; |
2847 | PaletteToRGB_or_RGBToRGB; |
- | 2848 | end |
|
2185 | end else |
2849 | else |
2186 | if (Temp.BitCount>8) and (BitCount<=8) then |
2850 | if (Temp.BitCount > 8) and (BitCount <= 8) then |
2187 | begin |
2851 | begin |
2188 | { The image is converted from the rgb color image into the palette color image. } |
2852 | { The image is converted from the rgb color image into the palette color image. } |
2189 | case BitCount of |
2853 | case BitCount of |
2190 | 1: begin |
2854 | 1: begin |
Line 2195... | Line 2859... | ||
2195 | 8: CreateHalftonePalette(3, 3, 2); |
2859 | 8: CreateHalftonePalette(3, 3, 2); |
2196 | end; |
2860 | end; |
2197 | UpdatePalette; |
2861 | UpdatePalette; |
2198 | 2862 | ||
2199 | Canvas.Draw(0, 0, Temp); |
2863 | Canvas.Draw(0, 0, Temp); |
- | 2864 | end |
|
2200 | end else |
2865 | else |
2201 | if (Temp.BitCount>8) and (BitCount>8) then |
2866 | if (Temp.BitCount > 8) and (BitCount > 8) then |
2202 | begin |
2867 | begin |
2203 | { The image is converted from the rgb color image into the rgb color image. } |
2868 | { The image is converted from the rgb color image into the rgb color image. } |
2204 | PaletteToRGB_or_RGBToRGB; |
2869 | PaletteToRGB_or_RGBToRGB; |
2205 | end; |
2870 | end; |
Line 2249... | Line 2914... | ||
2249 | end; |
2914 | end; |
2250 | 2915 | ||
2251 | Inc(FProgressY); |
2916 | Inc(FProgressY); |
2252 | end; |
2917 | end; |
2253 | 2918 | ||
- | 2919 | procedure TDIB.Mirror(MirrorX, MirrorY: Boolean); |
|
- | 2920 | var |
|
- | 2921 | x, y, Width2, c: Integer; |
|
- | 2922 | P1, P2, TempBuf: Pointer; |
|
- | 2923 | begin |
|
- | 2924 | if Empty then Exit; |
|
- | 2925 | if (not MirrorX) and (not MirrorY) then Exit; |
|
- | 2926 | ||
- | 2927 | if (not MirrorX) and (MirrorY) then |
|
- | 2928 | begin |
|
- | 2929 | GetMem(TempBuf, WidthBytes); |
|
- | 2930 | try |
|
- | 2931 | StartProgress('Mirror'); |
|
- | 2932 | try |
|
- | 2933 | for y := 0 to Height shr 1 - 1 do |
|
- | 2934 | begin |
|
- | 2935 | P1 := ScanLine[y]; |
|
- | 2936 | P2 := ScanLine[Height - y - 1]; |
|
- | 2937 | ||
- | 2938 | Move(P1^, TempBuf^, WidthBytes); |
|
- | 2939 | Move(P2^, P1^, WidthBytes); |
|
- | 2940 | Move(TempBuf^, P2^, WidthBytes); |
|
- | 2941 | ||
- | 2942 | UpdateProgress(y * 2); |
|
- | 2943 | end; |
|
- | 2944 | finally |
|
- | 2945 | EndProgress; |
|
- | 2946 | end; |
|
- | 2947 | finally |
|
- | 2948 | FreeMem(TempBuf, WidthBytes); |
|
- | 2949 | end; |
|
- | 2950 | end |
|
- | 2951 | else |
|
- | 2952 | if (MirrorX) and (not MirrorY) then |
|
- | 2953 | begin |
|
- | 2954 | Width2 := Width shr 1; |
|
- | 2955 | ||
- | 2956 | StartProgress('Mirror'); |
|
- | 2957 | try |
|
- | 2958 | for y := 0 to Height - 1 do |
|
- | 2959 | begin |
|
- | 2960 | P1 := ScanLine[y]; |
|
- | 2961 | ||
- | 2962 | case BitCount of |
|
- | 2963 | 1: |
|
- | 2964 | begin |
|
- | 2965 | for x := 0 to Width2 - 1 do |
|
- | 2966 | begin |
|
- | 2967 | c := Pixels[x, y]; |
|
- | 2968 | Pixels[x, y] := Pixels[Width - x - 1, y]; |
|
- | 2969 | Pixels[Width - x - 1, y] := c; |
|
- | 2970 | end; |
|
- | 2971 | end; |
|
- | 2972 | 4: |
|
- | 2973 | begin |
|
- | 2974 | for x := 0 to Width2 - 1 do |
|
- | 2975 | begin |
|
- | 2976 | c := Pixels[x, y]; |
|
- | 2977 | Pixels[x, y] := Pixels[Width - x - 1, y]; |
|
- | 2978 | Pixels[Width - x - 1, y] := c; |
|
- | 2979 | end; |
|
- | 2980 | end; |
|
- | 2981 | 8: |
|
- | 2982 | begin |
|
- | 2983 | P2 := Pointer(Integer(P1) + Width - 1); |
|
- | 2984 | for x := 0 to Width2 - 1 do |
|
- | 2985 | begin |
|
- | 2986 | PByte(@c)^ := PByte(P1)^; |
|
- | 2987 | PByte(P1)^ := PByte(P2)^; |
|
- | 2988 | PByte(P2)^ := PByte(@c)^; |
|
- | 2989 | Inc(PByte(P1)); |
|
- | 2990 | Dec(PByte(P2)); |
|
- | 2991 | end; |
|
- | 2992 | end; |
|
- | 2993 | 16: |
|
- | 2994 | begin |
|
- | 2995 | P2 := Pointer(Integer(P1) + (Width - 1) * 2); |
|
- | 2996 | for x := 0 to Width2 - 1 do |
|
- | 2997 | begin |
|
- | 2998 | PWord(@c)^ := PWord(P1)^; |
|
- | 2999 | PWord(P1)^ := PWord(P2)^; |
|
- | 3000 | PWord(P2)^ := PWord(@c)^; |
|
- | 3001 | Inc(PWord(P1)); |
|
- | 3002 | Dec(PWord(P2)); |
|
- | 3003 | end; |
|
- | 3004 | end; |
|
- | 3005 | 24: |
|
- | 3006 | begin |
|
- | 3007 | P2 := Pointer(Integer(P1) + (Width - 1) * 3); |
|
- | 3008 | for x := 0 to Width2 - 1 do |
|
- | 3009 | begin |
|
- | 3010 | PBGR(@c)^ := PBGR(P1)^; |
|
- | 3011 | PBGR(P1)^ := PBGR(P2)^; |
|
- | 3012 | PBGR(P2)^ := PBGR(@c)^; |
|
- | 3013 | Inc(PBGR(P1)); |
|
- | 3014 | Dec(PBGR(P2)); |
|
- | 3015 | end; |
|
- | 3016 | end; |
|
- | 3017 | 32: |
|
- | 3018 | begin |
|
- | 3019 | P2 := Pointer(Integer(P1) + (Width - 1) * 4); |
|
- | 3020 | for x := 0 to Width2 - 1 do |
|
- | 3021 | begin |
|
- | 3022 | PDWORD(@c)^ := PDWORD(P1)^; |
|
- | 3023 | PDWORD(P1)^ := PDWORD(P2)^; |
|
- | 3024 | PDWORD(P2)^ := PDWORD(@c)^; |
|
- | 3025 | Inc(PDWORD(P1)); |
|
- | 3026 | Dec(PDWORD(P2)); |
|
- | 3027 | end; |
|
- | 3028 | end; |
|
- | 3029 | end; |
|
- | 3030 | ||
- | 3031 | UpdateProgress(y); |
|
- | 3032 | end; |
|
- | 3033 | finally |
|
- | 3034 | EndProgress; |
|
- | 3035 | end; |
|
- | 3036 | end |
|
- | 3037 | else |
|
- | 3038 | if (MirrorX) and (MirrorY) then |
|
- | 3039 | begin |
|
- | 3040 | StartProgress('Mirror'); |
|
- | 3041 | try |
|
- | 3042 | for y := 0 to Height shr 1 - 1 do |
|
- | 3043 | begin |
|
- | 3044 | P1 := ScanLine[y]; |
|
- | 3045 | P2 := ScanLine[Height - y - 1]; |
|
- | 3046 | ||
- | 3047 | case BitCount of |
|
- | 3048 | 1: |
|
- | 3049 | begin |
|
- | 3050 | for x := 0 to Width - 1 do |
|
- | 3051 | begin |
|
- | 3052 | c := Pixels[x, y]; |
|
- | 3053 | Pixels[x, y] := Pixels[Width - x - 1, Height - y - 1]; |
|
- | 3054 | Pixels[Width - x - 1, Height - y - 1] := c; |
|
- | 3055 | end; |
|
- | 3056 | end; |
|
- | 3057 | 4: |
|
- | 3058 | begin |
|
- | 3059 | for x := 0 to Width - 1 do |
|
- | 3060 | begin |
|
- | 3061 | c := Pixels[x, y]; |
|
- | 3062 | Pixels[x, y] := Pixels[Width - x - 1, Height - y - 1]; |
|
- | 3063 | Pixels[Width - x - 1, Height - y - 1] := c; |
|
- | 3064 | end; |
|
- | 3065 | end; |
|
- | 3066 | 8: |
|
- | 3067 | begin |
|
- | 3068 | P2 := Pointer(Integer(P2) + Width - 1); |
|
- | 3069 | for x := 0 to Width - 1 do |
|
- | 3070 | begin |
|
- | 3071 | PByte(@c)^ := PByte(P1)^; |
|
- | 3072 | PByte(P1)^ := PByte(P2)^; |
|
- | 3073 | PByte(P2)^ := PByte(@c)^; |
|
- | 3074 | Inc(PByte(P1)); |
|
- | 3075 | Dec(PByte(P2)); |
|
- | 3076 | end; |
|
- | 3077 | end; |
|
- | 3078 | 16: |
|
- | 3079 | begin |
|
- | 3080 | P2 := Pointer(Integer(P2) + (Width - 1) * 2); |
|
- | 3081 | for x := 0 to Width - 1 do |
|
- | 3082 | begin |
|
- | 3083 | PWord(@c)^ := PWord(P1)^; |
|
- | 3084 | PWord(P1)^ := PWord(P2)^; |
|
- | 3085 | PWord(P2)^ := PWord(@c)^; |
|
- | 3086 | Inc(PWord(P1)); |
|
- | 3087 | Dec(PWord(P2)); |
|
- | 3088 | end; |
|
- | 3089 | end; |
|
- | 3090 | 24: |
|
- | 3091 | begin |
|
- | 3092 | P2 := Pointer(Integer(P2) + (Width - 1) * 3); |
|
- | 3093 | for x := 0 to Width - 1 do |
|
- | 3094 | begin |
|
- | 3095 | PBGR(@c)^ := PBGR(P1)^; |
|
- | 3096 | PBGR(P1)^ := PBGR(P2)^; |
|
- | 3097 | PBGR(P2)^ := PBGR(@c)^; |
|
- | 3098 | Inc(PBGR(P1)); |
|
- | 3099 | Dec(PBGR(P2)); |
|
- | 3100 | end; |
|
- | 3101 | end; |
|
- | 3102 | 32: |
|
- | 3103 | begin |
|
- | 3104 | P2 := Pointer(Integer(P2) + (Width - 1) * 4); |
|
- | 3105 | for x := 0 to Width - 1 do |
|
- | 3106 | begin |
|
- | 3107 | PDWORD(@c)^ := PDWORD(P1)^; |
|
- | 3108 | PDWORD(P1)^ := PDWORD(P2)^; |
|
- | 3109 | PDWORD(P2)^ := PDWORD(@c)^; |
|
- | 3110 | Inc(PDWORD(P1)); |
|
- | 3111 | Dec(PDWORD(P2)); |
|
- | 3112 | end; |
|
- | 3113 | end; |
|
- | 3114 | end; |
|
- | 3115 | ||
- | 3116 | UpdateProgress(y * 2); |
|
- | 3117 | end; |
|
- | 3118 | finally |
|
- | 3119 | EndProgress; |
|
- | 3120 | end; |
|
- | 3121 | end; |
|
- | 3122 | end; |
|
- | 3123 | ||
2254 | procedure TDIB.Blur(ABitCount: Integer; Radius: Integer); |
3124 | procedure TDIB.Blur(ABitCount: Integer; Radius: Integer); |
2255 | type |
3125 | type |
2256 | TAve = record |
3126 | TAve = record |
2257 | cR, cG, cB: DWORD; |
3127 | cR, cG, cB: DWORD; |
2258 | c: DWORD; |
3128 | c: DWORD; |
Line 2268... | Line 3138... | ||
2268 | SrcP: Pointer; |
3138 | SrcP: Pointer; |
2269 | AveP: ^TAve; |
3139 | AveP: ^TAve; |
2270 | R, G, B: Byte; |
3140 | R, G, B: Byte; |
2271 | begin |
3141 | begin |
2272 | case Temp.BitCount of |
3142 | case Temp.BitCount of |
- | 3143 | 1: |
|
2273 | 1 : begin |
3144 | begin |
2274 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3145 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2275 | AveP := @Ave; |
3146 | AveP := @Ave; |
2276 | for x:=0 to XCount-1 do |
3147 | for x := 0 to XCount - 1 do |
2277 | begin |
3148 | begin |
2278 | with Temp.ColorTable[(PByte(Integer(SrcP)+X shr 3)^ and Mask1[x and 7]) shr Shift1[x and 7]], AveP^ do |
3149 | with Temp.ColorTable[(PByte(Integer(SrcP) + X shr 3)^ and Mask1[x and 7]) shr Shift1[x and 7]], AveP^ do |
Line 2283... | Line 3154... | ||
2283 | Inc(c); |
3154 | Inc(c); |
2284 | end; |
3155 | end; |
2285 | Inc(AveP); |
3156 | Inc(AveP); |
2286 | end; |
3157 | end; |
2287 | end; |
3158 | end; |
- | 3159 | 4: |
|
2288 | 4 : begin |
3160 | begin |
2289 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3161 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2290 | AveP := @Ave; |
3162 | AveP := @Ave; |
2291 | for x:=0 to XCount-1 do |
3163 | for x := 0 to XCount - 1 do |
2292 | begin |
3164 | begin |
2293 | with Temp.ColorTable[(PByte(Integer(SrcP)+X shr 1)^ and Mask4[x and 1]) shr Shift4[x and 1]], AveP^ do |
3165 | with Temp.ColorTable[(PByte(Integer(SrcP) + X shr 1)^ and Mask4[x and 1]) shr Shift4[x and 1]], AveP^ do |
Line 2298... | Line 3170... | ||
2298 | Inc(c); |
3170 | Inc(c); |
2299 | end; |
3171 | end; |
2300 | Inc(AveP); |
3172 | Inc(AveP); |
2301 | end; |
3173 | end; |
2302 | end; |
3174 | end; |
- | 3175 | 8: |
|
2303 | 8 : begin |
3176 | begin |
2304 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3177 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2305 | AveP := @Ave; |
3178 | AveP := @Ave; |
2306 | for x:=0 to XCount-1 do |
3179 | for x := 0 to XCount - 1 do |
2307 | begin |
3180 | begin |
2308 | with Temp.ColorTable[PByte(SrcP)^], AveP^ do |
3181 | with Temp.ColorTable[PByte(SrcP)^], AveP^ do |
Line 2314... | Line 3187... | ||
2314 | end; |
3187 | end; |
2315 | Inc(PByte(SrcP)); |
3188 | Inc(PByte(SrcP)); |
2316 | Inc(AveP); |
3189 | Inc(AveP); |
2317 | end; |
3190 | end; |
2318 | end; |
3191 | end; |
- | 3192 | 16: |
|
2319 | 16: begin |
3193 | begin |
2320 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3194 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2321 | AveP := @Ave; |
3195 | AveP := @Ave; |
2322 | for x:=0 to XCount-1 do |
3196 | for x := 0 to XCount - 1 do |
2323 | begin |
3197 | begin |
2324 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
3198 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
Line 2331... | Line 3205... | ||
2331 | end; |
3205 | end; |
2332 | Inc(PWord(SrcP)); |
3206 | Inc(PWord(SrcP)); |
2333 | Inc(AveP); |
3207 | Inc(AveP); |
2334 | end; |
3208 | end; |
2335 | end; |
3209 | end; |
- | 3210 | 24: |
|
2336 | 24: begin |
3211 | begin |
2337 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3212 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2338 | AveP := @Ave; |
3213 | AveP := @Ave; |
2339 | for x:=0 to XCount-1 do |
3214 | for x := 0 to XCount - 1 do |
2340 | begin |
3215 | begin |
2341 | with PBGR(SrcP)^, AveP^ do |
3216 | with PBGR(SrcP)^, AveP^ do |
Line 2347... | Line 3222... | ||
2347 | end; |
3222 | end; |
2348 | Inc(PBGR(SrcP)); |
3223 | Inc(PBGR(SrcP)); |
2349 | Inc(AveP); |
3224 | Inc(AveP); |
2350 | end; |
3225 | end; |
2351 | end; |
3226 | end; |
- | 3227 | 32: |
|
2352 | 32: begin |
3228 | begin |
2353 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3229 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2354 | AveP := @Ave; |
3230 | AveP := @Ave; |
2355 | for x:=0 to XCount-1 do |
3231 | for x := 0 to XCount - 1 do |
2356 | begin |
3232 | begin |
2357 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
3233 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
Line 2375... | Line 3251... | ||
2375 | SrcP: Pointer; |
3251 | SrcP: Pointer; |
2376 | AveP: ^TAve; |
3252 | AveP: ^TAve; |
2377 | R, G, B: Byte; |
3253 | R, G, B: Byte; |
2378 | begin |
3254 | begin |
2379 | case Temp.BitCount of |
3255 | case Temp.BitCount of |
- | 3256 | 1: |
|
2380 | 1 : begin |
3257 | begin |
2381 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3258 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2382 | AveP := @Ave; |
3259 | AveP := @Ave; |
2383 | for x:=0 to XCount-1 do |
3260 | for x := 0 to XCount - 1 do |
2384 | begin |
3261 | begin |
2385 | with Temp.ColorTable[(PByte(Integer(SrcP)+X shr 3)^ and Mask1[x and 7]) shr Shift1[x and 7]], AveP^ do |
3262 | with Temp.ColorTable[(PByte(Integer(SrcP) + X shr 3)^ and Mask1[x and 7]) shr Shift1[x and 7]], AveP^ do |
Line 2390... | Line 3267... | ||
2390 | Dec(c); |
3267 | Dec(c); |
2391 | end; |
3268 | end; |
2392 | Inc(AveP); |
3269 | Inc(AveP); |
2393 | end; |
3270 | end; |
2394 | end; |
3271 | end; |
- | 3272 | 4: |
|
2395 | 4 : begin |
3273 | begin |
2396 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3274 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2397 | AveP := @Ave; |
3275 | AveP := @Ave; |
2398 | for x:=0 to XCount-1 do |
3276 | for x := 0 to XCount - 1 do |
2399 | begin |
3277 | begin |
2400 | with Temp.ColorTable[(PByte(Integer(SrcP)+X shr 1)^ and Mask4[x and 1]) shr Shift4[x and 1]], AveP^ do |
3278 | with Temp.ColorTable[(PByte(Integer(SrcP) + X shr 1)^ and Mask4[x and 1]) shr Shift4[x and 1]], AveP^ do |
Line 2405... | Line 3283... | ||
2405 | Dec(c); |
3283 | Dec(c); |
2406 | end; |
3284 | end; |
2407 | Inc(AveP); |
3285 | Inc(AveP); |
2408 | end; |
3286 | end; |
2409 | end; |
3287 | end; |
- | 3288 | 8: |
|
2410 | 8 : begin |
3289 | begin |
2411 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3290 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2412 | AveP := @Ave; |
3291 | AveP := @Ave; |
2413 | for x:=0 to XCount-1 do |
3292 | for x := 0 to XCount - 1 do |
2414 | begin |
3293 | begin |
2415 | with Temp.ColorTable[PByte(SrcP)^], AveP^ do |
3294 | with Temp.ColorTable[PByte(SrcP)^], AveP^ do |
Line 2421... | Line 3300... | ||
2421 | end; |
3300 | end; |
2422 | Inc(PByte(SrcP)); |
3301 | Inc(PByte(SrcP)); |
2423 | Inc(AveP); |
3302 | Inc(AveP); |
2424 | end; |
3303 | end; |
2425 | end; |
3304 | end; |
- | 3305 | 16: |
|
2426 | 16: begin |
3306 | begin |
2427 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3307 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2428 | AveP := @Ave; |
3308 | AveP := @Ave; |
2429 | for x:=0 to XCount-1 do |
3309 | for x := 0 to XCount - 1 do |
2430 | begin |
3310 | begin |
2431 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
3311 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
Line 2438... | Line 3318... | ||
2438 | end; |
3318 | end; |
2439 | Inc(PWord(SrcP)); |
3319 | Inc(PWord(SrcP)); |
2440 | Inc(AveP); |
3320 | Inc(AveP); |
2441 | end; |
3321 | end; |
2442 | end; |
3322 | end; |
- | 3323 | 24: |
|
2443 | 24: begin |
3324 | begin |
2444 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3325 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2445 | AveP := @Ave; |
3326 | AveP := @Ave; |
2446 | for x:=0 to XCount-1 do |
3327 | for x := 0 to XCount - 1 do |
2447 | begin |
3328 | begin |
2448 | with PBGR(SrcP)^, AveP^ do |
3329 | with PBGR(SrcP)^, AveP^ do |
Line 2454... | Line 3335... | ||
2454 | end; |
3335 | end; |
2455 | Inc(PBGR(SrcP)); |
3336 | Inc(PBGR(SrcP)); |
2456 | Inc(AveP); |
3337 | Inc(AveP); |
2457 | end; |
3338 | end; |
2458 | end; |
3339 | end; |
- | 3340 | 32: |
|
2459 | 32: begin |
3341 | begin |
2460 | SrcP := Pointer(Integer(Temp.TopPBits)+Y*Temp.NextLine); |
3342 | SrcP := Pointer(Integer(Temp.TopPBits) + Y * Temp.NextLine); |
2461 | AveP := @Ave; |
3343 | AveP := @Ave; |
2462 | for x:=0 to XCount-1 do |
3344 | for x := 0 to XCount - 1 do |
2463 | begin |
3345 | begin |
2464 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
3346 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
Line 2577... | Line 3459... | ||
2577 | end; |
3459 | end; |
2578 | end; |
3460 | end; |
2579 | 3461 | ||
2580 | { The average is written. } |
3462 | { The average is written. } |
2581 | case BitCount of |
3463 | case BitCount of |
- | 3464 | 1: |
|
2582 | 1 : begin |
3465 | begin |
2583 | P := @PArrayByte(DestP)[X shr 3]; |
3466 | P := @PArrayByte(DestP)[X shr 3]; |
2584 | with Ave do |
3467 | with Ave do |
2585 | P^ := (P^ and Mask1n[X and 7]) or (DWORD(Ord(((cR+cG+cB) div c) div 3>127)) shl Shift1[X and 7]); |
3468 | P^ := (P^ and Mask1n[X and 7]) or (DWORD(Ord(((cR + cG + cB) div c) div 3 > 127)) shl Shift1[X and 7]); |
2586 | end; |
3469 | end; |
- | 3470 | 4: |
|
2587 | 4 : begin |
3471 | begin |
2588 | P := @PArrayByte(DestP)[X shr 1]; |
3472 | P := @PArrayByte(DestP)[X shr 1]; |
2589 | with Ave do |
3473 | with Ave do |
2590 | P^ := (P^ and Mask4n[X and 1]) or (((((cR+cG+cB) div c) div 3) shr 4) shl Shift4[X and 1]); |
3474 | P^ := (P^ and Mask4n[X and 1]) or (((((cR + cG + cB) div c) div 3) shr 4) shl Shift4[X and 1]); |
2591 | end; |
3475 | end; |
- | 3476 | 8: |
|
2592 | 8 : begin |
3477 | begin |
2593 | with Ave do |
3478 | with Ave do |
2594 | PByte(DestP)^ := ((cR+cG+cB) div c) div 3; |
3479 | PByte(DestP)^ := ((cR + cG + cB) div c) div 3; |
2595 | Inc(PByte(DestP)); |
3480 | Inc(PByte(DestP)); |
2596 | end; |
3481 | end; |
- | 3482 | 16: |
|
2597 | 16: begin |
3483 | begin |
2598 | with Ave do |
3484 | with Ave do |
2599 | PWORD(DestP)^ := pfRGB(NowPixelFormat, cR div c, cG div c, cB div c); |
3485 | PWORD(DestP)^ := pfRGB(NowPixelFormat, cR div c, cG div c, cB div c); |
2600 | Inc(PWORD(DestP)); |
3486 | Inc(PWORD(DestP)); |
2601 | end; |
3487 | end; |
- | 3488 | 24: |
|
2602 | 24: begin |
3489 | begin |
2603 | with PBGR(DestP)^, Ave do |
3490 | with PBGR(DestP)^, Ave do |
2604 | begin |
3491 | begin |
2605 | R := cR div c; |
3492 | R := cR div c; |
2606 | G := cG div c; |
3493 | G := cG div c; |
2607 | B := cB div c; |
3494 | B := cB div c; |
2608 | end; |
3495 | end; |
2609 | Inc(PBGR(DestP)); |
3496 | Inc(PBGR(DestP)); |
2610 | end; |
3497 | end; |
- | 3498 | 32: |
|
2611 | 32: begin |
3499 | begin |
2612 | with Ave do |
3500 | with Ave do |
2613 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, cR div c, cG div c, cB div c); |
3501 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, cR div c, cG div c, cB div c); |
2614 | Inc(PDWORD(DestP)); |
3502 | Inc(PDWORD(DestP)); |
2615 | end; |
3503 | end; |
2616 | end; |
3504 | end; |
Line 2656... | Line 3544... | ||
2656 | finally |
3544 | finally |
2657 | EndProgress; |
3545 | EndProgress; |
2658 | end; |
3546 | end; |
2659 | end; |
3547 | end; |
2660 | 3548 | ||
- | 3549 | procedure TDIB.Negative; |
|
- | 3550 | var |
|
- | 3551 | i, i2: Integer; |
|
- | 3552 | P: Pointer; |
|
- | 3553 | begin |
|
- | 3554 | if Empty then exit; |
|
- | 3555 | ||
- | 3556 | if BitCount <= 8 then |
|
- | 3557 | begin |
|
- | 3558 | for i := 0 to 255 do |
|
- | 3559 | with ColorTable[i] do |
|
- | 3560 | begin |
|
- | 3561 | rgbRed := 255 - rgbRed; |
|
- | 3562 | rgbGreen := 255 - rgbGreen; |
|
- | 3563 | rgbBlue := 255 - rgbBlue; |
|
- | 3564 | end; |
|
- | 3565 | UpdatePalette; |
|
- | 3566 | end else |
|
- | 3567 | begin |
|
- | 3568 | P := PBits; |
|
- | 3569 | i2 := Size; |
|
- | 3570 | asm |
|
- | 3571 | mov ecx,i2 |
|
- | 3572 | mov eax,P |
|
- | 3573 | mov edx,ecx |
|
- | 3574 | ||
- | 3575 | { Unit of DWORD. } |
|
- | 3576 | @@qword_skip: |
|
- | 3577 | shr ecx,2 |
|
- | 3578 | jz @@dword_skip |
|
- | 3579 | ||
- | 3580 | dec ecx |
|
- | 3581 | @@dword_loop: |
|
- | 3582 | not dword ptr [eax+ecx*4] |
|
- | 3583 | dec ecx |
|
- | 3584 | jnl @@dword_loop |
|
- | 3585 | ||
- | 3586 | mov ecx,edx |
|
- | 3587 | shr ecx,2 |
|
- | 3588 | add eax,ecx*4 |
|
- | 3589 | ||
- | 3590 | { Unit of Byte. } |
|
- | 3591 | @@dword_skip: |
|
- | 3592 | mov ecx,edx |
|
- | 3593 | and ecx,3 |
|
- | 3594 | jz @@byte_skip |
|
- | 3595 | ||
- | 3596 | dec ecx |
|
- | 3597 | @@loop_byte: |
|
- | 3598 | not byte ptr [eax+ecx] |
|
- | 3599 | dec ecx |
|
- | 3600 | jnl @@loop_byte |
|
- | 3601 | ||
- | 3602 | @@byte_skip: |
|
- | 3603 | end; |
|
- | 3604 | end; |
|
- | 3605 | end; |
|
- | 3606 | ||
2661 | procedure TDIB.Greyscale(ABitCount: Integer); |
3607 | procedure TDIB.Greyscale(ABitCount: Integer); |
2662 | var |
3608 | var |
2663 | YTblR, YTblG, YTblB: array[0..255] of Byte; |
3609 | YTblR, YTblG, YTblB: array[0..255] of Byte; |
2664 | i, j, x, y: Integer; |
3610 | i, j, x, y: Integer; |
2665 | c: DWORD; |
3611 | c: DWORD; |
2666 | R, G, B: Byte; |
3612 | R, G, B: Byte; |
2667 | Temp: TDIB; |
3613 | Temp: TDIB; |
2668 | DestP, SrcP: Pointer; |
3614 | DestP, SrcP: Pointer; |
2669 | P: PByte; |
3615 | P: PByte; |
2670 | begin |
3616 | begin |
2671 | if Empty then exit; |
3617 | if Empty then Exit; |
2672 | 3618 | ||
2673 | Temp := TDIB.Create; |
3619 | Temp := TDIB.Create; |
2674 | try |
3620 | try |
2675 | Temp.Assign(Self); |
3621 | Temp.Assign(Self); |
2676 | SetSize(Width, Height, ABitCount); |
3622 | SetSize(Width, Height, ABitCount); |
Line 2704... | Line 3650... | ||
2704 | SrcP := Temp.ScanLine[y]; |
3650 | SrcP := Temp.ScanLine[y]; |
2705 | 3651 | ||
2706 | for x:=0 to Width-1 do |
3652 | for x := 0 to Width - 1 do |
2707 | begin |
3653 | begin |
2708 | case Temp.BitCount of |
3654 | case Temp.BitCount of |
- | 3655 | 1: |
|
2709 | 1 : begin |
3656 | begin |
2710 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]] do |
3657 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 3] and Mask1[X and 7]) shr Shift1[X and 7]] do |
2711 | c := YTblR[rgbRed]+YTblG[rgbGreen]+YTblB[rgbBlue]; |
3658 | c := YTblR[rgbRed] + YTblG[rgbGreen] + YTblB[rgbBlue]; |
2712 | end; |
3659 | end; |
- | 3660 | 4: |
|
2713 | 4 : begin |
3661 | begin |
2714 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]] do |
3662 | with Temp.ColorTable[(PArrayByte(SrcP)[X shr 1] and Mask4[X and 1]) shr Shift4[X and 1]] do |
2715 | c := YTblR[rgbRed]+YTblG[rgbGreen]+YTblB[rgbBlue]; |
3663 | c := YTblR[rgbRed] + YTblG[rgbGreen] + YTblB[rgbBlue]; |
2716 | end; |
3664 | end; |
- | 3665 | 8: |
|
2717 | 8 : begin |
3666 | begin |
2718 | with Temp.ColorTable[PByte(SrcP)^] do |
3667 | with Temp.ColorTable[PByte(SrcP)^] do |
2719 | c := YTblR[rgbRed]+YTblG[rgbGreen]+YTblB[rgbBlue]; |
3668 | c := YTblR[rgbRed] + YTblG[rgbGreen] + YTblB[rgbBlue]; |
2720 | Inc(PByte(SrcP)); |
3669 | Inc(PByte(SrcP)); |
2721 | end; |
3670 | end; |
- | 3671 | 16: |
|
2722 | 16: begin |
3672 | begin |
2723 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
3673 | pfGetRGB(Temp.NowPixelFormat, PWord(SrcP)^, R, G, B); |
2724 | c := YTblR[R]+YTblR[G]+YTblR[B]; |
3674 | c := YTblR[R] + YTblR[G] + YTblR[B]; |
2725 | Inc(PWord(SrcP)); |
3675 | Inc(PWord(SrcP)); |
2726 | end; |
3676 | end; |
- | 3677 | 24: |
|
2727 | 24: begin |
3678 | begin |
2728 | with PBGR(SrcP)^ do |
3679 | with PBGR(SrcP)^ do |
2729 | c := YTblR[R]+YTblG[G]+YTblB[B]; |
3680 | c := YTblR[R] + YTblG[G] + YTblB[B]; |
2730 | Inc(PBGR(SrcP)); |
3681 | Inc(PBGR(SrcP)); |
2731 | end; |
3682 | end; |
- | 3683 | 32: |
|
2732 | 32: begin |
3684 | begin |
2733 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
3685 | pfGetRGB(Temp.NowPixelFormat, PDWORD(SrcP)^, R, G, B); |
2734 | c := YTblR[R]+YTblR[G]+YTblR[B]; |
3686 | c := YTblR[R] + YTblR[G] + YTblR[B]; |
2735 | Inc(PDWORD(SrcP)); |
3687 | Inc(PDWORD(SrcP)); |
2736 | end; |
3688 | end; |
2737 | end; |
3689 | end; |
2738 | 3690 | ||
2739 | case BitCount of |
3691 | case BitCount of |
- | 3692 | 1: |
|
2740 | 1 : begin |
3693 | begin |
2741 | P := @PArrayByte(DestP)[X shr 3]; |
3694 | P := @PArrayByte(DestP)[X shr 3]; |
2742 | P^ := (P^ and Mask1n[X and 7]) or (DWORD(Ord(c>127)) shl Shift1[X and 7]); |
3695 | P^ := (P^ and Mask1n[X and 7]) or (DWORD(Ord(c > 127)) shl Shift1[X and 7]); |
2743 | end; |
3696 | end; |
- | 3697 | 4: |
|
2744 | 4 : begin |
3698 | begin |
2745 | P := @PArrayByte(DestP)[X shr 1]; |
3699 | P := @PArrayByte(DestP)[X shr 1]; |
2746 | P^ := (P^ and Mask4n[X and 1]) or ((c shr 4) shl Shift4[X and 1]); |
3700 | P^ := (P^ and Mask4n[X and 1]) or ((c shr 4) shl Shift4[X and 1]); |
2747 | end; |
3701 | end; |
- | 3702 | 8: |
|
2748 | 8 : begin |
3703 | begin |
2749 | PByte(DestP)^ := c; |
3704 | PByte(DestP)^ := c; |
2750 | Inc(PByte(DestP)); |
3705 | Inc(PByte(DestP)); |
2751 | end; |
3706 | end; |
- | 3707 | 16: |
|
2752 | 16: begin |
3708 | begin |
2753 | PWord(DestP)^ := pfRGB(NowPixelFormat, c, c, c); |
3709 | PWord(DestP)^ := pfRGB(NowPixelFormat, c, c, c); |
2754 | Inc(PWord(DestP)); |
3710 | Inc(PWord(DestP)); |
2755 | end; |
3711 | end; |
- | 3712 | 24: |
|
2756 | 24: begin |
3713 | begin |
2757 | with PBGR(DestP)^ do |
3714 | with PBGR(DestP)^ do |
2758 | begin |
3715 | begin |
2759 | R := c; |
3716 | R := c; |
2760 | G := c; |
3717 | G := c; |
2761 | B := c; |
3718 | B := c; |
2762 | end; |
3719 | end; |
2763 | Inc(PBGR(DestP)); |
3720 | Inc(PBGR(DestP)); |
2764 | end; |
3721 | end; |
- | 3722 | 32: |
|
2765 | 32: begin |
3723 | begin |
2766 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, c, c, c); |
3724 | PDWORD(DestP)^ := pfRGB(NowPixelFormat, c, c, c); |
2767 | Inc(PDWORD(DestP)); |
3725 | Inc(PDWORD(DestP)); |
2768 | end; |
3726 | end; |
2769 | end; |
3727 | end; |
2770 | end; |
3728 | end; |
Line 2777... | Line 3735... | ||
2777 | finally |
3735 | finally |
2778 | Temp.Free; |
3736 | Temp.Free; |
2779 | end; |
3737 | end; |
2780 | end; |
3738 | end; |
2781 | 3739 | ||
- | 3740 | //-------------------------------------------------------------------------------------------------- |
|
- | 3741 | // Version : 0.1 - 26/06/2000 // |
|
- | 3742 | // Version : 0.2 - 04/07/2000 // |
|
- | 3743 | // At someone's request, i have added 3 news effects : // |
|
- | 3744 | // 1 - Rotate // |
|
- | 3745 | // 2 - SplitBlur // |
|
- | 3746 | // 3 - GaussianBlur // |
|
- | 3747 | //-------------------------------------------------------------------------------------------------- |
|
- | 3748 | // - NEW SPECIAL EFFECT - (English) // |
|
- | 3749 | //-------------------------------------------------------------------------------------------------- |
|
- | 3750 | // At the start, my idea was to create a component derived from TCustomDXDraw. Unfortunately, // |
|
- | 3751 | // it's impossible to run a graphic component (derived from TCustomDXDraw) in a conception's // |
|
- | 3752 | // mode (i don't success, but perhaps, somebody know how doing ! In that case, please help me !!!)// |
|
2782 | procedure TDIB.Mirror(MirrorX, MirrorY: Boolean); |
3753 | // Then, i'm used the DIB's unit for my work, but this unit is poor in special effect. Knowing a // |
- | 3754 | // library with more effect, i'm undertaked to import this library in DIB's unit. You can see the // |
|
- | 3755 | // FastLib library at : // |
|
- | 3756 | // // |
|
- | 3757 | // -> Gordon Alex Cowie <gfody@jps.net> www.jps.net/gfody // |
|
- | 3758 | // // |
|
- | 3759 | // It was very difficult, because implementation's graphic was very different that DIB's unit. // |
|
- | 3760 | // Sometimes, i'm deserted the possibility of original effect, particularly in conversion of DIB // |
|
- | 3761 | // whith 256, 16 and 2 colors. If someone can implement this fonctionnality, thanks to tell me // |
|
- | 3762 | // how this miracle is possible !!! // |
|
- | 3763 | // All these procedures are translated and adapted by : // |
|
- | 3764 | // // |
|
- | 3765 | // -> Mickey (Michel HIBON) <mhibon@ifrance.com> http://mickey.tsx.org // |
|
- | 3766 | // // |
|
- | 3767 | // IMPORTANT : These procedures don't modify the DIB's unit structure // |
|
- | 3768 | // Nota Bene : I don't implement these type of graphics (32 and 16 bit per pixels), // |
|
- | 3769 | // for one reason : I haven't bitmaps of this type !!! // |
|
- | 3770 | //-------------------------------------------------------------------------------------------------- |
|
- | 3771 | //-------------------------------------------------------------------------------------------------- |
|
- | 3772 | // - NOUVEAUX EFFETS SPECIAUX - (Français) // |
|
- | 3773 | //-------------------------------------------------------------------------------------------------- |
|
- | 3774 | // Au commencement, mon idée était de dériver un composant de TCustomDXDraw. Malheureusement, // |
|
- | 3775 | // c'est impossible de faire fonctionner un composant graphique (derivé de TCustomDXDraw) en mode // |
|
- | 3776 | // conception (je n'y suis pas parvenu, mais peut-être, que quelqu'un sait comment faire ! Dans // |
|
- | 3777 | // ce cas, vous seriez aimable de m'aider !!!) // |
|
- | 3778 | // Alors, j'ai utilisé l'unité DIB pour mon travail,mais celle-ci est pauvre en effet spéciaux. // |
|
- | 3779 | // Connaissant une librairie avec beaucoup plus d'effets spéciaux, j'ai entrepris d'importer // |
|
- | 3780 | // cette librairie dans l'unité DIB. Vous pouvez voir la librairie FastLib à : // |
|
- | 3781 | // // |
|
- | 3782 | // -> Gordon Alex Cowie <gfody@jps.net> www.jps.net/gfody // |
|
- | 3783 | // // |
|
- | 3784 | // C'était très difficile car l'implémentation graphique est très différente de l'unité DIB. // |
|
- | 3785 | // Parfois, j'ai abandonné les possibilités de l'effet original, particulièrement dans la // |
|
- | 3786 | // conversion des DIB avec 256, 16 et 2 couleurs. Si quelqu'un arrive à implémenter ces // |
|
- | 3787 | // fonctionnalités, merci de me dire comment ce miracle est possible !!! // |
|
- | 3788 | // Toutes ces procédures ont été traduites et adaptées par: // |
|
- | 3789 | // // |
|
- | 3790 | // -> Mickey (Michel HIBON) <mhibon@ifrance.com> http://mickey.tsx.org // |
|
- | 3791 | // // |
|
- | 3792 | // IMPORTANT : Ces procédures ne modifient pas la structure de l'unité DIB // |
|
- | 3793 | // Nota Bene : Je n'ai pas implémenté ces types de graphiques (32 et 16 bit par pixels), // |
|
- | 3794 | // pour une raison : je n'ai pas de bitmap de ce type !!! // |
|
- | 3795 | //-------------------------------------------------------------------------------------------------- |
|
2783 | var |
3796 | |
2784 | x, y, Width2, c: Integer; |
3797 | function TDIB.IntToColor(i: Integer): TBGR; |
2785 | P1, P2, TempBuf: Pointer; |
- | |
2786 | begin |
3798 | begin |
2787 | if Empty then exit; |
3799 | Result.b := i shr 16; |
2788 | if (not MirrorX) and (not MirrorY) then Exit; |
3800 | Result.g := i shr 8; |
- | 3801 | Result.r := i; |
|
- | 3802 | end; |
|
2789 | 3803 | ||
2790 | if (not MirrorX) and (MirrorY) then |
3804 | function TDIB.Interval(iMin, iMax, iValue: Integer; iMark: Boolean): Integer; |
2791 | begin |
3805 | begin |
2792 | GetMem(TempBuf, WidthBytes); |
- | |
2793 | try |
- | |
2794 | StartProgress('Mirror'); |
- | |
2795 | try |
3806 | if iMark then |
2796 | for y:=0 to Height shr 1-1 do |
- | |
2797 | begin |
3807 | begin |
- | 3808 | if iValue < iMin then |
|
2798 | P1 := ScanLine[y]; |
3809 | Result := iMin |
- | 3810 | else |
|
- | 3811 | if iValue > iMax then |
|
- | 3812 | Result := iMax |
|
- | 3813 | else |
|
2799 | P2 := ScanLine[Height-y-1]; |
3814 | Result := iValue; |
2800 | 3815 | end |
|
- | 3816 | else |
|
- | 3817 | begin |
|
2801 | Move(P1^, TempBuf^, WidthBytes); |
3818 | if iValue < iMin then |
- | 3819 | Result := iMin |
|
- | 3820 | else |
|
2802 | Move(P2^, P1^, WidthBytes); |
3821 | if iValue > iMax then |
- | 3822 | Result := iMin |
|
- | 3823 | else |
|
2803 | Move(TempBuf^, P2^, WidthBytes); |
3824 | Result := iValue; |
- | 3825 | end; |
|
- | 3826 | end; |
|
2804 | 3827 | ||
- | 3828 | procedure TDIB.Contrast(Amount: Integer); |
|
- | 3829 | var |
|
- | 3830 | x, y: Integer; |
|
- | 3831 | Table1: array[0..255] of Byte; |
|
- | 3832 | i: Byte; |
|
- | 3833 | S, D: pointer; |
|
- | 3834 | Temp1: TDIB; |
|
- | 3835 | color: DWORD; |
|
- | 3836 | P: PByte; |
|
- | 3837 | R, G, B: Byte; |
|
- | 3838 | begin |
|
- | 3839 | D := nil; |
|
- | 3840 | S := nil; |
|
- | 3841 | Temp1 := nil; |
|
- | 3842 | for i := 0 to 126 do |
|
- | 3843 | begin |
|
- | 3844 | y := (Abs(128 - i) * Amount) div 256; |
|
2805 | UpdateProgress(y*2); |
3845 | Table1[i] := IntToByte(i - y); |
2806 | end; |
3846 | end; |
- | 3847 | for i := 127 to 255 do |
|
- | 3848 | begin |
|
- | 3849 | y := (Abs(128 - i) * Amount) div 256; |
|
- | 3850 | Table1[i] := IntToByte(i + y); |
|
- | 3851 | end; |
|
- | 3852 | case BitCount of |
|
- | 3853 | 32: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 3854 | 24: ; // nothing to do |
|
- | 3855 | 16: ; // I have an artificial bitmap for this type ! i don't sure that it works |
|
- | 3856 | 8, 4: |
|
- | 3857 | begin |
|
- | 3858 | Temp1 := TDIB.Create; |
|
- | 3859 | Temp1.Assign(self); |
|
- | 3860 | Temp1.SetSize(Width, Height, BitCount); |
|
- | 3861 | for i := 0 to 255 do |
|
2807 | finally |
3862 | begin |
- | 3863 | with ColorTable[i] do |
|
2808 | EndProgress; |
3864 | begin |
- | 3865 | rgbRed := IntToByte(Table1[rgbRed]); |
|
- | 3866 | rgbGreen := IntToByte(Table1[rgbGreen]); |
|
- | 3867 | rgbBlue := IntToByte(Table1[rgbBlue]); |
|
2809 | end; |
3868 | end; |
2810 | finally |
- | |
2811 | FreeMem(TempBuf, WidthBytes); |
- | |
2812 | end; |
3869 | end; |
- | 3870 | UpdatePalette; |
|
- | 3871 | end; |
|
- | 3872 | else |
|
- | 3873 | // if the number of pixel is equal to 1 then exit of procedure |
|
- | 3874 | Exit; |
|
- | 3875 | end; |
|
2813 | end else if (MirrorX) and (not MirrorY) then |
3876 | for y := 0 to Pred(Height) do |
2814 | begin |
3877 | begin |
- | 3878 | case BitCount of |
|
- | 3879 | 24, 16: D := ScanLine[y]; |
|
- | 3880 | 8, 4: |
|
- | 3881 | begin |
|
- | 3882 | D := Temp1.ScanLine[y]; |
|
- | 3883 | S := Temp1.ScanLine[y]; |
|
- | 3884 | end; |
|
- | 3885 | else |
|
- | 3886 | end; |
|
- | 3887 | for x := 0 to Pred(Width) do |
|
- | 3888 | begin |
|
2815 | Width2 := Width shr 1; |
3889 | case BitCount of |
- | 3890 | 32: ; |
|
- | 3891 | 24: |
|
- | 3892 | begin |
|
- | 3893 | PBGR(D)^.B := Table1[PBGR(D)^.B]; |
|
- | 3894 | PBGR(D)^.G := Table1[PBGR(D)^.G]; |
|
- | 3895 | PBGR(D)^.R := Table1[PBGR(D)^.R]; |
|
- | 3896 | Inc(PBGR(D)); |
|
- | 3897 | end; |
|
- | 3898 | 16: |
|
- | 3899 | begin |
|
- | 3900 | pfGetRGB(NowPixelFormat, PWord(D)^, R, G, B); |
|
- | 3901 | PWord(D)^ := Table1[R] + Table1[G] + Table1[B]; |
|
- | 3902 | Inc(PWord(D)); |
|
- | 3903 | end; |
|
- | 3904 | 8: |
|
- | 3905 | begin |
|
- | 3906 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 3907 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 3908 | Inc(PByte(S)); |
|
- | 3909 | PByte(D)^ := color; |
|
- | 3910 | Inc(PByte(D)); |
|
- | 3911 | end; |
|
- | 3912 | 4: |
|
- | 3913 | begin |
|
- | 3914 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 3915 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 3916 | Inc(PByte(S)); |
|
- | 3917 | P := @PArrayByte(D)[X shr 1]; |
|
- | 3918 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
|
- | 3919 | end; |
|
- | 3920 | else |
|
- | 3921 | end; |
|
- | 3922 | end; |
|
- | 3923 | end; |
|
- | 3924 | case BitCount of |
|
- | 3925 | 8, 4: Temp1.Free; |
|
- | 3926 | else |
|
- | 3927 | end; |
|
- | 3928 | end; |
|
2816 | 3929 | ||
- | 3930 | procedure TDIB.Saturation(Amount: Integer); |
|
- | 3931 | var |
|
- | 3932 | Grays: array[0..767] of Integer; |
|
2817 | StartProgress('Mirror'); |
3933 | Alpha: array[0..255] of Word; |
- | 3934 | Gray, x, y: Integer; |
|
2818 | try |
3935 | i: Byte; |
2819 | for y:=0 to Height-1 do |
3936 | S, D: pointer; |
- | 3937 | Temp1: TDIB; |
|
- | 3938 | color: DWORD; |
|
- | 3939 | P: PByte; |
|
- | 3940 | R, G, B: Byte; |
|
2820 | begin |
3941 | begin |
- | 3942 | D := nil; |
|
- | 3943 | S := nil; |
|
- | 3944 | Temp1 := nil; |
|
- | 3945 | for i := 0 to 255 do |
|
- | 3946 | Alpha[i] := (i * Amount) shr 8; |
|
- | 3947 | x := 0; |
|
- | 3948 | for i := 0 to 255 do |
|
- | 3949 | begin |
|
- | 3950 | Gray := i - Alpha[i]; |
|
- | 3951 | Grays[x] := Gray; |
|
- | 3952 | Inc(x); |
|
- | 3953 | Grays[x] := Gray; |
|
- | 3954 | Inc(x); |
|
- | 3955 | Grays[x] := Gray; |
|
- | 3956 | Inc(x); |
|
- | 3957 | end; |
|
- | 3958 | case BitCount of |
|
- | 3959 | 32: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 3960 | 24: ; // nothing to do |
|
- | 3961 | 16: ; // I have an artificial bitmap for this type ! i don't sure that it works |
|
- | 3962 | 8, 4: |
|
- | 3963 | begin |
|
- | 3964 | Temp1 := TDIB.Create; |
|
- | 3965 | Temp1.Assign(self); |
|
- | 3966 | Temp1.SetSize(Width, Height, BitCount); |
|
- | 3967 | for i := 0 to 255 do |
|
- | 3968 | begin |
|
- | 3969 | with ColorTable[i] do |
|
- | 3970 | begin |
|
- | 3971 | Gray := Grays[rgbRed + rgbGreen + rgbBlue]; |
|
- | 3972 | rgbRed := IntToByte(Gray + Alpha[rgbRed]); |
|
- | 3973 | rgbGreen := IntToByte(Gray + Alpha[rgbGreen]); |
|
- | 3974 | rgbBlue := IntToByte(Gray + Alpha[rgbBlue]); |
|
- | 3975 | end; |
|
- | 3976 | end; |
|
- | 3977 | UpdatePalette; |
|
- | 3978 | end; |
|
- | 3979 | else |
|
- | 3980 | // if the number of pixel is equal to 1 then exit of procedure |
|
- | 3981 | Exit; |
|
- | 3982 | end; |
|
- | 3983 | for y := 0 to Pred(Height) do |
|
- | 3984 | begin |
|
- | 3985 | case BitCount of |
|
2821 | P1 := ScanLine[y]; |
3986 | 24, 16: D := ScanLine[y]; |
- | 3987 | 8, 4: |
|
- | 3988 | begin |
|
- | 3989 | D := Temp1.ScanLine[y]; |
|
- | 3990 | S := Temp1.ScanLine[y]; |
|
- | 3991 | end; |
|
- | 3992 | else |
|
- | 3993 | end; |
|
- | 3994 | for x := 0 to Pred(Width) do |
|
- | 3995 | begin |
|
- | 3996 | case BitCount of |
|
- | 3997 | 32: ; |
|
- | 3998 | 24: |
|
- | 3999 | begin |
|
- | 4000 | Gray := Grays[PBGR(D)^.R + PBGR(D)^.G + PBGR(D)^.B]; |
|
- | 4001 | PBGR(D)^.B := IntToByte(Gray + Alpha[PBGR(D)^.B]); |
|
- | 4002 | PBGR(D)^.G := IntToByte(Gray + Alpha[PBGR(D)^.G]); |
|
- | 4003 | PBGR(D)^.R := IntToByte(Gray + Alpha[PBGR(D)^.R]); |
|
- | 4004 | Inc(PBGR(D)); |
|
- | 4005 | end; |
|
- | 4006 | 16: |
|
- | 4007 | begin |
|
- | 4008 | pfGetRGB(NowPixelFormat, PWord(D)^, R, G, B); |
|
- | 4009 | PWord(D)^ := IntToByte(Gray + Alpha[B]) + IntToByte(Gray + Alpha[G]) + |
|
- | 4010 | IntToByte(Gray + Alpha[R]); |
|
- | 4011 | Inc(PWord(D)); |
|
- | 4012 | end; |
|
- | 4013 | 8: |
|
- | 4014 | begin |
|
- | 4015 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 4016 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 4017 | Inc(PByte(S)); |
|
- | 4018 | PByte(D)^ := color; |
|
- | 4019 | Inc(PByte(D)); |
|
- | 4020 | end; |
|
- | 4021 | 4: |
|
- | 4022 | begin |
|
- | 4023 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 4024 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 4025 | Inc(PByte(S)); |
|
- | 4026 | P := @PArrayByte(D)[X shr 1]; |
|
- | 4027 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
|
- | 4028 | end; |
|
- | 4029 | else |
|
- | 4030 | end; |
|
- | 4031 | end; |
|
- | 4032 | end; |
|
- | 4033 | case BitCount of |
|
- | 4034 | 8, 4: Temp1.Free; |
|
- | 4035 | else |
|
- | 4036 | end; |
|
- | 4037 | end; |
|
2822 | 4038 | ||
- | 4039 | procedure TDIB.Lightness(Amount: Integer); |
|
- | 4040 | var |
|
- | 4041 | x, y: Integer; |
|
- | 4042 | Table1: array[0..255] of Byte; |
|
- | 4043 | i: Byte; |
|
- | 4044 | S, D: pointer; |
|
- | 4045 | Temp1: TDIB; |
|
- | 4046 | color: DWORD; |
|
- | 4047 | P: PByte; |
|
- | 4048 | R, G, B: Byte; |
|
- | 4049 | begin |
|
- | 4050 | D := nil; |
|
- | 4051 | S := nil; |
|
- | 4052 | Temp1 := nil; |
|
- | 4053 | if Amount < 0 then |
|
- | 4054 | begin |
|
- | 4055 | Amount := -Amount; |
|
- | 4056 | for i := 0 to 255 do |
|
- | 4057 | Table1[i] := IntToByte(i - ((Amount * i) shr 8)); |
|
- | 4058 | end |
|
- | 4059 | else |
|
- | 4060 | for i := 0 to 255 do |
|
- | 4061 | Table1[i] := IntToByte(i + ((Amount * (i xor 255)) shr 8)); |
|
2823 | case BitCount of |
4062 | case BitCount of |
- | 4063 | 32: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 4064 | 24: ; // nothing to do |
|
- | 4065 | 16: ; // I have an artificial bitmap for this type ! i don't sure that it works |
|
- | 4066 | 8, 4: |
|
2824 | 1 : begin |
4067 | begin |
- | 4068 | Temp1 := TDIB.Create; |
|
- | 4069 | Temp1.Assign(self); |
|
- | 4070 | Temp1.SetSize(Width, Height, BitCount); |
|
2825 | for x:=0 to Width2-1 do |
4071 | for i := 0 to 255 do |
2826 | begin |
4072 | begin |
2827 | c := Pixels[x, y]; |
4073 | with ColorTable[i] do |
- | 4074 | begin |
|
- | 4075 | rgbRed := IntToByte(Table1[rgbRed]); |
|
2828 | Pixels[x, y] := Pixels[Width-x-1, y]; |
4076 | rgbGreen := IntToByte(Table1[rgbGreen]); |
2829 | Pixels[Width-x-1, y] := c; |
4077 | rgbBlue := IntToByte(Table1[rgbBlue]); |
2830 | end; |
4078 | end; |
2831 | end; |
4079 | end; |
2832 | 4 : begin |
4080 | UpdatePalette; |
- | 4081 | end; |
|
- | 4082 | else |
|
- | 4083 | // if the number of pixel is equal to 1 then exit of procedure |
|
- | 4084 | Exit; |
|
- | 4085 | end; |
|
2833 | for x:=0 to Width2-1 do |
4086 | for y := 0 to Pred(Height) do |
2834 | begin |
4087 | begin |
- | 4088 | case BitCount of |
|
2835 | c := Pixels[x, y]; |
4089 | 24, 16: D := ScanLine[y]; |
- | 4090 | 8, 4: |
|
- | 4091 | begin |
|
2836 | Pixels[x, y] := Pixels[Width-x-1, y]; |
4092 | D := Temp1.ScanLine[y]; |
2837 | Pixels[Width-x-1, y] := c; |
4093 | S := Temp1.ScanLine[y]; |
2838 | end; |
4094 | end; |
- | 4095 | else |
|
2839 | end; |
4096 | end; |
2840 | 8 : begin |
- | |
2841 | P2 := Pointer(Integer(P1)+Width-1); |
- | |
2842 | for x:=0 to Width2-1 do |
4097 | for x := 0 to Pred(Width) do |
2843 | begin |
4098 | begin |
- | 4099 | case BitCount of |
|
- | 4100 | 32: ; |
|
- | 4101 | 24: |
|
- | 4102 | begin |
|
2844 | PByte(@c)^ := PByte(P1)^; |
4103 | PBGR(D)^.B := Table1[PBGR(D)^.B]; |
- | 4104 | PBGR(D)^.G := Table1[PBGR(D)^.G]; |
|
- | 4105 | PBGR(D)^.R := Table1[PBGR(D)^.R]; |
|
- | 4106 | Inc(PBGR(D)); |
|
- | 4107 | end; |
|
- | 4108 | 16: |
|
- | 4109 | begin |
|
- | 4110 | pfGetRGB(NowPixelFormat, PWord(D)^, R, G, B); |
|
- | 4111 | PWord(D)^ := Table1[R] + Table1[G] + Table1[B]; |
|
- | 4112 | Inc(PWord(D)); |
|
- | 4113 | end; |
|
- | 4114 | 8: |
|
- | 4115 | begin |
|
2845 | PByte(P1)^ := PByte(P2)^; |
4116 | with Temp1.ColorTable[PByte(S)^] do |
- | 4117 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 4118 | Inc(PByte(S)); |
|
2846 | PByte(P2)^ := PByte(@c)^; |
4119 | PByte(D)^ := color; |
2847 | Inc(PByte(P1)); |
4120 | Inc(PByte(D)); |
- | 4121 | end; |
|
- | 4122 | 4: |
|
- | 4123 | begin |
|
- | 4124 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 4125 | color := rgbRed + rgbGreen + rgbBlue; |
|
2848 | Dec(PByte(P2)); |
4126 | Inc(PByte(S)); |
- | 4127 | P := @PArrayByte(D)[X shr 1]; |
|
- | 4128 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
|
2849 | end; |
4129 | end; |
- | 4130 | else |
|
2850 | end; |
4131 | end; |
- | 4132 | end; |
|
- | 4133 | end; |
|
- | 4134 | case BitCount of |
|
2851 | 16: begin |
4135 | 8, 4: Temp1.Free; |
- | 4136 | else |
|
- | 4137 | end; |
|
- | 4138 | end; |
|
- | 4139 | ||
2852 | P2 := Pointer(Integer(P1)+(Width-1)*2); |
4140 | procedure TDIB.AddRGB(aR, aG, aB: Byte); |
- | 4141 | var |
|
2853 | for x:=0 to Width2-1 do |
4142 | Table: array[0..255] of TBGR; |
- | 4143 | x, y: Integer; |
|
- | 4144 | i: Byte; |
|
- | 4145 | D: pointer; |
|
- | 4146 | P: PByte; |
|
- | 4147 | color: DWORD; |
|
- | 4148 | Temp1: TDIB; |
|
- | 4149 | R, G, B: Byte; |
|
2854 | begin |
4150 | begin |
- | 4151 | color := 0; |
|
- | 4152 | D := nil; |
|
- | 4153 | Temp1 := nil; |
|
- | 4154 | case BitCount of |
|
2855 | PWord(@c)^ := PWord(P1)^; |
4155 | 32: Exit; // I haven't bitmap of this type ! Sorry |
- | 4156 | 24, 16: |
|
- | 4157 | begin |
|
2856 | PWord(P1)^ := PWord(P2)^; |
4158 | for i := 0 to 255 do |
- | 4159 | begin |
|
2857 | PWord(P2)^ := PWord(@c)^; |
4160 | Table[i].b := IntToByte(i + aB); |
2858 | Inc(PWord(P1)); |
4161 | Table[i].g := IntToByte(i + aG); |
2859 | Dec(PWord(P2)); |
4162 | Table[i].r := IntToByte(i + aR); |
2860 | end; |
4163 | end; |
2861 | end; |
4164 | end; |
2862 | 24: begin |
4165 | 8, 4: |
2863 | P2 := Pointer(Integer(P1)+(Width-1)*3); |
- | |
2864 | for x:=0 to Width2-1 do |
- | |
2865 | begin |
4166 | begin |
- | 4167 | Temp1 := TDIB.Create; |
|
- | 4168 | Temp1.Assign(self); |
|
- | 4169 | Temp1.SetSize(Width, Height, BitCount); |
|
2866 | PBGR(@c)^ := PBGR(P1)^; |
4170 | for i := 0 to 255 do |
- | 4171 | begin |
|
2867 | PBGR(P1)^ := PBGR(P2)^; |
4172 | with ColorTable[i] do |
- | 4173 | begin |
|
2868 | PBGR(P2)^ := PBGR(@c)^; |
4174 | rgbRed := IntToByte(rgbRed + aR); |
2869 | Inc(PBGR(P1)); |
4175 | rgbGreen := IntToByte(rgbGreen + aG); |
2870 | Dec(PBGR(P2)); |
4176 | rgbBlue := IntToByte(rgbBlue + aB); |
2871 | end; |
4177 | end; |
2872 | end; |
4178 | end; |
2873 | 32: begin |
4179 | UpdatePalette; |
- | 4180 | end; |
|
- | 4181 | else |
|
2874 | P2 := Pointer(Integer(P1)+(Width-1)*4); |
4182 | // if the number of pixel is equal to 1 then exit of procedure |
- | 4183 | Exit; |
|
- | 4184 | end; |
|
2875 | for x:=0 to Width2-1 do |
4185 | for y := 0 to Pred(Height) do |
2876 | begin |
4186 | begin |
2877 | PDWORD(@c)^ := PDWORD(P1)^; |
4187 | case BitCount of |
2878 | PDWORD(P1)^ := PDWORD(P2)^; |
4188 | 24, 16: D := ScanLine[y]; |
2879 | PDWORD(P2)^ := PDWORD(@c)^; |
4189 | 8, 4: |
2880 | Inc(PDWORD(P1)); |
4190 | begin |
2881 | Dec(PDWORD(P2)); |
4191 | D := Temp1.ScanLine[y]; |
2882 | end; |
4192 | end; |
- | 4193 | else |
|
- | 4194 | end; |
|
- | 4195 | for x := 0 to Pred(Width) do |
|
- | 4196 | begin |
|
- | 4197 | case BitCount of |
|
- | 4198 | 32: ; // I haven't bitmap of this type ! Sorry |
|
- | 4199 | 24: |
|
- | 4200 | begin |
|
- | 4201 | PBGR(D)^.B := Table[PBGR(D)^.B].b; |
|
- | 4202 | PBGR(D)^.G := Table[PBGR(D)^.G].g; |
|
- | 4203 | PBGR(D)^.R := Table[PBGR(D)^.R].r; |
|
- | 4204 | Inc(PBGR(D)); |
|
- | 4205 | end; |
|
- | 4206 | 16: |
|
- | 4207 | begin |
|
- | 4208 | pfGetRGB(NowPixelFormat, PWord(D)^, R, G, B); |
|
- | 4209 | PWord(D)^ := Table[R].r + Table[G].g + Table[B].b; |
|
- | 4210 | Inc(PWord(D)); |
|
- | 4211 | end; |
|
- | 4212 | 8: |
|
- | 4213 | begin |
|
- | 4214 | Inc(PByte(D)); |
|
- | 4215 | end; |
|
- | 4216 | 4: |
|
- | 4217 | begin |
|
- | 4218 | P := @PArrayByte(D)[X shr 1]; |
|
- | 4219 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
|
- | 4220 | end; |
|
- | 4221 | else |
|
- | 4222 | end; |
|
- | 4223 | end; |
|
- | 4224 | end; |
|
- | 4225 | case BitCount of |
|
- | 4226 | 8, 4: Temp1.Free; |
|
- | 4227 | else |
|
2883 | end; |
4228 | end; |
2884 | end; |
4229 | end; |
2885 | 4230 | ||
- | 4231 | function TDIB.Filter(Dest: TDIB; Filter: TFilter): Boolean; |
|
- | 4232 | var |
|
- | 4233 | Sum, r, g, b, x, y: Integer; |
|
- | 4234 | a, i, j: byte; |
|
- | 4235 | tmp: TBGR; |
|
- | 4236 | Col: PBGR; |
|
- | 4237 | D: Pointer; |
|
- | 4238 | begin |
|
- | 4239 | Result := True; |
|
- | 4240 | Sum := Filter[0, 0] + Filter[1, 0] + Filter[2, 0] + |
|
- | 4241 | Filter[0, 1] + Filter[1, 1] + Filter[2, 1] + |
|
- | 4242 | Filter[0, 2] + Filter[1, 2] + Filter[2, 2]; |
|
- | 4243 | if Sum = 0 then |
|
- | 4244 | Sum := 1; |
|
- | 4245 | Col := PBits; |
|
- | 4246 | for y := 0 to Pred(Height) do |
|
- | 4247 | begin |
|
- | 4248 | D := Dest.ScanLine[y]; |
|
- | 4249 | for x := 0 to Pred(Width) do |
|
- | 4250 | begin |
|
- | 4251 | r := 0; g := 0; b := 0; |
|
- | 4252 | case BitCount of |
|
- | 4253 | 32, 16, 4, 1: |
|
- | 4254 | begin |
|
2886 | UpdateProgress(y); |
4255 | Result := False; |
- | 4256 | Exit; |
|
2887 | end; |
4257 | end; |
2888 | finally |
4258 | 24: |
- | 4259 | begin |
|
- | 4260 | for i := 0 to 2 do |
|
- | 4261 | begin |
|
- | 4262 | for j := 0 to 2 do |
|
- | 4263 | begin |
|
- | 4264 | Tmp := IntToColor(Pixels[Interval(0, Pred(Width), x + Pred(i), True), |
|
- | 4265 | Interval(0, Pred(Height), y + Pred(j), True)]); |
|
- | 4266 | Inc(b, Filter[i, j] * Tmp.b); |
|
- | 4267 | Inc(g, Filter[i, j] * Tmp.g); |
|
- | 4268 | Inc(r, Filter[i, j] * Tmp.r); |
|
2889 | EndProgress; |
4269 | end; |
- | 4270 | end; |
|
- | 4271 | Col.b := IntToByte(b div Sum); |
|
- | 4272 | Col.g := IntToByte(g div Sum); |
|
- | 4273 | Col.r := IntToByte(r div Sum); |
|
- | 4274 | Dest.Pixels[x, y] := rgb(Col.r, Col.g, Col.b); |
|
2890 | end; |
4275 | end; |
2891 | end else if (MirrorX) and (MirrorY) then |
4276 | 8: |
2892 | begin |
4277 | begin |
2893 | StartProgress('Mirror'); |
- | |
2894 | try |
- | |
2895 | for y:=0 to Height shr 1-1 do |
4278 | for i := 0 to 2 do |
2896 | begin |
4279 | begin |
- | 4280 | for j := 0 to 2 do |
|
2897 | P1 := ScanLine[y]; |
4281 | begin |
- | 4282 | a := (Pixels[Interval(0, Pred(Width), x + Pred(i), True), |
|
- | 4283 | Interval(0, Pred(Height), y + Pred(j), True)]); |
|
- | 4284 | tmp.r := ColorTable[a].rgbRed; |
|
- | 4285 | tmp.g := ColorTable[a].rgbGreen; |
|
- | 4286 | tmp.b := ColorTable[a].rgbBlue; |
|
- | 4287 | Inc(b, Filter[i, j] * Tmp.b); |
|
- | 4288 | Inc(g, Filter[i, j] * Tmp.g); |
|
- | 4289 | Inc(r, Filter[i, j] * Tmp.r); |
|
- | 4290 | end; |
|
- | 4291 | end; |
|
- | 4292 | Col.b := IntToByte(b div Sum); |
|
- | 4293 | Col.g := IntToByte(g div Sum); |
|
- | 4294 | Col.r := IntToByte(r div Sum); |
|
- | 4295 | PByte(D)^ := rgb(Col.r, Col.g, Col.b); |
|
2898 | P2 := ScanLine[Height-y-1]; |
4296 | Inc(PByte(D)); |
- | 4297 | end; |
|
- | 4298 | end; |
|
- | 4299 | end; |
|
- | 4300 | end; |
|
- | 4301 | end; |
|
2899 | 4302 | ||
- | 4303 | procedure TDIB.Spray(Amount: Integer); |
|
- | 4304 | var |
|
- | 4305 | value, x, y: Integer; |
|
- | 4306 | D: Pointer; |
|
- | 4307 | color: DWORD; |
|
- | 4308 | P: PByte; |
|
- | 4309 | begin |
|
- | 4310 | for y := Pred(Height) downto 0 do |
|
- | 4311 | begin |
|
- | 4312 | D := ScanLine[y]; |
|
- | 4313 | for x := 0 to Pred(Width) do |
|
- | 4314 | begin |
|
- | 4315 | value := Random(Amount); |
|
- | 4316 | color := Pixels[Interval(0, Pred(Width), x + (value - Random(value * 2)), True), |
|
- | 4317 | Interval(0, Pred(Height), y + (value - Random(value * 2)), True)]; |
|
2900 | case BitCount of |
4318 | case BitCount of |
2901 | 1 : begin |
4319 | 32: |
2902 | for x:=0 to Width-1 do |
- | |
2903 | begin |
4320 | begin |
2904 | c := Pixels[x, y]; |
4321 | PDWord(D)^ := color; |
2905 | Pixels[x, y] := Pixels[Width-x-1, Height-y-1]; |
- | |
2906 | Pixels[Width-x-1, Height-y-1] := c; |
4322 | Inc(PDWord(D)); |
2907 | end; |
4323 | end; |
- | 4324 | 24: |
|
- | 4325 | begin |
|
- | 4326 | PBGR(D)^ := IntToColor(color); |
|
- | 4327 | Inc(PBGR(D)); |
|
2908 | end; |
4328 | end; |
2909 | 4 : begin |
4329 | 16: |
2910 | for x:=0 to Width-1 do |
- | |
2911 | begin |
4330 | begin |
2912 | c := Pixels[x, y]; |
4331 | PWord(D)^ := color; |
2913 | Pixels[x, y] := Pixels[Width-x-1, Height-y-1]; |
- | |
2914 | Pixels[Width-x-1, Height-y-1] := c; |
4332 | Inc(PWord(D)); |
2915 | end; |
4333 | end; |
- | 4334 | 8: |
|
- | 4335 | begin |
|
- | 4336 | PByte(D)^ := color; |
|
- | 4337 | Inc(PByte(D)); |
|
2916 | end; |
4338 | end; |
2917 | 8 : begin |
4339 | 4: |
2918 | P2 := Pointer(Integer(P2)+Width-1); |
- | |
2919 | for x:=0 to Width-1 do |
- | |
2920 | begin |
4340 | begin |
2921 | PByte(@c)^ := PByte(P1)^; |
4341 | P := @PArrayByte(D)[X shr 1]; |
2922 | PByte(P1)^ := PByte(P2)^; |
- | |
2923 | PByte(P2)^ := PByte(@c)^; |
4342 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
2924 | Inc(PByte(P1)); |
- | |
2925 | Dec(PByte(P2)); |
- | |
2926 | end; |
4343 | end; |
- | 4344 | 1: |
|
- | 4345 | begin |
|
- | 4346 | P := @PArrayByte(D)[X shr 3]; |
|
- | 4347 | P^ := (P^ and Mask1n[X and 7]) or (color shl Shift1[X and 7]); |
|
2927 | end; |
4348 | end; |
- | 4349 | else |
|
2928 | 16: begin |
4350 | end; |
- | 4351 | end; |
|
- | 4352 | end; |
|
- | 4353 | end; |
|
- | 4354 | ||
2929 | P2 := Pointer(Integer(P2)+(Width-1)*2); |
4355 | procedure TDIB.Sharpen(Amount: Integer); |
- | 4356 | var |
|
2930 | for x:=0 to Width-1 do |
4357 | Lin0, Lin1, Lin2: PLines; |
- | 4358 | pc: PBGR; |
|
- | 4359 | cx, x, y: Integer; |
|
- | 4360 | Buf: array[0..8] of TBGR; |
|
- | 4361 | D: pointer; |
|
- | 4362 | c: DWORD; |
|
- | 4363 | i: byte; |
|
- | 4364 | P1: PByte; |
|
- | 4365 | Temp1: TDIB; |
|
- | 4366 | ||
2931 | begin |
4367 | begin |
- | 4368 | D := nil; |
|
- | 4369 | GetMem(pc, SizeOf(TBGR)); |
|
- | 4370 | c := 0; |
|
- | 4371 | Temp1 := nil; |
|
- | 4372 | case Bitcount of |
|
- | 4373 | 32, 16, 1: Exit; |
|
- | 4374 | 24: |
|
- | 4375 | begin |
|
- | 4376 | Temp1 := TDIB.Create; |
|
- | 4377 | Temp1.Assign(self); |
|
- | 4378 | Temp1.SetSize(Width, Height, bitCount); |
|
- | 4379 | end; |
|
- | 4380 | 8: |
|
- | 4381 | begin |
|
- | 4382 | Temp1 := TDIB.Create; |
|
- | 4383 | Temp1.Assign(self); |
|
- | 4384 | Temp1.SetSize(Width, Height, bitCount); |
|
- | 4385 | for i := 0 to 255 do |
|
- | 4386 | begin |
|
- | 4387 | with Temp1.ColorTable[i] do |
|
- | 4388 | begin |
|
- | 4389 | Buf[0].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4390 | Buf[0].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4391 | Buf[0].R := ColorTable[i - Amount].rgbRed; |
|
2932 | PWord(@c)^ := PWord(P1)^; |
4392 | Buf[1].B := ColorTable[i].rgbBlue; |
- | 4393 | Buf[1].G := ColorTable[i].rgbGreen; |
|
2933 | PWord(P1)^ := PWord(P2)^; |
4394 | Buf[1].R := ColorTable[i].rgbRed; |
- | 4395 | Buf[2].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4396 | Buf[2].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4397 | Buf[2].R := ColorTable[i + Amount].rgbRed; |
|
- | 4398 | Buf[3].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4399 | Buf[3].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4400 | Buf[3].R := ColorTable[i - Amount].rgbRed; |
|
2934 | PWord(P2)^ := PWord(@c)^; |
4401 | Buf[4].B := ColorTable[i].rgbBlue; |
- | 4402 | Buf[4].G := ColorTable[i].rgbGreen; |
|
2935 | Inc(PWord(P1)); |
4403 | Buf[4].R := ColorTable[i].rgbRed; |
- | 4404 | Buf[5].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4405 | Buf[5].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4406 | Buf[5].R := ColorTable[i + Amount].rgbRed; |
|
- | 4407 | Buf[6].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4408 | Buf[6].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4409 | Buf[6].R := ColorTable[i - Amount].rgbRed; |
|
- | 4410 | Buf[7].B := ColorTable[i].rgbBlue; |
|
- | 4411 | Buf[7].G := ColorTable[i].rgbGreen; |
|
2936 | Dec(PWord(P2)); |
4412 | Buf[7].R := ColorTable[i].rgbRed; |
- | 4413 | Buf[8].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4414 | Buf[8].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4415 | Buf[8].R := ColorTable[i + Amount].rgbRed; |
|
- | 4416 | Temp1.colorTable[i].rgbBlue := IntToByte((256 * Buf[4].b - (Buf[0].b + Buf[1].b + Buf[2].b + Buf[3].b + |
|
- | 4417 | Buf[5].b + Buf[6].b + Buf[7].b + Buf[8].b) * 16) div 128); |
|
- | 4418 | Temp1.colorTable[i].rgbGreen := IntToByte((256 * Buf[4].g - (Buf[0].g + Buf[1].g + Buf[2].g + Buf[3].g + |
|
- | 4419 | Buf[5].g + Buf[6].g + Buf[7].g + Buf[8].g) * 16) div 128); |
|
- | 4420 | Temp1.colorTable[i].rgbRed := IntToByte((256 * Buf[4].r - (Buf[0].r + Buf[1].r + Buf[2].r + Buf[3].r + |
|
- | 4421 | Buf[5].r + Buf[6].r + Buf[7].r + Buf[8].r) * 16) div 128); |
|
- | 4422 | ||
2937 | end; |
4423 | end; |
2938 | end; |
4424 | end; |
- | 4425 | Temp1.UpdatePalette; |
|
- | 4426 | end; |
|
- | 4427 | 4: |
|
2939 | 24: begin |
4428 | begin |
- | 4429 | Temp1 := TDIB.Create; |
|
- | 4430 | Temp1.Assign(self); |
|
2940 | P2 := Pointer(Integer(P2)+(Width-1)*3); |
4431 | Temp1.SetSize(Width, Height, bitCount); |
2941 | for x:=0 to Width-1 do |
4432 | for i := 0 to 255 do |
2942 | begin |
4433 | begin |
- | 4434 | with Temp1.ColorTable[i] do |
|
- | 4435 | begin |
|
- | 4436 | Buf[0].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4437 | Buf[0].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4438 | Buf[0].R := ColorTable[i - Amount].rgbRed; |
|
- | 4439 | Buf[1].B := ColorTable[i].rgbBlue; |
|
2943 | PBGR(@c)^ := PBGR(P1)^; |
4440 | Buf[1].G := ColorTable[i].rgbGreen; |
2944 | PBGR(P1)^ := PBGR(P2)^; |
4441 | Buf[1].R := ColorTable[i].rgbRed; |
- | 4442 | Buf[2].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4443 | Buf[2].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4444 | Buf[2].R := ColorTable[i + Amount].rgbRed; |
|
- | 4445 | Buf[3].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4446 | Buf[3].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4447 | Buf[3].R := ColorTable[i - Amount].rgbRed; |
|
- | 4448 | Buf[4].B := ColorTable[i].rgbBlue; |
|
2945 | PBGR(P2)^ := PBGR(@c)^; |
4449 | Buf[4].G := ColorTable[i].rgbGreen; |
2946 | Inc(PBGR(P1)); |
4450 | Buf[4].R := ColorTable[i].rgbRed; |
- | 4451 | Buf[5].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4452 | Buf[5].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4453 | Buf[5].R := ColorTable[i + Amount].rgbRed; |
|
- | 4454 | Buf[6].B := ColorTable[i - Amount].rgbBlue; |
|
- | 4455 | Buf[6].G := ColorTable[i - Amount].rgbGreen; |
|
- | 4456 | Buf[6].R := ColorTable[i - Amount].rgbRed; |
|
2947 | Dec(PBGR(P2)); |
4457 | Buf[7].B := ColorTable[i].rgbBlue; |
- | 4458 | Buf[7].G := ColorTable[i].rgbGreen; |
|
- | 4459 | Buf[7].R := ColorTable[i].rgbRed; |
|
- | 4460 | Buf[8].B := ColorTable[i + Amount].rgbBlue; |
|
- | 4461 | Buf[8].G := ColorTable[i + Amount].rgbGreen; |
|
- | 4462 | Buf[8].R := ColorTable[i + Amount].rgbRed; |
|
- | 4463 | colorTable[i].rgbBlue := IntToByte((256 * Buf[4].b - (Buf[0].b + Buf[1].b + Buf[2].b + Buf[3].b + |
|
- | 4464 | Buf[5].b + Buf[6].b + Buf[7].b + Buf[8].b) * 16) div 128); |
|
- | 4465 | colorTable[i].rgbGreen := IntToByte((256 * Buf[4].g - (Buf[0].g + Buf[1].g + Buf[2].g + Buf[3].g + |
|
- | 4466 | Buf[5].g + Buf[6].g + Buf[7].g + Buf[8].g) * 16) div 128); |
|
- | 4467 | colorTable[i].rgbRed := IntToByte((256 * Buf[4].r - (Buf[0].r + Buf[1].r + Buf[2].r + Buf[3].r + |
|
- | 4468 | Buf[5].r + Buf[6].r + Buf[7].r + Buf[8].r) * 16) div 128); |
|
2948 | end; |
4469 | end; |
2949 | end; |
4470 | end; |
2950 | 32: begin |
4471 | UpdatePalette; |
2951 | P2 := Pointer(Integer(P2)+(Width-1)*4); |
4472 | end; |
- | 4473 | end; |
|
2952 | for x:=0 to Width-1 do |
4474 | for y := 0 to Pred(Height) do |
2953 | begin |
4475 | begin |
2954 | PDWORD(@c)^ := PDWORD(P1)^; |
4476 | Lin0 := ScanLine[Interval(0, Pred(Height), y - Amount, True)]; |
2955 | PDWORD(P1)^ := PDWORD(P2)^; |
4477 | Lin1 := ScanLine[y]; |
2956 | PDWORD(P2)^ := PDWORD(@c)^; |
4478 | Lin2 := ScanLine[Interval(0, Pred(Height), y + Amount, True)]; |
2957 | Inc(PDWORD(P1)); |
4479 | case Bitcount of |
2958 | Dec(PDWORD(P2)); |
4480 | 24, 8, 4: D := Temp1.ScanLine[y]; |
2959 | end; |
4481 | end; |
- | 4482 | for x := 0 to Pred(Width) do |
|
- | 4483 | begin |
|
- | 4484 | case BitCount of |
|
- | 4485 | 24: |
|
- | 4486 | begin |
|
- | 4487 | cx := Interval(0, Pred(Width), x - Amount, True); |
|
- | 4488 | Buf[0] := Lin0[cx]; |
|
- | 4489 | Buf[1] := Lin1[cx]; |
|
- | 4490 | Buf[2] := Lin2[cx]; |
|
- | 4491 | Buf[3] := Lin0[x]; |
|
- | 4492 | Buf[4] := Lin1[x]; |
|
- | 4493 | Buf[5] := Lin2[x]; |
|
- | 4494 | cx := Interval(0, Pred(Width), x + Amount, true); |
|
- | 4495 | Buf[6] := Lin0[cx]; |
|
- | 4496 | Buf[7] := Lin1[cx]; |
|
- | 4497 | Buf[8] := Lin0[cx]; |
|
- | 4498 | pc.b := IntToByte((256 * Buf[4].b - (Buf[0].b + Buf[1].b + Buf[2].b + Buf[3].b + |
|
- | 4499 | Buf[5].b + Buf[6].b + Buf[7].b + Buf[8].b) * 16) div 128); |
|
- | 4500 | pc.g := IntToByte((256 * Buf[4].g - (Buf[0].g + Buf[1].g + Buf[2].g + Buf[3].g + |
|
- | 4501 | Buf[5].g + Buf[6].g + Buf[7].g + Buf[8].g) * 16) div 128); |
|
- | 4502 | pc.r := IntToByte((256 * Buf[4].r - (Buf[0].r + Buf[1].r + Buf[2].r + Buf[3].r + |
|
- | 4503 | Buf[5].r + Buf[6].r + Buf[7].r + Buf[8].r) * 16) div 128); |
|
- | 4504 | PBGR(D)^.B := pc.b; |
|
- | 4505 | PBGR(D)^.G := pc.g; |
|
- | 4506 | PBGR(D)^.R := pc.r; |
|
- | 4507 | Inc(PBGR(D)); |
|
- | 4508 | end; |
|
- | 4509 | 8: |
|
- | 4510 | begin |
|
- | 4511 | Inc(PByte(D)); |
|
- | 4512 | end; |
|
- | 4513 | 4: |
|
- | 4514 | begin |
|
- | 4515 | P1 := @PArrayByte(D)[X shr 1]; |
|
- | 4516 | P1^ := ((P1^ and Mask4n[X and 1]) or ((c shl Shift4[X and 1]))); |
|
2960 | end; |
4517 | end; |
2961 | end; |
4518 | end; |
- | 4519 | end; |
|
- | 4520 | end; |
|
- | 4521 | case BitCount of |
|
- | 4522 | 24, 8: |
|
- | 4523 | begin |
|
- | 4524 | Assign(Temp1); |
|
- | 4525 | Temp1.Free; |
|
- | 4526 | end; |
|
- | 4527 | 4: Temp1.Free; |
|
- | 4528 | end; |
|
- | 4529 | FreeMem(pc, SizeOf(TBGR)); |
|
- | 4530 | end; |
|
2962 | 4531 | ||
- | 4532 | procedure TDIB.Emboss; |
|
- | 4533 | var |
|
- | 4534 | x, y: longint; |
|
- | 4535 | D, D1, P: pointer; |
|
- | 4536 | color: TBGR; |
|
- | 4537 | c: DWORD; |
|
- | 4538 | P1: PByte; |
|
- | 4539 | ||
- | 4540 | begin |
|
- | 4541 | D := nil; |
|
- | 4542 | D1 := nil; |
|
- | 4543 | P := nil; |
|
- | 4544 | case BitCount of |
|
- | 4545 | 32, 16, 1: Exit; |
|
- | 4546 | 24: |
|
- | 4547 | begin |
|
- | 4548 | D := PBits; |
|
2963 | UpdateProgress(y*2); |
4549 | D1 := Ptr(Integer(D) + 3); |
2964 | end; |
4550 | end; |
- | 4551 | else |
|
- | 4552 | end; |
|
- | 4553 | for y := 0 to Pred(Height) do |
|
- | 4554 | begin |
|
- | 4555 | case Bitcount of |
|
- | 4556 | 8, 4: |
|
- | 4557 | begin |
|
- | 4558 | P := ScanLine[y]; |
|
- | 4559 | end; |
|
- | 4560 | end; |
|
- | 4561 | for x := 0 to Pred(Width) do |
|
- | 4562 | begin |
|
- | 4563 | case BitCount of |
|
- | 4564 | 24: |
|
- | 4565 | begin |
|
- | 4566 | PBGR(D)^.B := ((PBGR(D)^.B + (PBGR(D1)^.B xor $FF)) shr 1); |
|
- | 4567 | PBGR(D)^.G := ((PBGR(D)^.G + (PBGR(D1)^.G xor $FF)) shr 1); |
|
- | 4568 | PBGR(D)^.R := ((PBGR(D)^.R + (PBGR(D1)^.R xor $FF)) shr 1); |
|
- | 4569 | Inc(PBGR(D)); |
|
- | 4570 | if (y < Height - 2) and (x < Width - 2) then |
|
- | 4571 | Inc(PBGR(D1)); |
|
- | 4572 | end; |
|
- | 4573 | 8: |
|
- | 4574 | begin |
|
- | 4575 | color.R := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF)) shr 1) + 30) div 3; |
|
- | 4576 | color.G := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF)) shr 1) + 30) div 3; |
|
- | 4577 | color.B := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF)) shr 1) + 30) div 3; |
|
- | 4578 | c := (color.R + color.G + color.B) shr 1; |
|
- | 4579 | PByte(P)^ := c; |
|
- | 4580 | Inc(PByte(P)); |
|
- | 4581 | end; |
|
- | 4582 | 4: |
|
- | 4583 | begin |
|
- | 4584 | color.R := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF) + 1) shr 1) + 30) div 3; |
|
- | 4585 | color.G := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF) - 1) shr 1) + 30) div 3; |
|
- | 4586 | color.B := (((Pixels[x, y] + (Pixels[x + 3, y] xor $FF) + 1) shr 1) + 30) div 3; |
|
- | 4587 | c := (color.R + color.G + color.B) shr 1; |
|
- | 4588 | if c > 64 then |
|
- | 4589 | c := c - 8; |
|
- | 4590 | P1 := @PArrayByte(P)[X shr 1]; |
|
- | 4591 | P1^ := (P1^ and Mask4n[X and 1]) or ((c) shl Shift4[X and 1]); |
|
- | 4592 | end; |
|
2965 | finally |
4593 | else |
- | 4594 | end; |
|
- | 4595 | end; |
|
- | 4596 | case BitCount of |
|
- | 4597 | 24: |
|
- | 4598 | begin |
|
- | 4599 | D := Ptr(Integer(D1)); |
|
- | 4600 | if y < Height - 2 then |
|
- | 4601 | D1 := Ptr(Integer(D1) + 6) |
|
2966 | EndProgress; |
4602 | else |
- | 4603 | D1 := Ptr(Integer(ScanLine[Pred(Height)]) + 3); |
|
- | 4604 | end; |
|
- | 4605 | else |
|
2967 | end; |
4606 | end; |
2968 | end; |
4607 | end; |
2969 | end; |
4608 | end; |
2970 | 4609 | ||
2971 | procedure TDIB.Negative; |
4610 | procedure TDIB.AddMonoNoise(Amount: Integer); |
2972 | var |
4611 | var |
- | 4612 | value: cardinal; |
|
2973 | i, i2: Integer; |
4613 | x, y: longint; |
- | 4614 | a: byte; |
|
2974 | P: Pointer; |
4615 | D: pointer; |
- | 4616 | color: DWORD; |
|
- | 4617 | P: PByte; |
|
2975 | begin |
4618 | begin |
- | 4619 | for y := 0 to Pred(Height) do |
|
- | 4620 | begin |
|
- | 4621 | D := ScanLine[y]; |
|
- | 4622 | for x := 0 to Pred(Width) do |
|
- | 4623 | begin |
|
- | 4624 | case BitCount of |
|
- | 4625 | 32: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 4626 | 24: |
|
- | 4627 | begin |
|
- | 4628 | value := Random(Amount) - (Amount shr 1); |
|
- | 4629 | PBGR(D)^.B := IntToByte(PBGR(D)^.B + value); |
|
- | 4630 | PBGR(D)^.G := IntToByte(PBGR(D)^.G + value); |
|
- | 4631 | PBGR(D)^.R := IntToByte(PBGR(D)^.R + value); |
|
- | 4632 | Inc(PBGR(D)); |
|
- | 4633 | end; |
|
- | 4634 | 16: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 4635 | 8: |
|
- | 4636 | begin |
|
- | 4637 | a := ((Random(Amount shr 1) - (Amount div 4))) div 8; |
|
- | 4638 | color := Interval(0, 255, (pixels[x, y] - a), True); |
|
- | 4639 | PByte(D)^ := color; |
|
- | 4640 | Inc(PByte(D)); |
|
- | 4641 | end; |
|
- | 4642 | 4: |
|
- | 4643 | begin |
|
- | 4644 | a := ((Random(Amount shr 1) - (Amount div 4))) div 16; |
|
- | 4645 | color := Interval(0, 15, (pixels[x, y] - a), True); |
|
- | 4646 | P := @PArrayByte(D)[X shr 1]; |
|
- | 4647 | P^ := ((P^ and Mask4n[X and 1]) or ((color shl Shift4[X and 1]))); |
|
- | 4648 | end; |
|
- | 4649 | 1: |
|
- | 4650 | begin |
|
- | 4651 | a := ((Random(Amount shr 1) - (Amount div 4))) div 32; |
|
- | 4652 | color := Interval(0, 1, (pixels[x, y] - a), True); |
|
- | 4653 | P := @PArrayByte(D)[X shr 3]; |
|
- | 4654 | P^ := (P^ and Mask1n[X and 7]) or (color shl Shift1[X and 7]); |
|
- | 4655 | end; |
|
- | 4656 | else |
|
- | 4657 | end; |
|
- | 4658 | end; |
|
- | 4659 | end; |
|
- | 4660 | end; |
|
- | 4661 | ||
- | 4662 | procedure TDIB.AddGradiantNoise(Amount: byte); |
|
- | 4663 | var |
|
- | 4664 | a, i: byte; |
|
- | 4665 | x, y: Integer; |
|
- | 4666 | Table: array[0..255] of TBGR; |
|
2976 | if Empty then exit; |
4667 | S, D: pointer; |
- | 4668 | color: DWORD; |
|
- | 4669 | Temp1: TDIB; |
|
- | 4670 | P: PByte; |
|
2977 | 4671 | ||
2978 | if BitCount<=8 then |
- | |
2979 | begin |
4672 | begin |
- | 4673 | D := nil; |
|
- | 4674 | S := nil; |
|
- | 4675 | Temp1 := nil; |
|
- | 4676 | case BitCount of |
|
- | 4677 | 32: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 4678 | 24: |
|
- | 4679 | begin |
|
- | 4680 | for i := 0 to 255 do |
|
- | 4681 | begin |
|
- | 4682 | a := Random(Amount); |
|
- | 4683 | Table[i].b := IntToByte(i + a); |
|
- | 4684 | Table[i].g := IntToByte(i + a); |
|
- | 4685 | Table[i].r := IntToByte(i + a); |
|
- | 4686 | end; |
|
- | 4687 | end; |
|
- | 4688 | 16: Exit; // I haven't bitmap of this type ! Sorry |
|
- | 4689 | 8, 4: |
|
- | 4690 | begin |
|
- | 4691 | Temp1 := TDIB.Create; |
|
- | 4692 | Temp1.Assign(self); |
|
- | 4693 | Temp1.SetSize(Width, Height, BitCount); |
|
2980 | for i:=0 to 255 do |
4694 | for i := 0 to 255 do |
- | 4695 | begin |
|
2981 | with ColorTable[i] do |
4696 | with ColorTable[i] do |
2982 | begin |
4697 | begin |
- | 4698 | a := Random(Amount); |
|
2983 | rgbRed := 255-rgbRed; |
4699 | rgbRed := IntToByte(rgbRed + a); |
2984 | rgbGreen := 255-rgbGreen; |
4700 | rgbGreen := IntToByte(rgbGreen + a); |
2985 | rgbBlue := 255-rgbBlue; |
4701 | rgbBlue := IntToByte(rgbBlue + a); |
- | 4702 | end; |
|
2986 | end; |
4703 | end; |
2987 | UpdatePalette; |
4704 | UpdatePalette; |
- | 4705 | end; |
|
2988 | end else |
4706 | else |
- | 4707 | // if the number of pixel is equal to 1 then exit of procedure |
|
- | 4708 | Exit; |
|
- | 4709 | end; |
|
- | 4710 | for y := 0 to Pred(Height) do |
|
2989 | begin |
4711 | begin |
- | 4712 | case BitCount of |
|
- | 4713 | 24: D := ScanLine[y]; |
|
- | 4714 | 8, 4: |
|
2990 | P := PBits; |
4715 | begin |
- | 4716 | D := Temp1.ScanLine[y]; |
|
- | 4717 | S := Temp1.ScanLine[y]; |
|
2991 | i2 := Size; |
4718 | end; |
2992 | asm |
4719 | else |
- | 4720 | end; |
|
- | 4721 | for x := 0 to Pred(Width) do |
|
- | 4722 | begin |
|
- | 4723 | case BitCount of |
|
- | 4724 | 32: ; // I haven't bitmap of this type ! Sorry |
|
- | 4725 | 24: |
|
- | 4726 | begin |
|
- | 4727 | PBGR(D)^.B := Table[PBGR(D)^.B].b; |
|
- | 4728 | PBGR(D)^.G := Table[PBGR(D)^.G].g; |
|
- | 4729 | PBGR(D)^.R := Table[PBGR(D)^.R].r; |
|
- | 4730 | Inc(PBGR(D)); |
|
- | 4731 | end; |
|
- | 4732 | 16: ; // I haven't bitmap of this type ! Sorry |
|
- | 4733 | 8: |
|
2993 | mov ecx,i2 |
4734 | begin |
- | 4735 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 4736 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 4737 | Inc(PByte(S)); |
|
- | 4738 | PByte(D)^ := color; |
|
- | 4739 | Inc(PByte(D)); |
|
2994 | mov eax,P |
4740 | end; |
- | 4741 | 4: |
|
- | 4742 | begin |
|
- | 4743 | with Temp1.ColorTable[PByte(S)^] do |
|
- | 4744 | color := rgbRed + rgbGreen + rgbBlue; |
|
- | 4745 | Inc(PByte(S)); |
|
- | 4746 | P := @PArrayByte(D)[X shr 1]; |
|
- | 4747 | P^ := (P^ and Mask4n[X and 1]) or (color shl Shift4[X and 1]); |
|
2995 | mov edx,ecx |
4748 | end; |
- | 4749 | else |
|
- | 4750 | end; |
|
- | 4751 | end; |
|
- | 4752 | end; |
|
- | 4753 | case BitCount of |
|
- | 4754 | 8, 4: Temp1.Free; |
|
- | 4755 | else |
|
- | 4756 | end; |
|
- | 4757 | end; |
|
2996 | 4758 | ||
- | 4759 | function TDIB.FishEye(bmp: TDIB): Boolean; |
|
- | 4760 | var |
|
- | 4761 | 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; |
|
- | 4763 | weight_x, weight_y: array[0..1] of Double; |
|
- | 4764 | total_red, total_green, total_blue: Double; |
|
- | 4765 | sli, slo: PLines; |
|
- | 4766 | D: Pointer; |
|
- | 4767 | begin |
|
- | 4768 | Result := True; |
|
- | 4769 | case BitCount of |
|
- | 4770 | 32, 16, 8, 4, 1: |
|
- | 4771 | begin |
|
- | 4772 | Result := False; |
|
- | 4773 | Exit; |
|
- | 4774 | end; |
|
- | 4775 | end; |
|
- | 4776 | Amount := 1; |
|
- | 4777 | xmid := Width / 2; |
|
- | 4778 | ymid := Height / 2; |
|
- | 4779 | rmax := Max(Bmp.Width, Bmp.Height) * Amount; |
|
- | 4780 | for ty := 0 to Pred(Height) do |
|
- | 4781 | begin |
|
- | 4782 | for tx := 0 to Pred(Width) do |
|
- | 4783 | begin |
|
- | 4784 | dx := tx - xmid; |
|
- | 4785 | dy := ty - ymid; |
|
- | 4786 | r1 := Sqrt(Sqr(dx) + Sqr(dy)); |
|
- | 4787 | if r1 <> 0 then |
|
- | 4788 | begin |
|
- | 4789 | r2 := rmax / 2 * (1 / (1 - r1 / rmax) - 1); |
|
- | 4790 | fx := dx * r2 / r1 + xmid; |
|
- | 4791 | fy := dy * r2 / r1 + ymid; |
|
- | 4792 | end |
|
- | 4793 | else |
|
- | 4794 | begin |
|
- | 4795 | fx := xmid; |
|
- | 4796 | fy := ymid; |
|
- | 4797 | end; |
|
- | 4798 | ify := Trunc(fy); |
|
- | 4799 | ifx := Trunc(fx); |
|
- | 4800 | if fy >= 0 then |
|
- | 4801 | begin |
|
- | 4802 | weight_y[1] := fy - ify; |
|
- | 4803 | weight_y[0] := 1 - weight_y[1]; |
|
- | 4804 | end |
|
- | 4805 | else |
|
- | 4806 | begin |
|
- | 4807 | weight_y[0] := -(fy - ify); |
|
- | 4808 | weight_y[1] := 1 - weight_y[0]; |
|
- | 4809 | end; |
|
- | 4810 | if fx >= 0 then |
|
- | 4811 | begin |
|
- | 4812 | weight_x[1] := fx - ifx; |
|
- | 4813 | weight_x[0] := 1 - weight_x[1]; |
|
- | 4814 | end |
|
- | 4815 | else |
|
- | 4816 | begin |
|
- | 4817 | weight_x[0] := -(fx - ifx); |
|
- | 4818 | Weight_x[1] := 1 - weight_x[0]; |
|
- | 4819 | end; |
|
- | 4820 | if ifx < 0 then |
|
- | 4821 | ifx := Pred(Width) - (-ifx mod Width) |
|
- | 4822 | else |
|
- | 4823 | if ifx > Pred(Width) then |
|
- | 4824 | ifx := ifx mod Width; |
|
- | 4825 | if ify < 0 then |
|
- | 4826 | ify := Pred(Height) - (-ify mod Height) |
|
- | 4827 | else |
|
- | 4828 | if ify > Pred(Height) then |
|
- | 4829 | ify := ify mod Height; |
|
- | 4830 | total_red := 0.0; |
|
- | 4831 | total_green := 0.0; |
|
- | 4832 | total_blue := 0.0; |
|
2997 | { Unit of DWORD. } |
4833 | for ix := 0 to 1 do |
- | 4834 | begin |
|
- | 4835 | for iy := 0 to 1 do |
|
- | 4836 | begin |
|
- | 4837 | if ify + iy < Height then |
|
- | 4838 | sli := ScanLine[ify + iy] |
|
- | 4839 | else |
|
- | 4840 | sli := ScanLine[Height - ify - iy]; |
|
- | 4841 | if ifx + ix < Width then |
|
- | 4842 | begin |
|
- | 4843 | new_red := sli^[ifx + ix].r; |
|
- | 4844 | new_green := sli^[ifx + ix].g; |
|
- | 4845 | new_blue := sli^[ifx + ix].b; |
|
- | 4846 | end |
|
- | 4847 | else |
|
2998 | @@qword_skip: |
4848 | begin |
- | 4849 | new_red := sli^[Width - ifx - ix].r; |
|
- | 4850 | new_green := sli^[Width - ifx - ix].g; |
|
- | 4851 | new_blue := sli^[Width - ifx - ix].b; |
|
2999 | shr ecx,2 |
4852 | end; |
- | 4853 | weight := weight_x[ix] * weight_y[iy]; |
|
- | 4854 | total_red := total_red + new_red * weight; |
|
- | 4855 | total_green := total_green + new_green * weight; |
|
- | 4856 | total_blue := total_blue + new_blue * weight; |
|
- | 4857 | end; |
|
- | 4858 | end; |
|
3000 | jz @@dword_skip |
4859 | case bitCount of |
- | 4860 | 24: |
|
- | 4861 | begin |
|
- | 4862 | slo := Bmp.ScanLine[ty]; |
|
- | 4863 | slo^[tx].r := Round(total_red); |
|
- | 4864 | slo^[tx].g := Round(total_green); |
|
- | 4865 | slo^[tx].b := Round(total_blue); |
|
- | 4866 | end; |
|
- | 4867 | else |
|
- | 4868 | // You can implement this procedure for 16,8,4,2 and 32 BitCount's DIB |
|
- | 4869 | Exit; |
|
- | 4870 | end; |
|
- | 4871 | end; |
|
- | 4872 | end; |
|
- | 4873 | end; |
|
3001 | 4874 | ||
- | 4875 | function TDIB.SmoothRotateWrap(Bmp: TDIB; cx, cy: Integer; Degree: Extended): Boolean; |
|
- | 4876 | var |
|
- | 4877 | weight, Theta, cosTheta, sinTheta, sfrom_y, sfrom_x: Double; |
|
- | 4878 | ifrom_y, ifrom_x, xDiff, yDiff, to_y, to_x: Integer; |
|
- | 4879 | weight_x, weight_y: array[0..1] of Double; |
|
- | 4880 | ix, iy, new_red, new_green, new_blue: Integer; |
|
- | 4881 | total_red, total_green, total_blue: Double; |
|
- | 4882 | sli, slo: PLines; |
|
- | 4883 | begin |
|
- | 4884 | Result := True; |
|
- | 4885 | case BitCount of |
|
- | 4886 | 32, 16, 8, 4, 1: |
|
- | 4887 | begin |
|
- | 4888 | Result := False; |
|
- | 4889 | Exit; |
|
- | 4890 | end; |
|
- | 4891 | end; |
|
- | 4892 | Theta := -Degree * Pi / 180; |
|
- | 4893 | sinTheta := Sin(Theta); |
|
- | 4894 | cosTheta := Cos(Theta); |
|
- | 4895 | xDiff := (Bmp.Width - Width) div 2; |
|
- | 4896 | yDiff := (Bmp.Height - Height) div 2; |
|
- | 4897 | for to_y := 0 to Pred(Bmp.Height) do |
|
- | 4898 | begin |
|
- | 4899 | for to_x := 0 to Pred(Bmp.Width) do |
|
- | 4900 | begin |
|
- | 4901 | sfrom_x := (cx + (to_x - cx) * cosTheta - (to_y - cy) * sinTheta) - xDiff; |
|
- | 4902 | ifrom_x := Trunc(sfrom_x); |
|
- | 4903 | sfrom_y := (cy + (to_x - cx) * sinTheta + (to_y - cy) * cosTheta) - yDiff; |
|
- | 4904 | ifrom_y := Trunc(sfrom_y); |
|
- | 4905 | if sfrom_y >= 0 then |
|
- | 4906 | begin |
|
- | 4907 | weight_y[1] := sfrom_y - ifrom_y; |
|
- | 4908 | weight_y[0] := 1 - weight_y[1]; |
|
- | 4909 | end |
|
- | 4910 | else |
|
- | 4911 | begin |
|
- | 4912 | weight_y[0] := -(sfrom_y - ifrom_y); |
|
- | 4913 | weight_y[1] := 1 - weight_y[0]; |
|
- | 4914 | end; |
|
- | 4915 | if sfrom_x >= 0 then |
|
- | 4916 | begin |
|
- | 4917 | weight_x[1] := sfrom_x - ifrom_x; |
|
- | 4918 | weight_x[0] := 1 - weight_x[1]; |
|
- | 4919 | end |
|
- | 4920 | else |
|
- | 4921 | begin |
|
- | 4922 | weight_x[0] := -(sfrom_x - ifrom_x); |
|
- | 4923 | Weight_x[1] := 1 - weight_x[0]; |
|
- | 4924 | end; |
|
- | 4925 | if ifrom_x < 0 then |
|
- | 4926 | ifrom_x := Pred(Width) - (-ifrom_x mod Width) |
|
- | 4927 | else |
|
- | 4928 | if ifrom_x > Pred(Width) then |
|
- | 4929 | ifrom_x := ifrom_x mod Width; |
|
- | 4930 | if ifrom_y < 0 then |
|
- | 4931 | ifrom_y := Pred(Height) - (-ifrom_y mod Height) |
|
3002 | dec ecx |
4932 | else |
- | 4933 | if ifrom_y > Pred(Height) then |
|
- | 4934 | ifrom_y := ifrom_y mod Height; |
|
- | 4935 | total_red := 0.0; |
|
- | 4936 | total_green := 0.0; |
|
- | 4937 | total_blue := 0.0; |
|
- | 4938 | for ix := 0 to 1 do |
|
- | 4939 | begin |
|
- | 4940 | for iy := 0 to 1 do |
|
- | 4941 | begin |
|
- | 4942 | if ifrom_y + iy < Height then |
|
- | 4943 | sli := ScanLine[ifrom_y + iy] |
|
3003 | @@dword_loop: |
4944 | else |
- | 4945 | sli := ScanLine[Height - ifrom_y - iy]; |
|
- | 4946 | if ifrom_x + ix < Width then |
|
- | 4947 | begin |
|
3004 | not dword ptr [eax+ecx*4] |
4948 | new_red := sli^[ifrom_x + ix].r; |
- | 4949 | new_green := sli^[ifrom_x + ix].g; |
|
- | 4950 | new_blue := sli^[ifrom_x + ix].b; |
|
3005 | dec ecx |
4951 | end |
- | 4952 | else |
|
- | 4953 | begin |
|
- | 4954 | new_red := sli^[Width - ifrom_x - ix].r; |
|
- | 4955 | new_green := sli^[Width - ifrom_x - ix].g; |
|
- | 4956 | new_blue := sli^[Width - ifrom_x - ix].b; |
|
- | 4957 | end; |
|
- | 4958 | weight := weight_x[ix] * weight_y[iy]; |
|
- | 4959 | total_red := total_red + new_red * weight; |
|
- | 4960 | total_green := total_green + new_green * weight; |
|
- | 4961 | total_blue := total_blue + new_blue * weight; |
|
- | 4962 | end; |
|
- | 4963 | end; |
|
3006 | jnl @@dword_loop |
4964 | case bitCount of |
- | 4965 | 24: |
|
- | 4966 | begin |
|
- | 4967 | slo := Bmp.ScanLine[to_y]; |
|
- | 4968 | slo^[to_x].r := Round(total_red); |
|
- | 4969 | slo^[to_x].g := Round(total_green); |
|
- | 4970 | slo^[to_x].b := Round(total_blue); |
|
- | 4971 | end; |
|
- | 4972 | else |
|
- | 4973 | // You can implement this procedure for 16,8,4,2 and 32 BitCount's DIB |
|
- | 4974 | Exit; |
|
- | 4975 | end; |
|
- | 4976 | end; |
|
- | 4977 | end; |
|
- | 4978 | end; |
|
3007 | 4979 | ||
- | 4980 | function TDIB.Rotate(Dst: TDIB; cx, cy: Integer; Angle: Double): Boolean; |
|
- | 4981 | var |
|
- | 4982 | x, y, dx, dy, sdx, sdy, xDiff, yDiff, isinTheta, icosTheta: Integer; |
|
- | 4983 | D, S: Pointer; |
|
- | 4984 | sinTheta, cosTheta, Theta: Double; |
|
- | 4985 | Col: TBGR; |
|
- | 4986 | i: byte; |
|
- | 4987 | color: DWORD; |
|
- | 4988 | P: PByte; |
|
- | 4989 | begin |
|
- | 4990 | D := nil; |
|
- | 4991 | S := nil; |
|
- | 4992 | Result := True; |
|
- | 4993 | dst.SetSize(Width, Height, Bitcount); |
|
- | 4994 | dst.Canvas.Brush.Color := clBlack; |
|
- | 4995 | Dst.Canvas.FillRect(Bounds(0, 0, Width, Height)); |
|
- | 4996 | case BitCount of |
|
- | 4997 | 32, 16: |
|
- | 4998 | begin |
|
- | 4999 | Result := False; |
|
3008 | mov ecx,edx |
5000 | Exit; |
- | 5001 | end; |
|
- | 5002 | 8, 4, 1: |
|
- | 5003 | begin |
|
- | 5004 | for i := 0 to 255 do |
|
- | 5005 | Dst.ColorTable[i] := ColorTable[i]; |
|
- | 5006 | Dst.UpdatePalette; |
|
- | 5007 | end; |
|
- | 5008 | end; |
|
- | 5009 | Theta := -Angle * Pi / 180; |
|
- | 5010 | sinTheta := Sin(Theta); |
|
- | 5011 | cosTheta := Cos(Theta); |
|
- | 5012 | xDiff := (Dst.Width - Width) div 2; |
|
- | 5013 | yDiff := (Dst.Height - Height) div 2; |
|
- | 5014 | isinTheta := Round(sinTheta * $10000); |
|
- | 5015 | icosTheta := Round(cosTheta * $10000); |
|
- | 5016 | for y := 0 to Pred(Dst.Height) do |
|
- | 5017 | begin |
|
- | 5018 | case BitCount of |
|
- | 5019 | 4, 1: |
|
- | 5020 | begin |
|
- | 5021 | D := Dst.ScanLine[y]; |
|
- | 5022 | S := ScanLine[y]; |
|
3009 | shr ecx,2 |
5023 | end; |
- | 5024 | else |
|
- | 5025 | end; |
|
- | 5026 | sdx := Round(((cx + (-cx) * cosTheta - (y - cy) * sinTheta) - xDiff) * $10000); |
|
- | 5027 | sdy := Round(((cy + (-cy) * sinTheta + (y - cy) * cosTheta) - yDiff) * $10000); |
|
- | 5028 | for x := 0 to Pred(Dst.Width) do |
|
- | 5029 | begin |
|
- | 5030 | dx := (sdx shr 16); |
|
- | 5031 | dy := (sdy shr 16); |
|
- | 5032 | if (dx > -1) and (dx < Width) and (dy > -1) and (dy < Height) then |
|
- | 5033 | begin |
|
- | 5034 | case bitcount of |
|
- | 5035 | 8, 24: Dst.pixels[x, y] := Pixels[dx, dy]; |
|
- | 5036 | 4: |
|
- | 5037 | begin |
|
- | 5038 | pfGetRGB(NowPixelFormat, Pixels[dx, dy], col.r, col.g, col.b); |
|
- | 5039 | color := col.r + col.g + col.b; |
|
- | 5040 | Inc(PByte(S)); |
|
- | 5041 | P := @PArrayByte(D)[x shr 1]; |
|
- | 5042 | P^ := (P^ and Mask4n[x and 1]) or (color shl Shift4[x and 1]); |
|
- | 5043 | end; |
|
- | 5044 | 1: |
|
3010 | add eax,ecx*4 |
5045 | begin |
- | 5046 | pfGetRGB(NowPixelFormat, Pixels[dx, dy], col.r, col.g, col.b); |
|
- | 5047 | color := col.r + col.g + col.b; |
|
- | 5048 | Inc(PByte(S)); |
|
- | 5049 | P := @PArrayByte(D)[X shr 3]; |
|
- | 5050 | P^ := (P^ and Mask1n[X and 7]) or (color shl Shift1[X and 7]); |
|
- | 5051 | end; |
|
- | 5052 | end; |
|
- | 5053 | end; |
|
- | 5054 | Inc(sdx, icosTheta); |
|
- | 5055 | Inc(sdy, isinTheta); |
|
- | 5056 | end; |
|
- | 5057 | end; |
|
- | 5058 | end; |
|
3011 | 5059 | ||
3012 | { Unit of Byte. } |
5060 | procedure TDIB.GaussianBlur(Bmp: TDIB; Amount: Integer); |
3013 | @@dword_skip: |
5061 | var |
3014 | mov ecx,edx |
5062 | i: Integer; |
- | 5063 | begin |
|
3015 | and ecx,3 |
5064 | for i := 1 to Amount do |
3016 | jz @@byte_skip |
5065 | Bmp.SplitBlur(i); |
- | 5066 | end; |
|
3017 | 5067 | ||
- | 5068 | procedure TDIB.SplitBlur(Amount: Integer); |
|
- | 5069 | var |
|
3018 | dec ecx |
5070 | Lin1, Lin2: PLines; |
3019 | @@loop_byte: |
5071 | cx, x, y: Integer; |
3020 | not byte ptr [eax+ecx] |
5072 | Buf: array[0..3] of TBGR; |
3021 | dec ecx |
5073 | D: Pointer; |
3022 | jnl @@loop_byte |
- | |
3023 | 5074 | ||
- | 5075 | begin |
|
- | 5076 | case Bitcount of |
|
- | 5077 | 32, 16, 8, 4, 1: Exit; |
|
- | 5078 | end; |
|
- | 5079 | for y := 0 to Pred(Height) do |
|
- | 5080 | begin |
|
- | 5081 | Lin1 := ScanLine[TrimInt(y + Amount, 0, Pred(Height))]; |
|
- | 5082 | Lin2 := ScanLine[TrimInt(y - Amount, 0, Pred(Height))]; |
|
- | 5083 | D := ScanLine[y]; |
|
- | 5084 | for x := 0 to Pred(Width) do |
|
- | 5085 | begin |
|
- | 5086 | cx := TrimInt(x + Amount, 0, Pred(Width)); |
|
- | 5087 | Buf[0] := Lin1[cx]; |
|
- | 5088 | Buf[1] := Lin2[cx]; |
|
- | 5089 | cx := TrimInt(x - Amount, 0, Pred(Width)); |
|
- | 5090 | Buf[2] := Lin1[cx]; |
|
- | 5091 | Buf[3] := Lin2[cx]; |
|
- | 5092 | PBGR(D)^.b := (Buf[0].b + Buf[1].b + Buf[2].b + Buf[3].b) shr 2; |
|
- | 5093 | PBGR(D)^.g := (Buf[0].g + Buf[1].g + Buf[2].g + Buf[3].g) shr 2; |
|
- | 5094 | PBGR(D)^.r := (Buf[0].r + Buf[1].r + Buf[2].r + Buf[3].r) shr 2; |
|
- | 5095 | Inc(PBGR(D)); |
|
- | 5096 | end; |
|
- | 5097 | end; |
|
- | 5098 | end; |
|
- | 5099 | ||
- | 5100 | function TDIB.Twist(bmp: TDIB; Amount: byte): Boolean; |
|
- | 5101 | var |
|
- | 5102 | fxmid, fymid: Single; |
|
- | 5103 | txmid, tymid: Single; |
|
- | 5104 | fx, fy: Single; |
|
- | 5105 | tx2, ty2: Single; |
|
- | 5106 | r: Single; |
|
- | 5107 | theta: Single; |
|
- | 5108 | ifx, ify: Integer; |
|
- | 5109 | dx, dy: Single; |
|
- | 5110 | OFFSET: Single; |
|
- | 5111 | ty, tx, ix, iy: Integer; |
|
- | 5112 | weight_x, weight_y: array[0..1] of Single; |
|
- | 5113 | weight: Single; |
|
- | 5114 | new_red, new_green, new_blue: Integer; |
|
- | 5115 | total_red, total_green, total_blue: Single; |
|
- | 5116 | sli, slo: PLines; |
|
- | 5117 | ||
- | 5118 | function ArcTan2(xt, yt: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 5119 | begin |
|
- | 5120 | if xt = 0 then |
|
- | 5121 | if yt > 0 then |
|
- | 5122 | Result := Pi / 2 |
|
- | 5123 | else |
|
- | 5124 | Result := -(Pi / 2) |
|
- | 5125 | else |
|
- | 5126 | begin |
|
- | 5127 | Result := ArcTan(yt / xt); |
|
- | 5128 | if xt < 0 then |
|
- | 5129 | Result := Pi + ArcTan(yt / xt); |
|
- | 5130 | end; |
|
- | 5131 | end; |
|
- | 5132 | ||
- | 5133 | begin |
|
- | 5134 | Result := True; |
|
- | 5135 | case BitCount of |
|
- | 5136 | 32, 16, 8, 4, 1: |
|
- | 5137 | begin |
|
- | 5138 | Result := False; |
|
- | 5139 | Exit; |
|
- | 5140 | end; |
|
- | 5141 | end; |
|
- | 5142 | if Amount = 0 then |
|
- | 5143 | Amount := 1; |
|
- | 5144 | OFFSET := -(Pi / 2); |
|
- | 5145 | dx := Pred(Width); |
|
- | 5146 | dy := Pred(Height); |
|
- | 5147 | r := Sqrt(dx * dx + dy * dy); |
|
- | 5148 | tx2 := r; |
|
- | 5149 | ty2 := r; |
|
- | 5150 | txmid := (Pred(Width)) / 2; |
|
- | 5151 | tymid := (Pred(Height)) / 2; |
|
- | 5152 | fxmid := (Pred(Width)) / 2; |
|
- | 5153 | fymid := (Pred(Height)) / 2; |
|
- | 5154 | if tx2 >= Width then |
|
- | 5155 | tx2 := Pred(Width); |
|
- | 5156 | if ty2 >= Height then |
|
- | 5157 | ty2 := Pred(Height); |
|
- | 5158 | for ty := 0 to Round(ty2) do |
|
- | 5159 | begin |
|
- | 5160 | for tx := 0 to Round(tx2) do |
|
- | 5161 | begin |
|
- | 5162 | dx := tx - txmid; |
|
- | 5163 | dy := ty - tymid; |
|
- | 5164 | r := Sqrt(dx * dx + dy * dy); |
|
- | 5165 | if r = 0 then |
|
- | 5166 | begin |
|
- | 5167 | fx := 0; |
|
- | 5168 | fy := 0; |
|
- | 5169 | end |
|
- | 5170 | else |
|
- | 5171 | begin |
|
- | 5172 | theta := ArcTan2(dx, dy) - r / Amount - OFFSET; |
|
- | 5173 | fx := r * Cos(theta); |
|
- | 5174 | fy := r * Sin(theta); |
|
- | 5175 | end; |
|
- | 5176 | fx := fx + fxmid; |
|
- | 5177 | fy := fy + fymid; |
|
- | 5178 | ify := Trunc(fy); |
|
- | 5179 | ifx := Trunc(fx); |
|
- | 5180 | if fy >= 0 then |
|
- | 5181 | begin |
|
- | 5182 | weight_y[1] := fy - ify; |
|
- | 5183 | weight_y[0] := 1 - weight_y[1]; |
|
- | 5184 | end |
|
- | 5185 | else |
|
- | 5186 | begin |
|
- | 5187 | weight_y[0] := -(fy - ify); |
|
- | 5188 | weight_y[1] := 1 - weight_y[0]; |
|
- | 5189 | end; |
|
- | 5190 | if fx >= 0 then |
|
- | 5191 | begin |
|
- | 5192 | weight_x[1] := fx - ifx; |
|
- | 5193 | weight_x[0] := 1 - weight_x[1]; |
|
- | 5194 | end |
|
- | 5195 | else |
|
- | 5196 | begin |
|
- | 5197 | weight_x[0] := -(fx - ifx); |
|
- | 5198 | Weight_x[1] := 1 - weight_x[0]; |
|
- | 5199 | end; |
|
- | 5200 | if ifx < 0 then |
|
- | 5201 | ifx := Pred(Width) - (-ifx mod Width) |
|
- | 5202 | else |
|
- | 5203 | if ifx > Pred(Width) then |
|
- | 5204 | ifx := ifx mod Width; |
|
- | 5205 | if ify < 0 then |
|
- | 5206 | ify := Pred(Height) - (-ify mod Height) |
|
- | 5207 | else |
|
- | 5208 | if ify > Pred(Height) then |
|
- | 5209 | ify := ify mod Height; |
|
- | 5210 | total_red := 0.0; |
|
- | 5211 | total_green := 0.0; |
|
- | 5212 | total_blue := 0.0; |
|
- | 5213 | for ix := 0 to 1 do |
|
3024 | @@byte_skip: |
5214 | begin |
- | 5215 | for iy := 0 to 1 do |
|
- | 5216 | begin |
|
- | 5217 | if ify + iy < Height then |
|
- | 5218 | sli := ScanLine[ify + iy] |
|
- | 5219 | else |
|
- | 5220 | sli := ScanLine[Height - ify - iy]; |
|
- | 5221 | if ifx + ix < Width then |
|
- | 5222 | begin |
|
- | 5223 | new_red := sli^[ifx + ix].r; |
|
- | 5224 | new_green := sli^[ifx + ix].g; |
|
- | 5225 | new_blue := sli^[ifx + ix].b; |
|
- | 5226 | end |
|
- | 5227 | else |
|
- | 5228 | begin |
|
- | 5229 | new_red := sli^[Width - ifx - ix].r; |
|
- | 5230 | new_green := sli^[Width - ifx - ix].g; |
|
- | 5231 | new_blue := sli^[Width - ifx - ix].b; |
|
- | 5232 | end; |
|
- | 5233 | weight := weight_x[ix] * weight_y[iy]; |
|
- | 5234 | total_red := total_red + new_red * weight; |
|
- | 5235 | total_green := total_green + new_green * weight; |
|
- | 5236 | total_blue := total_blue + new_blue * weight; |
|
- | 5237 | end; |
|
- | 5238 | end; |
|
- | 5239 | case bitCount of |
|
- | 5240 | 24: |
|
- | 5241 | begin |
|
- | 5242 | slo := bmp.ScanLine[ty]; |
|
- | 5243 | slo^[tx].r := Round(total_red); |
|
- | 5244 | slo^[tx].g := Round(total_green); |
|
- | 5245 | slo^[tx].b := Round(total_blue); |
|
- | 5246 | end; |
|
- | 5247 | else |
|
- | 5248 | // You can implement this procedure for 16,8,4,2 and 32 BitCount's DIB |
|
- | 5249 | Exit; |
|
- | 5250 | end; |
|
- | 5251 | end; |
|
- | 5252 | end; |
|
- | 5253 | end; |
|
- | 5254 | ||
- | 5255 | function TDIB.TrimInt(i, Min, Max: Integer): Integer; |
|
- | 5256 | begin |
|
- | 5257 | if i > Max then |
|
- | 5258 | Result := Max |
|
- | 5259 | else |
|
- | 5260 | if i < Min then |
|
- | 5261 | Result := Min |
|
- | 5262 | else |
|
- | 5263 | Result := i; |
|
- | 5264 | end; |
|
- | 5265 | ||
- | 5266 | function TDIB.IntToByte(i: Integer): Byte; |
|
- | 5267 | begin |
|
- | 5268 | if i > 255 then |
|
- | 5269 | Result := 255 |
|
- | 5270 | else |
|
- | 5271 | if i < 0 then |
|
- | 5272 | Result := 0 |
|
- | 5273 | else |
|
- | 5274 | Result := i; |
|
3025 | end; |
5275 | end; |
- | 5276 | ||
- | 5277 | //-------------------------------------------------------------------------------------------------- |
|
- | 5278 | // End of these New Special Effect // |
|
- | 5279 | // Please contributes to add effects and filters to this collection // |
|
- | 5280 | // Please, work to implement 32,16,8,4,2 BitCount's DIB // |
|
- | 5281 | // Have fun - Mickey - Good job // |
|
- | 5282 | //-------------------------------------------------------------------------------------------------- |
|
- | 5283 | ||
- | 5284 | function TDIB.GetAlphaChannel: TDIB; |
|
- | 5285 | begin |
|
- | 5286 | RetAlphaChannel(Result); |
|
- | 5287 | ||
- | 5288 | FFreeList.Add(Result); |
|
- | 5289 | end; |
|
- | 5290 | ||
- | 5291 | procedure TDIB.SetAlphaChannel(const Value: TDIB); |
|
- | 5292 | begin |
|
- | 5293 | if not AssignAlphaChannel(Value{$IFNDEF VER4UP}, False{$ENDIF}) then |
|
- | 5294 | Exception.Create('Cannot set alphachannel from DIB.'); |
|
- | 5295 | end; |
|
- | 5296 | ||
- | 5297 | procedure TDIB.Fill(aColor: TColor); |
|
- | 5298 | begin |
|
- | 5299 | Canvas.Brush.Color := aColor; |
|
- | 5300 | Canvas.FillRect(ClientRect); |
|
3026 | end; |
5301 | end; |
- | 5302 | ||
- | 5303 | function TDIB.GetClientRect: TRect; |
|
- | 5304 | begin |
|
- | 5305 | Result := Bounds(0, 0, Width, Height); |
|
3027 | end; |
5306 | end; |
3028 | 5307 | ||
3029 | { TCustomDXDIB } |
5308 | { TCustomDXDIB } |
3030 | 5309 | ||
3031 | constructor TCustomDXDIB.Create(AOnwer: TComponent); |
5310 | constructor TCustomDXDIB.Create(AOnwer: TComponent); |
Line 3076... | Line 5355... | ||
3076 | begin |
5355 | begin |
3077 | if FCenter then |
5356 | if FCenter then |
3078 | begin |
5357 | begin |
3079 | inherited Canvas.StretchDraw(Bounds(-(Width-ClientWidth) div 2, |
5358 | inherited Canvas.StretchDraw(Bounds(-(Width - ClientWidth) div 2, |
3080 | -(Height-ClientHeight) div 2, Width, Height), FDIB); |
5359 | -(Height - ClientHeight) div 2, Width, Height), FDIB); |
- | 5360 | end |
|
3081 | end else |
5361 | else |
3082 | begin |
5362 | begin |
3083 | inherited Canvas.StretchDraw(Bounds(0, 0, Width, Height), FDIB); |
5363 | inherited Canvas.StretchDraw(Bounds(0, 0, Width, Height), FDIB); |
3084 | end; |
5364 | end; |
- | 5365 | end |
|
3085 | end else |
5366 | else |
3086 | begin |
5367 | begin |
3087 | if FCenter then |
5368 | if FCenter then |
3088 | begin |
5369 | begin |
3089 | inherited Canvas.Draw(-(Width-ClientWidth) div 2, -(Height-ClientHeight) div 2, |
5370 | inherited Canvas.Draw(-(Width - ClientWidth) div 2, -(Height - ClientHeight) div 2, |
3090 | FDIB); |
5371 | FDIB); |
- | 5372 | end |
|
3091 | end else |
5373 | else |
3092 | begin |
5374 | begin |
3093 | inherited Canvas.Draw(0, 0, FDIB); |
5375 | inherited Canvas.Draw(0, 0, FDIB); |
3094 | end; |
5376 | end; |
3095 | end; |
5377 | end; |
3096 | end; |
5378 | end; |
Line 3126... | Line 5408... | ||
3126 | r := ViewWidth2/ClientWidth; |
5408 | r := ViewWidth2 / ClientWidth; |
3127 | r2 := ViewHeight2/ClientHeight; |
5409 | r2 := ViewHeight2 / ClientHeight; |
3128 | if r>r2 then |
5410 | if r > r2 then |
3129 | r := r2; |
5411 | r := r2; |
3130 | Draw2(Round(r*ClientWidth), Round(r*ClientHeight)); |
5412 | Draw2(Round(r * ClientWidth), Round(r * ClientHeight)); |
- | 5413 | end |
|
3131 | end else |
5414 | else |
3132 | Draw2(ViewWidth2, ViewHeight2); |
5415 | Draw2(ViewWidth2, ViewHeight2); |
- | 5416 | end |
|
3133 | end else |
5417 | else |
3134 | Draw2(ViewWidth2, ViewHeight2); |
5418 | Draw2(ViewWidth2, ViewHeight2); |
- | 5419 | end |
|
3135 | end else |
5420 | else |
3136 | begin |
5421 | begin |
3137 | if FAutoStretch then |
5422 | if FAutoStretch then |
3138 | begin |
5423 | begin |
3139 | if (FDIB.Width>ClientWidth) or (FDIB.Height>ClientHeight) then |
5424 | if (FDIB.Width > ClientWidth) or (FDIB.Height > ClientHeight) then |
3140 | begin |
5425 | begin |
3141 | r := ClientWidth/FDIB.Width; |
5426 | r := ClientWidth / FDIB.Width; |
3142 | r2 := ClientHeight/FDIB.Height; |
5427 | r2 := ClientHeight / FDIB.Height; |
3143 | if r>r2 then |
5428 | if r > r2 then |
3144 | r := r2; |
5429 | r := r2; |
3145 | Draw2(Round(r*FDIB.Width), Round(r*FDIB.Height)); |
5430 | Draw2(Round(r * FDIB.Width), Round(r * FDIB.Height)); |
- | 5431 | end |
|
3146 | end else |
5432 | else |
3147 | Draw2(FDIB.Width, FDIB.Height); |
5433 | Draw2(FDIB.Width, FDIB.Height); |
- | 5434 | end |
|
3148 | end else |
5435 | else |
3149 | if FStretch then |
5436 | if FStretch then |
3150 | begin |
5437 | begin |
3151 | if FKeepAspect then |
5438 | if FKeepAspect then |
3152 | begin |
5439 | begin |
3153 | r := ClientWidth/FDIB.Width; |
5440 | r := ClientWidth / FDIB.Width; |
3154 | r2 := ClientHeight/FDIB.Height; |
5441 | r2 := ClientHeight / FDIB.Height; |
3155 | if r>r2 then |
5442 | if r > r2 then |
3156 | r := r2; |
5443 | r := r2; |
3157 | Draw2(Round(r*FDIB.Width), Round(r*FDIB.Height)); |
5444 | Draw2(Round(r * FDIB.Width), Round(r * FDIB.Height)); |
- | 5445 | end |
|
3158 | end else |
5446 | else |
3159 | Draw2(ClientWidth, ClientHeight); |
5447 | Draw2(ClientWidth, ClientHeight); |
- | 5448 | end |
|
3160 | end else |
5449 | else |
3161 | Draw2(FDIB.Width, FDIB.Height); |
5450 | Draw2(FDIB.Width, FDIB.Height); |
3162 | end; |
5451 | end; |
3163 | end; |
5452 | end; |
3164 | end; |
5453 | end; |
3165 | 5454 | ||
Line 3226... | Line 5515... | ||
3226 | FViewHeight := Value; |
5515 | FViewHeight := Value; |
3227 | Invalidate; |
5516 | Invalidate; |
3228 | end; |
5517 | end; |
3229 | end; |
5518 | end; |
3230 | 5519 | ||
- | 5520 | { DXFusion -> } |
|
- | 5521 | ||
- | 5522 | function PosValue(Value: Integer): Integer; |
|
- | 5523 | begin |
|
- | 5524 | if Value < 0 then result := 0 else result := Value; |
|
- | 5525 | end; |
|
- | 5526 | ||
- | 5527 | procedure TDIB.CreateDIBFromBitmap(const Bitmap: TBitmap); |
|
- | 5528 | var |
|
- | 5529 | pf: Integer; |
|
- | 5530 | begin |
|
- | 5531 | if Bitmap.PixelFormat = pf32bit then pf := 32 else pf := 24; |
|
- | 5532 | SetSize(Bitmap.Width, Bitmap.Height, pf); {always >=24} |
|
- | 5533 | Canvas.Draw(0, 0, Bitmap); |
|
- | 5534 | end; |
|
- | 5535 | ||
- | 5536 | function TDIB.CreateBitmapFromDIB: TBitmap; |
|
- | 5537 | //var |
|
- | 5538 | // X, Y: Integer; |
|
- | 5539 | begin |
|
- | 5540 | Result := TBitmap.Create; |
|
- | 5541 | if BitCount = 32 then |
|
- | 5542 | Result.PixelFormat := pf32bit |
|
- | 5543 | else if BitCount = 24 then |
|
- | 5544 | Result.PixelFormat := pf24bit |
|
- | 5545 | else if BitCount = 16 then |
|
- | 5546 | Result.PixelFormat := pf16bit |
|
- | 5547 | else if BitCount = 8 then |
|
- | 5548 | Result.PixelFormat := pf8bit |
|
- | 5549 | else Result.PixelFormat := pf24bit; |
|
- | 5550 | Result.Width := Width; |
|
- | 5551 | Result.Height := Height; |
|
- | 5552 | Result.Canvas.Draw(0, 0, Self); |
|
- | 5553 | // for Y := 0 to Height - 1 do |
|
- | 5554 | // for X := 0 to Width - 1 do |
|
- | 5555 | // Result.Canvas.Pixels[X, Y] := Canvas.Pixels[X, Y]; |
|
- | 5556 | end; |
|
- | 5557 | ||
- | 5558 | procedure TDIB.DrawTo(SrcDIB: TDIB; X, Y, Width, Height, |
|
- | 5559 | SourceX, SourceY: Integer); |
|
- | 5560 | begin |
|
- | 5561 | SrcDIB.DrawOn(Rect(X, Y, Width, Height), Self.Canvas, SourceX, SourceY); |
|
- | 5562 | end; |
|
- | 5563 | ||
- | 5564 | procedure TDIB.DrawTransparent(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 5565 | SourceX, SourceY: Integer; const Color: TColor); |
|
- | 5566 | var |
|
- | 5567 | i, j: Integer; |
|
- | 5568 | k1, k2: Integer; |
|
- | 5569 | n: Integer; |
|
- | 5570 | p1, p2: PByteArray; |
|
- | 5571 | ||
- | 5572 | Startk1, Startk2: Integer; |
|
- | 5573 | ||
- | 5574 | StartY: Integer; |
|
- | 5575 | EndY: Integer; |
|
- | 5576 | ||
- | 5577 | DestStartY: Integer; |
|
- | 5578 | begin |
|
- | 5579 | if Self.BitCount <> 24 then Exit; |
|
- | 5580 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5581 | Startk1 := 3 * SourceX; |
|
- | 5582 | Startk2 := 3 * X; |
|
- | 5583 | ||
- | 5584 | DestStartY := Y - SourceY; |
|
- | 5585 | ||
- | 5586 | StartY := SourceY; |
|
- | 5587 | EndY := SourceY + Height; |
|
- | 5588 | ||
- | 5589 | if (StartY + DestStartY < 0) then |
|
- | 5590 | StartY := -DestStartY; |
|
- | 5591 | if (EndY + DestStartY > Self.Height) then |
|
- | 5592 | EndY := Self.Height - DestStartY; |
|
- | 5593 | ||
- | 5594 | if (StartY < 0) then |
|
- | 5595 | StartY := 0; |
|
- | 5596 | if (EndY > SrcDIB.Height) then |
|
- | 5597 | EndY := SrcDIB.Height; |
|
- | 5598 | ||
- | 5599 | for j := StartY to EndY - 1 do |
|
- | 5600 | begin |
|
- | 5601 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 5602 | p2 := SrcDIB.Scanline[j]; |
|
- | 5603 | ||
- | 5604 | k1 := Startk1; |
|
- | 5605 | k2 := Startk2; |
|
- | 5606 | ||
- | 5607 | for i := SourceX to SourceX + Width - 1 do |
|
- | 5608 | begin |
|
- | 5609 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 5610 | ||
- | 5611 | if not (n = Color) then |
|
- | 5612 | begin |
|
- | 5613 | p1[k2] := p2[k1]; |
|
- | 5614 | p1[k2 + 1] := p2[k1 + 1]; |
|
- | 5615 | p1[k2 + 2] := p2[k1 + 2]; |
|
- | 5616 | end; |
|
- | 5617 | ||
- | 5618 | k1 := k1 + 3; |
|
- | 5619 | k2 := k2 + 3; |
|
- | 5620 | end; |
|
- | 5621 | end; |
|
- | 5622 | end; |
|
- | 5623 | ||
- | 5624 | procedure TDIB.DrawShadow(SrcDIB: TDIB; X, Y, Width, Height, |
|
- | 5625 | Frame: Integer; FilterMode: TFilterMode); |
|
- | 5626 | var |
|
- | 5627 | i, j: Integer; |
|
- | 5628 | p1, p2: PByte; |
|
- | 5629 | FW: Integer; |
|
- | 5630 | begin |
|
- | 5631 | if Self.BitCount <> 24 then Exit; |
|
- | 5632 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5633 | ||
- | 5634 | FW := Frame * Width; |
|
- | 5635 | for i := 1 to Height - 1 do |
|
- | 5636 | begin |
|
- | 5637 | p1 := Self.Scanline[i + Y]; |
|
- | 5638 | p2 := SrcDIB.Scanline[i]; |
|
- | 5639 | Inc(p1, 3 * (X + 1)); |
|
- | 5640 | Inc(p2, 3 * (FW + 1)); |
|
- | 5641 | for j := 1 to Width - 1 do |
|
- | 5642 | begin |
|
- | 5643 | if (p2^ = 0) then |
|
- | 5644 | begin |
|
- | 5645 | case FilterMode of |
|
- | 5646 | fmNormal, fmMix50: |
|
- | 5647 | begin |
|
- | 5648 | p1^ := p1^ shr 1; // Blue |
|
- | 5649 | Inc(p1); |
|
- | 5650 | p1^ := p1^ shr 1; // Green |
|
- | 5651 | Inc(p1); |
|
- | 5652 | p1^ := p1^ shr 1; // Red |
|
- | 5653 | Inc(p1); |
|
- | 5654 | end; |
|
- | 5655 | fmMix25: |
|
- | 5656 | begin |
|
- | 5657 | p1^ := p1^ - p1^ shr 2; // Blue |
|
- | 5658 | Inc(p1); |
|
- | 5659 | p1^ := p1^ - p1^ shr 2; // Green |
|
- | 5660 | Inc(p1); |
|
- | 5661 | p1^ := p1^ - p1^ shr 2; // Red |
|
- | 5662 | Inc(p1); |
|
- | 5663 | end; |
|
- | 5664 | fmMix75: |
|
- | 5665 | begin |
|
- | 5666 | p1^ := p1^ shr 2; // Blue |
|
- | 5667 | Inc(p1); |
|
- | 5668 | p1^ := p1^ shr 2; // Green |
|
- | 5669 | Inc(p1); |
|
- | 5670 | p1^ := p1^ shr 2; // Red |
|
- | 5671 | Inc(p1); |
|
- | 5672 | end; |
|
- | 5673 | end; |
|
- | 5674 | end |
|
- | 5675 | else |
|
- | 5676 | Inc(p1, 3); // Not in the loop... |
|
- | 5677 | Inc(p2, 3); |
|
- | 5678 | end; |
|
- | 5679 | end; |
|
- | 5680 | end; |
|
- | 5681 | ||
- | 5682 | procedure TDIB.DrawShadows(SrcDIB: TDIB; X, Y, Width, Height, |
|
- | 5683 | Frame: Integer; Alpha: Byte); |
|
- | 5684 | {plynule nastavovani stiny dle alpha} |
|
- | 5685 | type |
|
- | 5686 | P3ByteArray = ^T3ByteArray; |
|
- | 5687 | T3ByteArray = array[0..32767] of TBGR; |
|
- | 5688 | var |
|
- | 5689 | i, j, l1, l2: Integer; |
|
- | 5690 | p1, p2: P3ByteArray; |
|
- | 5691 | FW: Integer; |
|
- | 5692 | begin |
|
- | 5693 | if Self.BitCount <> 24 then Exit; |
|
- | 5694 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5695 | ||
- | 5696 | FW := Frame * Width; |
|
- | 5697 | for i := 0 to Height - 1 do |
|
- | 5698 | begin |
|
- | 5699 | p1 := Self.Scanline[i + Y]; |
|
- | 5700 | p2 := SrcDIB.Scanline[i]; |
|
- | 5701 | l1 := X; |
|
- | 5702 | l2 := FW; |
|
- | 5703 | for j := 0 to Width - 1 do |
|
- | 5704 | begin |
|
- | 5705 | if (p2[j + l2].B = 0) and (p2[j + l2].G = 0) and (p2[j + l2].R = 0) then |
|
- | 5706 | begin |
|
- | 5707 | p1[J + l1].B := Round(p1[J + l1].B / $FF * Alpha); |
|
- | 5708 | p1[J + l1].G := Round(p1[J + l1].G / $FF * Alpha); |
|
- | 5709 | p1[J + l1].R := Round(p1[J + l1].R / $FF * Alpha); |
|
- | 5710 | end |
|
- | 5711 | end; |
|
- | 5712 | end; |
|
- | 5713 | end; |
|
- | 5714 | ||
- | 5715 | procedure TDIB.DrawDarken(SrcDIB: TDIB; X, Y, Width, Height, |
|
- | 5716 | Frame: Integer); |
|
- | 5717 | var |
|
- | 5718 | frameoffset, i, j: Integer; |
|
- | 5719 | p1, p2: pByte; |
|
- | 5720 | XOffset: Integer; |
|
- | 5721 | begin |
|
- | 5722 | if Self.BitCount <> 24 then Exit; |
|
- | 5723 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5724 | ||
- | 5725 | frameoffset := 3 * (Frame * Width) + 3; |
|
- | 5726 | XOffset := 3 * X + 3; |
|
- | 5727 | for i := 1 to Height - 1 do |
|
- | 5728 | begin |
|
- | 5729 | p1 := Self.Scanline[i + Y]; |
|
- | 5730 | p2 := SrcDIB.Scanline[i]; |
|
- | 5731 | inc(p1, XOffset); |
|
- | 5732 | inc(p2, frameoffset); |
|
- | 5733 | for j := 1 to Width - 1 do |
|
- | 5734 | begin |
|
- | 5735 | p1^ := (p2^ * p1^) shr 8; // R |
|
- | 5736 | inc(p1); |
|
- | 5737 | inc(p2); |
|
- | 5738 | p1^ := (p2^ * p1^) shr 8; // G |
|
- | 5739 | inc(p1); |
|
- | 5740 | inc(p2); |
|
- | 5741 | p1^ := (p2^ * p1^) shr 8; // B |
|
- | 5742 | inc(p1); |
|
- | 5743 | inc(p2); |
|
- | 5744 | end; |
|
- | 5745 | end; |
|
- | 5746 | end; |
|
- | 5747 | ||
- | 5748 | procedure TDIB.DrawQuickAlpha(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 5749 | SourceX, SourceY: Integer; const Color: TColor; FilterMode: TFilterMode); |
|
- | 5750 | var |
|
- | 5751 | i, j: Integer; |
|
- | 5752 | k1, k2: Integer; |
|
- | 5753 | n: Integer; |
|
- | 5754 | p1, p2: PByteArray; |
|
- | 5755 | BitSwitch1, BitSwitch2: Boolean; |
|
- | 5756 | ||
- | 5757 | Startk1, Startk2: Integer; |
|
- | 5758 | StartY: Integer; |
|
- | 5759 | EndY: Integer; |
|
- | 5760 | ||
- | 5761 | DestStartY: Integer; |
|
- | 5762 | begin |
|
- | 5763 | if Self.BitCount <> 24 then Exit; |
|
- | 5764 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5765 | ||
- | 5766 | Startk1 := 3 * SourceX; |
|
- | 5767 | Startk2 := 3 * X; |
|
- | 5768 | ||
- | 5769 | DestStartY := Y - SourceY; |
|
- | 5770 | ||
- | 5771 | StartY := SourceY; |
|
- | 5772 | EndY := SourceY + Height; |
|
- | 5773 | ||
- | 5774 | if (StartY + DestStartY < 0) then |
|
- | 5775 | StartY := -DestStartY; |
|
- | 5776 | if (EndY + DestStartY > Self.Height) then |
|
- | 5777 | EndY := Self.Height - DestStartY; |
|
- | 5778 | ||
- | 5779 | if (StartY < 0) then |
|
- | 5780 | StartY := 0; |
|
- | 5781 | if (EndY > SrcDIB.Height) then |
|
- | 5782 | EndY := SrcDIB.Height; |
|
- | 5783 | ||
- | 5784 | if Odd(Y) then BitSwitch1 := true else BitSwitch1 := false; |
|
- | 5785 | if Odd(X) then BitSwitch2 := true else BitSwitch2 := false; |
|
- | 5786 | ||
- | 5787 | for j := StartY to EndY - 1 do |
|
- | 5788 | begin |
|
- | 5789 | BitSwitch1 := not BitSwitch1; |
|
- | 5790 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 5791 | p2 := SrcDIB.Scanline[j]; |
|
- | 5792 | ||
- | 5793 | k1 := Startk1; |
|
- | 5794 | k2 := Startk2; |
|
- | 5795 | ||
- | 5796 | for i := SourceX to SourceX + Width - 1 do |
|
- | 5797 | begin |
|
- | 5798 | BitSwitch2 := not BitSwitch2; |
|
- | 5799 | ||
- | 5800 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 5801 | ||
- | 5802 | case FilterMode of |
|
- | 5803 | fmNormal, fmMix50: if not (n = Color) and (BitSwitch1 xor BitSwitch2) then |
|
- | 5804 | begin |
|
- | 5805 | p1[k2] := p2[k1]; |
|
- | 5806 | p1[k2 + 1] := p2[k1 + 1]; |
|
- | 5807 | p1[k2 + 2] := p2[k1 + 2]; |
|
- | 5808 | end; |
|
- | 5809 | fmMix25: if not (n = Color) and (BitSwitch1 and BitSwitch2) then |
|
- | 5810 | begin |
|
- | 5811 | p1[k2] := p2[k1]; |
|
- | 5812 | p1[k2 + 1] := p2[k1 + 1]; |
|
- | 5813 | p1[k2 + 2] := p2[k1 + 2]; |
|
- | 5814 | end; |
|
- | 5815 | fmMix75: if not (n = Color) and (BitSwitch1 or BitSwitch2) then |
|
- | 5816 | begin |
|
- | 5817 | p1[k2] := p2[k1]; |
|
- | 5818 | p1[k2 + 1] := p2[k1 + 1]; |
|
- | 5819 | p1[k2 + 2] := p2[k1 + 2]; |
|
- | 5820 | end; |
|
- | 5821 | end; |
|
- | 5822 | ||
- | 5823 | k1 := k1 + 3; |
|
- | 5824 | k2 := k2 + 3; |
|
- | 5825 | end; |
|
- | 5826 | end; |
|
- | 5827 | end; |
|
- | 5828 | ||
- | 5829 | procedure TDIB.DrawAdditive(SrcDIB: TDIB; X, Y, Width, Height, Alpha, Frame: |
|
- | 5830 | Integer); |
|
- | 5831 | var |
|
- | 5832 | frameoffset, i, j, Wid: Integer; |
|
- | 5833 | p1, p2: pByte; |
|
- | 5834 | begin |
|
- | 5835 | if Self.BitCount <> 24 then Exit; |
|
- | 5836 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5837 | ||
- | 5838 | if (Alpha < 1) or (Alpha > 256) then Exit; |
|
- | 5839 | Wid := Width shl 1 + Width; |
|
- | 5840 | frameoffset := Wid * Frame; |
|
- | 5841 | for i := 1 to Height - 1 do |
|
- | 5842 | begin |
|
- | 5843 | if (i + Y) > (Self.Height - 1) then Break; //add 25.5.2004 JB. |
|
- | 5844 | p1 := Self.Scanline[i + Y]; |
|
- | 5845 | p2 := SrcDIB.Scanline[i]; |
|
- | 5846 | inc(p1, X shl 1 + X + 3); |
|
- | 5847 | inc(p2, frameoffset + 3); |
|
- | 5848 | for j := 3 to Wid - 4 do |
|
- | 5849 | begin |
|
- | 5850 | inc(p1^, (Alpha - p1^) * p2^ shr 8); |
|
- | 5851 | inc(p1); |
|
- | 5852 | inc(p2); |
|
- | 5853 | end; |
|
- | 5854 | end; |
|
- | 5855 | end; |
|
- | 5856 | ||
- | 5857 | procedure TDIB.DrawTranslucent(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 5858 | SourceX, SourceY: Integer; const Color: TColor); |
|
- | 5859 | var |
|
- | 5860 | i, j: Integer; |
|
- | 5861 | k1, k2: Integer; |
|
- | 5862 | n: Integer; |
|
- | 5863 | p1, p2: PByteArray; |
|
- | 5864 | ||
- | 5865 | Startk1, Startk2: Integer; |
|
- | 5866 | StartY: Integer; |
|
- | 5867 | EndY: Integer; |
|
- | 5868 | ||
- | 5869 | DestStartY: Integer; |
|
- | 5870 | begin |
|
- | 5871 | if Self.BitCount <> 24 then Exit; |
|
- | 5872 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5873 | ||
- | 5874 | Startk1 := 3 * SourceX; |
|
- | 5875 | Startk2 := 3 * X; |
|
- | 5876 | ||
- | 5877 | DestStartY := Y - SourceY; |
|
- | 5878 | ||
- | 5879 | StartY := SourceY; |
|
- | 5880 | EndY := SourceY + Height; |
|
- | 5881 | ||
- | 5882 | if (StartY + DestStartY < 0) then |
|
- | 5883 | StartY := -DestStartY; |
|
- | 5884 | if (EndY + DestStartY > Self.Height) then |
|
- | 5885 | EndY := Self.Height - DestStartY; |
|
- | 5886 | ||
- | 5887 | if (StartY < 0) then |
|
- | 5888 | StartY := 0; |
|
- | 5889 | if (EndY > SrcDIB.Height) then |
|
- | 5890 | EndY := SrcDIB.Height; |
|
- | 5891 | ||
- | 5892 | for j := StartY to EndY - 1 do |
|
- | 5893 | begin |
|
- | 5894 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 5895 | p2 := SrcDIB.Scanline[j]; |
|
- | 5896 | ||
- | 5897 | k1 := Startk1; |
|
- | 5898 | k2 := Startk2; |
|
- | 5899 | ||
- | 5900 | for i := SourceX to SourceX + Width - 1 do |
|
- | 5901 | begin |
|
- | 5902 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 5903 | ||
- | 5904 | if not (n = Color) then |
|
- | 5905 | begin |
|
- | 5906 | p1[k2] := (p1[k2] + p2[k1]) shr 1; |
|
- | 5907 | p1[k2 + 1] := (p1[k2 + 1] + p2[k1 + 1]) shr 1; |
|
- | 5908 | p1[k2 + 2] := (p1[k2 + 2] + p2[k1 + 2]) shr 1; |
|
- | 5909 | end; |
|
- | 5910 | ||
- | 5911 | k1 := k1 + 3; |
|
- | 5912 | k2 := k2 + 3; |
|
- | 5913 | end; |
|
- | 5914 | end; |
|
- | 5915 | end; |
|
- | 5916 | ||
- | 5917 | procedure TDIB.DrawAlpha(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 5918 | SourceX, SourceY, Alpha: Integer; const Color: TColor); |
|
- | 5919 | var |
|
- | 5920 | i, j: Integer; |
|
- | 5921 | k1, k2: Integer; |
|
- | 5922 | n: Integer; |
|
- | 5923 | p1, p2: PByteArray; |
|
- | 5924 | ||
- | 5925 | Startk1, Startk2: Integer; |
|
- | 5926 | StartY: Integer; |
|
- | 5927 | EndY: Integer; |
|
- | 5928 | ||
- | 5929 | DestStartY: Integer; |
|
- | 5930 | begin |
|
- | 5931 | if Self.BitCount <> 24 then Exit; |
|
- | 5932 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5933 | ||
- | 5934 | Startk1 := 3 * SourceX; |
|
- | 5935 | Startk2 := 3 * x; |
|
- | 5936 | ||
- | 5937 | DestStartY := Y - SourceY; |
|
- | 5938 | ||
- | 5939 | StartY := SourceY; |
|
- | 5940 | EndY := SourceY + Height; |
|
- | 5941 | ||
- | 5942 | if (EndY + DestStartY > Self.Height) then |
|
- | 5943 | EndY := Self.Height - DestStartY; |
|
- | 5944 | ||
- | 5945 | if (EndY > SrcDIB.Height) then |
|
- | 5946 | EndY := SrcDIB.Height; |
|
- | 5947 | ||
- | 5948 | if (StartY < 0) then |
|
- | 5949 | StartY := 0; |
|
- | 5950 | ||
- | 5951 | if (StartY + DestStartY < 0) then |
|
- | 5952 | StartY := DestStartY; |
|
- | 5953 | ||
- | 5954 | for j := StartY to EndY - 1 do |
|
- | 5955 | begin |
|
- | 5956 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 5957 | p2 := SrcDIB.Scanline[j]; |
|
- | 5958 | ||
- | 5959 | k1 := Startk1; |
|
- | 5960 | k2 := Startk2; |
|
- | 5961 | ||
- | 5962 | for i := SourceX to SourceX + Width - 1 do |
|
- | 5963 | begin |
|
- | 5964 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 5965 | ||
- | 5966 | if not (n = Color) then |
|
- | 5967 | begin |
|
- | 5968 | p1[k2] := (p1[k2] * (256 - Alpha) + p2[k1] * Alpha) shr 8; |
|
- | 5969 | p1[k2 + 1] := (p1[k2 + 1] * (256 - Alpha) + p2[k1 + 1] * Alpha) shr 8; |
|
- | 5970 | p1[k2 + 2] := (p1[k2 + 2] * (256 - Alpha) + p2[k1 + 2] * Alpha) shr 8; |
|
- | 5971 | end; |
|
- | 5972 | ||
- | 5973 | k1 := k1 + 3; |
|
- | 5974 | k2 := k2 + 3; |
|
- | 5975 | end; |
|
- | 5976 | end; |
|
- | 5977 | end; |
|
- | 5978 | ||
- | 5979 | procedure TDIB.DrawAlphaMask(SrcDIB, MaskDIB: TDIB; const X, Y, |
|
- | 5980 | Width, Height, SourceX, SourceY: Integer); |
|
- | 5981 | var |
|
- | 5982 | i, j: Integer; |
|
- | 5983 | k1, k2, k3: Integer; |
|
- | 5984 | p1, p2, p3: PByteArray; |
|
- | 5985 | ||
- | 5986 | Startk1, Startk2: Integer; |
|
- | 5987 | StartY: Integer; |
|
- | 5988 | EndY: Integer; |
|
- | 5989 | ||
- | 5990 | DestStartY: Integer; |
|
- | 5991 | begin |
|
- | 5992 | if Self.BitCount <> 24 then Exit; |
|
- | 5993 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 5994 | ||
- | 5995 | Startk1 := 3 * SourceX; |
|
- | 5996 | Startk2 := 3 * x; |
|
- | 5997 | ||
- | 5998 | DestStartY := Y - SourceY; |
|
- | 5999 | ||
- | 6000 | StartY := SourceY; |
|
- | 6001 | EndY := SourceY + Height; |
|
- | 6002 | ||
- | 6003 | if (EndY + DestStartY > Self.Height) then |
|
- | 6004 | EndY := Self.Height - DestStartY; |
|
- | 6005 | ||
- | 6006 | if (EndY > SrcDIB.Height) then |
|
- | 6007 | EndY := SrcDIB.Height; |
|
- | 6008 | ||
- | 6009 | if (StartY < 0) then |
|
- | 6010 | StartY := 0; |
|
- | 6011 | ||
- | 6012 | if (StartY + DestStartY < 0) then |
|
- | 6013 | StartY := DestStartY; |
|
- | 6014 | ||
- | 6015 | for j := StartY to EndY - 1 do |
|
- | 6016 | begin |
|
- | 6017 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 6018 | p2 := SrcDIB.Scanline[j]; |
|
- | 6019 | p3 := MaskDIB.Scanline[j]; |
|
- | 6020 | ||
- | 6021 | k1 := Startk1; |
|
- | 6022 | k2 := Startk2; |
|
- | 6023 | k3 := 0; |
|
- | 6024 | ||
- | 6025 | for i := SourceX to SourceX + Width - 1 do |
|
- | 6026 | begin |
|
- | 6027 | p1[k2] := (p1[k2] * (256 - p3[k3]) + p2[k1] * p3[k3]) shr 8; |
|
- | 6028 | p1[k2 + 1] := (p1[k2 + 1] * (256 - p3[k3]) + p2[k1 + 1] * p3[k3]) shr 8; |
|
- | 6029 | p1[k2 + 2] := (p1[k2 + 2] * (256 - p3[k3]) + p2[k1 + 2] * p3[k3]) shr 8; |
|
- | 6030 | ||
- | 6031 | k1 := k1 + 3; |
|
- | 6032 | k2 := k2 + 3; |
|
- | 6033 | k3 := k3 + 3; |
|
- | 6034 | end; |
|
- | 6035 | end; |
|
- | 6036 | end; |
|
- | 6037 | ||
- | 6038 | procedure TDIB.DrawMorphed(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 6039 | SourceX, SourceY: Integer; const Color: TColor); |
|
- | 6040 | var |
|
- | 6041 | i, j, r, g, b: Integer; |
|
- | 6042 | k1, k2: Integer; |
|
- | 6043 | n: Integer; |
|
- | 6044 | p1, p2: PByteArray; |
|
- | 6045 | ||
- | 6046 | Startk1, Startk2: Integer; |
|
- | 6047 | StartY: Integer; |
|
- | 6048 | EndY: Integer; |
|
- | 6049 | ||
- | 6050 | DestStartY: Integer; |
|
- | 6051 | begin |
|
- | 6052 | if Self.BitCount <> 24 then Exit; |
|
- | 6053 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 6054 | ||
- | 6055 | Startk1 := 3 * SourceX; |
|
- | 6056 | Startk2 := 3 * x; |
|
- | 6057 | ||
- | 6058 | DestStartY := Y - SourceY; |
|
- | 6059 | ||
- | 6060 | StartY := SourceY; |
|
- | 6061 | EndY := SourceY + Height; |
|
- | 6062 | ||
- | 6063 | if (EndY + DestStartY > Self.Height) then |
|
- | 6064 | EndY := Self.Height - DestStartY; |
|
- | 6065 | ||
- | 6066 | if (EndY > SrcDIB.Height) then |
|
- | 6067 | EndY := SrcDIB.Height; |
|
- | 6068 | ||
- | 6069 | if (StartY < 0) then |
|
- | 6070 | StartY := 0; |
|
- | 6071 | ||
- | 6072 | if (StartY + DestStartY < 0) then |
|
- | 6073 | StartY := DestStartY; |
|
- | 6074 | ||
- | 6075 | r := 0; |
|
- | 6076 | g := 0; |
|
- | 6077 | b := 0; |
|
- | 6078 | ||
- | 6079 | for j := StartY to EndY - 1 do |
|
- | 6080 | begin |
|
- | 6081 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 6082 | p2 := SrcDIB.Scanline[j]; |
|
- | 6083 | ||
- | 6084 | k1 := Startk1; |
|
- | 6085 | k2 := Startk2; |
|
- | 6086 | ||
- | 6087 | for i := SourceX to SourceX + Width - 1 do |
|
- | 6088 | begin |
|
- | 6089 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 6090 | ||
- | 6091 | if Random(100) < 50 then |
|
- | 6092 | begin |
|
- | 6093 | b := p1[k2]; |
|
- | 6094 | g := p1[k2 + 1]; |
|
- | 6095 | r := p1[k2 + 2]; |
|
- | 6096 | end; |
|
- | 6097 | ||
- | 6098 | if not (n = Color) then |
|
- | 6099 | begin |
|
- | 6100 | p1[k2] := b; |
|
- | 6101 | p1[k2 + 1] := g; |
|
- | 6102 | p1[k2 + 2] := r; |
|
- | 6103 | end; |
|
- | 6104 | ||
- | 6105 | k1 := k1 + 3; |
|
- | 6106 | k2 := k2 + 3; |
|
- | 6107 | end; |
|
- | 6108 | end; |
|
- | 6109 | end; |
|
- | 6110 | ||
- | 6111 | procedure TDIB.DrawMono(SrcDIB: TDIB; const X, Y, Width, Height, |
|
- | 6112 | SourceX, SourceY: Integer; const TransColor, ForeColor, BackColor: TColor); |
|
- | 6113 | var |
|
- | 6114 | i, j, r1, g1, b1, r2, g2, b2: Integer; |
|
- | 6115 | k1, k2: Integer; |
|
- | 6116 | n: Integer; |
|
- | 6117 | p1, p2: PByteArray; |
|
- | 6118 | Startk1, Startk2, StartY, EndY, DestStartY: Integer; |
|
- | 6119 | begin |
|
- | 6120 | if Self.BitCount <> 24 then Exit; |
|
- | 6121 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 6122 | ||
- | 6123 | Startk1 := 3 * SourceX; |
|
- | 6124 | Startk2 := 3 * x; |
|
- | 6125 | ||
- | 6126 | DestStartY := Y - SourceY; |
|
- | 6127 | ||
- | 6128 | StartY := SourceY; |
|
- | 6129 | EndY := SourceY + Height; |
|
- | 6130 | ||
- | 6131 | if (EndY + DestStartY > Self.Height) then |
|
- | 6132 | EndY := Self.Height - DestStartY; |
|
- | 6133 | ||
- | 6134 | if (EndY > SrcDIB.Height) then |
|
- | 6135 | EndY := SrcDIB.Height; |
|
- | 6136 | ||
- | 6137 | if (StartY < 0) then |
|
- | 6138 | StartY := 0; |
|
- | 6139 | ||
- | 6140 | if (StartY + DestStartY < 0) then |
|
- | 6141 | StartY := DestStartY; |
|
- | 6142 | ||
- | 6143 | r1 := GetRValue(BackColor); |
|
- | 6144 | g1 := GetGValue(BackColor); |
|
- | 6145 | b1 := GetBValue(BackColor); |
|
- | 6146 | ||
- | 6147 | r2 := GetRValue(ForeColor); |
|
- | 6148 | g2 := GetGValue(ForeColor); |
|
- | 6149 | b2 := GetBValue(ForeColor); |
|
- | 6150 | ||
- | 6151 | ||
- | 6152 | for j := StartY to EndY - 1 do |
|
- | 6153 | begin |
|
- | 6154 | p1 := Self.Scanline[j + DestStartY]; |
|
- | 6155 | p2 := SrcDIB.Scanline[j]; |
|
- | 6156 | ||
- | 6157 | k1 := Startk1; |
|
- | 6158 | k2 := Startk2; |
|
- | 6159 | ||
- | 6160 | for i := SourceX to SourceX + Width - 1 do |
|
- | 6161 | begin |
|
- | 6162 | n := (p2[k1] shl 16) + (p2[k1 + 1] shl 8) + p2[k1 + 2]; |
|
- | 6163 | ||
- | 6164 | if (n = TransColor) then |
|
- | 6165 | begin |
|
- | 6166 | p1[k2] := b1; |
|
- | 6167 | p1[k2 + 1] := g1; |
|
- | 6168 | p1[k2 + 2] := r1; |
|
- | 6169 | end |
|
- | 6170 | else |
|
- | 6171 | begin |
|
- | 6172 | p1[k2] := b2; |
|
- | 6173 | p1[k2 + 1] := g2; |
|
- | 6174 | p1[k2 + 2] := r2; |
|
- | 6175 | end; |
|
- | 6176 | ||
- | 6177 | k1 := k1 + 3; |
|
- | 6178 | k2 := k2 + 3; |
|
- | 6179 | end; |
|
- | 6180 | end; |
|
- | 6181 | end; |
|
- | 6182 | ||
- | 6183 | procedure TDIB.Draw3x3Matrix(SrcDIB: TDIB; Setting: TMatrixSetting); |
|
- | 6184 | var i, j, k: Integer; |
|
- | 6185 | p1, p2, p3, p4: PByteArray; |
|
- | 6186 | begin |
|
- | 6187 | if Self.BitCount <> 24 then Exit; |
|
- | 6188 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 6189 | ||
- | 6190 | for i := 1 to SrcDIB.Height - 2 do |
|
- | 6191 | begin |
|
- | 6192 | p1 := SrcDIB.ScanLine[i - 1]; |
|
- | 6193 | p2 := SrcDIB.ScanLine[i]; |
|
- | 6194 | p3 := SrcDIB.ScanLine[i + 1]; |
|
- | 6195 | p4 := Self.ScanLine[i]; |
|
- | 6196 | for j := 3 to 3 * SrcDIB.Width - 4 do |
|
- | 6197 | begin |
|
- | 6198 | k := (p1[j - 3] * Setting[0] + p1[j] * Setting[1] + p1[j + 3] * Setting[2] + |
|
- | 6199 | p2[j - 3] * Setting[3] + p2[j] * Setting[4] + p2[j + 3] * Setting[5] + |
|
- | 6200 | p3[j - 3] * Setting[6] + p3[j] * Setting[7] + p3[j + 3] * Setting[8]) |
|
- | 6201 | div Setting[9]; |
|
- | 6202 | if k < 0 then k := 0; |
|
- | 6203 | if k > 255 then k := 255; |
|
- | 6204 | p4[j] := k; |
|
- | 6205 | end; |
|
- | 6206 | end; |
|
- | 6207 | end; |
|
- | 6208 | ||
- | 6209 | procedure TDIB.DrawAntialias(SrcDIB: TDIB); |
|
- | 6210 | var i, j, k, l, m: Integer; |
|
- | 6211 | p1, p2, p3: PByteArray; |
|
- | 6212 | begin |
|
- | 6213 | if Self.BitCount <> 24 then Exit; |
|
- | 6214 | if SrcDIB.BitCount <> 24 then Exit; |
|
- | 6215 | ||
- | 6216 | for i := 1 to Self.Height - 1 do |
|
- | 6217 | begin |
|
- | 6218 | k := i shl 1; |
|
- | 6219 | p1 := SrcDIB.Scanline[k]; |
|
- | 6220 | p2 := SrcDIB.Scanline[k + 1]; |
|
- | 6221 | p3 := Self.Scanline[i]; |
|
- | 6222 | for j := 1 to Self.Width - 1 do |
|
- | 6223 | begin |
|
- | 6224 | m := 3 * j; |
|
- | 6225 | l := m shl 1; |
|
- | 6226 | p3[m] := (p1[l] + p1[l + 3] + p2[l] + p2[l + 3]) shr 2; |
|
- | 6227 | p3[m + 1] := (p1[l + 1] + p1[l + 4] + p2[l + 1] + p2[l + 4]) shr 2; |
|
- | 6228 | p3[m + 2] := (p1[l + 2] + p1[l + 5] + p2[l + 2] + p2[l + 5]) shr 2; |
|
- | 6229 | end; |
|
- | 6230 | end; |
|
- | 6231 | end; |
|
- | 6232 | ||
- | 6233 | procedure TDIB.FilterLine(X1, Y1, X2, Y2: Integer; Color: TColor; |
|
- | 6234 | FilterMode: TFilterMode); |
|
- | 6235 | var |
|
- | 6236 | i, j: Integer; |
|
- | 6237 | t: TColor; |
|
- | 6238 | r1, g1, b1, r2, g2, b2: Integer; |
|
- | 6239 | begin |
|
- | 6240 | j := ROUND(Sqrt(Sqr(ABS(X2 - X1)) + Sqr(ABS(Y2 - Y1)))); |
|
- | 6241 | if j < 1 then Exit; |
|
- | 6242 | ||
- | 6243 | r1 := GetRValue(Color); |
|
- | 6244 | g1 := GetGValue(Color); |
|
- | 6245 | b1 := GetBValue(Color); |
|
- | 6246 | ||
- | 6247 | for i := 0 to j do |
|
- | 6248 | begin |
|
- | 6249 | t := Self.Pixels[X1 + ((X2 - X1) * i div j), Y1 + ((Y2 - Y1) * i div j)]; |
|
- | 6250 | r2 := GetRValue(t); |
|
- | 6251 | g2 := GetGValue(t); |
|
- | 6252 | b2 := GetBValue(t); |
|
- | 6253 | case FilterMode of |
|
- | 6254 | fmNormal: t := RGB(r1 + (((256 - r1) * r2) shr 8), |
|
- | 6255 | g1 + (((256 - g1) * g2) shr 8), |
|
- | 6256 | b1 + (((256 - b1) * b2) shr 8)); |
|
- | 6257 | fmMix25: t := RGB((r1 + r2 * 3) shr 2, (g1 + g2 * 3) shr 2, (b1 + b2 * 3) shr 2); |
|
- | 6258 | fmMix50: t := RGB((r1 + r2) shr 1, (g1 + g2) shr 1, (b1 + b2) shr 1); |
|
- | 6259 | fmMix75: t := RGB((r1 * 3 + r2) shr 2, (g1 * 3 + g2) shr 2, (b1 * 3 + b2) shr 2); |
|
- | 6260 | end; |
|
- | 6261 | Self.Pixels[X1 + ((X2 - X1) * i div j), Y1 + ((Y2 - Y1) * i div j)] := t; |
|
- | 6262 | end; |
|
- | 6263 | end; |
|
- | 6264 | ||
- | 6265 | procedure TDIB.FilterRect(X, Y, Width, Height: Integer; |
|
- | 6266 | Color: TColor; FilterMode: TFilterMode); |
|
- | 6267 | var |
|
- | 6268 | i, j, r, g, b, C1: Integer; |
|
- | 6269 | p1, p2, p3: pByte; |
|
- | 6270 | begin |
|
- | 6271 | if Self.BitCount <> 24 then Exit; |
|
- | 6272 | ||
- | 6273 | r := GetRValue(Color); |
|
- | 6274 | g := GetGValue(Color); |
|
- | 6275 | b := GetBValue(Color); |
|
- | 6276 | ||
- | 6277 | for i := 0 to Height - 1 do |
|
- | 6278 | begin |
|
- | 6279 | p1 := Self.Scanline[i + Y]; |
|
- | 6280 | Inc(p1, (3 * X)); |
|
- | 6281 | for j := 0 to Width - 1 do |
|
- | 6282 | begin |
|
- | 6283 | case FilterMode of |
|
- | 6284 | fmNormal: |
|
- | 6285 | begin |
|
- | 6286 | p2 := p1; |
|
- | 6287 | Inc(p2); |
|
- | 6288 | p3 := p2; |
|
- | 6289 | Inc(p3); |
|
- | 6290 | C1 := (p1^ + p2^ + p3^) div 3; |
|
- | 6291 | ||
- | 6292 | p1^ := (C1 * b) shr 8; |
|
- | 6293 | Inc(p1); |
|
- | 6294 | p1^ := (C1 * g) shr 8; |
|
- | 6295 | Inc(p1); |
|
- | 6296 | p1^ := (C1 * r) shr 8; |
|
- | 6297 | Inc(p1); |
|
- | 6298 | end; |
|
- | 6299 | fmMix25: |
|
- | 6300 | begin |
|
- | 6301 | p1^ := (3 * p1^ + b) shr 2; |
|
- | 6302 | Inc(p1); |
|
- | 6303 | p1^ := (3 * p1^ + g) shr 2; |
|
- | 6304 | Inc(p1); |
|
- | 6305 | p1^ := (3 * p1^ + r) shr 2; |
|
- | 6306 | Inc(p1); |
|
- | 6307 | end; |
|
- | 6308 | fmMix50: |
|
- | 6309 | begin |
|
- | 6310 | p1^ := (p1^ + b) shr 1; |
|
- | 6311 | Inc(p1); |
|
- | 6312 | p1^ := (p1^ + g) shr 1; |
|
- | 6313 | Inc(p1); |
|
- | 6314 | p1^ := (p1^ + r) shr 1; |
|
- | 6315 | Inc(p1); |
|
- | 6316 | end; |
|
- | 6317 | fmMix75: |
|
- | 6318 | begin |
|
- | 6319 | p1^ := (p1^ + 3 * b) shr 2; |
|
- | 6320 | Inc(p1); |
|
- | 6321 | p1^ := (p1^ + 3 * g) shr 2; |
|
- | 6322 | Inc(p1); |
|
- | 6323 | p1^ := (p1^ + 3 * r) shr 2; |
|
- | 6324 | Inc(p1); |
|
- | 6325 | end; |
|
- | 6326 | end; |
|
- | 6327 | end; |
|
- | 6328 | end; |
|
- | 6329 | end; |
|
- | 6330 | ||
- | 6331 | procedure TDIB.InitLight(Count, Detail: Integer); |
|
- | 6332 | var |
|
- | 6333 | i, j: Integer; |
|
- | 6334 | begin |
|
- | 6335 | LG_COUNT := Count; |
|
- | 6336 | LG_DETAIL := Detail; |
|
- | 6337 | ||
- | 6338 | for i := 0 to 255 do // Build Lightning LUT |
|
- | 6339 | for j := 0 to 255 do |
|
- | 6340 | FLUTDist[i, j] := ROUND(Sqrt(Sqr(i * 10) + Sqr(j * 10))); |
|
- | 6341 | end; |
|
- | 6342 | ||
- | 6343 | procedure TDIB.DrawLights(FLight: TLightArray; |
|
- | 6344 | AmbientLight: TColor); |
|
- | 6345 | var |
|
- | 6346 | i, j, l, m, n, o, q, D1, D2, R, G, B, AR, AG, AB: Integer; |
|
- | 6347 | P: array{$IFNDEF VER4UP} [0..4096]{$ENDIF} of PByteArray; |
|
- | 6348 | begin |
|
- | 6349 | if Self.BitCount <> 24 then Exit; |
|
- | 6350 | ||
- | 6351 | {$IFDEF VER4UP} |
|
- | 6352 | SetLength(P, LG_DETAIL); |
|
- | 6353 | {$ENDIF} |
|
- | 6354 | AR := GetRValue(AmbientLight); |
|
- | 6355 | AG := GetGValue(AmbientLight); |
|
- | 6356 | AB := GetBValue(AmbientLight); |
|
- | 6357 | ||
- | 6358 | for i := (Self.Height div (LG_DETAIL + 1)) downto 1 do |
|
- | 6359 | begin |
|
- | 6360 | for o := 0 to LG_DETAIL do |
|
- | 6361 | P[o] := Self.Scanline[(LG_DETAIL + 1) * i - o]; |
|
- | 6362 | ||
- | 6363 | for j := (Self.Width div (LG_DETAIL + 1)) downto 1 do |
|
- | 6364 | begin |
|
- | 6365 | R := AR; |
|
- | 6366 | G := AG; |
|
- | 6367 | B := AB; |
|
- | 6368 | ||
- | 6369 | for l := LG_COUNT - 1 downto 0 do // Check the lightsources |
|
- | 6370 | begin |
|
- | 6371 | D1 := ABS(j * (LG_DETAIL + 1) - FLight[l].X) div FLight[l].Size1; |
|
- | 6372 | D2 := ABS(i * (LG_DETAIL + 1) - FLight[l].Y) div FLight[l].Size2; |
|
- | 6373 | if D1 > 255 then D1 := 255; |
|
- | 6374 | if D2 > 255 then D2 := 255; |
|
- | 6375 | ||
- | 6376 | m := 255 - FLUTDist[D1, D2]; |
|
- | 6377 | if m < 0 then m := 0; |
|
- | 6378 | ||
- | 6379 | Inc(R, (PosValue(GetRValue(FLight[l].Color) - R) * m shr 8)); |
|
- | 6380 | Inc(G, (PosValue(GetGValue(FLight[l].Color) - G) * m shr 8)); |
|
- | 6381 | Inc(B, (PosValue(GetBValue(FLight[l].Color) - B) * m shr 8)); |
|
- | 6382 | end; |
|
- | 6383 | ||
- | 6384 | for q := LG_DETAIL downto 0 do |
|
- | 6385 | begin |
|
- | 6386 | n := 3 * (j * (LG_DETAIL + 1) - q); |
|
- | 6387 | ||
- | 6388 | for o := LG_DETAIL downto 0 do |
|
- | 6389 | begin |
|
- | 6390 | P[o][n] := (P[o][n] * B) shr 8; |
|
- | 6391 | P[o][n + 1] := (P[o][n + 1] * G) shr 8; |
|
- | 6392 | P[o][n + 2] := (P[o][n + 2] * R) shr 8; |
|
- | 6393 | end; |
|
- | 6394 | end; |
|
- | 6395 | end; |
|
- | 6396 | end; |
|
- | 6397 | {$IFDEF VER4UP} |
|
- | 6398 | SetLength(P, 0); |
|
- | 6399 | {$ENDIF} |
|
- | 6400 | end; |
|
- | 6401 | ||
- | 6402 | procedure TDIB.DrawOn(Dest: TRect; DestCanvas: TCanvas; Xsrc, Ysrc: Integer); |
|
- | 6403 | {procedure is supplement of original TDIBUltra function} |
|
- | 6404 | begin |
|
- | 6405 | //if not AsSigned(SrcCanvas) then Exit; |
|
- | 6406 | if (Xsrc < 0) then |
|
- | 6407 | begin |
|
- | 6408 | Dec(Dest.Left, Xsrc); |
|
- | 6409 | Inc(Dest.Right {Width }, Xsrc); |
|
- | 6410 | Xsrc := 0 |
|
- | 6411 | end; |
|
- | 6412 | if (Ysrc < 0) then |
|
- | 6413 | begin |
|
- | 6414 | Dec(Dest.Top, Ysrc); |
|
- | 6415 | Inc(Dest.Bottom {Height}, Ysrc); |
|
- | 6416 | Ysrc := 0 |
|
- | 6417 | end; |
|
- | 6418 | BitBlt(DestCanvas.Handle, Dest.Left, Dest.Top, Dest.Right, Dest.Bottom, Self.Canvas.Handle, Xsrc, Ysrc, SRCCOPY); |
|
- | 6419 | end; |
|
- | 6420 | ||
- | 6421 | { DXFusion <- } |
|
- | 6422 | ||
- | 6423 | { added effect for DIB } |
|
- | 6424 | ||
- | 6425 | function IntToByte(i: Integer): Byte; |
|
- | 6426 | begin |
|
- | 6427 | if i > 255 then Result := 255 |
|
- | 6428 | else if i < 0 then Result := 0 |
|
- | 6429 | else Result := i; |
|
- | 6430 | end; |
|
- | 6431 | ||
- | 6432 | {standalone routine} |
|
- | 6433 | ||
- | 6434 | procedure TDIB.Darker(Percent: Integer); |
|
- | 6435 | {color to dark in percent} |
|
- | 6436 | var |
|
- | 6437 | p0: pbytearray; |
|
- | 6438 | r, g, b, x, y: Integer; |
|
- | 6439 | begin |
|
- | 6440 | if Self.BitCount <> 24 then Exit; |
|
- | 6441 | for y := 0 to Self.Height - 1 do |
|
- | 6442 | begin |
|
- | 6443 | p0 := Self.ScanLine[y]; |
|
- | 6444 | for x := 0 to Self.Width - 1 do |
|
- | 6445 | begin |
|
- | 6446 | r := p0[x * 3]; |
|
- | 6447 | g := p0[x * 3 + 1]; |
|
- | 6448 | b := p0[x * 3 + 2]; |
|
- | 6449 | p0[x * 3] := Round(R * Percent / 100); |
|
- | 6450 | p0[x * 3 + 1] := Round(G * Percent / 100); |
|
- | 6451 | p0[x * 3 + 2] := Round(B * Percent / 100); |
|
- | 6452 | end; |
|
- | 6453 | end; |
|
- | 6454 | end; |
|
- | 6455 | ||
- | 6456 | procedure TDIB.Lighter(Percent: Integer); |
|
- | 6457 | var |
|
- | 6458 | p0: pbytearray; |
|
- | 6459 | r, g, b, x, y: Integer; |
|
- | 6460 | begin |
|
- | 6461 | if Self.BitCount <> 24 then Exit; |
|
- | 6462 | for y := 0 to Self.Height - 1 do |
|
- | 6463 | begin |
|
- | 6464 | p0 := Self.ScanLine[y]; |
|
- | 6465 | for x := 0 to Self.Width - 1 do |
|
- | 6466 | begin |
|
- | 6467 | r := p0[x * 3]; |
|
- | 6468 | g := p0[x * 3 + 1]; |
|
- | 6469 | b := p0[x * 3 + 2]; |
|
- | 6470 | p0[x * 3] := Round(R * Percent / 100) + Round(255 - Percent / 100 * 255); |
|
- | 6471 | p0[x * 3 + 1] := Round(G * Percent / 100) + Round(255 - Percent / 100 * 255); |
|
- | 6472 | p0[x * 3 + 2] := Round(B * Percent / 100) + Round(255 - Percent / 100 * 255); |
|
- | 6473 | end; |
|
- | 6474 | end; |
|
- | 6475 | end; |
|
- | 6476 | ||
- | 6477 | procedure TDIB.Darkness(Amount: Integer); |
|
- | 6478 | var |
|
- | 6479 | p0: pbytearray; |
|
- | 6480 | r, g, b, x, y: Integer; |
|
- | 6481 | begin |
|
- | 6482 | if Self.BitCount <> 24 then Exit; |
|
- | 6483 | for y := 0 to Self.Height - 1 do |
|
- | 6484 | begin |
|
- | 6485 | p0 := Self.ScanLine[y]; |
|
- | 6486 | for x := 0 to Self.Width - 1 do |
|
- | 6487 | begin |
|
- | 6488 | r := p0[x * 3]; |
|
- | 6489 | g := p0[x * 3 + 1]; |
|
- | 6490 | b := p0[x * 3 + 2]; |
|
- | 6491 | p0[x * 3] := IntToByte(r - ((r) * Amount) div 255); |
|
- | 6492 | p0[x * 3 + 1] := IntToByte(g - ((g) * Amount) div 255); |
|
- | 6493 | p0[x * 3 + 2] := IntToByte(b - ((b) * Amount) div 255); |
|
- | 6494 | end; |
|
- | 6495 | end; |
|
- | 6496 | end; |
|
- | 6497 | ||
- | 6498 | function TrimInt(i, Min, Max: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 6499 | begin |
|
- | 6500 | if i > Max then Result := Max |
|
- | 6501 | else if i < Min then Result := Min |
|
- | 6502 | else Result := i; |
|
- | 6503 | end; |
|
- | 6504 | ||
- | 6505 | procedure TDIB.DoSmoothRotate(Src: TDIB; cx, cy: Integer; Angle: Extended); |
|
- | 6506 | var |
|
- | 6507 | Top, Bottom, Left, Right, eww, nsw, fx, fy, wx, wy: Extended; |
|
- | 6508 | cAngle, sAngle: Double; |
|
- | 6509 | xDiff, yDiff, ifx, ify, px, py, ix, iy, x, y: Integer; |
|
- | 6510 | nw, ne, sw, se: TBGR; |
|
- | 6511 | P1, P2, P3: Pbytearray; |
|
- | 6512 | begin |
|
- | 6513 | Angle := angle; |
|
- | 6514 | Angle := -Angle * Pi / 180; |
|
- | 6515 | sAngle := Sin(Angle); |
|
- | 6516 | cAngle := Cos(Angle); |
|
- | 6517 | xDiff := (Self.Width - Src.Width) div 2; |
|
- | 6518 | yDiff := (Self.Height - Src.Height) div 2; |
|
- | 6519 | for y := 0 to Self.Height - 1 do |
|
- | 6520 | begin |
|
- | 6521 | P3 := Self.scanline[y]; |
|
- | 6522 | py := 2 * (y - cy) + 1; |
|
- | 6523 | for x := 0 to Self.Width - 1 do |
|
- | 6524 | begin |
|
- | 6525 | px := 2 * (x - cx) + 1; |
|
- | 6526 | fx := (((px * cAngle - py * sAngle) - 1) / 2 + cx) - xDiff; |
|
- | 6527 | fy := (((px * sAngle + py * cAngle) - 1) / 2 + cy) - yDiff; |
|
- | 6528 | ifx := Round(fx); |
|
- | 6529 | ify := Round(fy); |
|
- | 6530 | ||
- | 6531 | if (ifx > -1) and (ifx < Src.Width) and (ify > -1) and (ify < Src.Height) then |
|
- | 6532 | begin |
|
- | 6533 | eww := fx - ifx; |
|
- | 6534 | nsw := fy - ify; |
|
- | 6535 | iy := TrimInt(ify + 1, 0, Src.Height - 1); |
|
- | 6536 | ix := TrimInt(ifx + 1, 0, Src.Width - 1); |
|
- | 6537 | P1 := Src.scanline[ify]; |
|
- | 6538 | P2 := Src.scanline[iy]; |
|
- | 6539 | nw.r := P1[ifx * 3]; |
|
- | 6540 | nw.g := P1[ifx * 3 + 1]; |
|
- | 6541 | nw.b := P1[ifx * 3 + 2]; |
|
- | 6542 | ne.r := P1[ix * 3]; |
|
- | 6543 | ne.g := P1[ix * 3 + 1]; |
|
- | 6544 | ne.b := P1[ix * 3 + 2]; |
|
- | 6545 | sw.r := P2[ifx * 3]; |
|
- | 6546 | sw.g := P2[ifx * 3 + 1]; |
|
- | 6547 | sw.b := P2[ifx * 3 + 2]; |
|
- | 6548 | se.r := P2[ix * 3]; |
|
- | 6549 | se.g := P2[ix * 3 + 1]; |
|
- | 6550 | se.b := P2[ix * 3 + 2]; |
|
- | 6551 | ||
- | 6552 | Top := nw.b + eww * (ne.b - nw.b); |
|
- | 6553 | Bottom := sw.b + eww * (se.b - sw.b); |
|
- | 6554 | P3[x * 3 + 2] := IntToByte(Round(Top + nsw * (Bottom - Top))); |
|
- | 6555 | ||
- | 6556 | Top := nw.g + eww * (ne.g - nw.g); |
|
- | 6557 | Bottom := sw.g + eww * (se.g - sw.g); |
|
- | 6558 | P3[x * 3 + 1] := IntToByte(Round(Top + nsw * (Bottom - Top))); |
|
- | 6559 | ||
- | 6560 | Top := nw.r + eww * (ne.r - nw.r); |
|
- | 6561 | Bottom := sw.r + eww * (se.r - sw.r); |
|
- | 6562 | P3[x * 3] := IntToByte(Round(Top + nsw * (Bottom - Top))); |
|
- | 6563 | end; |
|
- | 6564 | end; |
|
- | 6565 | end; |
|
- | 6566 | end; |
|
- | 6567 | ||
- | 6568 | //---------------------- |
|
- | 6569 | //--- 24 bit count routines ---------------------- |
|
- | 6570 | //---------------------- |
|
- | 6571 | ||
- | 6572 | procedure TDIB.DoInvert; |
|
- | 6573 | procedure PicInvert(src: TDIB); |
|
- | 6574 | var w, h, x, y: Integer; |
|
- | 6575 | p: pbytearray; |
|
- | 6576 | begin |
|
- | 6577 | w := src.width; |
|
- | 6578 | h := src.height; |
|
- | 6579 | src.BitCount := 24; |
|
- | 6580 | for y := 0 to h - 1 do |
|
- | 6581 | begin |
|
- | 6582 | p := src.scanline[y]; |
|
- | 6583 | for x := 0 to w - 1 do |
|
- | 6584 | begin |
|
- | 6585 | p[x * 3] := not p[x * 3]; |
|
- | 6586 | p[x * 3 + 1] := not p[x * 3 + 1]; |
|
- | 6587 | p[x * 3 + 2] := not p[x * 3 + 2]; |
|
- | 6588 | end; |
|
- | 6589 | end; |
|
- | 6590 | end; |
|
- | 6591 | begin |
|
- | 6592 | PicInvert(Self); |
|
- | 6593 | end; |
|
- | 6594 | ||
- | 6595 | procedure TDIB.DoAddColorNoise(Amount: Integer); |
|
- | 6596 | procedure AddColorNoise(var clip: TDIB; Amount: Integer); |
|
- | 6597 | var |
|
- | 6598 | p0: pbytearray; |
|
- | 6599 | x, y, r, g, b: Integer; |
|
- | 6600 | begin |
|
- | 6601 | for y := 0 to clip.Height - 1 do |
|
- | 6602 | begin |
|
- | 6603 | p0 := clip.ScanLine[y]; |
|
- | 6604 | for x := 0 to clip.Width - 1 do |
|
- | 6605 | begin |
|
- | 6606 | r := p0[x * 3] + (Random(Amount) - (Amount shr 1)); |
|
- | 6607 | g := p0[x * 3 + 1] + (Random(Amount) - (Amount shr 1)); |
|
- | 6608 | b := p0[x * 3 + 2] + (Random(Amount) - (Amount shr 1)); |
|
- | 6609 | p0[x * 3] := IntToByte(r); |
|
- | 6610 | p0[x * 3 + 1] := IntToByte(g); |
|
- | 6611 | p0[x * 3 + 2] := IntToByte(b); |
|
- | 6612 | end; |
|
- | 6613 | end; |
|
- | 6614 | end; |
|
- | 6615 | var BB: TDIB; |
|
- | 6616 | begin |
|
- | 6617 | BB := TDIB.Create; |
|
- | 6618 | BB.BitCount := 24; |
|
- | 6619 | BB.Assign(Self); |
|
- | 6620 | AddColorNoise(bb, Amount); |
|
- | 6621 | Self.Assign(BB); |
|
- | 6622 | BB.Free; |
|
- | 6623 | end; |
|
- | 6624 | ||
- | 6625 | procedure TDIB.DoAddMonoNoise(Amount: Integer); |
|
- | 6626 | procedure _AddMonoNoise(var clip: TDIB; Amount: Integer); |
|
- | 6627 | var |
|
- | 6628 | p0: pbytearray; |
|
- | 6629 | x, y, a, r, g, b: Integer; |
|
- | 6630 | begin |
|
- | 6631 | for y := 0 to clip.Height - 1 do |
|
- | 6632 | begin |
|
- | 6633 | p0 := clip.scanline[y]; |
|
- | 6634 | for x := 0 to clip.Width - 1 do |
|
- | 6635 | begin |
|
- | 6636 | a := Random(Amount) - (Amount shr 1); |
|
- | 6637 | r := p0[x * 3] + a; |
|
- | 6638 | g := p0[x * 3 + 1] + a; |
|
- | 6639 | b := p0[x * 3 + 2] + a; |
|
- | 6640 | p0[x * 3] := IntToByte(r); |
|
- | 6641 | p0[x * 3 + 1] := IntToByte(g); |
|
- | 6642 | p0[x * 3 + 2] := IntToByte(b); |
|
- | 6643 | end; |
|
- | 6644 | end; |
|
- | 6645 | end; |
|
- | 6646 | var BB: TDIB; |
|
- | 6647 | begin |
|
- | 6648 | BB := TDIB.Create; |
|
- | 6649 | BB.BitCount := 24; |
|
- | 6650 | BB.Assign(Self); |
|
- | 6651 | _AddMonoNoise(bb, Amount); |
|
- | 6652 | Self.Assign(BB); |
|
- | 6653 | BB.Free; |
|
- | 6654 | end; |
|
- | 6655 | ||
- | 6656 | procedure TDIB.DoAntiAlias; |
|
- | 6657 | procedure AntiAlias(clip: TDIB); |
|
- | 6658 | procedure AntiAliasRect(clip: TDIB; XOrigin, YOrigin, XFinal, YFinal: Integer); |
|
- | 6659 | var Memo, x, y: Integer; (* Composantes primaires des points environnants *) |
|
- | 6660 | p0, p1, p2: pbytearray; |
|
- | 6661 | begin |
|
- | 6662 | if XFinal < XOrigin then begin Memo := XOrigin; XOrigin := XFinal; XFinal := Memo; end; (* Inversion des valeurs *) |
|
- | 6663 | if YFinal < YOrigin then begin Memo := YOrigin; YOrigin := YFinal; YFinal := Memo; end; (* si diffrence ngative*) |
|
- | 6664 | XOrigin := max(1, XOrigin); |
|
- | 6665 | YOrigin := max(1, YOrigin); |
|
- | 6666 | XFinal := min(clip.width - 2, XFinal); |
|
- | 6667 | YFinal := min(clip.height - 2, YFinal); |
|
- | 6668 | clip.BitCount := 24; |
|
- | 6669 | for y := YOrigin to YFinal do |
|
- | 6670 | begin |
|
- | 6671 | p0 := clip.ScanLine[y - 1]; |
|
- | 6672 | p1 := clip.scanline[y]; |
|
- | 6673 | p2 := clip.ScanLine[y + 1]; |
|
- | 6674 | for x := XOrigin to XFinal do |
|
- | 6675 | begin |
|
- | 6676 | p1[x * 3] := (p0[x * 3] + p2[x * 3] + p1[(x - 1) * 3] + p1[(x + 1) * 3]) div 4; |
|
- | 6677 | p1[x * 3 + 1] := (p0[x * 3 + 1] + p2[x * 3 + 1] + p1[(x - 1) * 3 + 1] + p1[(x + 1) * 3 + 1]) div 4; |
|
- | 6678 | p1[x * 3 + 2] := (p0[x * 3 + 2] + p2[x * 3 + 2] + p1[(x - 1) * 3 + 2] + p1[(x + 1) * 3 + 2]) div 4; |
|
- | 6679 | end; |
|
- | 6680 | end; |
|
- | 6681 | end; |
|
- | 6682 | begin |
|
- | 6683 | AntiAliasRect(clip, 0, 0, clip.width, clip.height); |
|
- | 6684 | end; |
|
- | 6685 | begin |
|
- | 6686 | AntiAlias(Self); |
|
- | 6687 | end; |
|
- | 6688 | ||
- | 6689 | procedure TDIB.DoContrast(Amount: Integer); |
|
- | 6690 | procedure _Contrast(var clip: TDIB; Amount: Integer); |
|
- | 6691 | var |
|
- | 6692 | p0: pbytearray; |
|
- | 6693 | rg, gg, bg, r, g, b, x, y: Integer; |
|
- | 6694 | begin |
|
- | 6695 | for y := 0 to clip.Height - 1 do |
|
- | 6696 | begin |
|
- | 6697 | p0 := clip.scanline[y]; |
|
- | 6698 | for x := 0 to clip.Width - 1 do |
|
- | 6699 | begin |
|
- | 6700 | r := p0[x * 3]; |
|
- | 6701 | g := p0[x * 3 + 1]; |
|
- | 6702 | b := p0[x * 3 + 2]; |
|
- | 6703 | rg := (Abs(127 - r) * Amount) div 255; |
|
- | 6704 | gg := (Abs(127 - g) * Amount) div 255; |
|
- | 6705 | bg := (Abs(127 - b) * Amount) div 255; |
|
- | 6706 | if r > 127 then r := r + rg else r := r - rg; |
|
- | 6707 | if g > 127 then g := g + gg else g := g - gg; |
|
- | 6708 | if b > 127 then b := b + bg else b := b - bg; |
|
- | 6709 | p0[x * 3] := IntToByte(r); |
|
- | 6710 | p0[x * 3 + 1] := IntToByte(g); |
|
- | 6711 | p0[x * 3 + 2] := IntToByte(b); |
|
- | 6712 | end; |
|
- | 6713 | end; |
|
- | 6714 | end; |
|
- | 6715 | var BB: TDIB; |
|
- | 6716 | begin |
|
- | 6717 | BB := TDIB.Create; |
|
- | 6718 | BB.BitCount := 24; |
|
- | 6719 | BB.Assign(Self); |
|
- | 6720 | _Contrast(bb, Amount); |
|
- | 6721 | Self.Assign(BB); |
|
- | 6722 | BB.Free; |
|
- | 6723 | end; |
|
- | 6724 | ||
- | 6725 | procedure TDIB.DoFishEye(Amount: Integer); |
|
- | 6726 | procedure _FishEye(var Bmp, Dst: TDIB; Amount: Extended); |
|
- | 6727 | var |
|
- | 6728 | xmid, ymid: Single; |
|
- | 6729 | fx, fy: Single; |
|
- | 6730 | r1, r2: Single; |
|
- | 6731 | ifx, ify: Integer; |
|
- | 6732 | dx, dy: Single; |
|
- | 6733 | rmax: Single; |
|
- | 6734 | ty, tx: Integer; |
|
- | 6735 | weight_x, weight_y: array[0..1] of Single; |
|
- | 6736 | weight: Single; |
|
- | 6737 | new_red, new_green: Integer; |
|
- | 6738 | new_blue: Integer; |
|
- | 6739 | total_red, total_green: Single; |
|
- | 6740 | total_blue: Single; |
|
- | 6741 | ix, iy: Integer; |
|
- | 6742 | sli, slo: PByteArray; |
|
- | 6743 | begin |
|
- | 6744 | xmid := Bmp.Width / 2; |
|
- | 6745 | ymid := Bmp.Height / 2; |
|
- | 6746 | rmax := Dst.Width * Amount; |
|
- | 6747 | ||
- | 6748 | for ty := 0 to Dst.Height - 1 do |
|
- | 6749 | begin |
|
- | 6750 | for tx := 0 to Dst.Width - 1 do |
|
- | 6751 | begin |
|
- | 6752 | dx := tx - xmid; |
|
- | 6753 | dy := ty - ymid; |
|
- | 6754 | r1 := Sqrt(dx * dx + dy * dy); |
|
- | 6755 | if r1 = 0 then |
|
- | 6756 | begin |
|
- | 6757 | fx := xmid; |
|
- | 6758 | fy := ymid; |
|
- | 6759 | end |
|
- | 6760 | else |
|
- | 6761 | begin |
|
- | 6762 | r2 := rmax / 2 * (1 / (1 - r1 / rmax) - 1); |
|
- | 6763 | fx := dx * r2 / r1 + xmid; |
|
- | 6764 | fy := dy * r2 / r1 + ymid; |
|
- | 6765 | end; |
|
- | 6766 | ify := Trunc(fy); |
|
- | 6767 | ifx := Trunc(fx); |
|
- | 6768 | // Calculate the weights. |
|
- | 6769 | if fy >= 0 then |
|
- | 6770 | begin |
|
- | 6771 | weight_y[1] := fy - ify; |
|
- | 6772 | weight_y[0] := 1 - weight_y[1]; |
|
- | 6773 | end |
|
- | 6774 | else |
|
- | 6775 | begin |
|
- | 6776 | weight_y[0] := -(fy - ify); |
|
- | 6777 | weight_y[1] := 1 - weight_y[0]; |
|
- | 6778 | end; |
|
- | 6779 | if fx >= 0 then |
|
- | 6780 | begin |
|
- | 6781 | weight_x[1] := fx - ifx; |
|
- | 6782 | weight_x[0] := 1 - weight_x[1]; |
|
- | 6783 | end |
|
- | 6784 | else |
|
- | 6785 | begin |
|
- | 6786 | weight_x[0] := -(fx - ifx); |
|
- | 6787 | Weight_x[1] := 1 - weight_x[0]; |
|
- | 6788 | end; |
|
- | 6789 | ||
- | 6790 | if ifx < 0 then |
|
- | 6791 | ifx := Bmp.Width - 1 - (-ifx mod Bmp.Width) |
|
- | 6792 | else if ifx > Bmp.Width - 1 then |
|
- | 6793 | ifx := ifx mod Bmp.Width; |
|
- | 6794 | if ify < 0 then |
|
- | 6795 | ify := Bmp.Height - 1 - (-ify mod Bmp.Height) |
|
- | 6796 | else if ify > Bmp.Height - 1 then |
|
- | 6797 | ify := ify mod Bmp.Height; |
|
- | 6798 | ||
- | 6799 | total_red := 0.0; |
|
- | 6800 | total_green := 0.0; |
|
- | 6801 | total_blue := 0.0; |
|
- | 6802 | for ix := 0 to 1 do |
|
- | 6803 | begin |
|
- | 6804 | for iy := 0 to 1 do |
|
- | 6805 | begin |
|
- | 6806 | if ify + iy < Bmp.Height then |
|
- | 6807 | sli := Bmp.scanline[ify + iy] |
|
- | 6808 | else |
|
- | 6809 | sli := Bmp.scanline[Bmp.Height - ify - iy]; |
|
- | 6810 | if ifx + ix < Bmp.Width then |
|
- | 6811 | begin |
|
- | 6812 | new_red := sli[(ifx + ix) * 3]; |
|
- | 6813 | new_green := sli[(ifx + ix) * 3 + 1]; |
|
- | 6814 | new_blue := sli[(ifx + ix) * 3 + 2]; |
|
- | 6815 | end |
|
- | 6816 | else |
|
- | 6817 | begin |
|
- | 6818 | new_red := sli[(Bmp.Width - ifx - ix) * 3]; |
|
- | 6819 | new_green := sli[(Bmp.Width - ifx - ix) * 3 + 1]; |
|
- | 6820 | new_blue := sli[(Bmp.Width - ifx - ix) * 3 + 2]; |
|
- | 6821 | end; |
|
- | 6822 | weight := weight_x[ix] * weight_y[iy]; |
|
- | 6823 | total_red := total_red + new_red * weight; |
|
- | 6824 | total_green := total_green + new_green * weight; |
|
- | 6825 | total_blue := total_blue + new_blue * weight; |
|
- | 6826 | end; |
|
- | 6827 | end; |
|
- | 6828 | slo := Dst.scanline[ty]; |
|
- | 6829 | slo[tx * 3] := Round(total_red); |
|
- | 6830 | slo[tx * 3 + 1] := Round(total_green); |
|
- | 6831 | slo[tx * 3 + 2] := Round(total_blue); |
|
- | 6832 | ||
- | 6833 | end; |
|
- | 6834 | end; |
|
- | 6835 | end; |
|
- | 6836 | var BB1, BB2: TDIB; |
|
- | 6837 | begin |
|
- | 6838 | BB1 := TDIB.Create; |
|
- | 6839 | BB1.BitCount := 24; |
|
- | 6840 | BB1.Assign(Self); |
|
- | 6841 | BB2 := TDIB.Create; |
|
- | 6842 | BB2.BitCount := 24; |
|
- | 6843 | BB2.Assign(BB1); |
|
- | 6844 | _FishEye(BB1, BB2, Amount); |
|
- | 6845 | Self.Assign(BB2); |
|
- | 6846 | BB1.Free; |
|
- | 6847 | BB2.Free; |
|
- | 6848 | end; |
|
- | 6849 | ||
- | 6850 | procedure TDIB.DoGrayScale; |
|
- | 6851 | procedure GrayScale(var clip: TDIB); |
|
- | 6852 | var |
|
- | 6853 | p0: pbytearray; |
|
- | 6854 | Gray, x, y: Integer; |
|
- | 6855 | begin |
|
- | 6856 | for y := 0 to clip.Height - 1 do |
|
- | 6857 | begin |
|
- | 6858 | p0 := clip.scanline[y]; |
|
- | 6859 | for x := 0 to clip.Width - 1 do |
|
- | 6860 | begin |
|
- | 6861 | Gray := Round(p0[x * 3] * 0.3 + p0[x * 3 + 1] * 0.59 + p0[x * 3 + 2] * 0.11); |
|
- | 6862 | p0[x * 3] := Gray; |
|
- | 6863 | p0[x * 3 + 1] := Gray; |
|
- | 6864 | p0[x * 3 + 2] := Gray; |
|
- | 6865 | end; |
|
- | 6866 | end; |
|
- | 6867 | end; |
|
- | 6868 | var BB: TDIB; |
|
- | 6869 | begin |
|
- | 6870 | BB := TDIB.Create; |
|
- | 6871 | BB.BitCount := 24; |
|
- | 6872 | BB.Assign(Self); |
|
- | 6873 | GrayScale(BB); |
|
- | 6874 | Self.Assign(BB); |
|
- | 6875 | BB.Free; |
|
- | 6876 | end; |
|
- | 6877 | ||
- | 6878 | procedure TDIB.DoLightness(Amount: Integer); |
|
- | 6879 | procedure _Lightness(var clip: TDIB; Amount: Integer); |
|
- | 6880 | var |
|
- | 6881 | p0: pbytearray; |
|
- | 6882 | r, g, b, x, y: Integer; |
|
- | 6883 | begin |
|
- | 6884 | for y := 0 to clip.Height - 1 do |
|
- | 6885 | begin |
|
- | 6886 | p0 := clip.scanline[y]; |
|
- | 6887 | for x := 0 to clip.Width - 1 do |
|
- | 6888 | begin |
|
- | 6889 | r := p0[x * 3]; |
|
- | 6890 | g := p0[x * 3 + 1]; |
|
- | 6891 | b := p0[x * 3 + 2]; |
|
- | 6892 | p0[x * 3] := IntToByte(r + ((255 - r) * Amount) div 255); |
|
- | 6893 | p0[x * 3 + 1] := IntToByte(g + ((255 - g) * Amount) div 255); |
|
- | 6894 | p0[x * 3 + 2] := IntToByte(b + ((255 - b) * Amount) div 255); |
|
- | 6895 | end; |
|
- | 6896 | end; |
|
- | 6897 | end; |
|
- | 6898 | var BB: TDIB; |
|
- | 6899 | begin |
|
- | 6900 | BB := TDIB.Create; |
|
- | 6901 | BB.BitCount := 24; |
|
- | 6902 | BB.Assign(Self); |
|
- | 6903 | _Lightness(BB, Amount); |
|
- | 6904 | Self.Assign(BB); |
|
- | 6905 | BB.Free; |
|
- | 6906 | end; |
|
- | 6907 | ||
- | 6908 | procedure TDIB.DoDarkness(Amount: Integer); |
|
- | 6909 | var BB: TDIB; |
|
- | 6910 | begin |
|
- | 6911 | BB := TDIB.Create; |
|
- | 6912 | BB.BitCount := 24; |
|
- | 6913 | BB.Assign(Self); |
|
- | 6914 | BB.Darkness(Amount); |
|
- | 6915 | Self.Assign(BB); |
|
- | 6916 | BB.Free; |
|
- | 6917 | end; |
|
- | 6918 | ||
- | 6919 | procedure TDIB.DoSaturation(Amount: Integer); |
|
- | 6920 | procedure _Saturation(var clip: TDIB; Amount: Integer); |
|
- | 6921 | var |
|
- | 6922 | p0: pbytearray; |
|
- | 6923 | Gray, r, g, b, x, y: Integer; |
|
- | 6924 | begin |
|
- | 6925 | for y := 0 to clip.Height - 1 do |
|
- | 6926 | begin |
|
- | 6927 | p0 := clip.scanline[y]; |
|
- | 6928 | for x := 0 to clip.Width - 1 do |
|
- | 6929 | begin |
|
- | 6930 | r := p0[x * 3]; |
|
- | 6931 | g := p0[x * 3 + 1]; |
|
- | 6932 | b := p0[x * 3 + 2]; |
|
- | 6933 | Gray := (r + g + b) div 3; |
|
- | 6934 | p0[x * 3] := IntToByte(Gray + (((r - Gray) * Amount) div 255)); |
|
- | 6935 | p0[x * 3 + 1] := IntToByte(Gray + (((g - Gray) * Amount) div 255)); |
|
- | 6936 | p0[x * 3 + 2] := IntToByte(Gray + (((b - Gray) * Amount) div 255)); |
|
- | 6937 | end; |
|
- | 6938 | end; |
|
- | 6939 | end; |
|
- | 6940 | var BB: TDIB; |
|
- | 6941 | begin |
|
- | 6942 | BB := TDIB.Create; |
|
- | 6943 | BB.BitCount := 24; |
|
- | 6944 | BB.Assign(Self); |
|
- | 6945 | _Saturation(BB, Amount); |
|
- | 6946 | Self.Assign(BB); |
|
- | 6947 | BB.Free; |
|
- | 6948 | end; |
|
- | 6949 | ||
- | 6950 | procedure TDIB.DoSplitBlur(Amount: Integer); |
|
- | 6951 | {NOTE: For a gaussian blur is amount 3} |
|
- | 6952 | procedure _SplitBlur(var clip: TDIB; Amount: Integer); |
|
- | 6953 | var |
|
- | 6954 | p0, p1, p2: pbytearray; |
|
- | 6955 | cx, x, y: Integer; |
|
- | 6956 | Buf: array[0..3, 0..2] of byte; |
|
- | 6957 | begin |
|
- | 6958 | if Amount = 0 then Exit; |
|
- | 6959 | for y := 0 to clip.Height - 1 do |
|
- | 6960 | begin |
|
- | 6961 | p0 := clip.scanline[y]; |
|
- | 6962 | if y - Amount < 0 then p1 := clip.scanline[y] |
|
- | 6963 | else {y-Amount>0} p1 := clip.ScanLine[y - Amount]; |
|
- | 6964 | if y + Amount < clip.Height then p2 := clip.ScanLine[y + Amount] |
|
- | 6965 | else {y+Amount>=Height} p2 := clip.ScanLine[clip.Height - y]; |
|
- | 6966 | ||
- | 6967 | for x := 0 to clip.Width - 1 do |
|
- | 6968 | begin |
|
- | 6969 | if x - Amount < 0 then cx := x |
|
- | 6970 | else {x-Amount>0} cx := x - Amount; |
|
- | 6971 | Buf[0, 0] := p1[cx * 3]; |
|
- | 6972 | Buf[0, 1] := p1[cx * 3 + 1]; |
|
- | 6973 | Buf[0, 2] := p1[cx * 3 + 2]; |
|
- | 6974 | Buf[1, 0] := p2[cx * 3]; |
|
- | 6975 | Buf[1, 1] := p2[cx * 3 + 1]; |
|
- | 6976 | Buf[1, 2] := p2[cx * 3 + 2]; |
|
- | 6977 | if x + Amount < clip.Width then cx := x + Amount |
|
- | 6978 | else {x+Amount>=Width} cx := clip.Width - x; |
|
- | 6979 | Buf[2, 0] := p1[cx * 3]; |
|
- | 6980 | Buf[2, 1] := p1[cx * 3 + 1]; |
|
- | 6981 | Buf[2, 2] := p1[cx * 3 + 2]; |
|
- | 6982 | Buf[3, 0] := p2[cx * 3]; |
|
- | 6983 | Buf[3, 1] := p2[cx * 3 + 1]; |
|
- | 6984 | Buf[3, 2] := p2[cx * 3 + 2]; |
|
- | 6985 | p0[x * 3] := (Buf[0, 0] + Buf[1, 0] + Buf[2, 0] + Buf[3, 0]) shr 2; |
|
- | 6986 | p0[x * 3 + 1] := (Buf[0, 1] + Buf[1, 1] + Buf[2, 1] + Buf[3, 1]) shr 2; |
|
- | 6987 | p0[x * 3 + 2] := (Buf[0, 2] + Buf[1, 2] + Buf[2, 2] + Buf[3, 2]) shr 2; |
|
- | 6988 | end; |
|
- | 6989 | end; |
|
- | 6990 | end; |
|
- | 6991 | var BB: TDIB; |
|
- | 6992 | begin |
|
- | 6993 | BB := TDIB.Create; |
|
- | 6994 | BB.BitCount := 24; |
|
- | 6995 | BB.Assign(Self); |
|
- | 6996 | _SplitBlur(BB, Amount); |
|
- | 6997 | Self.Assign(BB); |
|
- | 6998 | BB.Free; |
|
- | 6999 | end; |
|
- | 7000 | ||
- | 7001 | procedure TDIB.DoGaussianBlur(Amount: Integer); |
|
- | 7002 | var BB: TDIB; |
|
- | 7003 | begin |
|
- | 7004 | BB := TDIB.Create; |
|
- | 7005 | BB.BitCount := 24; |
|
- | 7006 | BB.BitCount := 24; |
|
- | 7007 | BB.Assign(Self); |
|
- | 7008 | GaussianBlur(BB, Amount); |
|
- | 7009 | Self.Assign(BB); |
|
- | 7010 | BB.Free; |
|
- | 7011 | end; |
|
- | 7012 | ||
- | 7013 | procedure TDIB.DoMosaic(Size: Integer); |
|
- | 7014 | procedure Mosaic(var Bm: TDIB; size: Integer); |
|
- | 7015 | var |
|
- | 7016 | x, y, i, j: Integer; |
|
- | 7017 | p1, p2: pbytearray; |
|
- | 7018 | r, g, b: byte; |
|
- | 7019 | begin |
|
- | 7020 | y := 0; |
|
- | 7021 | repeat |
|
- | 7022 | p1 := bm.scanline[y]; |
|
- | 7023 | repeat |
|
- | 7024 | j := 1; |
|
- | 7025 | repeat |
|
- | 7026 | p2 := bm.scanline[y]; |
|
- | 7027 | x := 0; |
|
- | 7028 | repeat |
|
- | 7029 | r := p1[x * 3]; |
|
- | 7030 | g := p1[x * 3 + 1]; |
|
- | 7031 | b := p1[x * 3 + 2]; |
|
- | 7032 | i := 1; |
|
- | 7033 | repeat |
|
- | 7034 | p2[x * 3] := r; |
|
- | 7035 | p2[x * 3 + 1] := g; |
|
- | 7036 | p2[x * 3 + 2] := b; |
|
- | 7037 | inc(x); |
|
- | 7038 | inc(i); |
|
- | 7039 | until (x >= bm.width) or (i > size); |
|
- | 7040 | until x >= bm.width; |
|
- | 7041 | inc(j); |
|
- | 7042 | inc(y); |
|
- | 7043 | until (y >= bm.height) or (j > size); |
|
- | 7044 | until (y >= bm.height) or (x >= bm.width); |
|
- | 7045 | until y >= bm.height; |
|
- | 7046 | end; |
|
- | 7047 | var BB: TDIB; |
|
- | 7048 | begin |
|
- | 7049 | BB := TDIB.Create; |
|
- | 7050 | BB.BitCount := 24; |
|
- | 7051 | BB.Assign(Self); |
|
- | 7052 | Mosaic(BB, Size); |
|
- | 7053 | Self.Assign(BB); |
|
- | 7054 | BB.Free; |
|
- | 7055 | end; |
|
- | 7056 | ||
- | 7057 | procedure TDIB.DoTwist(Amount: Integer); |
|
- | 7058 | procedure _Twist(var Bmp, Dst: TDIB; Amount: Integer); |
|
- | 7059 | var |
|
- | 7060 | fxmid, fymid: Single; |
|
- | 7061 | txmid, tymid: Single; |
|
- | 7062 | fx, fy: Single; |
|
- | 7063 | tx2, ty2: Single; |
|
- | 7064 | r: Single; |
|
- | 7065 | theta: Single; |
|
- | 7066 | ifx, ify: Integer; |
|
- | 7067 | dx, dy: Single; |
|
- | 7068 | OFFSET: Single; |
|
- | 7069 | ty, tx: Integer; |
|
- | 7070 | weight_x, weight_y: array[0..1] of Single; |
|
- | 7071 | weight: Single; |
|
- | 7072 | new_red, new_green: Integer; |
|
- | 7073 | new_blue: Integer; |
|
- | 7074 | total_red, total_green: Single; |
|
- | 7075 | total_blue: Single; |
|
- | 7076 | ix, iy: Integer; |
|
- | 7077 | sli, slo: PBytearray; |
|
- | 7078 | ||
- | 7079 | function ArcTan2(xt, yt: Single): Single; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 7080 | begin |
|
- | 7081 | if xt = 0 then |
|
- | 7082 | if yt > 0 then |
|
- | 7083 | Result := Pi / 2 |
|
- | 7084 | else |
|
- | 7085 | Result := -(Pi / 2) |
|
- | 7086 | else |
|
- | 7087 | begin |
|
- | 7088 | Result := ArcTan(yt / xt); |
|
- | 7089 | if xt < 0 then |
|
- | 7090 | Result := Pi + ArcTan(yt / xt); |
|
- | 7091 | end; |
|
- | 7092 | end; |
|
- | 7093 | ||
- | 7094 | begin |
|
- | 7095 | OFFSET := -(Pi / 2); |
|
- | 7096 | dx := Bmp.Width - 1; |
|
- | 7097 | dy := Bmp.Height - 1; |
|
- | 7098 | r := Sqrt(dx * dx + dy * dy); |
|
- | 7099 | tx2 := r; |
|
- | 7100 | ty2 := r; |
|
- | 7101 | txmid := (Bmp.Width - 1) / 2; //Adjust these to move center of rotation |
|
- | 7102 | tymid := (Bmp.Height - 1) / 2; //Adjust these to move ...... |
|
- | 7103 | fxmid := (Bmp.Width - 1) / 2; |
|
- | 7104 | fymid := (Bmp.Height - 1) / 2; |
|
- | 7105 | if tx2 >= Bmp.Width then tx2 := Bmp.Width - 1; |
|
- | 7106 | if ty2 >= Bmp.Height then ty2 := Bmp.Height - 1; |
|
- | 7107 | ||
- | 7108 | for ty := 0 to Round(ty2) do |
|
- | 7109 | begin |
|
- | 7110 | for tx := 0 to Round(tx2) do |
|
- | 7111 | begin |
|
- | 7112 | dx := tx - txmid; |
|
- | 7113 | dy := ty - tymid; |
|
- | 7114 | r := Sqrt(dx * dx + dy * dy); |
|
- | 7115 | if r = 0 then |
|
- | 7116 | begin |
|
- | 7117 | fx := 0; |
|
- | 7118 | fy := 0; |
|
- | 7119 | end |
|
- | 7120 | else |
|
- | 7121 | begin |
|
- | 7122 | theta := ArcTan2(dx, dy) - r / Amount - OFFSET; |
|
- | 7123 | fx := r * Cos(theta); |
|
- | 7124 | fy := r * Sin(theta); |
|
- | 7125 | end; |
|
- | 7126 | fx := fx + fxmid; |
|
- | 7127 | fy := fy + fymid; |
|
- | 7128 | ||
- | 7129 | ify := Trunc(fy); |
|
- | 7130 | ifx := Trunc(fx); |
|
- | 7131 | // Calculate the weights. |
|
- | 7132 | if fy >= 0 then |
|
- | 7133 | begin |
|
- | 7134 | weight_y[1] := fy - ify; |
|
- | 7135 | weight_y[0] := 1 - weight_y[1]; |
|
- | 7136 | end |
|
- | 7137 | else |
|
- | 7138 | begin |
|
- | 7139 | weight_y[0] := -(fy - ify); |
|
- | 7140 | weight_y[1] := 1 - weight_y[0]; |
|
- | 7141 | end; |
|
- | 7142 | if fx >= 0 then |
|
- | 7143 | begin |
|
- | 7144 | weight_x[1] := fx - ifx; |
|
- | 7145 | weight_x[0] := 1 - weight_x[1]; |
|
- | 7146 | end |
|
- | 7147 | else |
|
- | 7148 | begin |
|
- | 7149 | weight_x[0] := -(fx - ifx); |
|
- | 7150 | Weight_x[1] := 1 - weight_x[0]; |
|
- | 7151 | end; |
|
- | 7152 | ||
- | 7153 | if ifx < 0 then |
|
- | 7154 | ifx := Bmp.Width - 1 - (-ifx mod Bmp.Width) |
|
- | 7155 | else if ifx > Bmp.Width - 1 then |
|
- | 7156 | ifx := ifx mod Bmp.Width; |
|
- | 7157 | if ify < 0 then |
|
- | 7158 | ify := Bmp.Height - 1 - (-ify mod Bmp.Height) |
|
- | 7159 | else if ify > Bmp.Height - 1 then |
|
- | 7160 | ify := ify mod Bmp.Height; |
|
- | 7161 | ||
- | 7162 | total_red := 0.0; |
|
- | 7163 | total_green := 0.0; |
|
- | 7164 | total_blue := 0.0; |
|
- | 7165 | for ix := 0 to 1 do |
|
- | 7166 | begin |
|
- | 7167 | for iy := 0 to 1 do |
|
- | 7168 | begin |
|
- | 7169 | if ify + iy < Bmp.Height then |
|
- | 7170 | sli := Bmp.scanline[ify + iy] |
|
- | 7171 | else |
|
- | 7172 | sli := Bmp.scanline[Bmp.Height - ify - iy]; |
|
- | 7173 | if ifx + ix < Bmp.Width then |
|
- | 7174 | begin |
|
- | 7175 | new_red := sli[(ifx + ix) * 3]; |
|
- | 7176 | new_green := sli[(ifx + ix) * 3 + 1]; |
|
- | 7177 | new_blue := sli[(ifx + ix) * 3 + 2]; |
|
- | 7178 | end |
|
- | 7179 | else |
|
- | 7180 | begin |
|
- | 7181 | new_red := sli[(Bmp.Width - ifx - ix) * 3]; |
|
- | 7182 | new_green := sli[(Bmp.Width - ifx - ix) * 3 + 1]; |
|
- | 7183 | new_blue := sli[(Bmp.Width - ifx - ix) * 3 + 2]; |
|
- | 7184 | end; |
|
- | 7185 | weight := weight_x[ix] * weight_y[iy]; |
|
- | 7186 | total_red := total_red + new_red * weight; |
|
- | 7187 | total_green := total_green + new_green * weight; |
|
- | 7188 | total_blue := total_blue + new_blue * weight; |
|
- | 7189 | end; |
|
- | 7190 | end; |
|
- | 7191 | slo := Dst.scanline[ty]; |
|
- | 7192 | slo[tx * 3] := Round(total_red); |
|
- | 7193 | slo[tx * 3 + 1] := Round(total_green); |
|
- | 7194 | slo[tx * 3 + 2] := Round(total_blue); |
|
- | 7195 | end; |
|
- | 7196 | end; |
|
- | 7197 | end; |
|
- | 7198 | var BB1, BB2: TDIB; |
|
- | 7199 | begin |
|
- | 7200 | BB1 := TDIB.Create; |
|
- | 7201 | BB1.BitCount := 24; |
|
- | 7202 | BB1.Assign(Self); |
|
- | 7203 | BB2 := TDIB.Create; |
|
- | 7204 | BB2.BitCount := 24; |
|
- | 7205 | BB2.Assign(BB1); |
|
- | 7206 | _Twist(BB1, BB2, Amount); |
|
- | 7207 | Self.Assign(BB2); |
|
- | 7208 | BB1.Free; |
|
- | 7209 | BB2.Free; |
|
- | 7210 | end; |
|
- | 7211 | ||
- | 7212 | procedure TDIB.DoTrace(Amount: Integer); |
|
- | 7213 | procedure Trace(src: TDIB; intensity: Integer); |
|
- | 7214 | var |
|
- | 7215 | x, y, i: Integer; |
|
- | 7216 | P1, P2, P3, P4: PByteArray; |
|
- | 7217 | tb, TraceB: byte; |
|
- | 7218 | hasb: Boolean; |
|
- | 7219 | bitmap: TDIB; |
|
- | 7220 | begin |
|
- | 7221 | bitmap := TDIB.create; |
|
- | 7222 | bitmap.width := src.width; |
|
- | 7223 | bitmap.height := src.height; |
|
- | 7224 | bitmap.canvas.draw(0, 0, src); |
|
- | 7225 | bitmap.BitCount := 8; |
|
- | 7226 | src.BitCount := 24; |
|
- | 7227 | hasb := false; |
|
- | 7228 | TraceB := $00; tb := 0; |
|
- | 7229 | for i := 1 to Intensity do |
|
- | 7230 | begin |
|
- | 7231 | for y := 0 to BitMap.height - 2 do |
|
- | 7232 | begin |
|
- | 7233 | P1 := BitMap.ScanLine[y]; |
|
- | 7234 | P2 := BitMap.scanline[y + 1]; |
|
- | 7235 | P3 := src.scanline[y]; |
|
- | 7236 | P4 := src.scanline[y + 1]; |
|
- | 7237 | x := 0; |
|
- | 7238 | repeat |
|
- | 7239 | if p1[x] <> p1[x + 1] then |
|
- | 7240 | begin |
|
- | 7241 | if not hasb then |
|
- | 7242 | begin |
|
- | 7243 | tb := p1[x + 1]; |
|
- | 7244 | hasb := true; |
|
- | 7245 | p3[x * 3] := TraceB; |
|
- | 7246 | p3[x * 3 + 1] := TraceB; |
|
- | 7247 | p3[x * 3 + 2] := TraceB; |
|
- | 7248 | end |
|
- | 7249 | else |
|
- | 7250 | begin |
|
- | 7251 | if p1[x] <> tb then |
|
- | 7252 | begin |
|
- | 7253 | p3[x * 3] := TraceB; |
|
- | 7254 | p3[x * 3 + 1] := TraceB; |
|
- | 7255 | p3[x * 3 + 2] := TraceB; |
|
- | 7256 | end |
|
- | 7257 | else |
|
- | 7258 | begin |
|
- | 7259 | p3[(x + 1) * 3] := TraceB; |
|
- | 7260 | p3[(x + 1) * 3 + 1] := TraceB; |
|
- | 7261 | p3[(x + 1) * 3 + 1] := TraceB; |
|
- | 7262 | end; |
|
- | 7263 | end; |
|
- | 7264 | end; |
|
- | 7265 | if p1[x] <> p2[x] then |
|
- | 7266 | begin |
|
- | 7267 | if not hasb then |
|
- | 7268 | begin |
|
- | 7269 | tb := p2[x]; |
|
- | 7270 | hasb := true; |
|
- | 7271 | p3[x * 3] := TraceB; |
|
- | 7272 | p3[x * 3 + 1] := TraceB; |
|
- | 7273 | p3[x * 3 + 2] := TraceB; |
|
- | 7274 | end |
|
- | 7275 | else |
|
- | 7276 | begin |
|
- | 7277 | if p1[x] <> tb then |
|
- | 7278 | begin |
|
- | 7279 | p3[x * 3] := TraceB; |
|
- | 7280 | p3[x * 3 + 1] := TraceB; |
|
- | 7281 | p3[x * 3 + 2] := TraceB; |
|
- | 7282 | end |
|
- | 7283 | else |
|
- | 7284 | begin |
|
- | 7285 | p4[x * 3] := TraceB; |
|
- | 7286 | p4[x * 3 + 1] := TraceB; |
|
- | 7287 | p4[x * 3 + 2] := TraceB; |
|
- | 7288 | end; |
|
- | 7289 | end; |
|
- | 7290 | end; |
|
- | 7291 | inc(x); |
|
- | 7292 | until x >= (BitMap.width - 2); |
|
- | 7293 | end; |
|
- | 7294 | if i > 1 then |
|
- | 7295 | for y := BitMap.height - 1 downto 1 do |
|
- | 7296 | begin |
|
- | 7297 | P1 := BitMap.ScanLine[y]; |
|
- | 7298 | P2 := BitMap.scanline[y - 1]; |
|
- | 7299 | P3 := src.scanline[y]; |
|
- | 7300 | P4 := src.scanline[y - 1]; |
|
- | 7301 | x := Bitmap.width - 1; |
|
- | 7302 | repeat |
|
- | 7303 | if p1[x] <> p1[x - 1] then |
|
- | 7304 | begin |
|
- | 7305 | if not hasb then |
|
- | 7306 | begin |
|
- | 7307 | tb := p1[x - 1]; |
|
- | 7308 | hasb := true; |
|
- | 7309 | p3[x * 3] := TraceB; |
|
- | 7310 | p3[x * 3 + 1] := TraceB; |
|
- | 7311 | p3[x * 3 + 2] := TraceB; |
|
- | 7312 | end |
|
- | 7313 | else |
|
- | 7314 | begin |
|
- | 7315 | if p1[x] <> tb then |
|
- | 7316 | begin |
|
- | 7317 | p3[x * 3] := TraceB; |
|
- | 7318 | p3[x * 3 + 1] := TraceB; |
|
- | 7319 | p3[x * 3 + 2] := TraceB; |
|
- | 7320 | end |
|
- | 7321 | else |
|
- | 7322 | begin |
|
- | 7323 | p3[(x - 1) * 3] := TraceB; |
|
- | 7324 | p3[(x - 1) * 3 + 1] := TraceB; |
|
- | 7325 | p3[(x - 1) * 3 + 2] := TraceB; |
|
- | 7326 | end; |
|
- | 7327 | end; |
|
- | 7328 | end; |
|
- | 7329 | if p1[x] <> p2[x] then |
|
- | 7330 | begin |
|
- | 7331 | if not hasb then |
|
- | 7332 | begin |
|
- | 7333 | tb := p2[x]; |
|
- | 7334 | hasb := true; |
|
- | 7335 | p3[x * 3] := TraceB; |
|
- | 7336 | p3[x * 3 + 1] := TraceB; |
|
- | 7337 | p3[x * 3 + 2] := TraceB; |
|
- | 7338 | end |
|
- | 7339 | else |
|
- | 7340 | begin |
|
- | 7341 | if p1[x] <> tb then |
|
- | 7342 | begin |
|
- | 7343 | p3[x * 3] := TraceB; |
|
- | 7344 | p3[x * 3 + 1] := TraceB; |
|
- | 7345 | p3[x * 3 + 2] := TraceB; |
|
- | 7346 | end |
|
- | 7347 | else |
|
- | 7348 | begin |
|
- | 7349 | p4[x * 3] := TraceB; |
|
- | 7350 | p4[x * 3 + 1] := TraceB; |
|
- | 7351 | p4[x * 3 + 2] := TraceB; |
|
- | 7352 | end; |
|
- | 7353 | end; |
|
- | 7354 | end; |
|
- | 7355 | dec(x); |
|
- | 7356 | until x <= 1; |
|
- | 7357 | end; |
|
- | 7358 | end; |
|
- | 7359 | bitmap.free; |
|
- | 7360 | end; |
|
- | 7361 | var BB1, BB2: TDIB; |
|
- | 7362 | begin |
|
- | 7363 | BB1 := TDIB.Create; |
|
- | 7364 | BB1.BitCount := 24; |
|
- | 7365 | BB1.Assign(Self); |
|
- | 7366 | BB2 := TDIB.Create; |
|
- | 7367 | BB2.BitCount := 24; |
|
- | 7368 | BB2.Assign(BB1); |
|
- | 7369 | Trace(BB2, Amount); |
|
- | 7370 | Self.Assign(BB2); |
|
- | 7371 | BB1.Free; |
|
- | 7372 | BB2.Free; |
|
- | 7373 | end; |
|
- | 7374 | ||
- | 7375 | procedure TDIB.DoSplitlight(Amount: Integer); |
|
- | 7376 | procedure Splitlight(var clip: TDIB; amount: Integer); |
|
- | 7377 | var |
|
- | 7378 | x, y, i: Integer; |
|
- | 7379 | p1: pbytearray; |
|
- | 7380 | ||
- | 7381 | function sinpixs(a: Integer): Integer; |
|
- | 7382 | begin |
|
- | 7383 | result := variant(sin(a / 255 * pi / 2) * 255); |
|
- | 7384 | end; |
|
- | 7385 | begin |
|
- | 7386 | for i := 1 to amount do |
|
- | 7387 | for y := 0 to clip.height - 1 do |
|
- | 7388 | begin |
|
- | 7389 | p1 := clip.scanline[y]; |
|
- | 7390 | for x := 0 to clip.width - 1 do |
|
- | 7391 | begin |
|
- | 7392 | p1[x * 3] := sinpixs(p1[x * 3]); |
|
- | 7393 | p1[x * 3 + 1] := sinpixs(p1[x * 3 + 1]); |
|
- | 7394 | p1[x * 3 + 2] := sinpixs(p1[x * 3 + 2]); |
|
- | 7395 | end; |
|
- | 7396 | end; |
|
- | 7397 | end; |
|
- | 7398 | var BB1 {,BB2}: TDIB; |
|
- | 7399 | begin |
|
- | 7400 | BB1 := TDIB.Create; |
|
- | 7401 | BB1.BitCount := 24; |
|
- | 7402 | BB1.Assign(Self); |
|
- | 7403 | // BB2 := TDIB.Create; |
|
- | 7404 | // BB2.BitCount := 24; |
|
- | 7405 | // BB2.Assign (BB1); |
|
- | 7406 | Splitlight(BB1, Amount); |
|
- | 7407 | Self.Assign(BB1); |
|
- | 7408 | BB1.Free; |
|
- | 7409 | // BB2.Free; |
|
- | 7410 | end; |
|
- | 7411 | ||
- | 7412 | procedure TDIB.DoTile(Amount: Integer); |
|
- | 7413 | procedure SmoothResize(var Src, Dst: TDIB); |
|
- | 7414 | var |
|
- | 7415 | x, y, xP, yP, |
|
- | 7416 | yP2, xP2: Integer; |
|
- | 7417 | Read, Read2: PByteArray; |
|
- | 7418 | t, z, z2, iz2: Integer; |
|
- | 7419 | pc: PBytearray; |
|
- | 7420 | w1, w2, w3, w4: Integer; |
|
- | 7421 | Col1r, col1g, col1b, Col2r, col2g, col2b: byte; |
|
- | 7422 | begin |
|
- | 7423 | xP2 := ((src.Width - 1) shl 15) div Dst.Width; |
|
- | 7424 | yP2 := ((src.Height - 1) shl 15) div Dst.Height; |
|
- | 7425 | yP := 0; |
|
- | 7426 | for y := 0 to Dst.Height - 1 do |
|
- | 7427 | begin |
|
- | 7428 | xP := 0; |
|
- | 7429 | Read := src.ScanLine[yP shr 15]; |
|
- | 7430 | if yP shr 16 < src.Height - 1 then |
|
- | 7431 | Read2 := src.ScanLine[yP shr 15 + 1] |
|
- | 7432 | else |
|
- | 7433 | Read2 := src.ScanLine[yP shr 15]; |
|
- | 7434 | pc := Dst.scanline[y]; |
|
- | 7435 | z2 := yP and $7FFF; |
|
- | 7436 | iz2 := $8000 - z2; |
|
- | 7437 | for x := 0 to Dst.Width - 1 do |
|
- | 7438 | begin |
|
- | 7439 | t := xP shr 15; |
|
- | 7440 | Col1r := Read[t * 3]; |
|
- | 7441 | Col1g := Read[t * 3 + 1]; |
|
- | 7442 | Col1b := Read[t * 3 + 2]; |
|
- | 7443 | Col2r := Read2[t * 3]; |
|
- | 7444 | Col2g := Read2[t * 3 + 1]; |
|
- | 7445 | Col2b := Read2[t * 3 + 2]; |
|
- | 7446 | z := xP and $7FFF; |
|
- | 7447 | w2 := (z * iz2) shr 15; |
|
- | 7448 | w1 := iz2 - w2; |
|
- | 7449 | w4 := (z * z2) shr 15; |
|
- | 7450 | w3 := z2 - w4; |
|
- | 7451 | pc[x * 3 + 2] := |
|
- | 7452 | (Col1b * w1 + Read[(t + 1) * 3 + 2] * w2 + |
|
- | 7453 | Col2b * w3 + Read2[(t + 1) * 3 + 2] * w4) shr 15; |
|
- | 7454 | pc[x * 3 + 1] := |
|
- | 7455 | (Col1g * w1 + Read[(t + 1) * 3 + 1] * w2 + |
|
- | 7456 | Col2g * w3 + Read2[(t + 1) * 3 + 1] * w4) shr 15; |
|
- | 7457 | pc[x * 3] := |
|
- | 7458 | (Col1r * w1 + Read2[(t + 1) * 3] * w2 + |
|
- | 7459 | Col2r * w3 + Read2[(t + 1) * 3] * w4) shr 15; |
|
- | 7460 | Inc(xP, xP2); |
|
- | 7461 | end; |
|
- | 7462 | Inc(yP, yP2); |
|
- | 7463 | end; |
|
- | 7464 | end; |
|
- | 7465 | procedure Tile(src, dst: TDIB; amount: Integer); |
|
- | 7466 | var |
|
- | 7467 | w, h, w2, h2, i, j: Integer; |
|
- | 7468 | bm: TDIB; |
|
- | 7469 | begin |
|
- | 7470 | w := src.width; |
|
- | 7471 | h := src.height; |
|
- | 7472 | dst.width := w; |
|
- | 7473 | dst.height := h; |
|
- | 7474 | dst.Canvas.draw(0, 0, src); |
|
- | 7475 | if (amount <= 0) or ((w div amount) < 5) or ((h div amount) < 5) then exit; |
|
- | 7476 | h2 := h div amount; |
|
- | 7477 | w2 := w div amount; |
|
- | 7478 | bm := TDIB.create; |
|
- | 7479 | bm.width := w2; |
|
- | 7480 | bm.height := h2; |
|
- | 7481 | bm.BitCount := 24; |
|
- | 7482 | smoothresize(src, bm); |
|
- | 7483 | for j := 0 to amount - 1 do |
|
- | 7484 | for i := 0 to amount - 1 do |
|
- | 7485 | dst.canvas.Draw(i * w2, j * h2, bm); |
|
- | 7486 | bm.free; |
|
- | 7487 | end; |
|
- | 7488 | var BB1, BB2: TDIB; |
|
- | 7489 | begin |
|
- | 7490 | BB1 := TDIB.Create; |
|
- | 7491 | BB1.BitCount := 24; |
|
- | 7492 | BB1.Assign(Self); |
|
- | 7493 | BB2 := TDIB.Create; |
|
- | 7494 | BB2.BitCount := 24; |
|
- | 7495 | BB2.Assign(BB1); |
|
- | 7496 | Tile(BB1, BB2, Amount); |
|
- | 7497 | Self.Assign(BB2); |
|
- | 7498 | BB1.Free; |
|
- | 7499 | BB2.Free; |
|
- | 7500 | end; |
|
- | 7501 | ||
- | 7502 | procedure TDIB.DoSpotLight(Amount: Integer; Spot: TRect); |
|
- | 7503 | procedure SpotLight(var src: TDIB; Amount: Integer; Spot: TRect); |
|
- | 7504 | var |
|
- | 7505 | bm, z: TDIB; |
|
- | 7506 | w, h: Integer; |
|
- | 7507 | begin |
|
- | 7508 | z := TDIB.Create; |
|
- | 7509 | try |
|
- | 7510 | z.SetSize(src.Width, src.Height, 24); |
|
- | 7511 | z.DrawTo(src, 0, 0, src.Width, src.Height, 0, 0); |
|
- | 7512 | w := z.Width; |
|
- | 7513 | h := z.Height; |
|
- | 7514 | bm := TDIB.create; |
|
- | 7515 | try |
|
- | 7516 | bm.Width := w; |
|
- | 7517 | bm.Height := h; |
|
- | 7518 | bm.Canvas.Brush.color := clblack; |
|
- | 7519 | bm.Canvas.FillRect(rect(0, 0, w, h)); |
|
- | 7520 | bm.Canvas.Brush.Color := clwhite; |
|
- | 7521 | bm.Canvas.Ellipse(Spot.left, spot.top, spot.right, spot.bottom); |
|
- | 7522 | bm.Transparent := true; |
|
- | 7523 | z.Canvas.CopyMode := cmSrcAnd; {as transparentcolor for white} |
|
- | 7524 | z.Canvas.Draw(0, 0, src); |
|
- | 7525 | z.Canvas.Draw(0, 0, bm); |
|
- | 7526 | src.Darkness(Amount); |
|
- | 7527 | src.Canvas.CopyMode := cmSrcPaint; |
|
- | 7528 | src.DrawTransparent(z, 0, 0, z.Width, z.Height, 0, 0, clBlack); |
|
- | 7529 | finally |
|
- | 7530 | bm.Free; |
|
- | 7531 | end; |
|
- | 7532 | finally |
|
- | 7533 | z.Free |
|
- | 7534 | end; |
|
- | 7535 | end; |
|
- | 7536 | var BB1, BB2: TDIB; |
|
- | 7537 | begin |
|
- | 7538 | BB1 := TDIB.Create; |
|
- | 7539 | BB1.BitCount := 24; |
|
- | 7540 | BB1.Assign(Self); |
|
- | 7541 | BB2 := TDIB.Create; |
|
- | 7542 | BB2.BitCount := 24; |
|
- | 7543 | BB2.Assign(BB1); |
|
- | 7544 | SpotLight(BB2, Amount, Spot); |
|
- | 7545 | Self.Assign(BB2); |
|
- | 7546 | BB1.Free; |
|
- | 7547 | BB2.Free; |
|
- | 7548 | end; |
|
- | 7549 | ||
- | 7550 | procedure TDIB.DoEmboss; |
|
- | 7551 | procedure Emboss(var Bmp: TDIB); |
|
- | 7552 | var |
|
- | 7553 | x, y: Integer; |
|
- | 7554 | p1, p2: Pbytearray; |
|
- | 7555 | begin |
|
- | 7556 | for y := 0 to Bmp.Height - 2 do |
|
- | 7557 | begin |
|
- | 7558 | p1 := bmp.scanline[y]; |
|
- | 7559 | p2 := bmp.scanline[y + 1]; |
|
- | 7560 | for x := 0 to Bmp.Width - 4 do |
|
- | 7561 | begin |
|
- | 7562 | p1[x * 3] := (p1[x * 3] + (p2[(x + 3) * 3] xor $FF)) shr 1; |
|
- | 7563 | p1[x * 3 + 1] := (p1[x * 3 + 1] + (p2[(x + 3) * 3 + 1] xor $FF)) shr 1; |
|
- | 7564 | p1[x * 3 + 2] := (p1[x * 3 + 2] + (p2[(x + 3) * 3 + 2] xor $FF)) shr 1; |
|
- | 7565 | end; |
|
- | 7566 | end; |
|
- | 7567 | end; |
|
- | 7568 | var BB1, BB2: TDIB; |
|
- | 7569 | begin |
|
- | 7570 | BB1 := TDIB.Create; |
|
- | 7571 | BB1.BitCount := 24; |
|
- | 7572 | BB1.Assign(Self); |
|
- | 7573 | BB2 := TDIB.Create; |
|
- | 7574 | BB2.BitCount := 24; |
|
- | 7575 | BB2.Assign(BB1); |
|
- | 7576 | Emboss(BB2); |
|
- | 7577 | Self.Assign(BB2); |
|
- | 7578 | BB1.Free; |
|
- | 7579 | BB2.Free; |
|
- | 7580 | end; |
|
- | 7581 | ||
- | 7582 | procedure TDIB.DoSolorize(Amount: Integer); |
|
- | 7583 | procedure Solorize(src, dst: TDIB; amount: Integer); |
|
- | 7584 | var |
|
- | 7585 | w, h, x, y: Integer; |
|
- | 7586 | ps, pd: pbytearray; |
|
- | 7587 | c: Integer; |
|
- | 7588 | begin |
|
- | 7589 | w := src.width; |
|
- | 7590 | h := src.height; |
|
- | 7591 | src.BitCount := 24; |
|
- | 7592 | dst.BitCount := 24; |
|
- | 7593 | for y := 0 to h - 1 do |
|
- | 7594 | begin |
|
- | 7595 | ps := src.scanline[y]; |
|
- | 7596 | pd := dst.scanline[y]; |
|
- | 7597 | for x := 0 to w - 1 do |
|
- | 7598 | begin |
|
- | 7599 | c := (ps[x * 3] + ps[x * 3 + 1] + ps[x * 3 + 2]) div 3; |
|
- | 7600 | if c > amount then |
|
- | 7601 | begin |
|
- | 7602 | pd[x * 3] := 255 - ps[x * 3]; |
|
- | 7603 | pd[x * 3 + 1] := 255 - ps[x * 3 + 1]; |
|
- | 7604 | pd[x * 3 + 2] := 255 - ps[x * 3 + 2]; |
|
- | 7605 | end |
|
- | 7606 | else |
|
- | 7607 | begin |
|
- | 7608 | pd[x * 3] := ps[x * 3]; |
|
- | 7609 | pd[x * 3 + 1] := ps[x * 3 + 1]; |
|
- | 7610 | pd[x * 3 + 2] := ps[x * 3 + 2]; |
|
- | 7611 | end; |
|
- | 7612 | end; |
|
- | 7613 | end; |
|
- | 7614 | end; |
|
- | 7615 | var BB1, BB2: TDIB; |
|
- | 7616 | begin |
|
- | 7617 | BB1 := TDIB.Create; |
|
- | 7618 | BB1.BitCount := 24; |
|
- | 7619 | BB1.Assign(Self); |
|
- | 7620 | BB2 := TDIB.Create; |
|
- | 7621 | BB2.BitCount := 24; |
|
- | 7622 | BB2.Assign(BB1); |
|
- | 7623 | Solorize(BB1, BB2, Amount); |
|
- | 7624 | Self.Assign(BB2); |
|
- | 7625 | BB1.Free; |
|
- | 7626 | BB2.Free; |
|
- | 7627 | end; |
|
- | 7628 | ||
- | 7629 | procedure TDIB.DoPosterize(Amount: Integer); |
|
- | 7630 | procedure Posterize(src, dst: TDIB; amount: Integer); |
|
- | 7631 | var |
|
- | 7632 | w, h, x, y: Integer; |
|
- | 7633 | ps, pd: pbytearray; |
|
- | 7634 | begin |
|
- | 7635 | w := src.width; |
|
- | 7636 | h := src.height; |
|
- | 7637 | src.BitCount := 24; |
|
- | 7638 | dst.BitCount := 24; |
|
- | 7639 | for y := 0 to h - 1 do |
|
- | 7640 | begin |
|
- | 7641 | ps := src.scanline[y]; |
|
- | 7642 | pd := dst.scanline[y]; |
|
- | 7643 | for x := 0 to w - 1 do |
|
- | 7644 | begin |
|
- | 7645 | pd[x * 3] := round(ps[x * 3] / amount) * amount; |
|
- | 7646 | pd[x * 3 + 1] := round(ps[x * 3 + 1] / amount) * amount; |
|
- | 7647 | pd[x * 3 + 2] := round(ps[x * 3 + 2] / amount) * amount; |
|
- | 7648 | end; |
|
- | 7649 | end; |
|
- | 7650 | end; |
|
- | 7651 | var BB1, BB2: TDIB; |
|
- | 7652 | begin |
|
- | 7653 | BB1 := TDIB.Create; |
|
- | 7654 | BB1.BitCount := 24; |
|
- | 7655 | BB1.Assign(Self); |
|
- | 7656 | BB2 := TDIB.Create; |
|
- | 7657 | BB2.BitCount := 24; |
|
- | 7658 | BB2.Assign(BB1); |
|
- | 7659 | Posterize(BB1, BB2, Amount); |
|
- | 7660 | Self.Assign(BB2); |
|
- | 7661 | BB1.Free; |
|
- | 7662 | BB2.Free; |
|
- | 7663 | end; |
|
- | 7664 | ||
- | 7665 | procedure TDIB.DoBrightness(Amount: Integer); |
|
- | 7666 | procedure Brightness(src, dst: TDIB; level: Integer); |
|
- | 7667 | const |
|
- | 7668 | MaxPixelCount = 32768; |
|
- | 7669 | type |
|
- | 7670 | pRGBArray = ^TRGBArray; |
|
- | 7671 | TRGBArray = array[0..MaxPixelCount - 1] of TRGBTriple; |
|
- | 7672 | var |
|
- | 7673 | i, j, value: Integer; |
|
- | 7674 | OrigRow, DestRow: pRGBArray; |
|
- | 7675 | begin |
|
- | 7676 | // get brightness increment value |
|
- | 7677 | value := level; |
|
- | 7678 | src.BitCount := 24; |
|
- | 7679 | dst.BitCount := 24; |
|
- | 7680 | // for each row of pixels |
|
- | 7681 | for i := 0 to src.Height - 1 do |
|
- | 7682 | begin |
|
- | 7683 | OrigRow := src.ScanLine[i]; |
|
- | 7684 | DestRow := dst.ScanLine[i]; |
|
- | 7685 | // for each pixel in row |
|
- | 7686 | for j := 0 to src.Width - 1 do |
|
- | 7687 | begin |
|
- | 7688 | // add brightness value to pixel's RGB values |
|
- | 7689 | if value > 0 then |
|
- | 7690 | begin |
|
- | 7691 | // RGB values must be less than 256 |
|
- | 7692 | DestRow[j].rgbtRed := Min(255, OrigRow[j].rgbtRed + value); |
|
- | 7693 | DestRow[j].rgbtGreen := Min(255, OrigRow[j].rgbtGreen + value); |
|
- | 7694 | DestRow[j].rgbtBlue := Min(255, OrigRow[j].rgbtBlue + value); |
|
- | 7695 | end |
|
- | 7696 | else |
|
- | 7697 | begin |
|
- | 7698 | // RGB values must be greater or equal than 0 |
|
- | 7699 | DestRow[j].rgbtRed := Max(0, OrigRow[j].rgbtRed + value); |
|
- | 7700 | DestRow[j].rgbtGreen := Max(0, OrigRow[j].rgbtGreen + value); |
|
- | 7701 | DestRow[j].rgbtBlue := Max(0, OrigRow[j].rgbtBlue + value); |
|
- | 7702 | end; |
|
- | 7703 | end; |
|
- | 7704 | end; |
|
- | 7705 | end; |
|
- | 7706 | var BB1, BB2: TDIB; |
|
- | 7707 | begin |
|
- | 7708 | BB1 := TDIB.Create; |
|
- | 7709 | BB1.BitCount := 24; |
|
- | 7710 | BB1.Assign(Self); |
|
- | 7711 | BB2 := TDIB.Create; |
|
- | 7712 | BB2.BitCount := 24; |
|
- | 7713 | BB2.Assign(BB1); |
|
- | 7714 | Brightness(BB1, BB2, Amount); |
|
- | 7715 | Self.Assign(BB2); |
|
- | 7716 | BB1.Free; |
|
- | 7717 | BB2.Free; |
|
- | 7718 | end; |
|
- | 7719 | ||
- | 7720 | procedure TDIB.DoResample(AmountX, AmountY: Integer; TypeResample: TFilterTypeResample); |
|
- | 7721 | procedure Resample(Src, Dst: TDIB; filtertype: TFilterTypeResample; fwidth: single); |
|
- | 7722 | // ----------------------------------------------------------------------------- |
|
- | 7723 | // |
|
- | 7724 | // Filter functions |
|
- | 7725 | // |
|
- | 7726 | // ----------------------------------------------------------------------------- |
|
- | 7727 | ||
- | 7728 | // Hermite filter |
|
- | 7729 | function HermiteFilter(Value: Single): Single; |
|
- | 7730 | begin |
|
- | 7731 | // f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 |
|
- | 7732 | if (Value < 0.0) then |
|
- | 7733 | Value := -Value; |
|
- | 7734 | if (Value < 1.0) then |
|
- | 7735 | Result := (2.0 * Value - 3.0) * Sqr(Value) + 1.0 |
|
- | 7736 | else |
|
- | 7737 | Result := 0.0; |
|
- | 7738 | end; |
|
- | 7739 | ||
- | 7740 | // Box filter |
|
- | 7741 | // a.k.a. "Nearest Neighbour" filter |
|
- | 7742 | // anme: I have not been able to get acceptable |
|
- | 7743 | // results with this filter for subsampling. |
|
- | 7744 | function BoxFilter(Value: Single): Single; |
|
- | 7745 | begin |
|
- | 7746 | if (Value > -0.5) and (Value <= 0.5) then |
|
- | 7747 | Result := 1.0 |
|
- | 7748 | else |
|
- | 7749 | Result := 0.0; |
|
- | 7750 | end; |
|
- | 7751 | ||
- | 7752 | // Triangle filter |
|
- | 7753 | // a.k.a. "Linear" or "Bilinear" filter |
|
- | 7754 | function TriangleFilter(Value: Single): Single; |
|
- | 7755 | begin |
|
- | 7756 | if (Value < 0.0) then |
|
- | 7757 | Value := -Value; |
|
- | 7758 | if (Value < 1.0) then |
|
- | 7759 | Result := 1.0 - Value |
|
- | 7760 | else |
|
- | 7761 | Result := 0.0; |
|
- | 7762 | end; |
|
- | 7763 | ||
- | 7764 | // Bell filter |
|
- | 7765 | function BellFilter(Value: Single): Single; |
|
- | 7766 | begin |
|
- | 7767 | if (Value < 0.0) then |
|
- | 7768 | Value := -Value; |
|
- | 7769 | if (Value < 0.5) then |
|
- | 7770 | Result := 0.75 - Sqr(Value) |
|
- | 7771 | else |
|
- | 7772 | if (Value < 1.5) then |
|
- | 7773 | begin |
|
- | 7774 | Value := Value - 1.5; |
|
- | 7775 | Result := 0.5 * Sqr(Value); |
|
- | 7776 | end |
|
- | 7777 | else |
|
- | 7778 | Result := 0.0; |
|
- | 7779 | end; |
|
- | 7780 | ||
- | 7781 | // B-spline filter |
|
- | 7782 | function SplineFilter(Value: Single): Single; |
|
- | 7783 | var |
|
- | 7784 | tt: single; |
|
- | 7785 | begin |
|
- | 7786 | if (Value < 0.0) then |
|
- | 7787 | Value := -Value; |
|
- | 7788 | if (Value < 1.0) then |
|
- | 7789 | begin |
|
- | 7790 | tt := Sqr(Value); |
|
- | 7791 | Result := 0.5 * tt * Value - tt + 2.0 / 3.0; |
|
- | 7792 | end |
|
- | 7793 | else |
|
- | 7794 | if (Value < 2.0) then |
|
- | 7795 | begin |
|
- | 7796 | Value := 2.0 - Value; |
|
- | 7797 | Result := 1.0 / 6.0 * Sqr(Value) * Value; |
|
- | 7798 | end |
|
- | 7799 | else |
|
- | 7800 | Result := 0.0; |
|
- | 7801 | end; |
|
- | 7802 | ||
- | 7803 | // Lanczos3 filter |
|
- | 7804 | function Lanczos3Filter(Value: Single): Single; |
|
- | 7805 | function SinC(Value: Single): Single; |
|
- | 7806 | begin |
|
- | 7807 | if (Value <> 0.0) then |
|
- | 7808 | begin |
|
- | 7809 | Value := Value * Pi; |
|
- | 7810 | Result := sin(Value) / Value |
|
- | 7811 | end |
|
- | 7812 | else |
|
- | 7813 | Result := 1.0; |
|
- | 7814 | end; |
|
- | 7815 | begin |
|
- | 7816 | if (Value < 0.0) then |
|
- | 7817 | Value := -Value; |
|
- | 7818 | if (Value < 3.0) then |
|
- | 7819 | Result := SinC(Value) * SinC(Value / 3.0) |
|
- | 7820 | else |
|
- | 7821 | Result := 0.0; |
|
- | 7822 | end; |
|
- | 7823 | ||
- | 7824 | function MitchellFilter(Value: Single): Single; |
|
- | 7825 | const |
|
- | 7826 | B = (1.0 / 3.0); |
|
- | 7827 | C = (1.0 / 3.0); |
|
- | 7828 | var |
|
- | 7829 | tt: single; |
|
- | 7830 | begin |
|
- | 7831 | if (Value < 0.0) then |
|
- | 7832 | Value := -Value; |
|
- | 7833 | tt := Sqr(Value); |
|
- | 7834 | if (Value < 1.0) then |
|
- | 7835 | begin |
|
- | 7836 | Value := (((12.0 - 9.0 * B - 6.0 * C) * (Value * tt)) |
|
- | 7837 | + ((-18.0 + 12.0 * B + 6.0 * C) * tt) |
|
- | 7838 | + (6.0 - 2 * B)); |
|
- | 7839 | Result := Value / 6.0; |
|
- | 7840 | end |
|
- | 7841 | else |
|
- | 7842 | if (Value < 2.0) then |
|
- | 7843 | begin |
|
- | 7844 | Value := (((-1.0 * B - 6.0 * C) * (Value * tt)) |
|
- | 7845 | + ((6.0 * B + 30.0 * C) * tt) |
|
- | 7846 | + ((-12.0 * B - 48.0 * C) * Value) |
|
- | 7847 | + (8.0 * B + 24 * C)); |
|
- | 7848 | Result := Value / 6.0; |
|
- | 7849 | end |
|
- | 7850 | else |
|
- | 7851 | Result := 0.0; |
|
- | 7852 | end; |
|
- | 7853 | ||
- | 7854 | // ----------------------------------------------------------------------------- |
|
- | 7855 | // |
|
- | 7856 | // Interpolator |
|
- | 7857 | // |
|
- | 7858 | // ----------------------------------------------------------------------------- |
|
- | 7859 | type |
|
- | 7860 | // Contributor for a pixel |
|
- | 7861 | TContributor = record |
|
- | 7862 | pixel: Integer; // Source pixel |
|
- | 7863 | weight: single; // Pixel weight |
|
- | 7864 | end; |
|
- | 7865 | ||
- | 7866 | TContributorList = array[0..0] of TContributor; |
|
- | 7867 | PContributorList = ^TContributorList; |
|
- | 7868 | ||
- | 7869 | // List of source pixels contributing to a destination pixel |
|
- | 7870 | TCList = record |
|
- | 7871 | n: Integer; |
|
- | 7872 | p: PContributorList; |
|
- | 7873 | end; |
|
- | 7874 | ||
- | 7875 | TCListList = array[0..0] of TCList; |
|
- | 7876 | PCListList = ^TCListList; |
|
- | 7877 | ||
- | 7878 | TRGB = packed record |
|
- | 7879 | r, g, b: single; |
|
- | 7880 | end; |
|
- | 7881 | ||
- | 7882 | // Physical bitmap pixel |
|
- | 7883 | TColorRGB = packed record |
|
- | 7884 | r, g, b: BYTE; |
|
- | 7885 | end; |
|
- | 7886 | PColorRGB = ^TColorRGB; |
|
- | 7887 | ||
- | 7888 | // Physical bitmap scanline (row) |
|
- | 7889 | TRGBList = packed array[0..0] of TColorRGB; |
|
- | 7890 | PRGBList = ^TRGBList; |
|
- | 7891 | ||
- | 7892 | var |
|
- | 7893 | xscale, yscale: single; // Zoom scale factors |
|
- | 7894 | i, j, k: Integer; // Loop variables |
|
- | 7895 | center: single; // Filter calculation variables |
|
- | 7896 | width, fscale, weight: single; // Filter calculation variables |
|
- | 7897 | left, right: Integer; // Filter calculation variables |
|
- | 7898 | n: Integer; // Pixel number |
|
- | 7899 | Work: TDIB; |
|
- | 7900 | contrib: PCListList; |
|
- | 7901 | rgb: TRGB; |
|
- | 7902 | color: TColorRGB; |
|
- | 7903 | {$IFDEF USE_SCANLINE} |
|
- | 7904 | SourceLine, |
|
- | 7905 | DestLine: PRGBList; |
|
- | 7906 | SourcePixel, |
|
- | 7907 | DestPixel: PColorRGB; |
|
- | 7908 | Delta, |
|
- | 7909 | DestDelta: Integer; |
|
- | 7910 | {$ENDIF} |
|
- | 7911 | SrcWidth, |
|
- | 7912 | SrcHeight, |
|
- | 7913 | DstWidth, |
|
- | 7914 | DstHeight: Integer; |
|
- | 7915 | ||
- | 7916 | function Color2RGB(Color: TColor): TColorRGB; |
|
- | 7917 | begin |
|
- | 7918 | Result.r := Color and $000000FF; |
|
- | 7919 | Result.g := (Color and $0000FF00) shr 8; |
|
- | 7920 | Result.b := (Color and $00FF0000) shr 16; |
|
- | 7921 | end; |
|
- | 7922 | ||
- | 7923 | function RGB2Color(Color: TColorRGB): TColor; |
|
- | 7924 | begin |
|
- | 7925 | Result := Color.r or (Color.g shl 8) or (Color.b shl 16); |
|
- | 7926 | end; |
|
- | 7927 | ||
- | 7928 | begin |
|
- | 7929 | DstWidth := Dst.Width; |
|
- | 7930 | DstHeight := Dst.Height; |
|
- | 7931 | SrcWidth := Src.Width; |
|
- | 7932 | SrcHeight := Src.Height; |
|
- | 7933 | if (SrcWidth < 1) or (SrcHeight < 1) then |
|
- | 7934 | raise Exception.Create('Source bitmap too small'); |
|
- | 7935 | ||
- | 7936 | // Create intermediate image to hold horizontal zoom |
|
- | 7937 | Work := TDIB.Create; |
|
- | 7938 | try |
|
- | 7939 | Work.Height := SrcHeight; |
|
- | 7940 | Work.Width := DstWidth; |
|
- | 7941 | // xscale := DstWidth / SrcWidth; |
|
- | 7942 | // yscale := DstHeight / SrcHeight; |
|
- | 7943 | // Improvement suggested by David Ullrich: |
|
- | 7944 | if (SrcWidth = 1) then |
|
- | 7945 | xscale := DstWidth / SrcWidth |
|
- | 7946 | else |
|
- | 7947 | xscale := (DstWidth - 1) / (SrcWidth - 1); |
|
- | 7948 | if (SrcHeight = 1) then |
|
- | 7949 | yscale := DstHeight / SrcHeight |
|
- | 7950 | else |
|
- | 7951 | yscale := (DstHeight - 1) / (SrcHeight - 1); |
|
- | 7952 | // This implementation only works on 24-bit images because it uses |
|
- | 7953 | // TDIB.Scanline |
|
- | 7954 | {$IFDEF USE_SCANLINE} |
|
- | 7955 | //Src.PixelFormat := pf24bit; |
|
- | 7956 | Src.BitCount := 24; |
|
- | 7957 | //Dst.PixelFormat := Src.PixelFormat; |
|
- | 7958 | dst.BitCount := 24; |
|
- | 7959 | //Work.PixelFormat := Src.PixelFormat; |
|
- | 7960 | work.BitCount := 24; |
|
- | 7961 | {$ENDIF} |
|
- | 7962 | ||
- | 7963 | // -------------------------------------------- |
|
- | 7964 | // Pre-calculate filter contributions for a row |
|
- | 7965 | // ----------------------------------------------- |
|
- | 7966 | GetMem(contrib, DstWidth * sizeof(TCList)); |
|
- | 7967 | // Horizontal sub-sampling |
|
- | 7968 | // Scales from bigger to smaller width |
|
- | 7969 | if (xscale < 1.0) then |
|
- | 7970 | begin |
|
- | 7971 | width := fwidth / xscale; |
|
- | 7972 | fscale := 1.0 / xscale; |
|
- | 7973 | for i := 0 to DstWidth - 1 do |
|
- | 7974 | begin |
|
- | 7975 | contrib^[i].n := 0; |
|
- | 7976 | GetMem(contrib^[i].p, trunc(width * 2.0 + 1) * sizeof(TContributor)); |
|
- | 7977 | center := i / xscale; |
|
- | 7978 | // Original code: |
|
- | 7979 | // left := ceil(center - width); |
|
- | 7980 | // right := floor(center + width); |
|
- | 7981 | left := floor(center - width); |
|
- | 7982 | right := ceil(center + width); |
|
- | 7983 | for j := left to right do |
|
- | 7984 | begin |
|
- | 7985 | case filtertype of |
|
- | 7986 | ftrBox: weight := boxfilter((center - j) / fscale) / fscale; |
|
- | 7987 | ftrTriangle: weight := trianglefilter((center - j) / fscale) / fscale; |
|
- | 7988 | ftrHermite: weight := hermitefilter((center - j) / fscale) / fscale; |
|
- | 7989 | ftrBell: weight := bellfilter((center - j) / fscale) / fscale; |
|
- | 7990 | ftrBSpline: weight := splinefilter((center - j) / fscale) / fscale; |
|
- | 7991 | ftrLanczos3: weight := Lanczos3filter((center - j) / fscale) / fscale; |
|
- | 7992 | ftrMitchell: weight := Mitchellfilter((center - j) / fscale) / fscale; |
|
- | 7993 | else |
|
- | 7994 | weight := 0 |
|
- | 7995 | end; |
|
- | 7996 | if (weight = 0.0) then |
|
- | 7997 | continue; |
|
- | 7998 | if (j < 0) then |
|
- | 7999 | n := -j |
|
- | 8000 | else if (j >= SrcWidth) then |
|
- | 8001 | n := SrcWidth - j + SrcWidth - 1 |
|
- | 8002 | else |
|
- | 8003 | n := j; |
|
- | 8004 | k := contrib^[i].n; |
|
- | 8005 | contrib^[i].n := contrib^[i].n + 1; |
|
- | 8006 | contrib^[i].p^[k].pixel := n; |
|
- | 8007 | contrib^[i].p^[k].weight := weight; |
|
- | 8008 | end; |
|
- | 8009 | end; |
|
- | 8010 | end |
|
- | 8011 | else |
|
- | 8012 | // Horizontal super-sampling |
|
- | 8013 | // Scales from smaller to bigger width |
|
- | 8014 | begin |
|
- | 8015 | for i := 0 to DstWidth - 1 do |
|
- | 8016 | begin |
|
- | 8017 | contrib^[i].n := 0; |
|
- | 8018 | GetMem(contrib^[i].p, trunc(fwidth * 2.0 + 1) * sizeof(TContributor)); |
|
- | 8019 | center := i / xscale; |
|
- | 8020 | // Original code: |
|
- | 8021 | // left := ceil(center - fwidth); |
|
- | 8022 | // right := floor(center + fwidth); |
|
- | 8023 | left := floor(center - fwidth); |
|
- | 8024 | right := ceil(center + fwidth); |
|
- | 8025 | for j := left to right do |
|
- | 8026 | begin |
|
- | 8027 | case filtertype of |
|
- | 8028 | ftrBox: weight := boxfilter(center - j); |
|
- | 8029 | ftrTriangle: weight := trianglefilter(center - j); |
|
- | 8030 | ftrHermite: weight := hermitefilter(center - j); |
|
- | 8031 | ftrBell: weight := bellfilter(center - j); |
|
- | 8032 | ftrBSpline: weight := splinefilter(center - j); |
|
- | 8033 | ftrLanczos3: weight := Lanczos3filter(center - j); |
|
- | 8034 | ftrMitchell: weight := Mitchellfilter(center - j); |
|
- | 8035 | else |
|
- | 8036 | weight := 0 |
|
- | 8037 | end; |
|
- | 8038 | if (weight = 0.0) then |
|
- | 8039 | continue; |
|
- | 8040 | if (j < 0) then |
|
- | 8041 | n := -j |
|
- | 8042 | else if (j >= SrcWidth) then |
|
- | 8043 | n := SrcWidth - j + SrcWidth - 1 |
|
- | 8044 | else |
|
- | 8045 | n := j; |
|
- | 8046 | k := contrib^[i].n; |
|
- | 8047 | contrib^[i].n := contrib^[i].n + 1; |
|
- | 8048 | contrib^[i].p^[k].pixel := n; |
|
- | 8049 | contrib^[i].p^[k].weight := weight; |
|
- | 8050 | end; |
|
- | 8051 | end; |
|
- | 8052 | end; |
|
- | 8053 | ||
- | 8054 | // ---------------------------------------------------- |
|
- | 8055 | // Apply filter to sample horizontally from Src to Work |
|
- | 8056 | // ---------------------------------------------------- |
|
- | 8057 | for k := 0 to SrcHeight - 1 do |
|
- | 8058 | begin |
|
- | 8059 | {$IFDEF USE_SCANLINE} |
|
- | 8060 | SourceLine := Src.ScanLine[k]; |
|
- | 8061 | DestPixel := Work.ScanLine[k]; |
|
- | 8062 | {$ENDIF} |
|
- | 8063 | for i := 0 to DstWidth - 1 do |
|
- | 8064 | begin |
|
- | 8065 | rgb.r := 0.0; |
|
- | 8066 | rgb.g := 0.0; |
|
- | 8067 | rgb.b := 0.0; |
|
- | 8068 | for j := 0 to contrib^[i].n - 1 do |
|
- | 8069 | begin |
|
- | 8070 | {$IFDEF USE_SCANLINE} |
|
- | 8071 | color := SourceLine^[contrib^[i].p^[j].pixel]; |
|
- | 8072 | {$ELSE} |
|
- | 8073 | color := Color2RGB(Src.Canvas.Pixels[contrib^[i].p^[j].pixel, k]); |
|
- | 8074 | {$ENDIF} |
|
- | 8075 | weight := contrib^[i].p^[j].weight; |
|
- | 8076 | if (weight = 0.0) then |
|
- | 8077 | continue; |
|
- | 8078 | rgb.r := rgb.r + color.r * weight; |
|
- | 8079 | rgb.g := rgb.g + color.g * weight; |
|
- | 8080 | rgb.b := rgb.b + color.b * weight; |
|
- | 8081 | end; |
|
- | 8082 | if (rgb.r > 255.0) then |
|
- | 8083 | color.r := 255 |
|
- | 8084 | else if (rgb.r < 0.0) then |
|
- | 8085 | color.r := 0 |
|
- | 8086 | else |
|
- | 8087 | color.r := round(rgb.r); |
|
- | 8088 | if (rgb.g > 255.0) then |
|
- | 8089 | color.g := 255 |
|
- | 8090 | else if (rgb.g < 0.0) then |
|
- | 8091 | color.g := 0 |
|
- | 8092 | else |
|
- | 8093 | color.g := round(rgb.g); |
|
- | 8094 | if (rgb.b > 255.0) then |
|
- | 8095 | color.b := 255 |
|
- | 8096 | else if (rgb.b < 0.0) then |
|
- | 8097 | color.b := 0 |
|
- | 8098 | else |
|
- | 8099 | color.b := round(rgb.b); |
|
- | 8100 | {$IFDEF USE_SCANLINE} |
|
- | 8101 | // Set new pixel value |
|
- | 8102 | DestPixel^ := color; |
|
- | 8103 | // Move on to next column |
|
- | 8104 | inc(DestPixel); |
|
- | 8105 | {$ELSE} |
|
- | 8106 | Work.Canvas.Pixels[i, k] := RGB2Color(color); |
|
- | 8107 | {$ENDIF} |
|
- | 8108 | end; |
|
- | 8109 | end; |
|
- | 8110 | ||
- | 8111 | // Free the memory allocated for horizontal filter weights |
|
- | 8112 | for i := 0 to DstWidth - 1 do |
|
- | 8113 | FreeMem(contrib^[i].p); |
|
- | 8114 | ||
- | 8115 | FreeMem(contrib); |
|
- | 8116 | ||
- | 8117 | // ----------------------------------------------- |
|
- | 8118 | // Pre-calculate filter contributions for a column |
|
- | 8119 | // ----------------------------------------------- |
|
- | 8120 | GetMem(contrib, DstHeight * sizeof(TCList)); |
|
- | 8121 | // Vertical sub-sampling |
|
- | 8122 | // Scales from bigger to smaller height |
|
- | 8123 | if (yscale < 1.0) then |
|
- | 8124 | begin |
|
- | 8125 | width := fwidth / yscale; |
|
- | 8126 | fscale := 1.0 / yscale; |
|
- | 8127 | for i := 0 to DstHeight - 1 do |
|
- | 8128 | begin |
|
- | 8129 | contrib^[i].n := 0; |
|
- | 8130 | GetMem(contrib^[i].p, trunc(width * 2.0 + 1) * sizeof(TContributor)); |
|
- | 8131 | center := i / yscale; |
|
- | 8132 | // Original code: |
|
- | 8133 | // left := ceil(center - width); |
|
- | 8134 | // right := floor(center + width); |
|
- | 8135 | left := floor(center - width); |
|
- | 8136 | right := ceil(center + width); |
|
- | 8137 | for j := left to right do |
|
- | 8138 | begin |
|
- | 8139 | case filtertype of |
|
- | 8140 | ftrBox: weight := boxfilter((center - j) / fscale) / fscale; |
|
- | 8141 | ftrTriangle: weight := trianglefilter((center - j) / fscale) / fscale; |
|
- | 8142 | ftrHermite: weight := hermitefilter((center - j) / fscale) / fscale; |
|
- | 8143 | ftrBell: weight := bellfilter((center - j) / fscale) / fscale; |
|
- | 8144 | ftrBSpline: weight := splinefilter((center - j) / fscale) / fscale; |
|
- | 8145 | ftrLanczos3: weight := Lanczos3filter((center - j) / fscale) / fscale; |
|
- | 8146 | ftrMitchell: weight := Mitchellfilter((center - j) / fscale) / fscale; |
|
- | 8147 | else |
|
- | 8148 | weight := 0 |
|
- | 8149 | end; |
|
- | 8150 | if (weight = 0.0) then |
|
- | 8151 | continue; |
|
- | 8152 | if (j < 0) then |
|
- | 8153 | n := -j |
|
- | 8154 | else if (j >= SrcHeight) then |
|
- | 8155 | n := SrcHeight - j + SrcHeight - 1 |
|
- | 8156 | else |
|
- | 8157 | n := j; |
|
- | 8158 | k := contrib^[i].n; |
|
- | 8159 | contrib^[i].n := contrib^[i].n + 1; |
|
- | 8160 | contrib^[i].p^[k].pixel := n; |
|
- | 8161 | contrib^[i].p^[k].weight := weight; |
|
- | 8162 | end; |
|
- | 8163 | end |
|
- | 8164 | end |
|
- | 8165 | else |
|
- | 8166 | // Vertical super-sampling |
|
- | 8167 | // Scales from smaller to bigger height |
|
- | 8168 | begin |
|
- | 8169 | for i := 0 to DstHeight - 1 do |
|
- | 8170 | begin |
|
- | 8171 | contrib^[i].n := 0; |
|
- | 8172 | GetMem(contrib^[i].p, trunc(fwidth * 2.0 + 1) * sizeof(TContributor)); |
|
- | 8173 | center := i / yscale; |
|
- | 8174 | // Original code: |
|
- | 8175 | // left := ceil(center - fwidth); |
|
- | 8176 | // right := floor(center + fwidth); |
|
- | 8177 | left := floor(center - fwidth); |
|
- | 8178 | right := ceil(center + fwidth); |
|
- | 8179 | for j := left to right do |
|
- | 8180 | begin |
|
- | 8181 | case filtertype of |
|
- | 8182 | ftrBox: weight := boxfilter(center - j); |
|
- | 8183 | ftrTriangle: weight := trianglefilter(center - j); |
|
- | 8184 | ftrHermite: weight := hermitefilter(center - j); |
|
- | 8185 | ftrBell: weight := bellfilter(center - j); |
|
- | 8186 | ftrBSpline: weight := splinefilter(center - j); |
|
- | 8187 | ftrLanczos3: weight := Lanczos3filter(center - j); |
|
- | 8188 | ftrMitchell: weight := Mitchellfilter(center - j); |
|
- | 8189 | else |
|
- | 8190 | weight := 0 |
|
- | 8191 | end; |
|
- | 8192 | if (weight = 0.0) then |
|
- | 8193 | continue; |
|
- | 8194 | if (j < 0) then |
|
- | 8195 | n := -j |
|
- | 8196 | else if (j >= SrcHeight) then |
|
- | 8197 | n := SrcHeight - j + SrcHeight - 1 |
|
- | 8198 | else |
|
- | 8199 | n := j; |
|
- | 8200 | k := contrib^[i].n; |
|
- | 8201 | contrib^[i].n := contrib^[i].n + 1; |
|
- | 8202 | contrib^[i].p^[k].pixel := n; |
|
- | 8203 | contrib^[i].p^[k].weight := weight; |
|
- | 8204 | end; |
|
- | 8205 | end; |
|
- | 8206 | end; |
|
- | 8207 | ||
- | 8208 | // -------------------------------------------------- |
|
- | 8209 | // Apply filter to sample vertically from Work to Dst |
|
- | 8210 | // -------------------------------------------------- |
|
- | 8211 | {$IFDEF USE_SCANLINE} |
|
- | 8212 | SourceLine := Work.ScanLine[0]; |
|
- | 8213 | Delta := Integer(Work.ScanLine[1]) - Integer(SourceLine); |
|
- | 8214 | DestLine := Dst.ScanLine[0]; |
|
- | 8215 | DestDelta := Integer(Dst.ScanLine[1]) - Integer(DestLine); |
|
- | 8216 | {$ENDIF} |
|
- | 8217 | for k := 0 to DstWidth - 1 do |
|
- | 8218 | begin |
|
- | 8219 | {$IFDEF USE_SCANLINE} |
|
- | 8220 | DestPixel := pointer(DestLine); |
|
- | 8221 | {$ENDIF} |
|
- | 8222 | for i := 0 to DstHeight - 1 do |
|
- | 8223 | begin |
|
- | 8224 | rgb.r := 0; |
|
- | 8225 | rgb.g := 0; |
|
- | 8226 | rgb.b := 0; |
|
- | 8227 | // weight := 0.0; |
|
- | 8228 | for j := 0 to contrib^[i].n - 1 do |
|
- | 8229 | begin |
|
- | 8230 | {$IFDEF USE_SCANLINE} |
|
- | 8231 | color := PColorRGB(Integer(SourceLine) + contrib^[i].p^[j].pixel * Delta)^; |
|
- | 8232 | {$ELSE} |
|
- | 8233 | color := Color2RGB(Work.Canvas.Pixels[k, contrib^[i].p^[j].pixel]); |
|
- | 8234 | {$ENDIF} |
|
- | 8235 | weight := contrib^[i].p^[j].weight; |
|
- | 8236 | if (weight = 0.0) then |
|
- | 8237 | continue; |
|
- | 8238 | rgb.r := rgb.r + color.r * weight; |
|
- | 8239 | rgb.g := rgb.g + color.g * weight; |
|
- | 8240 | rgb.b := rgb.b + color.b * weight; |
|
- | 8241 | end; |
|
- | 8242 | if (rgb.r > 255.0) then |
|
- | 8243 | color.r := 255 |
|
- | 8244 | else if (rgb.r < 0.0) then |
|
- | 8245 | color.r := 0 |
|
- | 8246 | else |
|
- | 8247 | color.r := round(rgb.r); |
|
- | 8248 | if (rgb.g > 255.0) then |
|
- | 8249 | color.g := 255 |
|
- | 8250 | else if (rgb.g < 0.0) then |
|
- | 8251 | color.g := 0 |
|
- | 8252 | else |
|
- | 8253 | color.g := round(rgb.g); |
|
- | 8254 | if (rgb.b > 255.0) then |
|
- | 8255 | color.b := 255 |
|
- | 8256 | else if (rgb.b < 0.0) then |
|
- | 8257 | color.b := 0 |
|
- | 8258 | else |
|
- | 8259 | color.b := round(rgb.b); |
|
- | 8260 | {$IFDEF USE_SCANLINE} |
|
- | 8261 | DestPixel^ := color; |
|
- | 8262 | inc(Integer(DestPixel), DestDelta); |
|
- | 8263 | {$ELSE} |
|
- | 8264 | Dst.Canvas.Pixels[k, i] := RGB2Color(color); |
|
- | 8265 | {$ENDIF} |
|
- | 8266 | end; |
|
- | 8267 | {$IFDEF USE_SCANLINE} |
|
- | 8268 | Inc(SourceLine, 1); |
|
- | 8269 | Inc(DestLine, 1); |
|
- | 8270 | {$ENDIF} |
|
- | 8271 | end; |
|
- | 8272 | ||
- | 8273 | // Free the memory allocated for vertical filter weights |
|
- | 8274 | for i := 0 to DstHeight - 1 do |
|
- | 8275 | FreeMem(contrib^[i].p); |
|
- | 8276 | ||
- | 8277 | FreeMem(contrib); |
|
- | 8278 | ||
- | 8279 | finally |
|
- | 8280 | Work.Free; |
|
- | 8281 | end; |
|
- | 8282 | end; |
|
- | 8283 | var BB1, BB2: TDIB; |
|
- | 8284 | begin |
|
- | 8285 | BB1 := TDIB.Create; |
|
- | 8286 | BB1.BitCount := 24; |
|
- | 8287 | BB1.Assign(Self); |
|
- | 8288 | BB2 := TDIB.Create; |
|
- | 8289 | BB2.SetSize(AmountX, AmountY, 24); |
|
- | 8290 | Resample(BB1, BB2, TypeResample, DefaultFilterRadius[TypeResample]); |
|
- | 8291 | Self.Assign(BB2); |
|
- | 8292 | BB1.Free; |
|
- | 8293 | BB2.Free; |
|
- | 8294 | end; |
|
- | 8295 | ||
- | 8296 | procedure TDIB.DoColorize(ForeColor, BackColor: TColor); |
|
- | 8297 | procedure Colorize(src, dst: TDIB; iForeColor, iBackColor: TColor; iDither: Boolean{$IFDEF VER4UP} = False{$ENDIF}); |
|
- | 8298 | {for monochromatic picture change colors} |
|
- | 8299 | procedure InvertBitmap(Bmp: TDIB); |
|
- | 8300 | begin |
|
- | 8301 | Bmp.Canvas.CopyMode := cmDstInvert; |
|
- | 8302 | Bmp.Canvas.CopyRect(rect(0, 0, Bmp.Width, Bmp.Height), |
|
- | 8303 | Bmp.Canvas, rect(0, 0, Bmp.Width, Bmp.Height)); |
|
- | 8304 | end; |
|
- | 8305 | var |
|
- | 8306 | fForeColor: TColor; |
|
- | 8307 | fForeDither: Boolean; |
|
- | 8308 | lTempBitmap: TDIB; |
|
- | 8309 | lTempBitmap2: TDIB; |
|
- | 8310 | lDitherBitmap: TDIB; |
|
- | 8311 | lCRect: TRect; |
|
- | 8312 | x, y, w, h: Integer; |
|
- | 8313 | begin |
|
- | 8314 | {--} |
|
- | 8315 | //fColor := iBackColor; ; |
|
- | 8316 | fForeColor := iForeColor; |
|
- | 8317 | fForeDither := iDither; |
|
- | 8318 | w := src.Width; |
|
- | 8319 | h := src.Height; |
|
- | 8320 | lDitherBitmap := nil; |
|
- | 8321 | lTempBitmap := TDIB.Create; |
|
- | 8322 | lTempBitmap.SetSize(w, h, 24); |
|
- | 8323 | lTempBitmap2 := TDIB.Create; |
|
- | 8324 | lTempBitmap2.SetSize(w, h, 24); |
|
- | 8325 | lCRect := rect(0, 0, w, h); |
|
- | 8326 | with lTempBitmap.Canvas do |
|
- | 8327 | begin |
|
- | 8328 | Brush.Style := bsSolid; |
|
- | 8329 | Brush.Color := iBackColor; |
|
- | 8330 | FillRect(lCRect); |
|
- | 8331 | CopyMode := cmSrcInvert; |
|
- | 8332 | CopyRect(lCRect, src.Canvas, lCRect); |
|
- | 8333 | InvertBitmap(src); |
|
- | 8334 | CopyMode := cmSrcPaint; |
|
- | 8335 | CopyRect(lCRect, src.Canvas, lCRect); |
|
- | 8336 | InvertBitmap(lTempBitmap); |
|
- | 8337 | CopyMode := cmSrcInvert; |
|
- | 8338 | CopyRect(lCRect, src.Canvas, lCRect); |
|
- | 8339 | InvertBitmap(src); |
|
- | 8340 | end; |
|
- | 8341 | with lTempBitmap2.Canvas do |
|
- | 8342 | begin |
|
- | 8343 | Brush.Style := bsSolid; |
|
- | 8344 | Brush.Color := clBlack; |
|
- | 8345 | FillRect(lCRect); |
|
- | 8346 | if fForeDither then |
|
- | 8347 | begin |
|
- | 8348 | InvertBitmap(src); |
|
- | 8349 | lDitherBitmap := TDIB.Create; |
|
- | 8350 | lDitherBitmap.SetSize(8, 8, 24); |
|
- | 8351 | with lDitherBitmap.Canvas do |
|
- | 8352 | begin |
|
- | 8353 | for x := 0 to 7 do |
|
- | 8354 | for y := 0 to 7 do |
|
- | 8355 | if ((x mod 2 = 0) and (y mod 2 > 0)) or ((x mod 2 > 0) and (y mod 2 = 0)) then |
|
- | 8356 | pixels[x, y] := fForeColor |
|
- | 8357 | else |
|
- | 8358 | pixels[x, y] := iBackColor; |
|
- | 8359 | end; |
|
- | 8360 | Brush.Bitmap.Assign(lDitherBitmap); |
|
- | 8361 | end |
|
- | 8362 | else |
|
- | 8363 | begin |
|
- | 8364 | Brush.Style := bsSolid; |
|
- | 8365 | Brush.Color := fForeColor; |
|
- | 8366 | end; |
|
- | 8367 | if not fForeDither then |
|
- | 8368 | InvertBitmap(src); |
|
- | 8369 | CopyMode := cmPatPaint; |
|
- | 8370 | CopyRect(lCRect, src.Canvas, lCRect); |
|
- | 8371 | if fForeDither then |
|
- | 8372 | if Assigned(lDitherBitmap) then |
|
- | 8373 | lDitherBitmap.Free; |
|
- | 8374 | CopyMode := cmSrcInvert; |
|
- | 8375 | CopyRect(lCRect, src.Canvas, lCRect); |
|
- | 8376 | end; |
|
- | 8377 | lTempBitmap.Canvas.CopyMode := cmSrcInvert; |
|
- | 8378 | lTempBitmap.Canvas.Copyrect(lCRect, lTempBitmap2.Canvas, lCRect); |
|
- | 8379 | InvertBitmap(src); |
|
- | 8380 | lTempBitmap.Canvas.CopyMode := cmSrcErase; |
|
- | 8381 | lTempBitmap.Canvas.Copyrect(lCRect, src.Canvas, lCRect); |
|
- | 8382 | InvertBitmap(src); |
|
- | 8383 | lTempBitmap.Canvas.CopyMode := cmSrcInvert; |
|
- | 8384 | lTempBitmap.Canvas.Copyrect(lCRect, lTempBitmap2.Canvas, lCRect); |
|
- | 8385 | InvertBitmap(lTempBitmap); |
|
- | 8386 | InvertBitmap(src); |
|
- | 8387 | dst.Assign(lTempBitmap); |
|
- | 8388 | lTempBitmap.Free; |
|
- | 8389 | end; |
|
- | 8390 | var BB1, BB2: TDIB; |
|
- | 8391 | begin |
|
- | 8392 | BB1 := TDIB.Create; |
|
- | 8393 | BB1.BitCount := 24; |
|
- | 8394 | BB1.Assign(Self); |
|
- | 8395 | BB2 := TDIB.Create; |
|
- | 8396 | Colorize(BB1, BB2, ForeColor, BackColor{$IFNDEF VER4UP}, False{$ENDIF}); |
|
- | 8397 | Self.Assign(BB2); |
|
- | 8398 | BB1.Free; |
|
- | 8399 | BB2.Free; |
|
- | 8400 | end; |
|
- | 8401 | ||
- | 8402 | { procedure for special purpose } |
|
- | 8403 | ||
- | 8404 | procedure TDIB.FadeOut(DIB2: TDIB; Step: Byte); |
|
- | 8405 | var |
|
- | 8406 | P1, P2: PByteArray; |
|
- | 8407 | W, H: Integer; |
|
- | 8408 | begin |
|
- | 8409 | P1 := ScanLine[DIB2.Height - 1]; |
|
- | 8410 | P2 := DIB2.ScanLine[DIB2.Height - 1]; |
|
- | 8411 | W := WidthBytes; |
|
- | 8412 | H := Height; |
|
- | 8413 | asm |
|
- | 8414 | PUSH ESI |
|
- | 8415 | PUSH EDI |
|
- | 8416 | MOV ESI, P1 |
|
- | 8417 | MOV EDI, P2 |
|
- | 8418 | MOV EDX, W |
|
- | 8419 | MOV EAX, H |
|
- | 8420 | IMUL EDX |
|
- | 8421 | MOV ECX, EAX |
|
- | 8422 | @@1: |
|
- | 8423 | MOV AL, Step |
|
- | 8424 | MOV AH, [ESI] |
|
- | 8425 | CMP AL, AH |
|
- | 8426 | JA @@2 |
|
- | 8427 | MOV AL, AH |
|
- | 8428 | @@2: |
|
- | 8429 | MOV [EDI], AL |
|
- | 8430 | INC ESI |
|
- | 8431 | INC EDI |
|
- | 8432 | DEC ECX |
|
- | 8433 | JNZ @@1 |
|
- | 8434 | POP EDI |
|
- | 8435 | POP ESI |
|
- | 8436 | end; |
|
- | 8437 | end; |
|
- | 8438 | ||
- | 8439 | procedure TDIB.DoZoom(DIB2: TDIB; ZoomRatio: Real); |
|
- | 8440 | var |
|
- | 8441 | P1, P2: PByteArray; |
|
- | 8442 | W, H: Integer; |
|
- | 8443 | x, y: Integer; |
|
- | 8444 | xr, yr, xstep, ystep: real; |
|
- | 8445 | xstart: real; |
|
- | 8446 | begin |
|
- | 8447 | W := WidthBytes; |
|
- | 8448 | H := Height; |
|
- | 8449 | xstart := (W - (W * ZoomRatio)) / 2; |
|
- | 8450 | ||
- | 8451 | xr := xstart; |
|
- | 8452 | yr := (H - (H * ZoomRatio)) / 2; |
|
- | 8453 | xstep := ZoomRatio; |
|
- | 8454 | ystep := ZoomRatio; |
|
- | 8455 | ||
- | 8456 | for y := 1 to Height - 1 do |
|
- | 8457 | begin |
|
- | 8458 | P2 := DIB2.ScanLine[y]; |
|
- | 8459 | if (yr >= 0) and (yr <= H) then |
|
- | 8460 | begin |
|
- | 8461 | P1 := ScanLine[Trunc(yr)]; |
|
- | 8462 | for x := 1 to Width - 1 do |
|
- | 8463 | begin |
|
- | 8464 | if (xr >= 0) and (xr <= W) then |
|
- | 8465 | begin |
|
- | 8466 | P2[x] := P1[Trunc(xr)]; |
|
- | 8467 | end |
|
- | 8468 | else |
|
- | 8469 | begin |
|
- | 8470 | P2[x] := 0; |
|
- | 8471 | end; |
|
- | 8472 | xr := xr + xstep; |
|
- | 8473 | end; |
|
- | 8474 | end |
|
- | 8475 | else |
|
- | 8476 | begin |
|
- | 8477 | for x := 1 to Width - 1 do |
|
- | 8478 | begin |
|
- | 8479 | P2[x] := 0; |
|
- | 8480 | end; |
|
- | 8481 | end; |
|
- | 8482 | xr := xstart; |
|
- | 8483 | yr := yr + ystep; |
|
- | 8484 | end; |
|
- | 8485 | end; |
|
- | 8486 | ||
- | 8487 | procedure TDIB.DoBlur(DIB2: TDIB); |
|
- | 8488 | var |
|
- | 8489 | P1, P2: PByteArray; |
|
- | 8490 | W: Integer; |
|
- | 8491 | x, y: Integer; |
|
- | 8492 | begin |
|
- | 8493 | W := WidthBytes; |
|
- | 8494 | for y := 1 to Height - 1 do |
|
- | 8495 | begin |
|
- | 8496 | P1 := ScanLine[y]; |
|
- | 8497 | P2 := DIB2.ScanLine[y]; |
|
- | 8498 | for x := 1 to Width - 1 do |
|
- | 8499 | begin |
|
- | 8500 | P2[x] := (P1[x] + P1[x - 1] + P1[x + 1] + P1[x + W] + P1[x - W]) div 5; |
|
- | 8501 | end; |
|
- | 8502 | end; |
|
- | 8503 | end; |
|
- | 8504 | ||
- | 8505 | procedure TDIB.FadeIn(DIB2: TDIB; Step: Byte); |
|
- | 8506 | var |
|
- | 8507 | P1, P2: PByteArray; |
|
- | 8508 | W, H: Integer; |
|
- | 8509 | begin |
|
- | 8510 | P1 := ScanLine[DIB2.Height - 1]; |
|
- | 8511 | P2 := DIB2.ScanLine[DIB2.Height - 1]; |
|
- | 8512 | W := WidthBytes; |
|
- | 8513 | H := Height; |
|
- | 8514 | asm |
|
- | 8515 | PUSH ESI |
|
- | 8516 | PUSH EDI |
|
- | 8517 | MOV ESI, P1 |
|
- | 8518 | MOV EDI, P2 |
|
- | 8519 | MOV EDX, W |
|
- | 8520 | MOV EAX, H |
|
- | 8521 | IMUL EDX |
|
- | 8522 | MOV ECX, EAX |
|
- | 8523 | @@1: |
|
- | 8524 | MOV AL, Step |
|
- | 8525 | MOV AH, [ESI] |
|
- | 8526 | CMP AL, AH |
|
- | 8527 | JB @@2 |
|
- | 8528 | MOV AL, AH |
|
- | 8529 | @@2: |
|
- | 8530 | MOV [EDI], AL |
|
- | 8531 | INC ESI |
|
- | 8532 | INC EDI |
|
- | 8533 | DEC ECX |
|
- | 8534 | JNZ @@1 |
|
- | 8535 | POP EDI |
|
- | 8536 | POP ESI |
|
- | 8537 | end; |
|
- | 8538 | end; |
|
- | 8539 | ||
- | 8540 | procedure TDIB.FillDIB8(Color: Byte); |
|
- | 8541 | var |
|
- | 8542 | P: PByteArray; |
|
- | 8543 | W, H: Integer; |
|
- | 8544 | begin |
|
- | 8545 | P := ScanLine[Height - 1]; |
|
- | 8546 | W := WidthBytes; |
|
- | 8547 | H := Height; |
|
- | 8548 | asm |
|
- | 8549 | PUSH ESI |
|
- | 8550 | MOV ESI, P |
|
- | 8551 | MOV EDX, W |
|
- | 8552 | MOV EAX, H |
|
- | 8553 | IMUL EDX |
|
- | 8554 | MOV ECX, EAX |
|
- | 8555 | MOV AL, Color |
|
- | 8556 | @@1: |
|
- | 8557 | MOV [ESI], AL |
|
- | 8558 | INC ESI |
|
- | 8559 | DEC ECX |
|
- | 8560 | JNZ @@1 |
|
- | 8561 | POP ESI |
|
- | 8562 | end; |
|
- | 8563 | end; |
|
- | 8564 | ||
- | 8565 | procedure TDIB.DoRotate(DIB1: TDIB; cX, cY, Angle: Integer); |
|
- | 8566 | type |
|
- | 8567 | T3Byte = array[0..2] of Byte; |
|
- | 8568 | P3ByteArray = ^T3ByteArray; |
|
- | 8569 | T3ByteArray = array[0..32767] of T3Byte; |
|
- | 8570 | PLongArray = ^TLongArray; |
|
- | 8571 | TLongArray = array[0..32767] of LongInt; |
|
- | 8572 | var |
|
- | 8573 | p, p2: PByteArray; |
|
- | 8574 | x, y, x2, y2, angled: Integer; |
|
- | 8575 | cosy, siny: real; |
|
- | 8576 | begin |
|
- | 8577 | angled := 384 + Angle; |
|
- | 8578 | for y := 0 to Height - 1 do |
|
- | 8579 | begin |
|
- | 8580 | p := DIB1.ScanLine[y]; |
|
- | 8581 | cosy := (y - cY) * dcos(angled and $1FF); |
|
- | 8582 | siny := (y - cY) * dsin(angled and $1FF); |
|
- | 8583 | for x := 0 to Width - 1 do |
|
- | 8584 | begin |
|
- | 8585 | x2 := Trunc((x - cX) * dsin(angled and $1FF) + cosy) + cX; |
|
- | 8586 | y2 := Trunc((x - cX) * dcos(angled and $1FF) - siny) + cY; |
|
- | 8587 | case bitcount of |
|
- | 8588 | 8: |
|
- | 8589 | begin |
|
- | 8590 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 8591 | begin |
|
- | 8592 | p2 := ScanLine[y2]; |
|
- | 8593 | p[x] := p2[Width - x2]; |
|
- | 8594 | end |
|
- | 8595 | else |
|
- | 8596 | begin |
|
- | 8597 | if p[x] > 4 then |
|
- | 8598 | p[x] := p[x] - 4 |
|
- | 8599 | else |
|
- | 8600 | p[x] := 0; |
|
- | 8601 | end; |
|
- | 8602 | end; |
|
- | 8603 | 16: |
|
- | 8604 | begin |
|
- | 8605 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 8606 | begin |
|
- | 8607 | PWordArray(p2) := ScanLine[y2]; |
|
- | 8608 | PWordArray(p)[x] := PWordArray(p2)[Width - x2]; |
|
- | 8609 | end |
|
- | 8610 | else |
|
- | 8611 | begin |
|
- | 8612 | if PWordArray(p)[x] > 4 then |
|
- | 8613 | PWordArray(p)[x] := PWordArray(p)[x] - 4 |
|
- | 8614 | else |
|
- | 8615 | PWordArray(p)[x] := 0; |
|
- | 8616 | end; |
|
- | 8617 | end; |
|
- | 8618 | 24: |
|
- | 8619 | begin |
|
- | 8620 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 8621 | begin |
|
- | 8622 | P3ByteArray(p2) := ScanLine[y2]; |
|
- | 8623 | P3ByteArray(p)[x] := P3ByteArray(p2)[Width - x2]; |
|
- | 8624 | end |
|
- | 8625 | else |
|
- | 8626 | begin |
|
- | 8627 | if P3ByteArray(p)[x][0] > 4 then |
|
- | 8628 | P3ByteArray(p)[x][0] := P3ByteArray(p)[x][0] - 4 |
|
- | 8629 | else if P3ByteArray(p)[x][1] > 4 then |
|
- | 8630 | P3ByteArray(p)[x][1] := P3ByteArray(p)[x][1] - 4 |
|
- | 8631 | else if P3ByteArray(p)[x][2] > 4 then |
|
- | 8632 | P3ByteArray(p)[x][2] := P3ByteArray(p)[x][2] - 4 |
|
- | 8633 | else |
|
- | 8634 | begin |
|
- | 8635 | P3ByteArray(p)[x][0] := 0; |
|
- | 8636 | P3ByteArray(p)[x][1] := 0; |
|
- | 8637 | P3ByteArray(p)[x][2] := 0; |
|
- | 8638 | end; |
|
- | 8639 | end; |
|
- | 8640 | end; |
|
- | 8641 | 32: begin |
|
- | 8642 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 8643 | begin |
|
- | 8644 | plongarray(p2) := ScanLine[y2]; |
|
- | 8645 | plongarray(p)[x] := plongarray(p2)[Width - x2]; |
|
- | 8646 | end |
|
- | 8647 | else |
|
- | 8648 | begin |
|
- | 8649 | if plongarray(p)[x] > 4 then |
|
- | 8650 | plongarray(p)[x] := plongarray(p)[x] - 4 |
|
- | 8651 | else |
|
- | 8652 | plongarray(p)[x] := 0; |
|
- | 8653 | end; |
|
- | 8654 | end; |
|
- | 8655 | end |
|
- | 8656 | end; |
|
- | 8657 | end; |
|
- | 8658 | end; |
|
- | 8659 | ||
- | 8660 | function TDIB.Ink(DIB: TDIB; const SprayInit: Boolean; const AmountSpray: Integer): Boolean; |
|
- | 8661 | type |
|
- | 8662 | T3Byte = array[0..2] of Byte; |
|
- | 8663 | P3ByteArray = ^T3ByteArray; |
|
- | 8664 | T3ByteArray = array[0..32767] of T3Byte; |
|
- | 8665 | PLongArray = ^TLongArray; |
|
- | 8666 | TLongArray = array[0..32767] of LongInt; |
|
- | 8667 | function ColorToRGBTriple(const Color: TColor): TRGBTriple; |
|
- | 8668 | begin |
|
- | 8669 | with RESULT do |
|
- | 8670 | begin |
|
- | 8671 | rgbtRed := GetRValue(Color); |
|
- | 8672 | rgbtGreen := GetGValue(Color); |
|
- | 8673 | rgbtBlue := GetBValue(Color) |
|
- | 8674 | end |
|
- | 8675 | end {ColorToRGBTriple}; |
|
- | 8676 | ||
- | 8677 | function TestQuad(T: T3Byte; Color: Integer): Boolean; |
|
- | 8678 | begin |
|
- | 8679 | Result := (T[0] > GetRValue(Color)) and |
|
- | 8680 | (T[1] > GetGValue(Color)) and |
|
- | 8681 | (T[2] > GetBValue(Color)) |
|
- | 8682 | end; |
|
- | 8683 | var |
|
- | 8684 | p0, p, p2: PByteArray; |
|
- | 8685 | x, y, c: Integer; |
|
- | 8686 | z: Integer; |
|
- | 8687 | begin |
|
- | 8688 | if SprayInit then |
|
- | 8689 | begin |
|
- | 8690 | DIB.Assign(Self); |
|
- | 8691 | { Spray seeds } |
|
- | 8692 | for c := 0 to AmountSpray do |
|
- | 8693 | begin |
|
- | 8694 | DIB.Pixels[Random(Width - 1), Random(Height - 1)] := 0; |
|
- | 8695 | end; |
|
- | 8696 | end; |
|
- | 8697 | Result := True; {all is black} |
|
- | 8698 | for y := 0 to DIB.Height - 1 do |
|
- | 8699 | begin |
|
- | 8700 | p := DIB.ScanLine[y]; |
|
- | 8701 | for x := 0 to DIB.Width - 1 do |
|
- | 8702 | begin |
|
- | 8703 | case bitcount of |
|
- | 8704 | 8: |
|
- | 8705 | begin |
|
- | 8706 | if p[x] < 16 then |
|
- | 8707 | begin |
|
- | 8708 | if p[x] > 0 then Result := False; |
|
- | 8709 | if y > 0 then |
|
- | 8710 | begin |
|
- | 8711 | p0 := DIB.ScanLine[y - 1]; |
|
- | 8712 | if p0[x] > 4 then |
|
- | 8713 | p0[x] := p0[x] - 4 |
|
- | 8714 | else |
|
- | 8715 | p0[x] := 0; |
|
- | 8716 | if x > 0 then |
|
- | 8717 | if p0[x - 1] > 2 then |
|
- | 8718 | p0[x - 1] := p0[x - 1] - 2 |
|
- | 8719 | else |
|
- | 8720 | p0[x - 1] := 0; |
|
- | 8721 | if x < (DIB.Width - 1) then |
|
- | 8722 | if p0[x + 1] > 2 then |
|
- | 8723 | p0[x + 1] := p0[x + 1] - 2 |
|
- | 8724 | else |
|
- | 8725 | p0[x + 1] := 0; |
|
- | 8726 | end; |
|
- | 8727 | if y < (DIB.Height - 1) then |
|
- | 8728 | begin |
|
- | 8729 | p2 := DIB.ScanLine[y + 1]; |
|
- | 8730 | if p2[x] > 4 then |
|
- | 8731 | p2[x] := p2[x] - 4 |
|
- | 8732 | else |
|
- | 8733 | p2[x] := 0; |
|
- | 8734 | if x > 0 then |
|
- | 8735 | if p2[x - 1] > 2 then |
|
- | 8736 | p2[x - 1] := p2[x - 1] - 2 |
|
- | 8737 | else |
|
- | 8738 | p2[x - 1] := 0; |
|
- | 8739 | if x < (DIB.Width - 1) then |
|
- | 8740 | if p2[x + 1] > 2 then |
|
- | 8741 | p2[x + 1] := p2[x + 1] - 2 |
|
- | 8742 | else |
|
- | 8743 | p2[x + 1] := 0; |
|
- | 8744 | end; |
|
- | 8745 | if p[x] > 8 then |
|
- | 8746 | p[x] := p[x] - 8 |
|
- | 8747 | else |
|
- | 8748 | p[x] := 0; |
|
- | 8749 | if x > 0 then |
|
- | 8750 | if p[x - 1] > 4 then |
|
- | 8751 | p[x - 1] := p[x - 1] - 4 |
|
- | 8752 | else |
|
- | 8753 | p[x - 1] := 0; |
|
- | 8754 | if x < (DIB.Width - 1) then |
|
- | 8755 | if p[x + 1] > 4 then |
|
- | 8756 | p[x + 1] := p[x + 1] - 4 |
|
- | 8757 | else |
|
- | 8758 | p[x + 1] := 0; |
|
- | 8759 | end; |
|
- | 8760 | end; |
|
- | 8761 | 16: |
|
- | 8762 | begin |
|
- | 8763 | if pwordarray(p)[x] < 16 then |
|
- | 8764 | begin |
|
- | 8765 | if pwordarray(p)[x] > 0 then Result := False; |
|
- | 8766 | if y > 0 then |
|
- | 8767 | begin |
|
- | 8768 | pwordarray(p0) := DIB.ScanLine[y - 1]; |
|
- | 8769 | if pwordarray(p0)[x] > 4 then |
|
- | 8770 | pwordarray(p0)[x] := pwordarray(p0)[x] - 4 |
|
- | 8771 | else |
|
- | 8772 | pwordarray(p0)[x] := 0; |
|
- | 8773 | if x > 0 then |
|
- | 8774 | if pwordarray(p0)[x - 1] > 2 then |
|
- | 8775 | pwordarray(p0)[x - 1] := pwordarray(p0)[x - 1] - 2 |
|
- | 8776 | else |
|
- | 8777 | pwordarray(p0)[x - 1] := 0; |
|
- | 8778 | if x < (DIB.Width - 1) then |
|
- | 8779 | if pwordarray(p0)[x + 1] > 2 then |
|
- | 8780 | pwordarray(p0)[x + 1] := pwordarray(p0)[x + 1] - 2 |
|
- | 8781 | else |
|
- | 8782 | pwordarray(p0)[x + 1] := 0; |
|
- | 8783 | end; |
|
- | 8784 | if y < (DIB.Height - 1) then |
|
- | 8785 | begin |
|
- | 8786 | pwordarray(p2) := DIB.ScanLine[y + 1]; |
|
- | 8787 | if pwordarray(p2)[x] > 4 then |
|
- | 8788 | pwordarray(p2)[x] := pwordarray(p2)[x] - 4 |
|
- | 8789 | else |
|
- | 8790 | pwordarray(p2)[x] := 0; |
|
- | 8791 | if x > 0 then |
|
- | 8792 | if pwordarray(p2)[x - 1] > 2 then |
|
- | 8793 | pwordarray(p2)[x - 1] := pwordarray(p2)[x - 1] - 2 |
|
- | 8794 | else |
|
- | 8795 | pwordarray(p2)[x - 1] := 0; |
|
- | 8796 | if x < (DIB.Width - 1) then |
|
- | 8797 | if pwordarray(p2)[x + 1] > 2 then |
|
- | 8798 | pwordarray(p2)[x + 1] := pwordarray(p2)[x + 1] - 2 |
|
- | 8799 | else |
|
- | 8800 | pwordarray(p2)[x + 1] := 0; |
|
- | 8801 | end; |
|
- | 8802 | if pwordarray(p)[x] > 8 then |
|
- | 8803 | pwordarray(p)[x] := pwordarray(p)[x] - 8 |
|
- | 8804 | else |
|
- | 8805 | pwordarray(p)[x] := 0; |
|
- | 8806 | if x > 0 then |
|
- | 8807 | if pwordarray(p)[x - 1] > 4 then |
|
- | 8808 | pwordarray(p)[x - 1] := pwordarray(p)[x - 1] - 4 |
|
- | 8809 | else |
|
- | 8810 | pwordarray(p)[x - 1] := 0; |
|
- | 8811 | if x < (DIB.Width - 1) then |
|
- | 8812 | if pwordarray(p)[x + 1] > 4 then |
|
- | 8813 | pwordarray(p)[x + 1] := pwordarray(p)[x + 1] - 4 |
|
- | 8814 | else |
|
- | 8815 | pwordarray(p)[x + 1] := 0; |
|
- | 8816 | end; |
|
- | 8817 | end; |
|
- | 8818 | 24: |
|
- | 8819 | begin |
|
- | 8820 | if not TestQuad(P3ByteArray(p)[x], 16) then |
|
- | 8821 | begin |
|
- | 8822 | if TestQuad(P3ByteArray(p)[x], 0) then Result := False; |
|
- | 8823 | if y > 0 then |
|
- | 8824 | begin |
|
- | 8825 | P3ByteArray(p0) := DIB.ScanLine[y - 1]; |
|
- | 8826 | if TestQuad(P3ByteArray(p0)[x], 4) then |
|
- | 8827 | begin |
|
- | 8828 | for z := 0 to 2 do |
|
- | 8829 | if P3ByteArray(p0)[x][z] > 4 then |
|
- | 8830 | P3ByteArray(p0)[x][z] := P3ByteArray(p0)[x][z] - 4 |
|
- | 8831 | end |
|
- | 8832 | else |
|
- | 8833 | for z := 0 to 2 do |
|
- | 8834 | P3ByteArray(p0)[x][z] := 0; |
|
- | 8835 | if x > 0 then |
|
- | 8836 | if TestQuad(P3ByteArray(p0)[x - 1], 2) then |
|
- | 8837 | begin |
|
- | 8838 | for z := 0 to 2 do |
|
- | 8839 | if P3ByteArray(p0)[x - 1][z] > 2 then |
|
- | 8840 | P3ByteArray(p0)[x - 1][z] := P3ByteArray(p0)[x - 1][z] - 2 |
|
- | 8841 | end |
|
- | 8842 | else |
|
- | 8843 | for z := 0 to 2 do |
|
- | 8844 | P3ByteArray(p0)[x - 1][z] := 0; |
|
- | 8845 | if x < (DIB.Width - 1) then |
|
- | 8846 | if TestQuad(P3ByteArray(p0)[x + 1], 2) then |
|
- | 8847 | begin |
|
- | 8848 | for z := 0 to 2 do |
|
- | 8849 | if P3ByteArray(p0)[x + 1][z] > 2 then |
|
- | 8850 | P3ByteArray(p0)[x + 1][z] := P3ByteArray(p0)[x + 1][z] - 2 |
|
- | 8851 | end |
|
- | 8852 | else |
|
- | 8853 | for z := 0 to 2 do |
|
- | 8854 | P3ByteArray(p0)[x + 1][z] := 0; |
|
- | 8855 | end; |
|
- | 8856 | if y < (DIB.Height - 1) then |
|
- | 8857 | begin |
|
- | 8858 | P3ByteArray(p2) := DIB.ScanLine[y + 1]; |
|
- | 8859 | if TestQuad(P3ByteArray(p2)[x], 4) then |
|
- | 8860 | begin |
|
- | 8861 | for z := 0 to 2 do |
|
- | 8862 | if P3ByteArray(p2)[x][z] > 4 then |
|
- | 8863 | P3ByteArray(p2)[x][z] := P3ByteArray(p2)[x][z] - 4 |
|
- | 8864 | end |
|
- | 8865 | else |
|
- | 8866 | for z := 0 to 2 do |
|
- | 8867 | P3ByteArray(p2)[x][z] := 0; |
|
- | 8868 | if x > 0 then |
|
- | 8869 | if TestQuad(P3ByteArray(p2)[x - 1], 2) then |
|
- | 8870 | begin |
|
- | 8871 | for z := 0 to 2 do |
|
- | 8872 | if P3ByteArray(p2)[x - 1][z] > 2 then |
|
- | 8873 | P3ByteArray(p2)[x - 1][z] := P3ByteArray(p2)[x - 1][z] - 2 |
|
- | 8874 | end |
|
- | 8875 | else |
|
- | 8876 | for z := 0 to 2 do |
|
- | 8877 | P3ByteArray(p2)[x - 1][z] := 0; |
|
- | 8878 | if x < (DIB.Width - 1) then |
|
- | 8879 | if TestQuad(P3ByteArray(p2)[x + 1], 2) then |
|
- | 8880 | begin |
|
- | 8881 | for z := 0 to 2 do |
|
- | 8882 | if P3ByteArray(p2)[x + 1][z] > 2 then |
|
- | 8883 | P3ByteArray(p2)[x + 1][z] := P3ByteArray(p2)[x + 1][z] - 2 |
|
- | 8884 | end |
|
- | 8885 | else |
|
- | 8886 | for z := 0 to 2 do |
|
- | 8887 | P3ByteArray(p2)[x + 1][z] := 0; |
|
- | 8888 | end; |
|
- | 8889 | if TestQuad(P3ByteArray(p)[x], 8) then |
|
- | 8890 | begin |
|
- | 8891 | for z := 0 to 2 do |
|
- | 8892 | if P3ByteArray(p)[x][z] > 8 then |
|
- | 8893 | P3ByteArray(p)[x][z] := P3ByteArray(p)[x][z] - 8 |
|
- | 8894 | end |
|
- | 8895 | else |
|
- | 8896 | for z := 0 to 2 do |
|
- | 8897 | P3ByteArray(p)[x][z] := 0; |
|
- | 8898 | if x > 0 then |
|
- | 8899 | if TestQuad(P3ByteArray(p)[x - 1], 4) then |
|
- | 8900 | begin |
|
- | 8901 | for z := 0 to 2 do |
|
- | 8902 | if P3ByteArray(p)[x - 1][z] > 4 then |
|
- | 8903 | P3ByteArray(p)[x - 1][z] := P3ByteArray(p)[x - 1][z] - 4 |
|
- | 8904 | end |
|
- | 8905 | else |
|
- | 8906 | for z := 0 to 2 do |
|
- | 8907 | P3ByteArray(p)[x - 1][z] := 0; |
|
- | 8908 | if x < (DIB.Width - 1) then |
|
- | 8909 | if TestQuad(P3ByteArray(p)[x + 1], 4) then |
|
- | 8910 | begin |
|
- | 8911 | for z := 0 to 2 do |
|
- | 8912 | if P3ByteArray(p)[x + 1][z] > 4 then |
|
- | 8913 | P3ByteArray(p)[x + 1][z] := P3ByteArray(p)[x + 1][z] - 4 |
|
- | 8914 | end |
|
- | 8915 | else |
|
- | 8916 | for z := 0 to 2 do |
|
- | 8917 | P3ByteArray(p)[x + 1][z] := 0; |
|
- | 8918 | end; |
|
- | 8919 | end; |
|
- | 8920 | 32: |
|
- | 8921 | begin |
|
- | 8922 | if plongarray(p)[x] < 16 then |
|
- | 8923 | begin |
|
- | 8924 | if plongarray(p)[x] > 0 then Result := False; |
|
- | 8925 | if y > 0 then |
|
- | 8926 | begin |
|
- | 8927 | plongarray(p0) := DIB.ScanLine[y - 1]; |
|
- | 8928 | if plongarray(p0)[x] > 4 then |
|
- | 8929 | plongarray(p0)[x] := plongarray(p0)[x] - 4 |
|
- | 8930 | else |
|
- | 8931 | plongarray(p0)[x] := 0; |
|
- | 8932 | if x > 0 then |
|
- | 8933 | if plongarray(p0)[x - 1] > 2 then |
|
- | 8934 | plongarray(p0)[x - 1] := plongarray(p0)[x - 1] - 2 |
|
- | 8935 | else |
|
- | 8936 | plongarray(p0)[x - 1] := 0; |
|
- | 8937 | if x < (DIB.Width - 1) then |
|
- | 8938 | if plongarray(p0)[x + 1] > 2 then |
|
- | 8939 | plongarray(p0)[x + 1] := plongarray(p0)[x + 1] - 2 |
|
- | 8940 | else |
|
- | 8941 | plongarray(p0)[x + 1] := 0; |
|
- | 8942 | end; |
|
- | 8943 | if y < (DIB.Height - 1) then |
|
- | 8944 | begin |
|
- | 8945 | plongarray(p2) := DIB.ScanLine[y + 1]; |
|
- | 8946 | if plongarray(p2)[x] > 4 then |
|
- | 8947 | plongarray(p2)[x] := plongarray(p2)[x] - 4 |
|
- | 8948 | else |
|
- | 8949 | plongarray(p2)[x] := 0; |
|
- | 8950 | if x > 0 then |
|
- | 8951 | if plongarray(p2)[x - 1] > 2 then |
|
- | 8952 | plongarray(p2)[x - 1] := plongarray(p2)[x - 1] - 2 |
|
- | 8953 | else |
|
- | 8954 | plongarray(p2)[x - 1] := 0; |
|
- | 8955 | if x < (DIB.Width - 1) then |
|
- | 8956 | if plongarray(p2)[x + 1] > 2 then |
|
- | 8957 | plongarray(p2)[x + 1] := plongarray(p2)[x + 1] - 2 |
|
- | 8958 | else |
|
- | 8959 | plongarray(p2)[x + 1] := 0; |
|
- | 8960 | end; |
|
- | 8961 | if plongarray(p)[x] > 8 then |
|
- | 8962 | plongarray(p)[x] := plongarray(p)[x] - 8 |
|
- | 8963 | else |
|
- | 8964 | plongarray(p)[x] := 0; |
|
- | 8965 | if x > 0 then |
|
- | 8966 | if plongarray(p)[x - 1] > 4 then |
|
- | 8967 | plongarray(p)[x - 1] := plongarray(p)[x - 1] - 4 |
|
- | 8968 | else |
|
- | 8969 | plongarray(p)[x - 1] := 0; |
|
- | 8970 | if x < (DIB.Width - 1) then |
|
- | 8971 | if plongarray(p)[x + 1] > 4 then |
|
- | 8972 | plongarray(p)[x + 1] := plongarray(p)[x + 1] - 4 |
|
- | 8973 | else |
|
- | 8974 | plongarray(p)[x + 1] := 0; |
|
- | 8975 | end; |
|
- | 8976 | end; |
|
- | 8977 | end {case}; |
|
- | 8978 | end; |
|
- | 8979 | end; |
|
- | 8980 | end; |
|
- | 8981 | ||
- | 8982 | procedure TDIB.Distort(DIB1: TDIB; dt: TDistortType; cX, cY, Angle: Integer; Factor: Real); |
|
- | 8983 | type |
|
- | 8984 | T3Byte = array[0..2] of Byte; |
|
- | 8985 | P3ByteArray = ^T3ByteArray; |
|
- | 8986 | T3ByteArray = array[0..32767] of T3Byte; |
|
- | 8987 | PLongArray = ^TLongArray; |
|
- | 8988 | TLongArray = array[0..32767] of LongInt; |
|
- | 8989 | var |
|
- | 8990 | p, p2: PByteArray; |
|
- | 8991 | x, y, x2, y2, angled, ysqr: Integer; |
|
- | 8992 | actdist, dist, cosy, siny: real; |
|
- | 8993 | begin |
|
- | 8994 | dist := Factor * sqrt(sqr(cX) + sqr(cY)); |
|
- | 8995 | for y := 0 to DIB1.Height - 1 do |
|
- | 8996 | begin |
|
- | 8997 | p := DIB1.ScanLine[y]; |
|
- | 8998 | ysqr := sqr(y - cY); |
|
- | 8999 | for x := 0 to (DIB1.Width) - 1 do |
|
- | 9000 | begin |
|
- | 9001 | actdist := (sqrt((sqr(x - cX) + ysqr)) / dist); |
|
- | 9002 | if dt = dtSlow then |
|
- | 9003 | actdist := dsin((Trunc(actdist * 1024)) and $1FF); |
|
- | 9004 | angled := 384 + Trunc((actdist) * Angle); |
|
- | 9005 | ||
- | 9006 | cosy := (y - cY) * dcos(angled and $1FF); |
|
- | 9007 | siny := (y - cY) * dsin(angled and $1FF); |
|
- | 9008 | ||
- | 9009 | x2 := Trunc((x - cX) * dsin(angled and $1FF) + cosy) + cX; |
|
- | 9010 | y2 := Trunc((x - cX) * dcos(angled and $1FF) - siny) + cY; |
|
- | 9011 | case bitcount of |
|
- | 9012 | 8: |
|
- | 9013 | begin |
|
- | 9014 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 9015 | begin |
|
- | 9016 | p2 := ScanLine[y2]; |
|
- | 9017 | p[x] := p2[Width - x2]; |
|
- | 9018 | end |
|
- | 9019 | else |
|
- | 9020 | begin |
|
- | 9021 | if p[x] > 2 then |
|
- | 9022 | p[x] := p[x] - 2 |
|
- | 9023 | else |
|
- | 9024 | p[x] := 0; |
|
- | 9025 | end; |
|
- | 9026 | end; |
|
- | 9027 | 16: |
|
- | 9028 | begin |
|
- | 9029 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 9030 | begin |
|
- | 9031 | pwordarray(p2) := ScanLine[y2]; |
|
- | 9032 | pwordarray(p)[x] := pwordarray(p2)[Width - x2]; |
|
- | 9033 | end |
|
- | 9034 | else |
|
- | 9035 | begin |
|
- | 9036 | if pwordarray(p)[x] > 2 then |
|
- | 9037 | pwordarray(p)[x] := pwordarray(p)[x] - 2 |
|
- | 9038 | else |
|
- | 9039 | pwordarray(p)[x] := 0; |
|
- | 9040 | end; |
|
- | 9041 | end; |
|
- | 9042 | 24: |
|
- | 9043 | begin |
|
- | 9044 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 9045 | begin |
|
- | 9046 | P3ByteArray(p2) := ScanLine[y2]; |
|
- | 9047 | P3ByteArray(p)[x] := P3ByteArray(p2)[Width - x2]; |
|
- | 9048 | end |
|
- | 9049 | else |
|
- | 9050 | begin |
|
- | 9051 | if P3ByteArray(p)[x][0] > 2 then |
|
- | 9052 | P3ByteArray(p)[x][0] := P3ByteArray(p)[x][0] - 2 |
|
- | 9053 | else if P3ByteArray(p)[x][1] > 2 then |
|
- | 9054 | P3ByteArray(p)[x][1] := P3ByteArray(p)[x][1] - 2 |
|
- | 9055 | else if P3ByteArray(p)[x][2] > 2 then |
|
- | 9056 | P3ByteArray(p)[x][2] := P3ByteArray(p)[x][2] - 2 |
|
- | 9057 | else |
|
- | 9058 | begin |
|
- | 9059 | P3ByteArray(p)[x][0] := 0; |
|
- | 9060 | P3ByteArray(p)[x][1] := 0; |
|
- | 9061 | P3ByteArray(p)[x][2] := 0; |
|
- | 9062 | end; |
|
- | 9063 | end; |
|
- | 9064 | end; |
|
- | 9065 | 32: |
|
- | 9066 | begin |
|
- | 9067 | if (y2 >= 0) and (y2 < Height) and (x2 >= 0) and (x2 < Width) then |
|
- | 9068 | begin |
|
- | 9069 | plongarray(p2) := ScanLine[y2]; |
|
- | 9070 | plongarray(p)[x] := plongarray(p2)[Width - x2]; |
|
- | 9071 | end |
|
- | 9072 | else |
|
- | 9073 | begin |
|
- | 9074 | if p[x] > 2 then |
|
- | 9075 | plongarray(p)[x] := plongarray(p)[x] - 2 |
|
- | 9076 | else |
|
- | 9077 | plongarray(p)[x] := 0; |
|
- | 9078 | end; |
|
- | 9079 | end; |
|
- | 9080 | end {case} |
|
- | 9081 | end; |
|
- | 9082 | end; |
|
- | 9083 | end; |
|
- | 9084 | ||
- | 9085 | procedure TDIB.AntialiasedLine(x1, y1, x2, y2: Integer; color: TColor); |
|
- | 9086 | //anti-aliased line using the Wu algorithm by Peter Bone |
|
- | 9087 | var |
|
- | 9088 | dX, dY, X, Y, start, finish: Integer; |
|
- | 9089 | LM, LR: Integer; |
|
- | 9090 | dxi, dyi, dydxi: Integer; |
|
- | 9091 | P: PLines; |
|
- | 9092 | R, G, B: byte; |
|
- | 9093 | begin |
|
- | 9094 | R := GetRValue(Color); |
|
- | 9095 | G := GetGValue(Color); |
|
- | 9096 | B := GetBValue(Color); |
|
- | 9097 | dX := abs(x2 - x1); // Calculate deltax and deltay for initialisation |
|
- | 9098 | dY := abs(y2 - y1); |
|
- | 9099 | if (dX = 0) or (dY = 0) then |
|
- | 9100 | begin |
|
- | 9101 | Canvas.Pen.Color := (B shl 16) + (G shl 8) + R; |
|
- | 9102 | Canvas.MoveTo(x1, y1); |
|
- | 9103 | Canvas.LineTo(x2, y2); |
|
- | 9104 | exit; |
|
- | 9105 | end; |
|
- | 9106 | if dX > dY then |
|
- | 9107 | begin // horizontal or vertical |
|
- | 9108 | if y2 > y1 then // determine rise and run |
|
- | 9109 | dydxi := -dY shl 16 div dX |
|
- | 9110 | else |
|
- | 9111 | dydxi := dY shl 16 div dX; |
|
- | 9112 | if x2 < x1 then |
|
- | 9113 | begin |
|
- | 9114 | start := x2; // right to left |
|
- | 9115 | finish := x1; |
|
- | 9116 | dyi := y2 shl 16; |
|
- | 9117 | end |
|
- | 9118 | else |
|
- | 9119 | begin |
|
- | 9120 | start := x1; // left to right |
|
- | 9121 | finish := x2; |
|
- | 9122 | dyi := y1 shl 16; |
|
- | 9123 | dydxi := -dydxi; // inverse slope |
|
- | 9124 | end; |
|
- | 9125 | if finish >= Width then finish := Width - 1; |
|
- | 9126 | for X := start to finish do |
|
- | 9127 | begin |
|
- | 9128 | Y := dyi shr 16; |
|
- | 9129 | if (X < 0) or (Y < 0) or (Y > Height - 2) then |
|
- | 9130 | begin |
|
- | 9131 | Inc(dyi, dydxi); |
|
- | 9132 | Continue; |
|
- | 9133 | end; |
|
- | 9134 | LM := dyi - Y shl 16; // fractional part of dyi - in fixed-point |
|
- | 9135 | LR := 65536 - LM; |
|
- | 9136 | P := Scanline[Y]; |
|
- | 9137 | P^[X].B := (B * LR + P^[X].B * LM) shr 16; |
|
- | 9138 | P^[X].G := (G * LR + P^[X].G * LM) shr 16; |
|
- | 9139 | P^[X].R := (R * LR + P^[X].R * LM) shr 16; |
|
- | 9140 | //Inc(Y); |
|
- | 9141 | P^[X].B := (B * LM + P^[X].B * LR) shr 16; |
|
- | 9142 | P^[X].G := (G * LM + P^[X].G * LR) shr 16; |
|
- | 9143 | P^[X].R := (R * LM + P^[X].R * LR) shr 16; |
|
- | 9144 | Inc(dyi, dydxi); // next point |
|
- | 9145 | end; |
|
- | 9146 | end |
|
- | 9147 | else |
|
- | 9148 | begin |
|
- | 9149 | if x2 > x1 then // determine rise and run |
|
- | 9150 | dydxi := -dX shl 16 div dY |
|
- | 9151 | else |
|
- | 9152 | dydxi := dX shl 16 div dY; |
|
- | 9153 | if y2 < y1 then |
|
- | 9154 | begin |
|
- | 9155 | start := y2; // right to left |
|
- | 9156 | finish := y1; |
|
- | 9157 | dxi := x2 shl 16; |
|
- | 9158 | end |
|
- | 9159 | else |
|
- | 9160 | begin |
|
- | 9161 | start := y1; // left to right |
|
- | 9162 | finish := y2; |
|
- | 9163 | dxi := x1 shl 16; |
|
- | 9164 | dydxi := -dydxi; // inverse slope |
|
- | 9165 | end; |
|
- | 9166 | if finish >= Height then finish := Height - 1; |
|
- | 9167 | for Y := start to finish do |
|
- | 9168 | begin |
|
- | 9169 | X := dxi shr 16; |
|
- | 9170 | if (Y < 0) or (X < 0) or (X > Width - 2) then |
|
- | 9171 | begin |
|
- | 9172 | Inc(dxi, dydxi); |
|
- | 9173 | Continue; |
|
- | 9174 | end; |
|
- | 9175 | LM := dxi - X shl 16; |
|
- | 9176 | LR := 65536 - LM; |
|
- | 9177 | P := Scanline[Y]; |
|
- | 9178 | P^[X].B := (B * LR + P^[X].B * LM) shr 16; |
|
- | 9179 | P^[X].G := (G * LR + P^[X].G * LM) shr 16; |
|
- | 9180 | P^[X].R := (R * LR + P^[X].R * LM) shr 16; |
|
- | 9181 | Inc(X); |
|
- | 9182 | P^[X].B := (B * LM + P^[X].B * LR) shr 16; |
|
- | 9183 | P^[X].G := (G * LM + P^[X].G * LR) shr 16; |
|
- | 9184 | P^[X].R := (R * LM + P^[X].R * LR) shr 16; |
|
- | 9185 | Inc(dxi, dydxi); // next point |
|
- | 9186 | end; |
|
- | 9187 | end; |
|
- | 9188 | end; |
|
- | 9189 | ||
- | 9190 | function TDIB.GetColorBetween(StartColor, EndColor: TColor; Pointvalue, |
|
- | 9191 | FromPoint, ToPoint: Extended): TColor; |
|
- | 9192 | var F: Extended; r1, r2, r3, g1, g2, g3, b1, b2, b3: Byte; |
|
- | 9193 | function CalcColorBytes(fb1, fb2: Byte): Byte; |
|
- | 9194 | begin |
|
- | 9195 | result := fb1; |
|
- | 9196 | if fb1 < fb2 then Result := FB1 + Trunc(F * (fb2 - fb1)); |
|
- | 9197 | if fb1 > fb2 then Result := FB1 - Trunc(F * (fb1 - fb2)); |
|
- | 9198 | end; |
|
- | 9199 | begin |
|
- | 9200 | if Pointvalue <= FromPoint then |
|
- | 9201 | begin |
|
- | 9202 | result := StartColor; |
|
- | 9203 | exit; |
|
- | 9204 | end; |
|
- | 9205 | if Pointvalue >= ToPoint then |
|
- | 9206 | begin |
|
- | 9207 | result := EndColor; |
|
- | 9208 | exit; |
|
- | 9209 | end; |
|
- | 9210 | F := (Pointvalue - FromPoint) / (ToPoint - FromPoint); |
|
- | 9211 | asm |
|
- | 9212 | mov EAX, Startcolor |
|
- | 9213 | cmp EAX, EndColor |
|
- | 9214 | je @@exit //when equal then exit |
|
- | 9215 | mov r1, AL |
|
- | 9216 | shr EAX,8 |
|
- | 9217 | mov g1, AL |
|
- | 9218 | shr EAX,8 |
|
- | 9219 | mov b1, AL |
|
- | 9220 | mov EAX, Endcolor |
|
- | 9221 | mov r2, AL |
|
- | 9222 | shr EAX,8 |
|
- | 9223 | mov g2, AL |
|
- | 9224 | shr EAX,8 |
|
- | 9225 | mov b2, AL |
|
- | 9226 | push ebp |
|
- | 9227 | mov AL, r1 |
|
- | 9228 | mov DL, r2 |
|
- | 9229 | call CalcColorBytes |
|
- | 9230 | pop ECX |
|
- | 9231 | push EBP |
|
- | 9232 | Mov r3, AL |
|
- | 9233 | mov DL, g2 |
|
- | 9234 | mov AL, g1 |
|
- | 9235 | call CalcColorBytes |
|
- | 9236 | pop ECX |
|
- | 9237 | push EBP |
|
- | 9238 | mov g3, Al |
|
- | 9239 | mov DL, B2 |
|
- | 9240 | mov Al, B1 |
|
- | 9241 | call CalcColorBytes |
|
- | 9242 | pop ECX |
|
- | 9243 | mov b3, AL |
|
- | 9244 | XOR EAX,EAX |
|
- | 9245 | mov AL, B3 |
|
- | 9246 | shl EAX,8 |
|
- | 9247 | mov AL, G3 |
|
- | 9248 | shl EAX,8 |
|
- | 9249 | mov AL, R3 |
|
- | 9250 | @@Exit: |
|
- | 9251 | mov @result, EAX |
|
- | 9252 | end; |
|
- | 9253 | end; |
|
- | 9254 | ||
- | 9255 | procedure TDIB.ColoredLine(const iStart, iEnd: TPoint; iColorStyle: TColorLineStyle; |
|
- | 9256 | iGradientFrom, iGradientTo: TColor; iPixelGeometry: TColorLinePixelGeometry; iRadius: Word); |
|
- | 9257 | var |
|
- | 9258 | tempColor: TColor; |
|
- | 9259 | const |
|
- | 9260 | WavelengthMinimum = 380; |
|
- | 9261 | WavelengthMaximum = 780; |
|
- | 9262 | ||
- | 9263 | procedure SetColor(Color: TColor); |
|
- | 9264 | begin |
|
- | 9265 | Canvas.Pen.Color := Color; |
|
- | 9266 | Canvas.Brush.Color := Color; |
|
- | 9267 | tempColor := Color |
|
- | 9268 | end {SetColor}; |
|
- | 9269 | ||
- | 9270 | function WL2RGB(const Wavelength: Double): TColor; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9271 | const |
|
- | 9272 | Gamma = 0.80; |
|
- | 9273 | IntensityMax = 255; |
|
- | 9274 | var |
|
- | 9275 | Red, Blue, Green, Factor: Double; |
|
- | 9276 | ||
- | 9277 | function Adjust(const Color, Factor: Double): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9278 | begin |
|
- | 9279 | if Color = 0.0 then Result := 0 |
|
- | 9280 | else Result := Round(IntensityMax * Power(Color * Factor, Gamma)) |
|
- | 9281 | end {Adjust}; |
|
- | 9282 | begin |
|
- | 9283 | case Trunc(Wavelength) of |
|
- | 9284 | 380..439: |
|
- | 9285 | begin |
|
- | 9286 | Red := -(Wavelength - 440) / (440 - 380); |
|
- | 9287 | Green := 0.0; |
|
- | 9288 | Blue := 1.0 |
|
- | 9289 | end; |
|
- | 9290 | 440..489: |
|
- | 9291 | begin |
|
- | 9292 | Red := 0.0; |
|
- | 9293 | Green := (Wavelength - 440) / (490 - 440); |
|
- | 9294 | Blue := 1.0 |
|
- | 9295 | end; |
|
- | 9296 | 490..509: |
|
- | 9297 | begin |
|
- | 9298 | Red := 0.0; |
|
- | 9299 | Green := 1.0; |
|
- | 9300 | Blue := -(Wavelength - 510) / (510 - 490) |
|
- | 9301 | end; |
|
- | 9302 | 510..579: |
|
- | 9303 | begin |
|
- | 9304 | Red := (Wavelength - 510) / (580 - 510); |
|
- | 9305 | Green := 1.0; |
|
- | 9306 | Blue := 0.0 |
|
- | 9307 | end; |
|
- | 9308 | 580..644: |
|
- | 9309 | begin |
|
- | 9310 | Red := 1.0; |
|
- | 9311 | Green := -(Wavelength - 645) / (645 - 580); |
|
- | 9312 | Blue := 0.0 |
|
- | 9313 | end; |
|
- | 9314 | 645..780: |
|
- | 9315 | begin |
|
- | 9316 | Red := 1.0; |
|
- | 9317 | Green := 0.0; |
|
- | 9318 | Blue := 0.0 |
|
- | 9319 | end; |
|
- | 9320 | else |
|
- | 9321 | Red := 0.0; |
|
- | 9322 | Green := 0.0; |
|
- | 9323 | Blue := 0.0 |
|
- | 9324 | end; |
|
- | 9325 | case Trunc(Wavelength) of |
|
- | 9326 | 380..419: factor := 0.3 + 0.7 * (Wavelength - 380) / (420 - 380); |
|
- | 9327 | 420..700: factor := 1.0; |
|
- | 9328 | 701..780: factor := 0.3 + 0.7 * (780 - Wavelength) / (780 - 700) |
|
- | 9329 | else |
|
- | 9330 | factor := 0.0 |
|
- | 9331 | end; |
|
- | 9332 | Result := RGB(Adjust(Red, Factor), Adjust(Green, Factor), Adjust(Blue, Factor)); |
|
- | 9333 | end; |
|
- | 9334 | ||
- | 9335 | function Rainbow(const fraction: Double): TColor; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9336 | begin |
|
- | 9337 | if (fraction < 0.0) or (fraction > 1.0) then Result := clBlack |
|
- | 9338 | else |
|
- | 9339 | Result := WL2RGB(WavelengthMinimum + Fraction * (WavelengthMaximum - WavelengthMinimum)) |
|
- | 9340 | end {Raindbow}; |
|
- | 9341 | ||
- | 9342 | function ColorInterpolate(const fraction: Double; const Color1, Color2: TColor): TColor; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9343 | var |
|
- | 9344 | complement: Double; |
|
- | 9345 | R1, R2, G1, G2, B1, B2: BYTE; |
|
- | 9346 | begin |
|
- | 9347 | if fraction <= 0 then Result := Color1 |
|
- | 9348 | else |
|
- | 9349 | if fraction >= 1.0 then Result := Color2 |
|
- | 9350 | else |
|
- | 9351 | begin |
|
- | 9352 | R1 := GetRValue(Color1); |
|
- | 9353 | G1 := GetGValue(Color1); |
|
- | 9354 | B1 := GetBValue(Color1); |
|
- | 9355 | R2 := GetRValue(Color2); |
|
- | 9356 | G2 := GetGValue(Color2); |
|
- | 9357 | B2 := GetBValue(Color2); |
|
- | 9358 | complement := 1.0 - fraction; |
|
- | 9359 | Result := RGB(Round(complement * R1 + fraction * R2), |
|
- | 9360 | Round(complement * G1 + fraction * G2), |
|
- | 9361 | Round(complement * B1 + fraction * B2)) |
|
- | 9362 | end |
|
- | 9363 | end {ColorInterpolate}; |
|
- | 9364 | ||
- | 9365 | // Conversion utility routines |
|
- | 9366 | function ColorToRGBTriple(const Color: TColor): TRGBTriple; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9367 | begin |
|
- | 9368 | with Result do |
|
- | 9369 | begin |
|
- | 9370 | rgbtRed := GetRValue(Color); |
|
- | 9371 | rgbtGreen := GetGValue(Color); |
|
- | 9372 | rgbtBlue := GetBValue(Color) |
|
- | 9373 | end |
|
- | 9374 | end {ColorToRGBTriple}; |
|
- | 9375 | ||
- | 9376 | function RGBTripleToColor(const Triple: TRGBTriple): TColor; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9377 | begin |
|
- | 9378 | Result := RGB(Triple.rgbtRed, Triple.rgbtGreen, Triple.rgbtBlue) |
|
- | 9379 | end {RGBTripleToColor}; |
|
- | 9380 | // Bresenham's Line Algorithm. Byte, March 1988, pp. 249-253. |
|
- | 9381 | var |
|
- | 9382 | a, b, d, diag_inc, dXdg, dXndg, dYdg, dYndg, i, nDginc, nDswap, x, y: Integer; |
|
- | 9383 | begin {DrawLine} |
|
- | 9384 | x := iStart.X; |
|
- | 9385 | y := iStart.Y; |
|
- | 9386 | a := iEnd.X - iStart.X; |
|
- | 9387 | b := iEnd.Y - iStart.Y; |
|
- | 9388 | if a < 0 then |
|
- | 9389 | begin |
|
- | 9390 | a := -a; |
|
- | 9391 | dXdg := -1 |
|
- | 9392 | end |
|
- | 9393 | else dXdg := 1; |
|
- | 9394 | if b < 0 then |
|
- | 9395 | begin |
|
- | 9396 | b := -b; |
|
- | 9397 | dYdg := -1 |
|
- | 9398 | end |
|
- | 9399 | else dYdg := 1; |
|
- | 9400 | if a < b then |
|
- | 9401 | begin |
|
- | 9402 | nDswap := a; |
|
- | 9403 | a := b; |
|
- | 9404 | b := nDswap; |
|
- | 9405 | dXndg := 0; |
|
- | 9406 | dYndg := dYdg |
|
- | 9407 | end |
|
- | 9408 | else |
|
- | 9409 | begin |
|
- | 9410 | dXndg := dXdg; |
|
- | 9411 | dYndg := 0 |
|
- | 9412 | end; |
|
- | 9413 | d := b + b - a; |
|
- | 9414 | nDginc := b + b; |
|
- | 9415 | diag_inc := b + b - a - a; |
|
- | 9416 | for i := 0 to a do |
|
- | 9417 | begin |
|
- | 9418 | case iPixelGeometry of |
|
- | 9419 | pgPoint: |
|
- | 9420 | case iColorStyle of |
|
- | 9421 | csSolid: |
|
- | 9422 | Canvas.Pixels[x, y] := tempColor; |
|
- | 9423 | csGradient: |
|
- | 9424 | Canvas.Pixels[x, y] := ColorInterpolate(i / a, iGradientFrom, iGradientTo); |
|
- | 9425 | csRainbow: |
|
- | 9426 | Canvas.Pixels[x, y] := Rainbow(i / a) |
|
- | 9427 | end; |
|
- | 9428 | pgCircular: |
|
- | 9429 | begin |
|
- | 9430 | case iColorStyle of |
|
- | 9431 | csSolid: ; |
|
- | 9432 | csGradient: SetColor(ColorInterpolate(i / a, iGradientFrom, iGradientTo)); |
|
- | 9433 | csRainbow: SetColor(Rainbow(i / a)) |
|
- | 9434 | end; |
|
- | 9435 | Canvas.Ellipse(x - iRadius, y - iRadius, x + iRadius, y + iRadius) |
|
- | 9436 | end; |
|
- | 9437 | pgRectangular: |
|
- | 9438 | begin |
|
- | 9439 | case iColorStyle of |
|
- | 9440 | csSolid: ; |
|
- | 9441 | csGradient: SetColor(ColorInterpolate(i / a, iGradientFrom, iGradientTo)); |
|
- | 9442 | csRainbow: SetColor(Rainbow(i / a)) |
|
- | 9443 | end; |
|
- | 9444 | Canvas.Rectangle(x - iRadius, y - iRadius, x + iRadius, y + iRadius) |
|
- | 9445 | end |
|
- | 9446 | end; |
|
- | 9447 | if d < 0 then |
|
- | 9448 | begin |
|
- | 9449 | Inc(x, dXndg); |
|
- | 9450 | Inc(y, dYndg); |
|
- | 9451 | Inc(d, nDginc); |
|
- | 9452 | end |
|
- | 9453 | else |
|
- | 9454 | begin |
|
- | 9455 | Inc(x, dXdg); |
|
- | 9456 | Inc(y, dYdg); |
|
- | 9457 | Inc(d, diag_inc); |
|
- | 9458 | end |
|
- | 9459 | end |
|
- | 9460 | end {Line}; |
|
- | 9461 | ||
- | 9462 | procedure TDIB.DoNovaEffect(sr, sg, sb, cx, cy, radius, |
|
- | 9463 | nspokes, randomhue, randomspok, randgauss: Integer; onProgress: TProgressEvent); |
|
- | 9464 | // Copyright (c) 2000 by Keith Murray (kmurray@hotfreeware.com) |
|
- | 9465 | // All rights reserved. |
|
- | 9466 | // Adapted for DIB by JB. |
|
- | 9467 | type |
|
- | 9468 | PByteArray = ^TByteArray; |
|
- | 9469 | TByteArray = array[0..32767] of Byte; |
|
- | 9470 | PDoubleArray = ^TDoubleArray; |
|
- | 9471 | TDoubleArray = array[0..32767] of Double; |
|
- | 9472 | PIntegerArray = ^TIntegerArray; |
|
- | 9473 | TIntegerArray = array[0..32767] of Integer; |
|
- | 9474 | type |
|
- | 9475 | TProgressEvent = procedure(progress: Integer; message: string; |
|
- | 9476 | var cancel: Boolean) of object; |
|
- | 9477 | const |
|
- | 9478 | M_PI = 3.14159265358979323846; |
|
- | 9479 | RAND_MAX = 2147483647; |
|
- | 9480 | ||
- | 9481 | function Gauss: double; |
|
- | 9482 | const magnitude = 6; |
|
- | 9483 | var |
|
- | 9484 | sum: double; |
|
- | 9485 | i: Integer; |
|
- | 9486 | begin |
|
- | 9487 | sum := 0; |
|
- | 9488 | for i := 1 to magnitude do |
|
- | 9489 | sum := sum + (randgauss / 2147483647); |
|
- | 9490 | result := sum / magnitude; |
|
- | 9491 | end; |
|
- | 9492 | ||
- | 9493 | function Clamp(i, l, h: double): double; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9494 | begin |
|
- | 9495 | if i < l then |
|
- | 9496 | result := l |
|
- | 9497 | else |
|
- | 9498 | if i > h then |
|
- | 9499 | result := h |
|
- | 9500 | else |
|
- | 9501 | result := i; |
|
- | 9502 | end; |
|
- | 9503 | ||
- | 9504 | function IClamp(i, l, h: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9505 | begin |
|
- | 9506 | if i < l then |
|
- | 9507 | result := l |
|
- | 9508 | else if i > h then |
|
- | 9509 | result := h |
|
- | 9510 | else result := i; |
|
- | 9511 | end; |
|
- | 9512 | ||
- | 9513 | procedure rgb_to_hsl(r, g, b: Double; var h, s, l: Double); {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9514 | {$IFNDEF VER4UP} |
|
- | 9515 | function Max(a, b: Double): Double; |
|
- | 9516 | begin |
|
- | 9517 | Result := a; if b > a then Result := b; |
|
- | 9518 | end; |
|
- | 9519 | function Min(a, b: Double): Double; |
|
- | 9520 | begin |
|
- | 9521 | Result := a; if b < a then Result := b; |
|
- | 9522 | end; |
|
- | 9523 | {$ENDIF} |
|
- | 9524 | var |
|
- | 9525 | v, m, vm: Double; |
|
- | 9526 | r2, g2, b2: Double; |
|
- | 9527 | begin |
|
- | 9528 | h := 0; |
|
- | 9529 | s := 0; |
|
- | 9530 | l := 0; |
|
- | 9531 | v := Max(r, g); |
|
- | 9532 | v := Max(v, b); |
|
- | 9533 | m := Min(r, g); |
|
- | 9534 | m := Min(m, b); |
|
- | 9535 | l := (m + v) / 2.0; |
|
- | 9536 | if l <= 0.0 then |
|
- | 9537 | exit; |
|
- | 9538 | vm := v - m; |
|
- | 9539 | s := vm; |
|
- | 9540 | if s > 0.0 then |
|
- | 9541 | begin |
|
- | 9542 | if l <= 0.5 then |
|
- | 9543 | s := s / (v + m) |
|
- | 9544 | else s := s / (2.0 - v - m); |
|
- | 9545 | end |
|
- | 9546 | else exit; |
|
- | 9547 | r2 := (v - 4) / vm; |
|
- | 9548 | g2 := (v - g) / vm; |
|
- | 9549 | b2 := (v - b) / vm; |
|
- | 9550 | if r = v then |
|
- | 9551 | begin |
|
- | 9552 | if g = m then |
|
- | 9553 | h := b2 + 5.0 |
|
- | 9554 | else h := 1.0 - g2; |
|
- | 9555 | end |
|
- | 9556 | else if g = v then |
|
- | 9557 | begin |
|
- | 9558 | if b = m then |
|
- | 9559 | h := 1.0 + r2 |
|
- | 9560 | else h := 3.0 - b2; |
|
- | 9561 | end |
|
- | 9562 | else |
|
- | 9563 | begin |
|
- | 9564 | if r = m then |
|
- | 9565 | h := 3.0 + g2 |
|
- | 9566 | else h := 5.0 - r2; |
|
- | 9567 | end; |
|
- | 9568 | h := h / 6; |
|
- | 9569 | end; |
|
- | 9570 | ||
- | 9571 | procedure hsl_to_rgb(h, sl, l: Double; var r, g, b: Double); {$IFDEF VER9UP}inline;{$ENDIF} |
|
- | 9572 | var |
|
- | 9573 | v: Double; |
|
- | 9574 | m, sv: Double; |
|
- | 9575 | sextant: Integer; |
|
- | 9576 | fract, vsf, mid1, mid2: Double; |
|
- | 9577 | begin |
|
- | 9578 | if l <= 0.5 then |
|
- | 9579 | v := l * (1.0 + sl) |
|
- | 9580 | else v := l + sl - l * sl; |
|
- | 9581 | if v <= 0 then |
|
- | 9582 | begin |
|
- | 9583 | r := 0.0; |
|
- | 9584 | g := 0.0; |
|
- | 9585 | b := 0.0; |
|
- | 9586 | end |
|
- | 9587 | else |
|
- | 9588 | begin |
|
- | 9589 | m := l + l - v; |
|
- | 9590 | sv := (v - m) / v; |
|
- | 9591 | h := h * 6.0; |
|
- | 9592 | sextant := Trunc(h); |
|
- | 9593 | fract := h - sextant; |
|
- | 9594 | vsf := v * sv * fract; |
|
- | 9595 | mid1 := m + vsf; |
|
- | 9596 | mid2 := v - vsf; |
|
- | 9597 | case sextant of |
|
- | 9598 | 0: |
|
- | 9599 | begin |
|
- | 9600 | r := v; g := mid1; b := m; |
|
- | 9601 | end; |
|
- | 9602 | 1: |
|
- | 9603 | begin |
|
- | 9604 | r := mid2; g := v; b := m; |
|
- | 9605 | end; |
|
- | 9606 | 2: |
|
- | 9607 | begin |
|
- | 9608 | r := m; g := v; b := mid1; |
|
- | 9609 | end; |
|
- | 9610 | 3: |
|
- | 9611 | begin |
|
- | 9612 | r := m; g := mid2; b := v; |
|
- | 9613 | end; |
|
- | 9614 | 4: |
|
- | 9615 | begin |
|
- | 9616 | r := mid1; g := m; b := v; |
|
- | 9617 | end; |
|
- | 9618 | 5: |
|
- | 9619 | begin |
|
- | 9620 | r := v; g := m; b := mid2; |
|
- | 9621 | end; |
|
- | 9622 | end; |
|
- | 9623 | end; |
|
- | 9624 | end; |
|
- | 9625 | ||
- | 9626 | var |
|
- | 9627 | src_row, dest_row: PByte; |
|
- | 9628 | src, dest: PByteArray; |
|
- | 9629 | color, colors: array[0..3] of Integer; |
|
- | 9630 | SpokeColor: PIntegerArray; |
|
- | 9631 | spoke: PDoubleArray; |
|
- | 9632 | x1, y1, x2, y2, row, col, x, y, alpha, has_alpha, bpp, progress, max_progress, 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; |
|
- | 9634 | dstDIB: TDIB; |
|
- | 9635 | begin |
|
- | 9636 | colors[0] := sr; |
|
- | 9637 | colors[1] := sg; |
|
- | 9638 | colors[2] := sb; |
|
- | 9639 | new_alpha := 0; |
|
- | 9640 | ||
- | 9641 | GetMem(spoke, NSpokes * sizeof(Double)); |
|
- | 9642 | GetMem(spokecolor, NSpokes * sizeof(Integer) * 3); |
|
- | 9643 | dstDIB := TDIB.Create; |
|
- | 9644 | dstDIB.Assign(Self); |
|
- | 9645 | dstDIB.Canvas.Brush.Color := clBlack; |
|
- | 9646 | dstDIB.Canvas.FillRect(dstDIB.Canvas.ClipRect); |
|
- | 9647 | try |
|
- | 9648 | rgb_to_hsl(colors[0] / 255.0, colors[1] / 255.0, colors[2] / 255.0, h, s, lu); |
|
- | 9649 | ||
- | 9650 | for i := 0 to NSpokes - 1 do |
|
- | 9651 | begin |
|
- | 9652 | spoke[i] := gauss; |
|
- | 9653 | h := h + randomhue / 360.0 * ({Random(RAND_MAX)}RandomSpok / RAND_MAX - 0.5); |
|
- | 9654 | if h < 0 then |
|
- | 9655 | h := h + 1.0 |
|
- | 9656 | else if h > 1.0 then |
|
- | 9657 | h := h - 1.0; |
|
- | 9658 | hsl_to_rgb(h, s, lu, r, g, b); |
|
- | 9659 | spokecolor[3 * i + 0] := Trunc(255 * r); |
|
- | 9660 | spokecolor[3 * i + 1] := Trunc(255 * g); |
|
- | 9661 | spokecolor[3 * i + 2] := Trunc(255 * b); |
|
- | 9662 | end; |
|
- | 9663 | ||
- | 9664 | xc := cx; |
|
- | 9665 | yc := cy; |
|
- | 9666 | l0 := (x2 - xc) / 4 + 1; |
|
- | 9667 | bpp := Self.BitCount div 8; |
|
- | 9668 | has_alpha := 0; |
|
- | 9669 | alpha := bpp; |
|
- | 9670 | y := 0; |
|
- | 9671 | for row := 0 to Self.Height - 1 do begin |
|
- | 9672 | src_row := Self.ScanLine[row]; |
|
- | 9673 | dest_row := dstDIB.ScanLine[row]; |
|
- | 9674 | src := Pointer(src_row); |
|
- | 9675 | dest := Pointer(dest_row); |
|
- | 9676 | x := 0; |
|
- | 9677 | for col := 0 to Self.Width - 1 do begin |
|
- | 9678 | u := (x - xc) / radius; |
|
- | 9679 | v := (y - yc) / radius; |
|
- | 9680 | l := sqrt((u * u) + (v * v)); |
|
- | 9681 | c := (arctan2(u, v) / (2 * M_PI) + 0.51) * NSpokes; |
|
- | 9682 | i := floor(c); |
|
- | 9683 | c := c - i; |
|
- | 9684 | i := i mod NSpokes; |
|
- | 9685 | w1 := spoke[i] * (1 - c) + spoke[(i + 1) mod NSpokes] * c; |
|
- | 9686 | w1 := w1 * w1; |
|
- | 9687 | w := 1 / (l + 0.001) * 0.9; |
|
- | 9688 | nova_alpha := Clamp(w, 0.0, 1.0); |
|
- | 9689 | ratio := nova_alpha; |
|
- | 9690 | compl_ratio := 1.0 - ratio; |
|
- | 9691 | for j := 0 to alpha - 1 do |
|
- | 9692 | begin |
|
- | 9693 | spokecol := spokecolor[3 * i + j] * (1.0 - c) + spokecolor[3 * ((i + 1) mod nspokes) + j] * c; |
|
- | 9694 | if w > 1.0 then |
|
- | 9695 | color[j] := IClamp(Trunc(spokecol * w), 0, 255) |
|
- | 9696 | else |
|
- | 9697 | color[j] := Trunc(src[j] * compl_ratio + spokecol * ratio); |
|
- | 9698 | color[j] := Trunc(color[j] + 255 * Clamp(w1 * w, 0.0, 1.0)); |
|
- | 9699 | dest[j] := IClamp(color[j], 0, 255); |
|
- | 9700 | end; |
|
- | 9701 | inc(Integer(src), bpp); |
|
- | 9702 | inc(Integer(dest), bpp); |
|
- | 9703 | inc(x); |
|
- | 9704 | end; |
|
- | 9705 | inc(y); |
|
- | 9706 | end; |
|
- | 9707 | finally |
|
- | 9708 | Self.Assign(dstDIB); |
|
- | 9709 | dstDIB.Free; |
|
- | 9710 | FreeMem(Spoke); |
|
- | 9711 | FreeMem(SpokeColor); |
|
- | 9712 | end; |
|
- | 9713 | end; |
|
- | 9714 | ||
- | 9715 | procedure TDIB.DrawMandelbrot(ao, au: Integer; bo, bu: Double); |
|
- | 9716 | var |
|
- | 9717 | c1, c2, z1, z2, tmp: Double; |
|
- | 9718 | i, j, Count: Integer; |
|
- | 9719 | dstDIB: TDIB; |
|
- | 9720 | X, Y: Double; |
|
- | 9721 | X2, Y2: Integer; |
|
- | 9722 | begin |
|
- | 9723 | dstDIB := TDIB.Create; |
|
- | 9724 | dstDIB.Assign(Self); |
|
- | 9725 | X2 := dstDIB.FWidth; |
|
- | 9726 | Y2 := dstDIB.FHeight; |
|
- | 9727 | {as Example |
|
- | 9728 | ao := 1; |
|
- | 9729 | au := -2; |
|
- | 9730 | bo := 1.5; |
|
- | 9731 | bu := -1.5; |
|
- | 9732 | } |
|
- | 9733 | X := (ao - au) / dstDIB.FWidth; |
|
- | 9734 | Y := (bo - bu) / dstDIB.FHeight; |
|
- | 9735 | try |
|
- | 9736 | c2 := bu; |
|
- | 9737 | for i := 10 to X2 do |
|
- | 9738 | begin |
|
- | 9739 | c1 := au; |
|
- | 9740 | for j := 0 to Y2 do |
|
- | 9741 | begin |
|
- | 9742 | z1 := 0; |
|
- | 9743 | z2 := 0; |
|
- | 9744 | Count := 0; |
|
- | 9745 | {count is deep of iteration of the mandelbrot set |
|
- | 9746 | if |z| >=2 then z is not a member of a mandelset} |
|
- | 9747 | while (((z1 * z1 + z2 * z2 < 4) and (Count <= 90))) do |
|
- | 9748 | begin |
|
- | 9749 | tmp := z1; |
|
- | 9750 | z1 := z1 * z1 - z2 * z2 + c1; |
|
- | 9751 | z2 := 2 * tmp * z2 + c2; |
|
- | 9752 | Inc(Count); |
|
- | 9753 | end; |
|
- | 9754 | //the color-palette depends on TColor(n*count mod t) |
|
- | 9755 | dstDIB.Canvas.Pixels[j, i] := (16 * Count mod 255); |
|
- | 9756 | c1 := c1 + X; |
|
- | 9757 | end; |
|
- | 9758 | c2 := c2 + Y; |
|
- | 9759 | end; |
|
- | 9760 | finally |
|
- | 9761 | Self.Assign(dstDIB); |
|
- | 9762 | dstDIB.Free; |
|
- | 9763 | end; |
|
- | 9764 | end; |
|
- | 9765 | ||
- | 9766 | procedure TDIB.SephiaEffect(Depth: Integer{$IFDEF VER4UP} = 20{$ENDIF}); |
|
- | 9767 | {Note: when depth parameter set to 0 will produce black and white picture only} |
|
- | 9768 | var |
|
- | 9769 | color, color2: longint; |
|
- | 9770 | r, g, b, rr, gg: byte; |
|
- | 9771 | h, w: Integer; |
|
- | 9772 | p0: pbytearray; |
|
- | 9773 | x, y: Integer; |
|
- | 9774 | begin |
|
- | 9775 | if Self.BitCount = 24 then |
|
- | 9776 | begin |
|
- | 9777 | Self.DoGrayScale; |
|
- | 9778 | for y := 0 to Self.Height - 1 do |
|
- | 9779 | begin |
|
- | 9780 | p0 := Self.ScanLine[y]; |
|
- | 9781 | for x := 0 to Self.Width - 1 do |
|
- | 9782 | begin |
|
- | 9783 | r := p0[x * 3]; |
|
- | 9784 | g := p0[x * 3 + 1]; |
|
- | 9785 | b := p0[x * 3 + 2]; |
|
- | 9786 | rr := r + (depth * 2); |
|
- | 9787 | gg := g + depth; |
|
- | 9788 | if rr <= ((depth * 2) - 1) then |
|
- | 9789 | rr := 255; |
|
- | 9790 | if gg <= (depth - 1) then |
|
- | 9791 | gg := 255; |
|
- | 9792 | p0[x * 3] := rr; |
|
- | 9793 | p0[x * 3 + 1] := gg; |
|
- | 9794 | p0[x * 3 + 2] := b; |
|
- | 9795 | end; |
|
- | 9796 | end; |
|
- | 9797 | Exit |
|
- | 9798 | end; |
|
- | 9799 | {this alogorithm is slower because does not use scanline property} |
|
- | 9800 | for h := 0 to Self.Height-1 do |
|
- | 9801 | begin |
|
- | 9802 | for w := 0 to Self.Width-1 do |
|
- | 9803 | begin |
|
- | 9804 | //first convert the bitmap to greyscale |
|
- | 9805 | color := ColorToRGB(Self.Canvas.Pixels[w, h]); |
|
- | 9806 | r := GetRValue(color); |
|
- | 9807 | g := GetGValue(color); |
|
- | 9808 | b := GetBValue(color); |
|
- | 9809 | color2 := (r + g + b) div 3; |
|
- | 9810 | Self.Canvas.Pixels[w, h] := RGB(color2, color2, color2); |
|
- | 9811 | //then convert it to sepia |
|
- | 9812 | color := ColorToRGB(Self.Canvas.Pixels[w, h]); |
|
- | 9813 | r := GetRValue(color); |
|
- | 9814 | g := GetGValue(color); |
|
- | 9815 | b := GetBValue(color); |
|
- | 9816 | rr := r + (depth * 2); |
|
- | 9817 | gg := g + depth; |
|
- | 9818 | if rr <= ((depth * 2) - 1) then |
|
- | 9819 | rr := 255; |
|
- | 9820 | if gg <= (depth - 1) then |
|
- | 9821 | gg := 255; |
|
- | 9822 | Self.Canvas.Pixels[w, h] := RGB(rr, gg, b); |
|
- | 9823 | end; |
|
- | 9824 | end; |
|
- | 9825 | ||
- | 9826 | end; |
|
- | 9827 | ||
- | 9828 | procedure TDIB.EncryptDecrypt(const Key: Integer); |
|
- | 9829 | {for decript call it again} |
|
- | 9830 | var |
|
- | 9831 | BytesPorScan: Integer; |
|
- | 9832 | w, h: Integer; |
|
- | 9833 | p: pByteArray; |
|
- | 9834 | begin |
|
- | 9835 | try |
|
- | 9836 | BytesPorScan := Abs(Integer(Self.ScanLine[1]) - |
|
- | 9837 | Integer(Self.ScanLine[0])); |
|
- | 9838 | except |
|
- | 9839 | raise Exception.Create('Error '); |
|
- | 9840 | end; |
|
- | 9841 | RandSeed := Key; |
|
- | 9842 | for h := 0 to Self.Height - 1 do |
|
- | 9843 | begin |
|
- | 9844 | P := Self.ScanLine[h]; |
|
- | 9845 | for w := 0 to BytesPorScan - 1 do |
|
- | 9846 | P^[w] := P^[w] xor Random(256); |
|
- | 9847 | end; |
|
- | 9848 | end; |
|
- | 9849 | ||
- | 9850 | procedure TDIB.LinePolar(x, y: Integer; AngleInDegree, Length: extended; Color: cardinal); |
|
- | 9851 | var |
|
- | 9852 | xp, yp: Integer; |
|
- | 9853 | begin |
|
- | 9854 | xp := Round(Sin(AngleInDegree * Pi / 180) * Length) + x; |
|
- | 9855 | yp := Round(Cos(AngleInDegree * Pi / 180) * Length) + y; |
|
- | 9856 | AntialiasedLine(x, y, xp, yp, Color); |
|
- | 9857 | end; |
|
- | 9858 | ||
- | 9859 | //y = 0.299*g + 0.587*b + 0.114*r; |
|
- | 9860 | ||
- | 9861 | procedure TDIB.BlendPixel(const X, Y: Integer; aColor: Cardinal; Alpha: byte); |
|
- | 9862 | var |
|
- | 9863 | cR, cG, cB: byte; |
|
- | 9864 | aR, aG, aB: byte; |
|
- | 9865 | dColor: Cardinal; |
|
- | 9866 | begin |
|
- | 9867 | aR := GetRValue(aColor); |
|
- | 9868 | aG := GetGValue(aColor); |
|
- | 9869 | aB := GetBValue(aColor); |
|
- | 9870 | dColor := Self.Canvas.Pixels[x, y]; |
|
- | 9871 | cR := GetRValue(dColor); |
|
- | 9872 | cG := GetGValue(dColor); |
|
- | 9873 | cB := GetBValue(dColor); |
|
- | 9874 | Canvas.Pixels[x, y] := RGB((Alpha * (aR - cR) shr 8) + cR, // R alpha |
|
- | 9875 | (Alpha * (aG - cG) shr 8) + cG, // G alpha |
|
- | 9876 | (Alpha * (aB - cB) shr 8) + cB); // B alpha |
|
- | 9877 | end; |
|
- | 9878 | ||
- | 9879 | ||
- | 9880 | procedure MakeDib(out DIB: TDIB; const iWidth, iHeight, iBitCount: Integer; iFillColor: TColor{$IFDEF VER4UP} = clBlack{$ENDIF}); {$IFDEF VER4UP} overload; {$ENDIF} |
|
- | 9881 | begin |
|
- | 9882 | DIB := TDIB.Create; |
|
- | 9883 | DIB.SetSize(iWidth, iHeight, iBitCount); |
|
- | 9884 | DIB.Fill(iFillColor); |
|
- | 9885 | end; |
|
- | 9886 | ||
- | 9887 | procedure{$IFDEF VER4UP}MakeDib{$ELSE}MakeDib2{$ENDIF}(out DIB: TDIB; iBitmap: TBitmap); {$IFDEF VER4UP} overload; {$ENDIF} |
|
- | 9888 | begin |
|
- | 9889 | DIB := TDIB.Create; |
|
- | 9890 | if Assigned(iBitmap) then |
|
- | 9891 | DIB.CreateDIBFromBitmap(iBitmap) |
|
- | 9892 | else |
|
- | 9893 | DIB.Fill(clBlack); |
|
- | 9894 | end; |
|
- | 9895 | ||
3231 | initialization |
9896 | initialization |
3232 | TPicture.RegisterClipBoardFormat(CF_DIB, TDIB); |
9897 | TPicture.RegisterClipBoardFormat(CF_DIB, TDIB); |
3233 | TPicture.RegisterFileFormat('dib', 'Device Independent Bitmap', TDIB); |
9898 | TPicture.RegisterFileFormat('dib', 'Device Independent Bitmap', TDIB); |
3234 | finalization |
9899 | finalization |
3235 | TPicture.UnRegisterGraphicClass(TDIB); |
9900 | TPicture.UnRegisterGraphicClass(TDIB); |