📄 graphiccolor.pas
字号:
TargetRunA16.B := Convert16_16(SourceB16^);
TargetRunA16.A := Convert16_16(SourceA16^);
Inc(SourceB16, SourceIncrement);
Inc(SourceG16, SourceIncrement);
Inc(SourceR16, SourceIncrement);
Inc(SourceA16, SourceIncrement);
end;
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
Inc(TargetRunA16);
end;
end
else
begin
TargetRun16 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
TargetRun16.R := Convert16_16(SourceR16^);
TargetRun16.G := Convert16_16(SourceG16^);
TargetRun16.B := Convert16_16(SourceB16^);
Inc(SourceB16, SourceIncrement);
Inc(SourceG16, SourceIncrement);
Inc(SourceR16, SourceIncrement);
end;
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
Inc(PWord(TargetRun16), TargetIncrement);
end;
end;
end;
end;
end;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TColorManager.RowConvertCIELAB2BGR(Source: array of Pointer; Target: Pointer; Count: Cardinal; Mask: Byte);
// conversion of the CIE L*a*b color space to BGR using a two way approach assuming a D65 white point,
// first a conversion to CIE XYZ is performed and then from there to RGB
var
LRun8,
aRun8,
bRun8: PByte;
LRun16,
aRun16,
bRun16: PWord;
L, a, b,
X, Y, Z, // color values in float format
T,
YYn3: Extended; // intermediate results
Target8: PByte;
Target16: PWord;
Increment: Integer;
AlphaSkip: Integer;
BitRun: Byte;
begin
BitRun := $80;
AlphaSkip := Ord(coAlpha in FTargetOptions); // 0 if no alpha must be skipped, otherwise 1
case FSourceBPS of
8:
begin
if Length(Source) = 1 then
begin
LRun8 := Source[0];
aRun8 := LRun8; Inc(aRun8);
bRun8 := aRun8; Inc(bRun8);
Increment := 3;
end
else
begin
LRun8 := Source[0];
aRun8 := Source[1];
bRun8 := Source[2];
Increment := 1;
end;
case FTargetBPS of
8: /// 888 to 888
begin
Target8 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
if coLabByteRange in FSourceOptions then L := LRun8^ / 2.55
else L := LRun8^;
Inc(LRun8, Increment);
if coLabChromaOffset in FSourceOptions then
begin
a := aRun8^ - 128;
Inc(aRun8, Increment);
b := bRun8^ - 128;
Inc(bRun8, Increment);
end
else
begin
a := ShortInt(aRun8^);
Inc(aRun8, Increment);
b := ShortInt(bRun8^);
Inc(bRun8, Increment);
end;
YYn3 := (L + 16) / 116; // this corresponds to (Y/Yn)^1/3
if L < 7.9996 then
begin
Y := L / 903.3;
X := a / 3893.5 + Y;
Z := Y - b / 1557.4;
end
else
begin
T := YYn3 + a / 500;
X := T * T * T;
Y := YYn3 * YYn3 * YYn3;
T := YYn3 - b / 200;
Z := T * T * T;
end;
// once we have CIE XYZ it is easy (yet quite expensive) to calculate RGB values from this
// blue
Target8^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * Z)));
Inc(Target8);
// green
Target8^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target8);
// red
Target8^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target8, 1 + AlphaSkip);
end
else Inc(Target8, 3 + AlphaSkip);
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
end;
end;
16: // 888 to 161616
begin
Target16 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
if coLabByteRange in FSourceOptions then L := LRun8^ / 2.55
else L := LRun8^;
Inc(LRun8, Increment);
if coLabChromaOffset in FSourceOptions then
begin
a := aRun8^ - 128;
Inc(aRun8, Increment);
b := bRun8^ - 128;
Inc(bRun8, Increment);
end
else
begin
a := ShortInt(aRun8^);
Inc(aRun8, Increment);
b := ShortInt(bRun8^);
Inc(bRun8, Increment);
end;
YYn3 := (L + 16) / 116; // this corresponds to (Y/Yn)^1/3
if L < 7.9996 then
begin
Y := L / 903.3;
X := a / 3893.5 + Y;
Z := Y - b / 1557.4;
end
else
begin
T := YYn3 + a / 500;
X := T * T * T;
Y := YYn3 * YYn3 * YYn3;
T := YYn3 - b / 200;
Z := T * T * T;
end;
// blue
Target16^ := MulDiv16(ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * Z))), 65535, 255);
Inc(Target16);
// green
Target16^ := MulDiv16(ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z))), 65535, 255);
Inc(Target16);
// red
Target16^ := MulDiv16(ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z))), 65535, 255);
Inc(Target16, 1 + AlphaSkip);
end
else Inc(Target16, 3 + AlphaSkip);
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
end
end;
end;
end;
16:
begin
if Length(Source) = 1 then
begin
LRun16 := Source[0];
aRun16 := LRun16; Inc(aRun16);
bRun16 := aRun16; Inc(bRun16);
Increment := 3;
end
else
begin
LRun16 := Source[0];
aRun16 := Source[1];
bRun16 := Source[2];
Increment := 1;
end;
case FTargetBPS of
8: // 161616 to 888
begin
Target8 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
if coLabByteRange in FSourceOptions then L := LRun16^ / 2.55
else L := LRun16^;
Inc(LRun16, Increment);
if coLabChromaOffset in FSourceOptions then
begin
a := aRun16^ - 128;
Inc(aRun16, Increment);
b := bRun16^ - 128;
Inc(bRun16, Increment);
end
else
begin
a := ShortInt(aRun16^);
Inc(aRun16, Increment);
b := ShortInt(bRun16^);
Inc(bRun16, Increment);
end;
YYn3 := (L + 16) / 116; // this corresponds to (Y/Yn)^1/3
if L < 7.9996 then
begin
Y := L / 903.3;
X := a / 3893.5 + Y;
Z := Y - b / 1557.4;
end
else
begin
T := YYn3 + a / 500;
X := T * T * T;
Y := YYn3 * YYn3 * YYn3;
T := YYn3 - b / 200;
Z := T * T * T;
end;
// blue
Target8^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * Z)));
Inc(Target8);
// green
Target8^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target8);
// red
Target8^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target8, 1 + AlphaSkip);
end
else Inc(Target8, 3 + AlphaSkip);
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
end;
end;
16: // 161616 to 161616
begin
Target16 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
if coLabByteRange in FSourceOptions then L := LRun16^ / 2.55
else L := LRun16^;
Inc(LRun16, Increment);
if coLabChromaOffset in FSourceOptions then
begin
a := aRun16^ - 128;
Inc(aRun16, Increment);
b := bRun16^ - 128;
Inc(bRun16, Increment);
end
else
begin
a := ShortInt(aRun16^);
Inc(aRun16, Increment);
b := ShortInt(bRun16^);
Inc(bRun16, Increment);
end;
YYn3 := (L + 16) / 116; // this corresponds to (Y/Yn)^1/3
if L < 7.9996 then
begin
Y := L / 903.3;
X := a / 3893.5 + Y;
Z := Y - b / 1557.4;
end
else
begin
T := YYn3 + a / 500;
X := T * T * T;
Y := YYn3 * YYn3 * YYn3;
T := YYn3 - b / 200;
Z := T * T * T;
end;
// blue
Target16^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * Z)));
Inc(Target16);
// green
Target16^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target16);
// red
Target16^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target16, 1 + AlphaSkip);
end
else Inc(Target16, 3 + AlphaSkip);
asm ROR BYTE PTR [BitRun], 1 end;
Dec(Count);
end;
end;
end;
end;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TColorManager.RowConvertCIELAB2RGB(Source: array of Pointer; Target: Pointer; Count: Cardinal; Mask: Byte);
// just like RowConvertCIELAB2BGR but for RGB target schemes
var
LRun8,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -