source: trunk/Packages/bgrabitmap/basiccolorspace.inc

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 40.4 KB
Line 
1{$IFDEF INCLUDE_INTERFACE}
2{$UNDEF INCLUDE_INTERFACE}
3type
4 {* Possible channels in a bitmap using any RGBA colorspace }
5 TChannel = (cRed, cGreen, cBlue, cAlpha);
6 {** Combination of channels }
7 TChannels = set of TChannel;
8
9{ Gamma conversion arrays. Should be used as readonly }
10var
11 // TBGRAPixel -> TExpandedPixel
12 GammaExpansionTab: packed array[0..255] of word;
13
14 // TExpandedPixel -> TBGRAPixel
15 GammaCompressionTab : packed array[0..65535] of byte; //rounded value
16 GammaCompressionTabFrac : packed array[0..65535] of shortint; //fractional part of value from -0.5 to +0.5
17
18procedure BGRASetGamma(AGamma: single = 1.7);
19function BGRAGetGamma: single;
20
21type
22 PExpandedPixel = ^TExpandedPixel;
23 { TExpandedPixel }
24 {* Stores a gamma expanded RGB color. Values range from 0 to 65535 }
25 TExpandedPixel = packed record
26 red, green, blue, alpha: word;
27 end;
28 TExpandedPixelBuffer = packed array of TExpandedPixel;
29
30 procedure AllocateExpandedPixelBuffer(var ABuffer: TExpandedPixelBuffer; ASize: integer);
31
32 {** Converts a pixel from sRGB to gamma expanded RGB }
33 function GammaExpansion(c: TBGRAPixel): TExpandedPixel; inline;
34 {** Converts a pixel from gamma expanded RGB to sRGB }
35 function GammaCompression(const ec: TExpandedPixel): TBGRAPixel; inline; overload;
36 {** Converts a pixel from gamma expanded RGB to sRGB }
37 function GammaCompression(red,green,blue,alpha: word): TBGRAPixel; inline; overload;
38 {** Returns the intensity of an gamma-expanded pixel. The intensity is the
39 maximum value reached by any component }
40 function GetIntensity(const c: TExpandedPixel): word; inline;
41 {** Sets the intensity of a gamma-expanded pixel }
42 function SetIntensity(const c: TExpandedPixel; intensity: word): TExpandedPixel;
43 {** Returns the lightness of an gamma-expanded pixel. The lightness is the
44 perceived brightness, 0 being black and 65535 being white }
45 function GetLightness(const c: TExpandedPixel): word; inline; overload;
46 {** Sets the lightness of a gamma-expanded pixel }
47 function SetLightness(const c: TExpandedPixel; lightness: word): TExpandedPixel; overload;
48 {** Sets the lightness of a gamma expanded pixel, provided you already know the current
49 value of lightness ''curLightness''. It is a bit faster than the previous function }
50 function SetLightness(const c: TExpandedPixel; lightness: word; curLightness: word): TExpandedPixel; overload;
51 {** Returns the importance of the color. It is similar to saturation
52 in HSL colorspace, except it is gamma corrected. A value of zero indicates
53 a black/gray/white, and a value of 65535 indicates a bright color }
54 function ColorImportance(ec: TExpandedPixel): word;
55 {** Merge two gamma expanded pixels (so taking into account gamma correction) }
56 function MergeBGRA(ec1, ec2: TExpandedPixel): TExpandedPixel; overload;
57 {** Computes the difference (with gamma correction) between two pixels,
58 taking into account all dimensions, including transparency. The
59 result ranges from 0 to 65535 }
60 function ExpandedDiff(ec1, ec2: TExpandedPixel): word;
61
62type
63 {* General purpose color variable with single-precision floating point values }
64 TColorF = packed array[1..4] of single;
65 ArrayOfTColorF = array of TColorF;
66
67 {** Creates a TColorF structure }
68 function ColorF(red,green,blue,alpha: single): TColorF;
69 function BGRAToColorF(c: TBGRAPixel; AGammaExpansion: boolean): TColorF; overload;
70 function BGRAToColorF(const a: array of TBGRAPixel; AGammaExpansion: boolean): ArrayOfTColorF; overload;
71 function ColorFToBGRA(c: TColorF; AGammaCompression: boolean): TBGRAPixel;
72 function GammaCompressionF(c: TColorF): TColorF;
73 function GammaExpansionF(c: TColorF): TColorF;
74 {** Subtract each component separately }
75 operator - (const c1, c2: TColorF): TColorF; inline;
76 {** Add each component separately }
77 operator + (const c1, c2: TColorF): TColorF; inline;
78 {** Multiply each component separately }
79 operator * (const c1, c2: TColorF): TColorF; inline;
80 {** Multiply each component by ''factor'' }
81 operator * (const c1: TColorF; factor: single): TColorF; inline;
82
83type
84 {* Pixel color defined in HSL colorspace. Values range from 0 to 65535 }
85
86 { THSLAPixel }
87
88 THSLAPixel = packed record
89 {** Hue of the pixel. Extremum values 0 and 65535 are red }
90 hue: word;
91 {** Saturation of the color. 0 is gray and 65535 is the brightest color (including white) }
92 saturation: word;
93 {** Lightness of the color. 0 is black, 32768 is normal, and 65535 is white }
94 lightness: word;
95 {** Opacity of the pixel. 0 is transparent and 65535 is opaque }
96 alpha: word;
97 end;
98
99 {** Creates a pixel with given HSLA values, where A stands for alpha }
100 function HSLA(hue, saturation, lightness, alpha: word): THSLAPixel; overload; inline;
101 {** Creates an opaque pixel with given HSL values }
102 function HSLA(hue, saturation, lightness: word): THSLAPixel; overload; inline;
103 {** Converts a pixel from sRGB to HSL color space }
104 function BGRAToHSLA(c: TBGRAPixel): THSLAPixel;
105 {** Converts a pixel from gamma expanded RGB to HSL color space }
106 function ExpandedToHSLA(const ec: TExpandedPixel): THSLAPixel;
107 {** Converts a pixel from HSL colorspace to sRGB }
108 function HSLAToBGRA(const c: THSLAPixel): TBGRAPixel;
109 {** Converts a pixel from HSL colorspace to gamma expanded RGB }
110 function HSLAToExpanded(const c: THSLAPixel): TExpandedPixel;
111 {** Computes the hue difference }
112 function HueDiff(h1, h2: word): word;
113 {** Returns the hue of a gamma expanded pixel }
114 function GetHue(ec: TExpandedPixel): word;
115
116type
117 {* Pixel color defined in corrected HSL colorspace. G stands for corrected hue
118 and B stands for actual brightness. Values range from 0 to 65535 }
119 TGSBAPixel = packed record
120 {** Hue of the pixel. Extremum values 0 and 65535 are red }
121 hue: word;
122 {** Saturation of the color. 0 is gray and 65535 is the brightest color (excluding white) }
123 saturation: word;
124 {** Actual perceived brightness. 0 is black, 32768 is normal, and 65535 is white }
125 lightness: word;
126 {** Opacity of the pixel. 0 is transparent and 65535 is opaque }
127 alpha: word;
128 end;
129
130 {** Converts a pixel from sRGB to correct HSL color space }
131 function BGRAToGSBA(c: TBGRAPixel): TGSBAPixel;
132 {** Converts a pixel from gamma expanded RGB to correct HSL color space }
133 function ExpandedToGSBA(ec: TExpandedPixel): TGSBAPixel;
134 {** Converts a G hue (GSBA) to a H hue (HSLA) }
135 function GtoH(ghue: word): word;
136 {** Converts a H hue (HSLA) to a G hue (GSBA) }
137 function HtoG(hue: word): word;
138 {** Converts a pixel from corrected HSL to sRGB }
139 function GSBAToBGRA(c: TGSBAPixel): TBGRAPixel; overload;
140 function GSBAToBGRA(const c: THSLAPixel): TBGRAPixel; overload;
141 {** Converts a pixel from correct HSL to gamma expanded RGB }
142 function GSBAToExpanded(c: TGSBAPixel): TExpandedPixel; overload;
143 function GSBAToExpanded(const c: THSLAPixel): TExpandedPixel; overload;
144 {** Converts a pixel from correct HSL to usual HSL }
145 function GSBAToHSLA(const c: TGSBAPixel): THSLAPixel; overload;
146 function GSBAToHSLA(const c: THSLAPixel): THSLAPixel; overload;
147 function HSLAToGSBA(const c: THSLAPixel): TGSBAPixel;
148
149type
150 { TBGRAPixelBasicHelper }
151
152 TBGRAPixelBasicHelper = record helper for TBGRAPixel
153 function ToExpanded: TExpandedPixel;
154 procedure FromExpanded(const AValue: TExpandedPixel);
155 function ToHSLAPixel: THSLAPixel;
156 procedure FromHSLAPixel(const AValue: THSLAPixel);
157 function ToGSBAPixel: TGSBAPixel;
158 procedure FromGSBAPixel(const AValue: TGSBAPixel); overload;
159 procedure FromGSBAPixel(const AValue: THSLAPixel); overload;
160 function ToColorF(AGammaExpansion: boolean): TColorF;
161 procedure FromColorF(const AValue: TColorF; AGammaCompression: boolean);
162 end;
163
164 { TExpandedPixelBasicHelper }
165
166 TExpandedPixelBasicHelper = record helper for TExpandedPixel
167 function ToFPColor(AGammaCompression: boolean = true): TFPColor;
168 procedure FromFPColor(const AValue: TFPColor; AGammaExpansion: boolean = true);
169 function ToColor: TColor;
170 procedure FromColor(const AValue: TColor);
171 function ToBGRAPixel: TBGRAPixel;
172 procedure FromBGRAPixel(AValue: TBGRAPixel);
173 function ToHSLAPixel: THSLAPixel;
174 procedure FromHSLAPixel(const AValue: THSLAPixel);
175 function ToGSBAPixel: TGSBAPixel;
176 procedure FromGSBAPixel(const AValue: TGSBAPixel); overload;
177 procedure FromGSBAPixel(const AValue: THSLAPixel); overload;
178 end;
179
180operator := (const AValue: TExpandedPixel): TColor;
181operator := (const AValue: TColor): TExpandedPixel;
182Operator := (const Source: TExpandedPixel): TBGRAPixel;
183Operator := (const Source: TBGRAPixel): TExpandedPixel;
184
185type
186 { TFPColorBasicHelper }
187
188 TFPColorBasicHelper = record helper for TFPColor
189 function ToColor: TColor;
190 procedure FromColor(const AValue: TColor);
191 function ToBGRAPixel: TBGRAPixel;
192 procedure FromBGRAPixel(AValue: TBGRAPixel);
193 function ToExpanded(AGammaExpansion: boolean = true): TExpandedPixel;
194 procedure FromExpanded(const AValue: TExpandedPixel; AGammaCompression: boolean = true);
195 end;
196
197 { THSLAPixelBasicHelper }
198
199 THSLAPixelBasicHelper = record helper for THSLAPixel
200 function ToColor: TColor;
201 procedure FromColor(const AValue: TColor);
202 function ToBGRAPixel: TBGRAPixel;
203 procedure FromBGRAPixel(AValue: TBGRAPixel);
204 function ToGSBAPixel: TGSBAPixel;
205 procedure FromGSBAPixel(AValue: TGSBAPixel);
206 function ToExpanded: TExpandedPixel;
207 procedure FromExpanded(AValue: TExpandedPixel);
208 end;
209
210Operator := (const Source: THSLAPixel): TBGRAPixel;
211Operator := (const Source: TBGRAPixel): THSLAPixel;
212Operator := (const Source: THSLAPixel): TExpandedPixel;
213Operator := (const Source: TExpandedPixel): THSLAPixel;
214operator := (const AValue: TColor): THSLAPixel;
215operator := (const AValue: THSLAPixel): TColor;
216
217type
218 { TGSBAPixelBasicHelper }
219
220 TGSBAPixelBasicHelper = record helper for TGSBAPixel
221 function ToColor: TColor;
222 procedure FromColor(const AValue: TColor);
223 function ToBGRAPixel: TBGRAPixel;
224 procedure FromBGRAPixel(AValue: TBGRAPixel);
225 function ToHSLAPixel: THSLAPixel;
226 procedure FromHSLAPixel(AValue: THSLAPixel);
227 function ToExpanded: TExpandedPixel;
228 procedure FromExpanded(AValue: TExpandedPixel);
229 end;
230
231Operator := (const Source: TGSBAPixel): TBGRAPixel;
232Operator := (const Source: TBGRAPixel): TGSBAPixel;
233Operator := (const Source: TGSBAPixel): TExpandedPixel;
234Operator := (const Source: TExpandedPixel): TGSBAPixel;
235operator := (const AValue: TColor): TGSBAPixel;
236operator := (const AValue: TGSBAPixel): TColor;
237Operator := (const Source: TGSBAPixel): THSLAPixel; //no conversion, just copying for backward compatibility (use ToHSLAPixel instead for conversion)
238Operator := (const Source: THSLAPixel): TGSBAPixel; //no conversion, just copying for backward compatibility (use ToGSBAPixel instead for conversion)
239{$ENDIF}
240
241
242{$IFDEF INCLUDE_IMPLEMENTATION}
243{$UNDEF INCLUDE_IMPLEMENTATION}
244{ TBGRAPixel }
245
246function TBGRAPixel.GetClassIntensity: word;
247begin
248 result := GetIntensity(self);
249end;
250
251function TBGRAPixel.GetClassLightness: word;
252begin
253 result := GetLightness(self);
254end;
255
256procedure TBGRAPixel.SetClassIntensity(AValue: word);
257begin
258 self := SetIntensity(self, AValue);
259end;
260
261procedure TBGRAPixel.SetClassLightness(AValue: word);
262begin
263 self := SetLightness(self, AValue);
264end;
265
266procedure TBGRAPixel.FromRGB(ARed, AGreen, ABlue: Byte; AAlpha: Byte);
267begin
268 red := ARed;
269 green := AGreen;
270 blue := ABlue;
271 alpha := AAlpha;
272end;
273
274procedure TBGRAPixel.FromColor(AColor: TColor; AAlpha: Byte);
275begin
276 if AColor = clNone then
277 Self := BGRAPixelTransparent
278 else
279 begin
280 RedGreenBlue(ColorToRGB(AColor), red,green,blue);
281 alpha := AAlpha;
282 end;
283end;
284
285procedure TBGRAPixel.FromString(AStr: string);
286begin
287 Self := StrToBGRA(AStr);
288end;
289
290procedure TBGRAPixel.FromFPColor(AColor: TFPColor);
291begin
292 self := FPColorToBGRA(AColor);
293end;
294
295procedure TBGRAPixel.ToRGB(out ARed, AGreen, ABlue, AAlpha: Byte);
296begin
297 ARed := red;
298 AGreen := green;
299 ABlue := blue;
300 AAlpha := alpha;
301end;
302
303procedure TBGRAPixel.ToRGB(out ARed, AGreen, ABlue: Byte);
304begin
305 ARed := red;
306 AGreen := green;
307 ABlue := blue
308end;
309
310function TBGRAPixel.ToColor: TColor;
311begin
312 if alpha = 0 then
313 result := clNone
314 else
315 result := RGBToColor(red,green,blue);
316end;
317
318function TBGRAPixel.ToString: string;
319begin
320 result := BGRAToStr(Self, CSSColors);
321end;
322
323function TBGRAPixel.ToGrayscale(AGammaCorrection: boolean): TBGRAPixel;
324begin
325 if AGammaCorrection then
326 result := BGRAToGrayscale(self)
327 else
328 result := BGRAToGrayscaleLinear(self);
329end;
330
331function TBGRAPixel.ToFPColor: TFPColor;
332begin
333 result := BGRAToFPColor(Self);
334end;
335
336class operator TBGRAPixel.:=(Source: TBGRAPixel): TColor;
337begin
338 result := Source.ToColor;
339end;
340
341class operator TBGRAPixel.:=(Source: TColor): TBGRAPixel;
342begin
343 result.FromColor(Source);
344end;
345
346{ The gamma correction is approximated here by a power function }
347var
348 GammaExpFactor : single; //exponent
349
350const
351 redWeightShl10 = 306; // = 0.299
352 greenWeightShl10 = 601; // = 0.587
353 blueWeightShl10 = 117; // = 0.114
354
355procedure BGRANoGamma;
356var i: integer;
357begin
358 GammaExpFactor := 1;
359 for i := 0 to 255 do
360 GammaExpansionTab[i] := (i shl 8) + i;
361 for i := 0 to 65535 do
362 GammaCompressionTab[i] := i shr 8;
363end;
364
365procedure BGRASetGamma(AGamma: single);
366var
367 GammaLinearFactor: single;
368 i,j,prevpos,nextpos,midpos: NativeInt;
369begin
370 if AGamma = 1 then
371 begin
372 BGRANoGamma;
373 exit;
374 end;
375 GammaExpFactor := AGamma;
376 //the linear factor is used to normalize expanded values in the range 0..65535
377 GammaLinearFactor := 65535 / power(255, GammaExpFactor);
378 GammaExpansionTab[0] := 0;
379 GammaCompressionTab[0] := 0;
380 nextpos := 0;
381 for i := 0 to 255 do
382 begin
383 prevpos := nextpos;
384 midpos := round(power(i, GammaExpFactor) * GammaLinearFactor);
385 if i = 255 then
386 nextpos := 65536
387 else
388 nextpos := round(power(i+0.5, GammaExpFactor) * GammaLinearFactor);
389 GammaExpansionTab[i] := midpos;
390 for j := prevpos to midpos-1 do
391 begin
392 GammaCompressionTab[j] := i;
393 GammaCompressionTabFrac[j] := -128 + (j-prevpos)*128 div (midpos-prevpos);
394 end;
395 for j := midpos to nextpos-1 do
396 begin
397 GammaCompressionTab[j] := i;
398 GammaCompressionTabFrac[j] := (j-midpos)*128 div (nextpos-midpos);
399 end;
400 end;
401 GammaCompressionTab[0] := 0;
402end;
403
404function BGRAGetGamma: single;
405begin
406 result := GammaExpFactor;
407end;
408
409procedure AllocateExpandedPixelBuffer(var ABuffer: TExpandedPixelBuffer;
410 ASize: integer);
411begin
412 if ASize > length(ABuffer) then
413 setlength(ABuffer, max(length(ABuffer)*2,ASize));
414end;
415
416{ Apply gamma correction using conversion tables }
417function GammaExpansion(c: TBGRAPixel): TExpandedPixel;
418begin
419 Result.red := GammaExpansionTab[c.red];
420 Result.green := GammaExpansionTab[c.green];
421 Result.blue := GammaExpansionTab[c.blue];
422 Result.alpha := c.alpha shl 8 + c.alpha;
423end;
424
425function GammaCompression(const ec: TExpandedPixel): TBGRAPixel;
426begin
427 Result.red := GammaCompressionTab[ec.red];
428 Result.green := GammaCompressionTab[ec.green];
429 Result.blue := GammaCompressionTab[ec.blue];
430 Result.alpha := ec.alpha shr 8;
431end;
432
433function GammaCompression(red, green, blue, alpha: word): TBGRAPixel;
434begin
435 Result.red := GammaCompressionTab[red];
436 Result.green := GammaCompressionTab[green];
437 Result.blue := GammaCompressionTab[blue];
438 Result.alpha := alpha shr 8;
439end;
440
441function GammaExpansionW(ACompressed: word): word;
442var
443 intPart: Integer;
444 f,fracPart: Single;
445begin
446 if ACompressed = 0 then
447 result := 0
448 else if ACompressed = $ffff then
449 result := $ffff
450 else
451 begin
452 f := ACompressed/$101;
453 intPart := trunc(f);
454 fracPart := f - intPart;
455 if fracPart = 0 then
456 result := GammaExpansionTab[intPart]
457 else
458 result := round(GammaExpansionTab[intPart]*(1-fracPart)+GammaExpansionTab[intPart+1]*fracPart);
459 end;
460end;
461
462function GammaCompressionW(AExpanded: word): word;
463begin
464 if AExpanded = 0 then
465 result := 0
466 else if AExpanded = $ffff then
467 result := $ffff
468 else
469 begin
470 result := GammaCompressionTab[AExpanded];
471 result := (result shl 8) + result;
472 result += GammaCompressionTabFrac[AExpanded];
473 end;
474end;
475
476{ The intensity is defined here as the maximum value of any color component }
477function GetIntensity(const c: TExpandedPixel): word; inline;
478begin
479 Result := c.red;
480 if c.green > Result then
481 Result := c.green;
482 if c.blue > Result then
483 Result := c.blue;
484end;
485
486function SetIntensity(const c: TExpandedPixel; intensity: word): TExpandedPixel;
487var
488 curIntensity: word;
489begin
490 curIntensity := GetIntensity(c);
491 if curIntensity = 0 then //suppose it's gray if there is no color information
492 begin
493 Result.red := intensity;
494 Result.green := intensity;
495 Result.blue := intensity;
496 result.alpha := c.alpha;
497 end
498 else
499 begin
500 //linear interpolation to reached wanted intensity
501 Result.red := (c.red * intensity + (curIntensity shr 1)) div curIntensity;
502 Result.green := (c.green * intensity + (curIntensity shr 1)) div curIntensity;
503 Result.blue := (c.blue * intensity + (curIntensity shr 1)) div curIntensity;
504 Result.alpha := c.alpha;
505 end;
506end;
507
508{ The lightness here is defined as the subjective sensation of luminosity, where
509 blue is the darkest component and green the lightest }
510function GetLightness(const c: TExpandedPixel): word; inline;
511begin
512 Result := (c.red * redWeightShl10 + c.green * greenWeightShl10 +
513 c.blue * blueWeightShl10 + 512) shr 10;
514end;
515
516function SetLightness(const c: TExpandedPixel; lightness: word): TExpandedPixel;
517var
518 curLightness: word;
519begin
520 curLightness := GetLightness(c);
521 if lightness = curLightness then
522 begin //no change
523 Result := c;
524 exit;
525 end;
526 result := SetLightness(c, lightness, curLightness);
527end;
528
529function SetLightness(const c: TExpandedPixel; lightness: word; curLightness: word): TExpandedPixel;
530var
531 AddedWhiteness, maxBeforeWhite: word;
532 clip: boolean;
533begin
534 if lightness = curLightness then
535 begin //no change
536 Result := c;
537 exit;
538 end;
539 if lightness = 65535 then //set to white
540 begin
541 Result.red := 65535;
542 Result.green := 65535;
543 Result.blue := 65535;
544 Result.alpha := c.alpha;
545 exit;
546 end;
547 if lightness = 0 then //set to black
548 begin
549 Result.red := 0;
550 Result.green := 0;
551 Result.blue := 0;
552 Result.alpha := c.alpha;
553 exit;
554 end;
555 if curLightness = 0 then //set from black
556 begin
557 Result.red := lightness;
558 Result.green := lightness;
559 Result.blue := lightness;
560 Result.alpha := c.alpha;
561 exit;
562 end;
563 if lightness < curLightness then //darker is easy
564 begin
565 result.alpha:= c.alpha;
566 result.red := (c.red * lightness + (curLightness shr 1)) div curLightness;
567 result.green := (c.green * lightness + (curLightness shr 1)) div curLightness;
568 result.blue := (c.blue * lightness + (curLightness shr 1)) div curLightness;
569 exit;
570 end;
571 //lighter and grayer
572 Result := c;
573 AddedWhiteness := lightness - curLightness;
574 maxBeforeWhite := 65535 - AddedWhiteness;
575 clip := False;
576 if Result.red <= maxBeforeWhite then
577 Inc(Result.red, AddedWhiteness)
578 else
579 begin
580 Result.red := 65535;
581 clip := True;
582 end;
583 if Result.green <= maxBeforeWhite then
584 Inc(Result.green, AddedWhiteness)
585 else
586 begin
587 Result.green := 65535;
588 clip := True;
589 end;
590 if Result.blue <= maxBeforeWhite then
591 Inc(Result.blue, AddedWhiteness)
592 else
593 begin
594 Result.blue := 65535;
595 clip := True;
596 end;
597
598 if clip then //light and whiter
599 begin
600 curLightness := GetLightness(Result);
601 addedWhiteness := lightness - curLightness;
602 maxBeforeWhite := 65535 - curlightness;
603 Result.red := Result.red + addedWhiteness * (65535 - Result.red) div
604 maxBeforeWhite;
605 Result.green := Result.green + addedWhiteness * (65535 - Result.green) div
606 maxBeforeWhite;
607 Result.blue := Result.blue + addedWhiteness * (65535 - Result.blue) div
608 maxBeforeWhite;
609 end;
610end;
611
612function ColorImportance(ec: TExpandedPixel): word;
613var min,max: word;
614begin
615 min := ec.red;
616 max := ec.red;
617 if ec.green > max then
618 max := ec.green
619 else
620 if ec.green < min then
621 min := ec.green;
622 if ec.blue > max then
623 max := ec.blue
624 else
625 if ec.blue < min then
626 min := ec.blue;
627 result := max - min;
628end;
629
630{ Merge two colors of same importance }
631function MergeBGRA(ec1, ec2: TExpandedPixel): TExpandedPixel;
632var c12: cardinal;
633begin
634 if (ec1.alpha = 0) then
635 Result := ec2
636 else
637 if (ec2.alpha = 0) then
638 Result := ec1
639 else
640 begin
641 c12 := ec1.alpha + ec2.alpha;
642 Result.red := (int64(ec1.red) * ec1.alpha + int64(ec2.red) * ec2.alpha + c12 shr 1) div c12;
643 Result.green := (int64(ec1.green) * ec1.alpha + int64(ec2.green) * ec2.alpha + c12 shr 1) div c12;
644 Result.blue := (int64(ec1.blue) * ec1.alpha + int64(ec2.blue) * ec2.alpha + c12 shr 1) div c12;
645 Result.alpha := (c12 + 1) shr 1;
646 end;
647end;
648
649function LessStartSlope65535(value: word): word;
650var factor: word;
651begin
652 factor := 4096 - (not value)*3 shr 7;
653 result := value*factor shr 12;
654end;
655
656function ExpandedDiff(ec1, ec2: TExpandedPixel): word;
657var
658 CompRedAlpha1, CompGreenAlpha1, CompBlueAlpha1, CompRedAlpha2,
659 CompGreenAlpha2, CompBlueAlpha2: integer;
660 DiffAlpha: word;
661 ColorDiff: word;
662 TempHueDiff: word;
663begin
664 CompRedAlpha1 := ec1.red * ec1.alpha shr 16; //gives 0..65535
665 CompGreenAlpha1 := ec1.green * ec1.alpha shr 16;
666 CompBlueAlpha1 := ec1.blue * ec1.alpha shr 16;
667 CompRedAlpha2 := ec2.red * ec2.alpha shr 16;
668 CompGreenAlpha2 := ec2.green * ec2.alpha shr 16;
669 CompBlueAlpha2 := ec2.blue * ec2.alpha shr 16;
670 Result := (Abs(CompRedAlpha2 - CompRedAlpha1)*redWeightShl10 +
671 Abs(CompBlueAlpha2 - CompBlueAlpha1)*blueWeightShl10 +
672 Abs(CompGreenAlpha2 - CompGreenAlpha1)*greenWeightShl10) shr 10;
673 ColorDiff := min(ColorImportance(ec1),ColorImportance(ec2));
674 if ColorDiff > 0 then
675 begin
676 TempHueDiff := HueDiff(HtoG(GetHue(ec1)),HtoG(GetHue(ec2)));
677 if TempHueDiff < 32768 then
678 TempHueDiff := LessStartSlope65535(TempHueDiff shl 1) shr 4
679 else
680 TempHueDiff := TempHueDiff shr 3;
681 Result := ((Result shr 4)* (not ColorDiff) + TempHueDiff*ColorDiff) shr 12;
682 end;
683 DiffAlpha := Abs(integer(ec2.Alpha) - integer(ec1.Alpha));
684 if DiffAlpha > Result then
685 Result := DiffAlpha;
686end;
687
688function ColorF(red, green, blue, alpha: single): TColorF;
689begin
690 result[1] := red;
691 result[2] := green;
692 result[3] := blue;
693 result[4] := alpha;
694end;
695
696function BGRAToColorF(c: TBGRAPixel; AGammaExpansion: boolean): TColorF;
697const OneOver255 = 1/255;
698 OneOver65535 = 1/65535;
699begin
700 if not AGammaExpansion then
701 begin
702 result[1] := c.red*OneOver255;
703 result[2] := c.green*OneOver255;
704 result[3] := c.blue*OneOver255;
705 result[4] := c.alpha*OneOver255;
706 end else
707 with GammaExpansion(c) do
708 begin
709 result[1] := red*OneOver65535;
710 result[2] := green*OneOver65535;
711 result[3] := blue*OneOver65535;
712 result[4] := alpha*OneOver65535;
713 end;
714end;
715
716function BGRAToColorF(const a: array of TBGRAPixel; AGammaExpansion: boolean
717 ): ArrayOfTColorF;
718var
719 i: NativeInt;
720begin
721 setlength(result, length(a));
722 for i := 0 to high(a) do
723 result[i] := BGRAToColorF(a[i],AGammaExpansion);
724end;
725
726function ColorFToBGRA(c: TColorF; AGammaCompression: boolean): TBGRAPixel;
727begin
728 if not AGammaCompression then
729 begin
730 result.red := Min(255,Max(0,round(c[1]*255)));
731 result.green := Min(255,Max(0,round(c[1]*255)));
732 result.blue := Min(255,Max(0,round(c[1]*255)));
733 end else
734 begin
735 result.red := GammaCompressionTab[Min(65535,Max(0,round(c[1]*65535)))];
736 result.green := GammaCompressionTab[Min(65535,Max(0,round(c[1]*65535)))];
737 result.blue := GammaCompressionTab[Min(65535,Max(0,round(c[1]*65535)))];
738 end;
739 result.alpha := Min(255,Max(0,round(c[4]*255)));
740end;
741
742function GammaCompressionF(c: TColorF): TColorF;
743var inv: single;
744begin
745 inv := 1/GammaExpFactor;
746 result := ColorF(power(c[1],inv),power(c[2],inv),power(c[3],inv),c[4]);
747end;
748
749function GammaExpansionF(c: TColorF): TColorF;
750begin
751 result := ColorF(power(c[1],GammaExpFactor),power(c[2],GammaExpFactor),power(c[3],GammaExpFactor),c[4]);
752end;
753
754operator-(const c1, c2: TColorF): TColorF;
755begin
756 result[1] := c1[1]-c2[1];
757 result[2] := c1[2]-c2[2];
758 result[3] := c1[3]-c2[3];
759 result[4] := c1[4]-c2[4];
760end;
761
762operator+(const c1, c2: TColorF): TColorF;
763begin
764 result[1] := c1[1]+c2[1];
765 result[2] := c1[2]+c2[2];
766 result[3] := c1[3]+c2[3];
767 result[4] := c1[4]+c2[4];
768end;
769
770operator*(const c1, c2: TColorF): TColorF;
771begin
772 result[1] := c1[1]*c2[1];
773 result[2] := c1[2]*c2[2];
774 result[3] := c1[3]*c2[3];
775 result[4] := c1[4]*c2[4];
776end;
777
778operator*(const c1: TColorF; factor: single): TColorF;
779begin
780 result[1] := c1[1]*factor;
781 result[2] := c1[2]*factor;
782 result[3] := c1[3]*factor;
783 result[4] := c1[4]*factor;
784end;
785
786{ THSLAPixel }
787
788function HSLA(hue, saturation, lightness, alpha: word): THSLAPixel;
789begin
790 Result.hue := hue;
791 Result.saturation := saturation;
792 Result.lightness := lightness;
793 Result.alpha := alpha;
794end;
795
796function HSLA(hue, saturation, lightness: word): THSLAPixel;
797begin
798 Result.hue := hue;
799 Result.saturation := saturation;
800 Result.lightness := lightness;
801 Result.alpha := $ffff;
802end;
803
804{ Conversion from RGB value to HSL colorspace. See : http://en.wikipedia.org/wiki/HSL_color_space }
805function BGRAToHSLA(c: TBGRAPixel): THSLAPixel;
806begin
807 result := ExpandedToHSLA(GammaExpansion(c));
808end;
809
810procedure ExpandedToHSLAInline(r,g,b: Int32Or64; var dest: THSLAPixel); inline;
811const
812 deg60 = 10922;
813 deg120 = 21845;
814 deg240 = 43690;
815var
816 min, max, minMax: Int32or64;
817 UMinMax,UTwiceLightness: UInt32or64;
818begin
819 if g > r then
820 begin
821 max := g;
822 min := r;
823 end else
824 begin
825 max := r;
826 min := g;
827 end;
828 if b > max then
829 max := b else
830 if b < min then
831 min := b;
832 minMax := max - min;
833
834 if minMax = 0 then
835 dest.hue := 0
836 else
837 if max = r then
838 {$PUSH}{$RANGECHECKS OFF}
839 dest.hue := ((g - b) * deg60) div minMax
840 {$POP}
841 else
842 if max = g then
843 dest.hue := ((b - r) * deg60) div minMax + deg120
844 else
845 {max = b} dest.hue := ((r - g) * deg60) div minMax + deg240;
846 UTwiceLightness := max + min;
847 if min = max then
848 dest.saturation := 0 else
849 begin
850 UMinMax:= minMax;
851 if UTwiceLightness < 65536 then
852 dest.saturation := (UMinMax shl 16) div (UTwiceLightness + 1)
853 else
854 dest.saturation := (UMinMax shl 16) div (131072 - UTwiceLightness);
855 end;
856 dest.lightness := UTwiceLightness shr 1;
857end;
858
859function ExpandedToHSLA(const ec: TExpandedPixel): THSLAPixel;
860begin
861 result.alpha := ec.alpha;
862 ExpandedToHSLAInline(ec.red,ec.green,ec.blue,result);
863end;
864
865{ Conversion from HSL colorspace to RGB. See : http://en.wikipedia.org/wiki/HSL_color_space }
866function HSLAToBGRA(const c: THSLAPixel): TBGRAPixel;
867var ec: TExpandedPixel;
868begin
869 ec := HSLAToExpanded(c);
870 Result := GammaCompression(ec);
871end;
872
873function HSLAToExpanded(const c: THSLAPixel): TExpandedPixel;
874const
875 deg30 = 4096;
876 deg60 = 8192;
877 deg120 = deg60 * 2;
878 deg180 = deg60 * 3;
879 deg240 = deg60 * 4;
880 deg360 = deg60 * 6;
881
882 function ComputeColor(p, q: Int32or64; h: Int32or64): Int32or64; inline;
883 begin
884 if h < deg180 then
885 begin
886 if h < deg60 then
887 Result := p + ((q - p) * h + deg30) div deg60
888 else
889 Result := q
890 end else
891 begin
892 if h < deg240 then
893 Result := p + ((q - p) * (deg240 - h) + deg30) div deg60
894 else
895 Result := p;
896 end;
897 end;
898
899var
900 q, p, L, S, H: Int32or64;
901begin
902 L := c.lightness;
903 S := c.saturation;
904 if S = 0 then //gray
905 begin
906 result.red := L;
907 result.green := L;
908 result.blue := L;
909 result.alpha := c.alpha;
910 exit;
911 end;
912 {$hints off}
913 if L < 32768 then
914 q := (L shr 1) * ((65535 + S) shr 1) shr 14
915 else
916 q := L + S - ((L shr 1) *
917 (S shr 1) shr 14);
918 {$hints on}
919 if q > 65535 then q := 65535;
920 p := (L shl 1) - q;
921 if p > 65535 then p := 65535;
922 H := c.hue * deg360 shr 16;
923 result.green := ComputeColor(p, q, H);
924 inc(H, deg120);
925 if H > deg360 then Dec(H, deg360);
926 result.red := ComputeColor(p, q, H);
927 inc(H, deg120);
928 if H > deg360 then Dec(H, deg360);
929 result.blue := ComputeColor(p, q, H);
930 result.alpha := c.alpha;
931end;
932
933function HueDiff(h1, h2: word): word;
934begin
935 result := abs(integer(h1)-integer(h2));
936 if result > 32768 then result := 65536-result;
937end;
938
939function GetHue(ec: TExpandedPixel): word;
940const
941 deg60 = 8192;
942 deg120 = deg60 * 2;
943 deg240 = deg60 * 4;
944 deg360 = deg60 * 6;
945var
946 min, max, minMax: integer;
947 r,g,b: integer;
948begin
949 r := ec.red;
950 g := ec.green;
951 b := ec.blue;
952 min := r;
953 max := r;
954 if g > max then
955 max := g
956 else
957 if g < min then
958 min := g;
959 if b > max then
960 max := b
961 else
962 if b < min then
963 min := b;
964 minMax := max - min;
965
966 if minMax = 0 then
967 Result := 0
968 else
969 if max = r then
970 Result := (((g - b) * deg60) div
971 minMax + deg360) mod deg360
972 else
973 if max = g then
974 Result := ((b - r) * deg60) div minMax + deg120
975 else
976 {max = b} Result :=
977 ((r - g) * deg60) div minMax + deg240;
978
979 Result := (Result shl 16) div deg360; //normalize
980end;
981
982{ TGSBAPixel }
983
984function BGRAToGSBA(c: TBGRAPixel): TGSBAPixel;
985var lightness: UInt32Or64;
986 red,green,blue: Int32or64;
987 hsla: THSLAPixel;
988begin
989 red := GammaExpansionTab[c.red];
990 green := GammaExpansionTab[c.green];
991 blue := GammaExpansionTab[c.blue];
992 hsla.alpha := c.alpha shl 8 + c.alpha;
993
994 lightness := (red * redWeightShl10 + green * greenWeightShl10 +
995 blue * blueWeightShl10 + 512) shr 10;
996
997 ExpandedToHSLAInline(red,green,blue,hsla);
998 result := TGSBAPixel(hsla);
999
1000 if result.lightness > 32768 then
1001 result.saturation := result.saturation* UInt32or64(not result.lightness) div 32767;
1002 result.lightness := lightness;
1003 result.hue := HtoG(result.hue);
1004end;
1005
1006function ExpandedToGSBA(ec: TExpandedPixel): TGSBAPixel;
1007var lightness: UInt32Or64;
1008 red,green,blue: Int32or64;
1009 hsla: THSLAPixel;
1010begin
1011 red := ec.red;
1012 green := ec.green;
1013 blue := ec.blue;
1014 hsla.alpha := ec.alpha;
1015
1016 lightness := (red * redWeightShl10 + green * greenWeightShl10 +
1017 blue * blueWeightShl10 + 512) shr 10;
1018
1019 ExpandedToHSLAInline(red,green,blue,hsla);
1020 result := TGSBAPixel(hsla);
1021
1022 if result.lightness > 32768 then
1023 result.saturation := result.saturation* UInt32or64(not result.lightness) div 32767;
1024 result.lightness := lightness;
1025 result.hue := HtoG(result.hue);
1026end;
1027
1028function GtoH(ghue: word): word;
1029const
1030 segment: array[0..5] of NativeUInt =
1031 (13653, 10923, 8192, 13653, 10923, 8192);
1032var g: NativeUint;
1033begin
1034 g := ghue;
1035 if g < segment[0] then
1036 result := g * 10923 div segment[0]
1037 else
1038 begin
1039 g -= segment[0];
1040 if g < segment[1] then
1041 result := g * (21845-10923) div segment[1] + 10923
1042 else
1043 begin
1044 g -= segment[1];
1045 if g < segment[2] then
1046 result := g * (32768-21845) div segment[2] + 21845
1047 else
1048 begin
1049 g -= segment[2];
1050 if g < segment[3] then
1051 result := g * (43691-32768) div segment[3] + 32768
1052 else
1053 begin
1054 g -= segment[3];
1055 if g < segment[4] then
1056 result := g * (54613-43691) div segment[4] + 43691
1057 else
1058 begin
1059 g -= segment[4];
1060 result := g * (65536-54613) div segment[5] + 54613;
1061 end;
1062 end;
1063 end;
1064 end;
1065 end;
1066end;
1067
1068function HtoG(hue: word): word;
1069const
1070 segmentDest: array[0..5] of NativeUInt =
1071 (13653, 10923, 8192, 13653, 10923, 8192);
1072 segmentSrc: array[0..5] of NativeUInt =
1073 (10923, 10922, 10923, 10923, 10922, 10923);
1074var
1075 h,g: NativeUInt;
1076begin
1077 h := hue;
1078 if h < segmentSrc[0] then
1079 g := h * segmentDest[0] div segmentSrc[0]
1080 else
1081 begin
1082 g := segmentDest[0];
1083 h -= segmentSrc[0];
1084 if h < segmentSrc[1] then
1085 g += h * segmentDest[1] div segmentSrc[1]
1086 else
1087 begin
1088 g += segmentDest[1];
1089 h -= segmentSrc[1];
1090 if h < segmentSrc[2] then
1091 g += h * segmentDest[2] div segmentSrc[2]
1092 else
1093 begin
1094 g += segmentDest[2];
1095 h -= segmentSrc[2];
1096 if h < segmentSrc[3] then
1097 g += h * segmentDest[3] div segmentSrc[3]
1098 else
1099 begin
1100 g += segmentDest[3];
1101 h -= segmentSrc[3];
1102 if h < segmentSrc[4] then
1103 g += h * segmentDest[4] div segmentSrc[4]
1104 else
1105 begin
1106 g += segmentDest[4];
1107 h -= segmentSrc[4];
1108 g += h * segmentDest[5] div segmentSrc[5];
1109 end;
1110 end;
1111 end;
1112 end;
1113 end;
1114 result := g;
1115end;
1116
1117function GSBAToBGRA(c: TGSBAPixel): TBGRAPixel;
1118var ec: TExpandedPixel;
1119 lightness: word;
1120begin
1121 c.hue := GtoH(c.hue);
1122 lightness := c.lightness;
1123 c.lightness := 32768;
1124 ec := HSLAToExpanded(THSLAPixel(c));
1125 result := GammaCompression(SetLightness(ec, lightness));
1126end;
1127
1128function GSBAToBGRA(const c: THSLAPixel): TBGRAPixel;
1129begin
1130 result := GSBAToBGRA(TGSBAPixel(c));
1131end;
1132
1133function GSBAToExpanded(c: TGSBAPixel): TExpandedPixel;
1134var lightness: word;
1135begin
1136 c.hue := GtoH(c.hue);
1137 lightness := c.lightness;
1138 c.lightness := 32768;
1139 result := SetLightness(HSLAToExpanded(THSLAPixel(c)),lightness);
1140end;
1141
1142function GSBAToExpanded(const c: THSLAPixel): TExpandedPixel;
1143begin
1144 result := GSBAToExpanded(TGSBAPixel(c));
1145end;
1146
1147function GSBAToHSLA(const c: TGSBAPixel): THSLAPixel;
1148begin
1149 result := ExpandedToHSLA(GSBAToExpanded(c));
1150end;
1151
1152function GSBAToHSLA(const c: THSLAPixel): THSLAPixel;
1153begin
1154 result := ExpandedToHSLA(GSBAToExpanded(TGSBAPixel(c)));
1155end;
1156
1157function HSLAToGSBA(const c: THSLAPixel): TGSBAPixel;
1158begin
1159 result := ExpandedToGSBA(HSLAToExpanded(c));
1160end;
1161
1162{ TBGRAPixelBasicHelper }
1163
1164function TBGRAPixelBasicHelper.ToExpanded: TExpandedPixel;
1165begin
1166 result := GammaExpansion(self);
1167end;
1168
1169procedure TBGRAPixelBasicHelper.FromExpanded(const AValue: TExpandedPixel);
1170begin
1171 Self := GammaCompression(AValue);
1172end;
1173
1174function TBGRAPixelBasicHelper.ToHSLAPixel: THSLAPixel;
1175begin
1176 result := BGRAToHSLA(Self);
1177end;
1178
1179procedure TBGRAPixelBasicHelper.FromHSLAPixel(const AValue: THSLAPixel);
1180begin
1181 Self := HSLAToBGRA(AValue);
1182end;
1183
1184function TBGRAPixelBasicHelper.ToGSBAPixel: TGSBAPixel;
1185begin
1186 result := BGRAToGSBA(Self);
1187end;
1188
1189procedure TBGRAPixelBasicHelper.FromGSBAPixel(const AValue: TGSBAPixel);
1190begin
1191 Self := GSBAToBGRA(AValue);
1192end;
1193
1194procedure TBGRAPixelBasicHelper.FromGSBAPixel(const AValue: THSLAPixel);
1195begin
1196 Self := GSBAToBGRA(AValue);
1197end;
1198
1199function TBGRAPixelBasicHelper.ToColorF(AGammaExpansion: boolean): TColorF;
1200begin
1201 result := BGRAToColorF(Self,AGammaExpansion);
1202end;
1203
1204procedure TBGRAPixelBasicHelper.FromColorF(const AValue: TColorF;
1205 AGammaCompression: boolean);
1206begin
1207 Self := ColorFToBGRA(AValue,AGammaCompression);
1208end;
1209
1210{ TExpandedPixelBasicHelper }
1211
1212function TExpandedPixelBasicHelper.ToFPColor(AGammaCompression: boolean): TFPColor;
1213begin
1214 if AGammaCompression then
1215 begin
1216 result.red := GammaCompressionW(self.red);
1217 result.green := GammaCompressionW(self.green);
1218 result.blue := GammaCompressionW(self.blue);
1219 end else
1220 begin
1221 result.red := self.red;
1222 result.green := self.green;
1223 result.blue := self.blue;
1224 end;
1225 result.alpha := self.alpha;
1226end;
1227
1228procedure TExpandedPixelBasicHelper.FromFPColor(const AValue: TFPColor;
1229 AGammaExpansion: boolean);
1230begin
1231 if AGammaExpansion then
1232 begin
1233 self.red := GammaExpansionW(AValue.red);
1234 self.green := GammaExpansionW(AValue.green);
1235 self.blue := GammaExpansionW(AValue.blue);
1236 end else
1237 begin
1238 self.red := AValue.red;
1239 self.green := AValue.green;
1240 self.blue := AValue.blue;
1241 end;
1242 self.alpha := AValue.alpha;
1243end;
1244
1245function TExpandedPixelBasicHelper.ToColor: TColor;
1246begin
1247 result := BGRAToColor(GammaCompression(self));
1248end;
1249
1250procedure TExpandedPixelBasicHelper.FromColor(const AValue: TColor);
1251begin
1252 self := GammaExpansion(ColorToBGRA(AValue));
1253end;
1254
1255function TExpandedPixelBasicHelper.ToBGRAPixel: TBGRAPixel;
1256begin
1257 result := GammaCompression(Self);
1258end;
1259
1260procedure TExpandedPixelBasicHelper.FromBGRAPixel(AValue: TBGRAPixel);
1261begin
1262 Self := GammaExpansion(AValue);
1263end;
1264
1265function TExpandedPixelBasicHelper.ToHSLAPixel: THSLAPixel;
1266begin
1267 result := ExpandedToHSLA(Self);
1268end;
1269
1270procedure TExpandedPixelBasicHelper.FromHSLAPixel(const AValue: THSLAPixel);
1271begin
1272 Self := HSLAToExpanded(AValue);
1273end;
1274
1275function TExpandedPixelBasicHelper.ToGSBAPixel: TGSBAPixel;
1276begin
1277 result := ExpandedToGSBA(Self);
1278end;
1279
1280procedure TExpandedPixelBasicHelper.FromGSBAPixel(const AValue: TGSBAPixel);
1281begin
1282 Self := GSBAToExpanded(AValue);
1283end;
1284
1285procedure TExpandedPixelBasicHelper.FromGSBAPixel(const AValue: THSLAPixel);
1286begin
1287 Self := GSBAToExpanded(AValue);
1288end;
1289
1290operator := (const AValue: TExpandedPixel): TColor;
1291begin Result := BGRAToColor(GammaCompression(AValue)); end;
1292
1293operator := (const AValue: TColor): TExpandedPixel;
1294begin Result := GammaExpansion(ColorToBGRA(ColorToRGB(AValue))) end;
1295
1296operator :=(const Source: TExpandedPixel): TBGRAPixel;
1297begin
1298 result := GammaCompression(Source);
1299end;
1300
1301operator :=(const Source: TBGRAPixel): TExpandedPixel;
1302begin
1303 result := GammaExpansion(Source);
1304end;
1305
1306{ TFPColorBasicHelper }
1307
1308function TFPColorBasicHelper.ToColor: TColor;
1309begin
1310 result := FPColorToTColor(self);
1311end;
1312
1313procedure TFPColorBasicHelper.FromColor(const AValue: TColor);
1314begin
1315 self := TColorToFPColor(AValue);
1316end;
1317
1318function TFPColorBasicHelper.ToBGRAPixel: TBGRAPixel;
1319begin
1320 result := FPColorToBGRA(self);
1321end;
1322
1323procedure TFPColorBasicHelper.FromBGRAPixel(AValue: TBGRAPixel);
1324begin
1325 self := BGRAToFPColor(AValue);
1326end;
1327
1328function TFPColorBasicHelper.ToExpanded(AGammaExpansion: boolean): TExpandedPixel;
1329begin
1330 result.FromFPColor(self, AGammaExpansion);
1331end;
1332
1333procedure TFPColorBasicHelper.FromExpanded(const AValue: TExpandedPixel;
1334 AGammaCompression: boolean);
1335begin
1336 self := AValue.ToFPColor(AGammaCompression);
1337end;
1338
1339{ THSLAPixelBasicHelper }
1340
1341function THSLAPixelBasicHelper.ToColor: TColor;
1342begin
1343 result := BGRAToColor(HSLAToBGRA(self));
1344end;
1345
1346procedure THSLAPixelBasicHelper.FromColor(const AValue: TColor);
1347begin
1348 self := BGRAToHSLA(ColorToBGRA(AValue));
1349end;
1350
1351function THSLAPixelBasicHelper.ToBGRAPixel: TBGRAPixel;
1352begin
1353 result := HSLAToBGRA(self);
1354end;
1355
1356procedure THSLAPixelBasicHelper.FromBGRAPixel(AValue: TBGRAPixel);
1357begin
1358 self := BGRAToHSLA(AValue);
1359end;
1360
1361function THSLAPixelBasicHelper.ToGSBAPixel: TGSBAPixel;
1362begin
1363 result := HSLAToGSBA(self);
1364end;
1365
1366procedure THSLAPixelBasicHelper.FromGSBAPixel(AValue: TGSBAPixel);
1367begin
1368 self := GSBAToHSLA(AValue);
1369end;
1370
1371function THSLAPixelBasicHelper.ToExpanded: TExpandedPixel;
1372begin
1373 result := HSLAToExpanded(Self);
1374end;
1375
1376procedure THSLAPixelBasicHelper.FromExpanded(AValue: TExpandedPixel);
1377begin
1378 Self := ExpandedToHSLA(AValue);
1379end;
1380
1381operator :=(const Source: THSLAPixel): TBGRAPixel;
1382begin
1383 result := HSLAToBGRA(Source);
1384end;
1385
1386operator :=(const Source: TBGRAPixel): THSLAPixel;
1387begin
1388 result := BGRAToHSLA(Source);
1389end;
1390
1391operator :=(const Source: THSLAPixel): TExpandedPixel;
1392begin
1393 result := HSLAToExpanded(Source);
1394end;
1395
1396operator:=(const Source: TExpandedPixel): THSLAPixel;
1397begin
1398 result := ExpandedToHSLA(Source);
1399end;
1400
1401operator := (const AValue: TColor): THSLAPixel;
1402begin Result := BGRAToHSLA(ColorToBGRA(ColorToRGB(AValue))) end;
1403
1404operator := (const AValue: THSLAPixel): TColor;
1405begin Result := BGRAToColor(HSLAToBGRA(AValue)) end;
1406
1407{ TGSBAPixelBasicHelper }
1408
1409function TGSBAPixelBasicHelper.ToColor: TColor;
1410begin
1411 result := BGRAToColor(GSBAToBGRA(self));
1412end;
1413
1414procedure TGSBAPixelBasicHelper.FromColor(const AValue: TColor);
1415begin
1416 self := BGRAToGSBA(ColorToBGRA(AValue));
1417end;
1418
1419function TGSBAPixelBasicHelper.ToBGRAPixel: TBGRAPixel;
1420begin
1421 result := GSBAToBGRA(self);
1422end;
1423
1424procedure TGSBAPixelBasicHelper.FromBGRAPixel(AValue: TBGRAPixel);
1425begin
1426 self := BGRAToGSBA(AValue);
1427end;
1428
1429function TGSBAPixelBasicHelper.ToHSLAPixel: THSLAPixel;
1430begin
1431 result := GSBAToHSLA(self);
1432end;
1433
1434procedure TGSBAPixelBasicHelper.FromHSLAPixel(AValue: THSLAPixel);
1435begin
1436 self := HSLAToGSBA(AValue);
1437end;
1438
1439function TGSBAPixelBasicHelper.ToExpanded: TExpandedPixel;
1440begin
1441 result := GSBAToExpanded(self);
1442end;
1443
1444procedure TGSBAPixelBasicHelper.FromExpanded(AValue: TExpandedPixel);
1445begin
1446 self := ExpandedToGSBA(AValue);
1447end;
1448
1449operator :=(const Source: TGSBAPixel): TBGRAPixel;
1450begin
1451 result := GSBAToBGRA(Source);
1452end;
1453
1454operator :=(const Source: TBGRAPixel): TGSBAPixel;
1455begin
1456 result := BGRAToGSBA(Source);
1457end;
1458
1459operator :=(const Source: TGSBAPixel): TExpandedPixel;
1460begin
1461 result := GSBAToExpanded(Source);
1462end;
1463
1464operator:=(const Source: TExpandedPixel): TGSBAPixel;
1465begin
1466 result := ExpandedToGSBA(Source);
1467end;
1468
1469operator := (const AValue: TColor): TGSBAPixel;
1470begin Result := BGRAToGSBA(ColorToBGRA(ColorToRGB(AValue))) end;
1471
1472operator := (const AValue: TGSBAPixel): TColor;
1473begin Result := BGRAToColor(GSBAToBGRA(AValue)) end;
1474
1475operator :=(const Source: TGSBAPixel): THSLAPixel;
1476begin
1477 result := THSLAPixel(Pointer(@Source)^);
1478end;
1479
1480operator:=(const Source: THSLAPixel): TGSBAPixel;
1481begin
1482 result := TGSBAPixel(Pointer(@Source)^);
1483end;
1484{$ENDIF}
Note: See TracBrowser for help on using the repository browser.