source: trunk/Packages/Graphics32/GR32_Gamma.pas

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 5.4 KB
Line 
1unit GR32_Gamma;
2
3interface
4
5uses
6 GR32;
7
8{ Gamma bias for line/pixel antialiasing }
9
10type
11 TGammaTable8Bit = array [Byte] of Byte;
12
13var
14 GAMMA_VALUE: Double;
15 GAMMA_ENCODING_TABLE: TGammaTable8Bit;
16 GAMMA_DECODING_TABLE: TGammaTable8Bit;
17
18const
19 DEFAULT_GAMMA: Double = 2.2;
20
21// set gamma
22procedure SetGamma; overload; {$IFDEF USEINLINING} inline; {$ENDIF}
23procedure SetGamma(Gamma: Double); overload; {$IFDEF USEINLINING} inline; {$ENDIF}
24procedure SetGamma(Gamma: Double; var GammaTable: TGammaTable8Bit); overload;
25
26procedure Set_sRGB; overload;
27procedure Set_sRGB(var GammaTable: TGammaTable8Bit); overload;
28procedure SetInv_sRGB(var GammaTable: TGammaTable8Bit);
29
30// apply gamma
31function ApplyGamma(Color: TColor32): TColor32; overload; {$IFDEF USEINLINING} inline; {$ENDIF}
32function ApplyInvGamma(Color: TColor32): TColor32; overload; {$IFDEF USEINLINING} inline; {$ENDIF}
33function ApplyCustomGamma(Color: TColor32; GammaTable: TGammaTable8Bit): TColor32; overload; {$IFDEF USEINLINING} inline; {$ENDIF}
34
35procedure ApplyGamma(Color: PColor32Array; Length: Integer); overload;
36procedure ApplyInvGamma(Color: PColor32Array; Length: Integer); overload;
37procedure ApplyCustomGamma(Color: PColor32Array; Length: Integer; GammaTable: TGammaTable8Bit); overload;
38
39procedure ApplyGamma(Bitmap: TBitmap32); overload;
40procedure ApplyInvGamma(Bitmap: TBitmap32); overload;
41procedure ApplyCustomGamma(Bitmap: TBitmap32; GammaTable: TGammaTable8Bit); overload;
42procedure ApplyCustomGamma(Bitmap: TBitmap32; Gamma: Double); overload;
43
44implementation
45
46uses
47 Math;
48
49function ApplyGamma(Color: TColor32): TColor32;
50var
51 C: TColor32Entry absolute Color;
52 R: TColor32Entry absolute Result;
53begin
54 C.R := GAMMA_ENCODING_TABLE[C.R];
55 C.G := GAMMA_ENCODING_TABLE[C.G];
56 C.B := GAMMA_ENCODING_TABLE[C.B];
57end;
58
59function ApplyInvGamma(Color: TColor32): TColor32;
60var
61 C: TColor32Entry absolute Color;
62 R: TColor32Entry absolute Result;
63begin
64 C.R := GAMMA_DECODING_TABLE[C.R];
65 C.G := GAMMA_DECODING_TABLE[C.G];
66 C.B := GAMMA_DECODING_TABLE[C.B];
67end;
68
69function ApplyCustomGamma(Color: TColor32; GammaTable: TGammaTable8Bit): TColor32;
70var
71 C: TColor32Entry absolute Color;
72 R: TColor32Entry absolute Result;
73begin
74 C.R := GammaTable[C.R];
75 C.G := GammaTable[C.G];
76 C.B := GammaTable[C.B];
77end;
78
79
80procedure ApplyGamma(Color: PColor32Array; Length: Integer);
81var
82 Index: Integer;
83begin
84 for Index := 0 to Length - 1 do
85 begin
86 PColor32Entry(Color)^.R := GAMMA_ENCODING_TABLE[PColor32Entry(Color)^.R];
87 PColor32Entry(Color)^.G := GAMMA_ENCODING_TABLE[PColor32Entry(Color)^.G];
88 PColor32Entry(Color)^.B := GAMMA_ENCODING_TABLE[PColor32Entry(Color)^.B];
89 Inc(Color);
90 end;
91end;
92
93procedure ApplyInvGamma(Color: PColor32Array; Length: Integer);
94var
95 Index: Integer;
96begin
97 for Index := 0 to Length - 1 do
98 begin
99 PColor32Entry(Color)^.R := GAMMA_DECODING_TABLE[PColor32Entry(Color)^.R];
100 PColor32Entry(Color)^.G := GAMMA_DECODING_TABLE[PColor32Entry(Color)^.G];
101 PColor32Entry(Color)^.B := GAMMA_DECODING_TABLE[PColor32Entry(Color)^.B];
102 Inc(Color);
103 end;
104end;
105
106procedure ApplyCustomGamma(Color: PColor32Array; Length: Integer;
107 GammaTable: TGammaTable8Bit);
108var
109 Index: Integer;
110begin
111 for Index := 0 to Length - 1 do
112 begin
113 PColor32Entry(Color)^.R := GammaTable[PColor32Entry(Color)^.R];
114 PColor32Entry(Color)^.G := GammaTable[PColor32Entry(Color)^.G];
115 PColor32Entry(Color)^.B := GammaTable[PColor32Entry(Color)^.B];
116 Inc(Color);
117 end;
118end;
119
120
121procedure ApplyGamma(Bitmap: TBitmap32);
122begin
123 ApplyGamma(Bitmap.Bits, Bitmap.Width * Bitmap.Height);
124end;
125
126procedure ApplyInvGamma(Bitmap: TBitmap32);
127begin
128 ApplyInvGamma(Bitmap.Bits, Bitmap.Width * Bitmap.Height);
129end;
130
131procedure ApplyCustomGamma(Bitmap: TBitmap32; GammaTable: TGammaTable8Bit);
132begin
133 ApplyCustomGamma(Bitmap.Bits, Bitmap.Width * Bitmap.Height, GammaTable);
134end;
135
136procedure ApplyCustomGamma(Bitmap: TBitmap32; Gamma: Double);
137var
138 GammaTable: TGammaTable8Bit;
139begin
140 if GAMMA_VALUE = Gamma then
141 ApplyGamma(Bitmap.Bits, Bitmap.Width * Bitmap.Height)
142 else
143 begin
144 SetGamma(Gamma, GammaTable);
145 ApplyCustomGamma(Bitmap.Bits, Bitmap.Width * Bitmap.Height, GammaTable);
146 end;
147end;
148
149
150{ Gamma / Pixel Shape Correction table }
151
152procedure SetGamma;
153begin
154 SetGamma(DEFAULT_GAMMA);
155end;
156
157procedure SetGamma(Gamma: Double);
158begin
159 GAMMA_VALUE := Gamma;
160
161 // calculate default gamma tables
162 SetGamma(1 / Gamma, GAMMA_ENCODING_TABLE);
163 SetGamma(Gamma, GAMMA_DECODING_TABLE);
164end;
165
166procedure SetGamma(Gamma: Double; var GammaTable: TGammaTable8Bit);
167var
168 i: Integer;
169begin
170 for i := 0 to $FF do
171 GammaTable[i] := Round($FF * Power(i * COne255th, Gamma));
172end;
173
174procedure Set_sRGB;
175begin
176 Set_sRGB(GAMMA_ENCODING_TABLE);
177 SetInv_sRGB(GAMMA_DECODING_TABLE);
178end;
179
180procedure Set_sRGB(var GammaTable: TGammaTable8Bit);
181var
182 i: Integer;
183 Value: Double;
184const
185 CExp = 1 / 2.4;
186begin
187 for i := 0 to $FF do
188 begin
189 Value := i * COne255th;
190 if (Value < 0.0031308) then
191 GammaTable[i] := Round($FF * Value * 12.92)
192 else
193 GammaTable[i] := Round($FF * (1.055 * Power(Value, CExp) - 0.055));
194 end;
195end;
196
197procedure SetInv_sRGB(var GammaTable: TGammaTable8Bit);
198var
199 i: Integer;
200 Value: Double;
201begin
202 for i := 0 to $FF do
203 begin
204 Value := i * COne255th;
205 if (Value < 0.004045) then
206 GammaTable[i] := Round($FF * Value / 12.92)
207 else
208 GammaTable[i] := Round($FF * Power((Value + 0.055) / 1.055, 2.4));
209 end;
210end;
211
212end.
Note: See TracBrowser for help on using the repository browser.