2016-12-08 23:14:26 +00:00
unit PalUtils;
interface
uses
LCLType, LCLIntf, SysUtils, Classes, Graphics,
RGBHSVUtils, RGBHSLUtils, RGBCIEUtils, RGBCMYKUtils,
HTMLColors;
const
clCustom = $2FFFFFFF ;
clTransparent = $3FFFFFFF ;
type
TSortOrder = ( soAscending, soDescending) ;
TSortMode = ( smRed, smGreen, smBlue, smHue, smSaturation, smLuminance, smValue, smNone, smCyan, smMagenta, smYellow, smBlacK, smCIEx, smCIEy, smCIEz, smCIEl, smCIEa, smCIEb) ;
AcoColors = record
Colors: array of TColor;
Names: array of WideString ;
HasNames: boolean ;
end ;
//replaces passed strings with passed value
function ReplaceFlags( s: string ; flags: array of string ; value: integer ) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//replaces the appropriate tags with values in a hint format string
function FormatHint( fmt: string ; c: TColor) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//converts a string value to TColor including clCustom and clTransparent
function mbStringToColor( s: string ) : TColor;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//converts a TColor to a string value including clCustom and clTransparent
function mbColorToString( c: TColor) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//blends two colors together in proportion C1 : C2 = W1 : 100 - W1, where 0 <= W1 <= 100
function Blend( C1, C2: TColor; W1: Integer ) : TColor;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//generates a white-color-black or a black-color-white gradient palette
function MakePalette( BaseColor: TColor; SortOrder: TSortOrder) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//generates a gradient palette from the given colors
function MakeGradientPalette( Colors: array of TColor) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//sorts colors in a string list
procedure SortPalColors( Colors: TStrings; SortMode: TSortMode; SortOrder: TSortOrder) ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//reads JASC .pal file
function ReadJASCPal( PalFile: TFileName) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//saves a string list to a JASC .pal file
procedure SaveJASCPal( pal: TStrings; FileName: TFileName) ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//reads Photoshop .aco file into an Aco record
function ReadPhotoshopAco( PalFile: TFileName) : AcoColors;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
//reads Photoshop .act file
function ReadPhotoshopAct( PalFile: TFileName) : string ;
2016-12-15 11:27:12 +00:00
2016-12-08 23:14:26 +00:00
implementation
function ReplaceFlags( s: string ; flags: array of string ; value: integer ) : string ;
var
i, p: integer ;
v: string ;
begin
Result : = s;
v : = IntToStr( value) ;
for i : = 0 to Length( flags) - 1 do
begin
p : = Pos( flags[ i] , Result ) ;
if p > 0 then
begin
Delete( Result , p, Length( flags[ i] ) ) ;
Insert( v, Result , p) ;
end ;
end ;
end ;
function AnsiReplaceText( const AText, AFromText, AToText: string ) : string ;
begin
Result : = StringReplace( AText, AFromText, AToText, [ rfReplaceAll, rfIgnoreCase] ) ;
end ;
function FormatHint( fmt: string ; c: TColor) : string ;
var
2016-12-15 11:27:12 +00:00
h: string ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
h : = AnsiReplaceText( fmt, '%hex' , ColorToHex( c) ) ;
h : = AnsiReplaceText( h, '%cieL' , IntToStr( Round( GetCIElValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieA' , IntToStr( Round( GetCIEaValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieB' , IntToStr( Round( GetCIEbValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieX' , IntToStr( Round( GetCIExValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieY' , IntToStr( Round( GetCIEyValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieZ' , IntToStr( Round( GetCIEzValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieC' , IntToStr( Round( GetCIEcValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%cieH' , IntToStr( Round( GetCIEhValue( c) ) ) ) ;
h : = AnsiReplaceText( h, '%hslH' , IntToStr( RGBHSLUtils. GetHValue( c) ) ) ;
h : = AnsiReplaceText( h, '%hslS' , IntToStr( RGBHSLUtils. GetSValue( c) ) ) ;
h : = AnsiReplaceText( h, '%hslL' , IntToStr( RGBHSLUtils. GetLValue( c) ) ) ;
h : = AnsiReplaceText( h, '%hsvH' , IntToStr( RGBHSVUtils. GetHValue( c) ) ) ;
h : = AnsiReplaceText( h, '%hsvS' , IntToStr( RGBHSVUtils. GetSValue( c) ) ) ;
h : = AnsiReplaceText( h, '%hsvV' , IntToStr( RGBHSVUtils. GetVValue( c) ) ) ;
h : = AnsiReplaceText( h, '%r' , IntToStr( GetRValue( c) ) ) ;
h : = AnsiReplaceText( h, '%g' , IntToStr( GetGValue( c) ) ) ;
h : = AnsiReplaceText( h, '%b' , IntToStr( GetBValue( c) ) ) ;
h : = AnsiReplaceText( h, '%c' , IntToStr( GetCValue( c) ) ) ;
h : = AnsiReplaceText( h, '%m' , IntToStr( GetMValue( c) ) ) ;
h : = AnsiReplaceText( h, '%y' , IntToStr( GetYValue( c) ) ) ;
h : = AnsiReplaceText( h, '%k' , IntToStr( GetKValue( c) ) ) ;
h : = AnsiReplaceText( h, '%h' , IntToStr( RGBHSLUtils. GetHValue( c) ) ) ;
h : = AnsiReplaceText( h, '%s' , IntToStr( RGBHSLUtils. GetSValue( c) ) ) ;
h : = AnsiReplaceText( h, '%l' , IntToStr( RGBHSLUtils. GetLValue( c) ) ) ;
h : = AnsiReplaceText( h, '%v' , IntToStr( RGBHSVUtils. GetVValue( c) ) ) ;
Result : = h;
2016-12-08 23:14:26 +00:00
end ;
function mbStringToColor( s: string ) : TColor;
begin
2016-12-15 11:27:12 +00:00
//remove spaces
s : = AnsiReplaceText( s, ' ' , '' ) ;
if SameText( s, 'clCustom' ) then
Result : = clCustom
else
2016-12-08 23:14:26 +00:00
if SameText( s, 'clTransparent' ) then
2016-12-15 11:27:12 +00:00
Result : = clTransparent
2016-12-08 23:14:26 +00:00
else
2016-12-15 11:27:12 +00:00
Result : = StringToColor( s) ;
2016-12-08 23:14:26 +00:00
end ;
function mbColorToString( c: TColor) : string ;
begin
2016-12-15 11:27:12 +00:00
if c = clCustom then
Result : = 'clCustom'
else
2016-12-08 23:14:26 +00:00
if c = clTransparent then
2016-12-15 11:27:12 +00:00
Result : = 'clTransparent'
2016-12-08 23:14:26 +00:00
else
2016-12-15 11:27:12 +00:00
Result : = ColorToString( c) ;
2016-12-08 23:14:26 +00:00
end ;
//taken from TBXUtils, TBX Package � Alex Denisov (www.g32.org)
function Blend( C1, C2: TColor; W1: Integer ) : TColor;
var
W2, A1, A2, D, F, G: Integer ;
begin
if C1 < 0 then C1 : = GetSysColor( C1 and $FF ) ;
if C2 < 0 then C2 : = GetSysColor( C2 and $FF ) ;
if W1 > = 1 0 0 then D : = 1 0 0 0
else D : = 1 0 0 ;
W2 : = D - W1;
F : = D div 2 ;
A2 : = C2 shr 1 6 * W2;
A1 : = C1 shr 1 6 * W1;
G : = ( A1 + A2 + F) div D and $FF ;
Result : = G shl 1 6 ;
A2 : = ( C2 shr 8 and $FF ) * W2;
A1 : = ( C1 shr 8 and $FF ) * W1;
G : = ( A1 + A2 + F) div D and $FF ;
Result : = Result or G shl 8 ;
A2 : = ( C2 and $FF ) * W2;
A1 : = ( C1 and $FF ) * W1;
G : = ( A1 + A2 + F) div D and $FF ;
Result : = Result or G;
end ;
function IsMember( sl: TStrings; s: string ) : boolean ;
var
2016-12-15 11:27:12 +00:00
i: integer ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
for i : = 0 to sl. count - 1 do
if sl. Strings[ i] = s then
begin
Result : = true ;
exit;
end ;
Result : = false ;
2016-12-08 23:14:26 +00:00
end ;
function MakePalette( BaseColor: TColor; SortOrder: TSortOrder) : string ;
var
2016-12-15 11:27:12 +00:00
i: integer ;
s: TStrings;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
Result : = '' ;
s : = TStringList. Create;
try
case SortOrder of
soAscending:
for i : = 2 3 9 downto 0 do
s. Add( ColorToString( HSLRangeToRGB( GetHValue( BaseColor) , GetSValue( BaseColor) , 2 4 0 - i) ) ) ;
soDescending:
for i : = 0 to 2 3 9 do
s. Add( ColorToString( HSLRangeToRGB( GetHValue( BaseColor) , GetSValue( BaseColor) , 2 4 0 - i) ) ) ;
end ;
Result : = s. Text ;
finally
s. Free;
2016-12-08 23:14:26 +00:00
end ;
end ;
function MakeGradientPalette( Colors: array of TColor) : string ;
type
RGBArray = array [ 0 .. 2 ] of Byte ;
var
i, j, k, Span: Integer ;
s: TStringList;
Scolor: string ;
Faktor: double ;
a: RGBArray;
b: array of RGBArray;
begin
2016-12-15 11:27:12 +00:00
Result : = '' ;
Span : = 3 0 0 ;
s : = TStringList. Create;
try
SetLength( b, High( Colors) + 1 ) ;
for i : = 0 to High( Colors) do
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
Colors[ i] : = ColorToRGB( Colors[ i] ) ;
b[ i, 0 ] : = GetRValue( Colors[ i] ) ;
b[ i, 1 ] : = GetGValue( Colors[ i] ) ;
b[ i, 2 ] : = GetBValue( Colors[ i] ) ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
for i : = 0 to High( Colors) - 1 do
for j : = 0 to Span do
begin
Faktor : = j / Span;
for k : = 0 to 3 do
a[ k] : = Trunc( b[ i, k] + ( ( b[ i + 1 , k] - b[ i, k] ) * Faktor) ) ;
Scolor : = ColorToString( RGB( a[ 0 ] , a[ 1 ] , a[ 2 ] ) ) ;
if not IsMember( s, Scolor) then
s. add( Scolor) ;
end ;
Result : = s. Text ;
finally
s. Free;
end ;
2016-12-08 23:14:26 +00:00
end ;
procedure SortPalColors( Colors: TStrings; SortMode: TSortMode; SortOrder: TSortOrder) ;
2016-12-15 11:27:12 +00:00
function MaxPos( s: TStrings; sm: TSortMode) : integer ;
var
i: integer ;
first: TColor;
begin
Result : = 0 ;
first : = clBlack;
for i : = 0 to s. Count - 1 do
case sm of
smRed:
if GetRValue( first) < GetRValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smGreen:
if GetGValue( first) < GetGValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smBlue:
if GetBValue( first) < GetBValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smHue:
if GetHValue( first) < GetHValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smSaturation:
if GetSValue( first) < GetSValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smLuminance:
if GetLValue( first) < GetLValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smValue:
if GetVValue( first) < GetVValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCyan:
if GetCValue( first) < GetCValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smMagenta:
if GetMValue( first) < GetMValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smYellow:
if GetYValue( first) < GetYValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smBlacK:
if GetKValue( first) < GetKValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEx:
if GetCIEXValue( first) < GetCIEXValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEy:
if GetCIEYValue( first) < GetCIEYValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEz:
if GetCIEZValue( first) < GetCIEZValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEl:
if GetCIELValue( first) < GetCIELValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEa:
if GetCIEAValue( first) < GetCIEAValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEb:
if GetCIEBValue( first) < GetCIEBValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
end ;
2016-12-08 23:14:26 +00:00
2016-12-15 11:27:12 +00:00
function MinPos( s: TStrings; sm: TSortMode) : integer ;
var
i: integer ;
first: TColor;
begin
Result : = 0 ;
first : = clWhite;
for i : = 0 to s. Count - 1 do
case sm of
smRed:
if GetRValue( first) > GetRValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smGreen:
if GetGValue( first) > GetGValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smBlue:
if GetBValue( first) > GetBValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smHue:
if GetHValue( first) > GetHValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smSaturation:
if GetSValue( first) > GetSValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smLuminance:
if GetLValue( first) > GetLValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smValue:
if GetVValue( first) > GetVValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCyan:
if GetCValue( first) > GetCValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smMagenta:
if GetMValue( first) > GetMValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smYellow:
if GetYValue( first) > GetYValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smBlacK:
if GetKValue( first) > GetKValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEx:
if GetCIEXValue( first) > GetCIEXValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEy:
if GetCIEYValue( first) > GetCIEYValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEz:
if GetCIEZValue( first) > GetCIEZValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEl:
if GetCIELValue( first) > GetCIELValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEa:
if GetCIEAValue( first) > GetCIEAValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
smCIEb:
if GetCIEBValue( first) > GetCIEBValue( mbStringToColor( s. Strings[ i] ) ) then
begin
first : = mbStringToColor( s. Strings[ i] ) ;
Result : = i;
end ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
end ;
2016-12-08 23:14:26 +00:00
var
2016-12-15 11:27:12 +00:00
i, m: integer ;
s: TStrings;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if SortMode < > smNone then
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if Colors. Count = 0 then Exit;
m : = 0 ;
s : = TStringList. Create;
try
s. AddStrings( Colors) ;
Colors. Clear;
for i : = s. Count - 1 downto 0 do
begin
case SortOrder of
soAscending : m : = MinPos( s, SortMode) ;
soDescending : m : = MaxPos( s, SortMode) ;
end ;
Colors. Add( s. Strings[ m] ) ;
s. Delete( m) ;
end ;
finally
s. Free;
2016-12-08 23:14:26 +00:00
end ;
end ;
end ;
function ReadJASCPal( PalFile: TFileName) : string ;
var
2016-12-15 11:27:12 +00:00
p, t, c: TStrings;
i: integer ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if not FileExists( PalFile) then
raise Exception. Create( 'File not found' ) ;
p : = TStringList. Create;
t : = TStringList. Create;
c : = TStringList. Create;
try
p. LoadFromFile( PalFile) ;
for i : = 0 to p. Count - 1 do
if p. strings[ i] < > '' then
begin
t. Clear;
ExtractStrings( [ ' ' ] , [ ] , PChar( p. strings[ i] ) , t) ;
if t. Count = 3 then
c. Add( ColorToString( RGB( StrToInt( t. strings[ 0 ] ) , StrToInt( t. strings[ 1 ] ) , StrToInt( t. strings[ 2 ] ) ) ) ) ;
end ;
Result : = c. Text ;
finally
c. Free;
t. Free;
p. Free;
2016-12-08 23:14:26 +00:00
end ;
end ;
procedure SaveJASCPal( pal: TStrings; FileName: TFileName) ;
var
2016-12-15 11:27:12 +00:00
i: integer ;
p: TStringList;
c: TColor;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if not FileExists( FileName) then
raise Exception. Create( 'File not found' ) ;
p : = TStringList. Create;
try
p. Add( 'JASC-PAL' ) ;
p. Add( '0100' ) ;
p. Add( '256' ) ;
for i : = 0 to pal. Count - 1 do
if ( pal. Strings[ i] < > '' ) and not SameText( pal. Strings[ i] , 'clCustom' ) and not SameText( pal. Strings[ i] , 'clTransparent' ) then
begin
c : = StringToColor( pal. Strings[ i] ) ;
p. Add( IntToStr( GetRValue( c) ) + ' ' + IntToStr( GetGValue( c) ) + ' ' + IntToStr( GetBValue( c) ) ) ;
end ;
p. SaveToFile( FileName) ;
finally
p. Free;
2016-12-08 23:14:26 +00:00
end ;
end ;
procedure ExchangeBytes( var w: Word ) ;
begin
Swap( w) ;
{
asm
MOV DX, [ w] //assign the word to the data register
XCHG DL, DH // exchange low and high data values
MOV [ w] , DX //assign the register data to the word
}
end ;
procedure ExchangeChars( var s: WideString ) ;
var
2016-12-15 11:27:12 +00:00
i: Integer ;
w: Word ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
for i : = 1 to Length( s) do
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
w : = Word( s[ i] ) ;
ExchangeBytes( w) ;
s[ i] : = WideChar( w) ;
2016-12-08 23:14:26 +00:00
end ;
end ;
function GetAcoColor( space, w, x, y, z: word ) : TColor;
begin
2016-12-15 11:27:12 +00:00
case space of
0 : //RGB
Result : = RGB( w div 2 5 6 , x div 2 5 6 , y div 2 5 6 ) ;
1 : //HSB - HSV
Result : = HSVToColor( Round( w/ 182.04 ) , Round( x/ 655.35 ) , Round( y/ 655.35 ) ) ;
2 : //CMYK
2016-12-19 16:38:29 +00:00
Result : = CMYKToColor( Round( 1 0 0 - w/ 55.35 ) , Round( 1 0 0 - x/ 655.35 ) , Round( 1 0 0 - y/ 655.35 ) , Round( 1 0 0 - z/ 655.35 ) ) ;
2016-12-15 11:27:12 +00:00
7 : //Lab
Result : = LabToRGB( w/ 1 0 0 , x/ 1 0 0 , y/ 1 0 0 ) ;
8 : //Grayscale
Result : = RGB( Round( w/ 39.0625 ) , Round( w/ 39.0625 ) , Round( w/ 39.0625 ) ) ;
9 : //Wide CMYK
2016-12-19 16:38:29 +00:00
Result : = CMYKToColor( w div 1 0 0 , x div 1 0 0 , y div 1 0 0 , z div 1 0 0 )
2016-12-15 11:27:12 +00:00
else //unknown
Result : = RGB( w div 2 5 6 , x div 2 5 6 , y div 2 5 6 ) ;
end ;
2016-12-08 23:14:26 +00:00
end ;
function ReadPhotoshopAco( PalFile: TFileName) : AcoColors;
var
2016-12-15 11:27:12 +00:00
f: file ;
ver, num, space, w, x, y, z, dummy: Word ;
i: integer ;
v0Length: byte ;
v0Name: string ;
v2Length: Word ;
v2Name: WideString ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if not FileExists( PalFile) then
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
SetLength( Result . Colors, 0 ) ;
SetLength( Result . Names, 0 ) ;
Result . HasNames : = false ;
raise Exception. Create( 'File not found' ) ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
AssignFile( f, PalFile) ;
Reset( f, 1 ) ;
//read version
BlockRead( f, ver, sizeof( ver) ) ;
ExchangeBytes( ver) ;
if not ( ver in [ 0 , 1 , 2 ] ) then
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
CloseFile( f) ;
raise Exception. Create( 'The file you are trying to load is not (yet) supported.' #13 'Please submit the file for testing to MXS so loading of this version will be supported too' ) ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
//read number of colors
BlockRead( f, num, sizeof( num) ) ;
ExchangeBytes( num) ;
//read names
if ( ver = 0 ) or ( ver = 2 ) then
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
SetLength( Result . Names, num) ;
Result . HasNames : = true ;
2016-12-08 23:14:26 +00:00
end
2016-12-15 11:27:12 +00:00
else
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
SetLength( Result . Names, 0 ) ;
Result . HasNames : = false ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
//read colors
SetLength( Result . Colors, num) ;
for i : = 0 to num - 1 do
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
BlockRead( f, space, sizeof( space) ) ;
ExchangeBytes( space) ;
BlockRead( f, w, sizeof( w) ) ;
ExchangeBytes( w) ;
BlockRead( f, x, sizeof( x) ) ;
ExchangeBytes( x) ;
BlockRead( f, y, sizeof( y) ) ;
ExchangeBytes( y) ;
BlockRead( f, z, sizeof( z) ) ;
ExchangeBytes( z) ;
Result . Colors[ i] : = GetAcoColor( space, w, x, y, z) ;
case ver of
0 : begin
BlockRead( f, v0Length, SizeOf( v0Length) ) ;
SetLength( v0Name, v0Length) ;
if v0Length > 0 then
BlockRead( f, PChar( v0Name) ^ , v0Length) ;
Result . Names[ i] : = v0Name;
end ;
2 : begin
BlockRead( f, dummy, sizeof( dummy) ) ;
BlockRead( f, v2Length, SizeOf( v2Length) ) ;
ExchangeBytes( v2Length) ;
SetLength( v2Name, v2Length - 1 ) ;
if v2Length > 0 then
begin
BlockRead( f, PWideChar( v2Name) ^ , 2 * ( v2Length - 1 ) ) ;
ExchangeChars( v2Name) ;
end ;
Result . Names[ i] : = v2Name;
BlockRead( f, dummy, sizeof( dummy) ) ;
end ;
end ;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
CloseFile( f) ;
2016-12-08 23:14:26 +00:00
end ;
function ReadPhotoshopAct( PalFile: TFileName) : string ;
var
2016-12-15 11:27:12 +00:00
f: file ;
r, g, b: byte ;
s: TStringList;
i: integer ;
2016-12-08 23:14:26 +00:00
begin
2016-12-15 11:27:12 +00:00
if not FileExists( PalFile) then
raise Exception. Create( 'File not found' ) ;
s : = TStringList. Create;
try
AssignFile( f, PalFile) ;
Reset( f, 1 ) ;
for i : = 0 to 2 5 5 do
begin
BlockRead( f, r, sizeof( r) ) ;
BlockRead( f, g, sizeof( g) ) ;
BlockRead( f, b, sizeof( b) ) ;
s. Add( ColorToString( RGB( r, g, b) ) ) ;
end ;
Result : = s. Text ;
finally
s. Free;
2016-12-08 23:14:26 +00:00
end ;
2016-12-15 11:27:12 +00:00
CloseFile( f) ;
2016-12-08 23:14:26 +00:00
end ;
end .