📄 graphiccolor.pas
字号:
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
// red
Target8^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target8);
// green
Target8^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target8);
// blue
Target8^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * 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;
// red
Target16^ := MulDiv16(ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z))), 65535, 255);
Inc(Target16);
// green
Target16^ := MulDiv16(ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z))), 65535, 255);
Inc(Target16);
// blue
Target16^ := MulDiv16(ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * 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;
// red
Target8^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target8);
// green
Target8^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target8);
// blue
Target8^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * 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;
// red
Target16^ := ClampByte(Round(255 * ( 2.998 * X - 1.458 * Y - 0.541 * Z)));
Inc(Target16);
// green
Target16^ := ClampByte(Round(255 * (-0.952 * X + 1.893 * Y + 0.059 * Z)));
Inc(Target16);
// blue
Target16^ := ClampByte(Round(255 * ( 0.099 * X - 0.198 * Y + 1.099 * 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.RowConvertCMYK2BGR(Source: array of Pointer; Target: Pointer; Count: Cardinal; Mask: Byte);
// converts a stream of Count CMYK values to BGR
var
C8, M8, Y8, K8: PByte;
C16, M16, Y16, K16: PWord;
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) = 4 then
begin
// plane mode
C8 := Source[0];
M8 := Source[1];
Y8 := Source[2];
K8 := Source[3];
Increment := 1;
end
else
begin
// interleaved mode
C8 := Source[0];
M8 := C8; Inc(M8);
Y8 := M8; Inc(Y8);
K8 := Y8; Inc(K8);
Increment := 4;
end;
case FTargetBPS of
8: // 888 to 888
begin
Target8 := Target;
while Count > 0 do
begin
if Boolean(Mask and BitRun) then
begin
// blue
Target8^ := ClampByte(255 - (Y8^ - MulDiv16(Y8^, K8^, 255) + K8^));
Inc(Target8);
// green
Target8^ := ClampByte(255 - (M8^ - MulDiv16(M8^, K8^, 255) + K8^));
Inc(Target8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -