diff options
Diffstat (limited to 'lcms2mt/utils')
45 files changed, 14930 insertions, 0 deletions
diff --git a/lcms2mt/utils/common/utils.h b/lcms2mt/utils/common/utils.h new file mode 100644 index 000000000..1572ac1ac --- /dev/null +++ b/lcms2mt/utils/common/utils.h @@ -0,0 +1,103 @@ + +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- + +#ifndef _lcms_utils_h + +// Deal with Microsoft's attempt at deprecating C standard runtime functions +#ifdef _MSC_VER +# if (_MSC_VER >= 1400) +# ifndef _CRT_SECURE_NO_DEPRECATE +# define _CRT_SECURE_NO_DEPRECATE +# endif +# ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +# endif +# endif +#endif + +#include "lcms2mt.h" + +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <math.h> +#include <wchar.h> + +// Avoid warnings + +#define UTILS_UNUSED_PARAMETER(x) ((void)x) + +// Init the utility functions + +void InitUtils(const char* PName); + +// Fatal Error (print the message and exit(1))--------------------------------------------- + +extern int Verbose; + +void FatalError(const char *frm, ...); + +// xgetopt() interface ------------------------------------------------------------- + +extern int xoptind; +extern char *xoptarg; +extern int xopterr; +extern char SW; + +int xgetopt(int argc, char *argv[], char *optionS); + +// The stock profile utility ------------------------------------------------------- + +cmsHPROFILE OpenStockProfile(cmsContext ContextID, const char* File); + +// The print info utility ---------------------------------------------------------- + +void PrintProfileInformation(cmsContext ContextID, cmsHPROFILE h); + +// --------------------------------------------------------------------------------- + +void PrintRenderingIntents(void); +void PrintBuiltins(void); + +// --------------------------------------------------------------------------------- + +cmsBool SaveMemoryBlock(const cmsUInt8Number* Buffer, cmsUInt32Number dwLen, const char* Filename); + +// --------------------------------------------------------------------------------- + +// Return a pixel type on depending on the number of channels +int PixelTypeFromChanCount(int ColorChannels); + +// ------------------------------------------------------------------------------ + +// Return number of channels of pixel type +int ChanCountFromPixelType(int ColorChannels); + +#define _lcms_utils_h +#endif diff --git a/lcms2mt/utils/common/vprf.c b/lcms2mt/utils/common/vprf.c new file mode 100644 index 000000000..7ba1e200a --- /dev/null +++ b/lcms2mt/utils/common/vprf.c @@ -0,0 +1,336 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "utils.h" + + +int Verbose = 0; + +static char ProgramName[256] = ""; + +void FatalError(const char *frm, ...) +{ + va_list args; + + va_start(args, frm); + fprintf(stderr, "[%s fatal error]: ", ProgramName); + vfprintf(stderr, frm, args); + fprintf(stderr, "\n"); + va_end(args); + + exit(1); +} + +// Show errors to the end user (unless quiet option) +static +void MyErrorLogHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text) +{ + if (Verbose >= 0) + fprintf(stderr, "[%s]: %s\n", ProgramName, Text); + + UTILS_UNUSED_PARAMETER(ErrorCode); + UTILS_UNUSED_PARAMETER(ContextID); +} + + +void InitUtils(const char* PName) +{ + strncpy(ProgramName, PName, sizeof(ProgramName)); + ProgramName[sizeof(ProgramName)-1] = 0; + + cmsSetLogErrorHandler(MyErrorLogHandler); +} + + +// Virtual profiles are handled here. +cmsHPROFILE OpenStockProfile(cmsContext ContextID, const char* File) +{ + if (!File) + return cmsCreate_sRGBProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*Lab2") == 0) + return cmsCreateLab2ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*Lab4") == 0) + return cmsCreateLab4ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*Lab") == 0) + return cmsCreateLab4ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*LabD65") == 0) { + + cmsCIExyY D65xyY; + + cmsWhitePointFromTemp(ContextID, &D65xyY, 6504); + return cmsCreateLab4ProfileTHR(ContextID, &D65xyY); + } + + if (cmsstrcasecmp(File, "*XYZ") == 0) + return cmsCreateXYZProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*Gray22") == 0) { + + cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2); + cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(ContextID), Curve); + cmsFreeToneCurve(ContextID, Curve); + return hProfile; + } + + if (cmsstrcasecmp(File, "*Gray30") == 0) { + + cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0); + cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(ContextID), Curve); + cmsFreeToneCurve(ContextID, Curve); + return hProfile; + } + + if (cmsstrcasecmp(File, "*srgb") == 0) + return cmsCreate_sRGBProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*null") == 0) + return cmsCreateNULLProfileTHR(ContextID); + + + if (cmsstrcasecmp(File, "*Lin2222") == 0) { + + cmsToneCurve* Gamma = cmsBuildGamma(0, 2.2); + cmsToneCurve* Gamma4[4]; + cmsHPROFILE hProfile; + + Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma; + hProfile = cmsCreateLinearizationDeviceLink(cmsSigCmykData, Gamma4); + cmsFreeToneCurve(ContextID, Gamma); + return hProfile; + } + + + return cmsOpenProfileFromFileTHR(ContextID, File, "r"); +} + +// Help on available built-ins +void PrintBuiltins(void) +{ + fprintf(stderr, "\nBuilt-in profiles:\n\n"); + fprintf(stderr, "\t*Lab2 -- D50-based v2 CIEL*a*b\n" + "\t*Lab4 -- D50-based v4 CIEL*a*b\n" + "\t*Lab -- D50-based v4 CIEL*a*b\n" + "\t*XYZ -- CIE XYZ (PCS)\n" + "\t*sRGB -- sRGB color space\n" + "\t*Gray22 - Monochrome of Gamma 2.2\n" + "\t*Gray30 - Monochrome of Gamma 3.0\n" + "\t*null - Monochrome black for all input\n" + "\t*Lin2222- CMYK linearization of gamma 2.2 on each channel\n"); +} + + +// Auxiliary for printing information on profile +static +void PrintInfo(cmsContext ContextID, cmsHPROFILE h, cmsInfoType Info) +{ + char* text; + int len; + + len = cmsGetProfileInfoASCII(ContextID, h, Info, "en", "US", NULL, 0); + if (len == 0) return; + + text = (char*) malloc(len * sizeof(char)); + if (text == NULL) return; + + cmsGetProfileInfoASCII(ContextID, h, Info, "en", "US", text, len); + + if (strlen(text) > 0) + printf("%s\n", text); + + free(text); +} + + + +// Displays the colorant table +static +void PrintColorantTable(cmsContext ContextID, cmsHPROFILE hInput, cmsTagSignature Sig, const char* Title) +{ + cmsNAMEDCOLORLIST* list; + int i, n; + + if (cmsIsTag(ContextID, hInput, Sig)) { + + printf("%s:\n", Title); + + list = (cmsNAMEDCOLORLIST*) cmsReadTag(ContextID, hInput, Sig); + if (list == NULL) { + printf("(Unavailable)\n"); + return; + } + + n = cmsNamedColorCount(ContextID, list); + for (i=0; i < n; i++) { + + char Name[cmsMAX_PATH]; + + cmsNamedColorInfo(ContextID, list, i, Name, NULL, NULL, NULL, NULL); + printf("\t%s\n", Name); + } + + printf("\n"); + } + +} + + +void PrintProfileInformation(cmsContext ContextID, cmsHPROFILE hInput) +{ + if (hInput == NULL) { + fprintf(stderr, "*Wrong or corrupted profile*\n"); + return; + } + + PrintInfo(ContextID, hInput, cmsInfoDescription); + PrintInfo(ContextID, hInput, cmsInfoManufacturer); + PrintInfo(ContextID, hInput, cmsInfoModel); + PrintInfo(ContextID, hInput, cmsInfoCopyright); + + if (Verbose > 2) { + + PrintColorantTable(ContextID, hInput, cmsSigColorantTableTag, "Input colorant table"); + PrintColorantTable(ContextID, hInput, cmsSigColorantTableOutTag, "Input colorant out table"); + } + + printf("\n"); +} + +// ----------------------------------------------------------------------------- + + +void PrintRenderingIntents(void) +{ + cmsUInt32Number Codes[200]; + char* Descriptions[200]; + cmsUInt32Number n, i; + + fprintf(stderr, "%ct<n> rendering intent:\n\n", SW); + + n = cmsGetSupportedIntents(200, Codes, Descriptions); + + for (i=0; i < n; i++) { + fprintf(stderr, "\t%u - %s\n", Codes[i], Descriptions[i]); + } + fprintf(stderr, "\n"); +} + + + +// ------------------------------------------------------------------------------ + +cmsBool SaveMemoryBlock(const cmsUInt8Number* Buffer, cmsUInt32Number dwLen, const char* Filename) +{ + FILE* out = fopen(Filename, "wb"); + if (out == NULL) { + FatalError("Cannot create '%s'", Filename); + return FALSE; + } + + if (fwrite(Buffer, 1, dwLen, out) != dwLen) { + FatalError("Cannot write %ld bytes to %s", dwLen, Filename); + return FALSE; + } + + if (fclose(out) != 0) { + FatalError("Error flushing file '%s'", Filename); + return FALSE; + } + + return TRUE; +} + +// ------------------------------------------------------------------------------ + +// Return a pixel type on depending on the number of channels +int PixelTypeFromChanCount(int ColorChannels) +{ + switch (ColorChannels) { + + case 1: return PT_GRAY; + case 2: return PT_MCH2; + case 3: return PT_MCH3; + case 4: return PT_CMYK; + case 5: return PT_MCH5; + case 6: return PT_MCH6; + case 7: return PT_MCH7; + case 8: return PT_MCH8; + case 9: return PT_MCH9; + case 10: return PT_MCH10; + case 11: return PT_MCH11; + case 12: return PT_MCH12; + case 13: return PT_MCH13; + case 14: return PT_MCH14; + case 15: return PT_MCH15; + + default: + + FatalError("What a weird separation of %d channels?!?!", ColorChannels); + return -1; + } +} + + +// ------------------------------------------------------------------------------ + +// Return number of channels of pixel type +int ChanCountFromPixelType(int ColorChannels) +{ + switch (ColorChannels) { + + case PT_GRAY: return 1; + + case PT_RGB: + case PT_CMY: + case PT_Lab: + case PT_YUV: + case PT_YCbCr: return 3; + + case PT_CMYK: return 4 ; + case PT_MCH2: return 2 ; + case PT_MCH3: return 3 ; + case PT_MCH4: return 4 ; + case PT_MCH5: return 5 ; + case PT_MCH6: return 6 ; + case PT_MCH7: return 7 ; + case PT_MCH8: return 8 ; + case PT_MCH9: return 9 ; + case PT_MCH10: return 10; + case PT_MCH11: return 11; + case PT_MCH12: return 12; + case PT_MCH13: return 12; + case PT_MCH14: return 14; + case PT_MCH15: return 15; + + default: + + FatalError("Unsupported color space of %d channels", ColorChannels); + return -1; + } +} diff --git a/lcms2mt/utils/common/xgetopt.c b/lcms2mt/utils/common/xgetopt.c new file mode 100644 index 000000000..7f3dc548a --- /dev/null +++ b/lcms2mt/utils/common/xgetopt.c @@ -0,0 +1,75 @@ +/* + getopt.c + +*/ + +#include <errno.h> +#include <string.h> +#include <stdio.h> + +int xoptind = 1; /* index of which argument is next */ +char *xoptarg; /* pointer to argument of current option */ +int xopterr = 0; /* allow error message */ + +static char *letP = NULL; /* remember next option char's location */ +char SW = '-'; /* DOS switch character, either '-' or '/' */ + +/* + Parse the command line options, System V style. + + Standard option syntax is: + + option ::= SW [optLetter]* [argLetter space* argument] + +*/ + +int xgetopt(int argc, char *argv[], char *optionS) +{ + unsigned char ch; + char *optP; + + if (SW == 0) { + SW = '/'; + } + + if (argc > xoptind) { + if (letP == NULL) { + if ((letP = argv[xoptind]) == NULL || + *(letP++) != SW) goto gopEOF; + if (*letP == SW) { + xoptind++; goto gopEOF; + } + } + if (0 == (ch = *(letP++))) { + xoptind++; goto gopEOF; + } + if (':' == ch || (optP = strchr(optionS, ch)) == NULL) + goto gopError; + if (':' == *(++optP)) { + xoptind++; + if (0 == *letP) { + if (argc <= xoptind) goto gopError; + letP = argv[xoptind++]; + } + xoptarg = letP; + letP = NULL; + } else { + if (0 == *letP) { + xoptind++; + letP = NULL; + } + xoptarg = NULL; + } + return ch; + } +gopEOF: + xoptarg = letP = NULL; + return EOF; + +gopError: + xoptarg = NULL; + errno = EINVAL; + if (xopterr) + perror ("get command line option"); + return ('?'); +} diff --git a/lcms2mt/utils/delphi/delphidemo.dpr b/lcms2mt/utils/delphi/delphidemo.dpr new file mode 100644 index 000000000..9180c04fe --- /dev/null +++ b/lcms2mt/utils/delphi/delphidemo.dpr @@ -0,0 +1,13 @@ +program delphidemo; + +uses + Forms, + demo1 in 'demo1.pas' {Form1}; + +{$R *.RES} + +begin + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/lcms2mt/utils/delphi/delphidemo.dproj b/lcms2mt/utils/delphi/delphidemo.dproj new file mode 100644 index 000000000..25b97d828 --- /dev/null +++ b/lcms2mt/utils/delphi/delphidemo.dproj @@ -0,0 +1,114 @@ + <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{E3F889E8-CB8A-49AE-8173-4DDA022466BE}</ProjectGuid> + <MainSource>delphidemo.dpr</MainSource> + <Config Condition="'$(Config)'==''">Debug</Config> + <DCC_DCCCompiler>DCC32</DCC_DCCCompiler> + <ProjectVersion>12.0</ProjectVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''"> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''"> + <Cfg_1>true</Cfg_1> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''"> + <Cfg_2>true</Cfg_2> + <CfgParent>Base</CfgParent> + <Base>true</Base> + </PropertyGroup> + <PropertyGroup Condition="'$(Base)'!=''"> + <DCC_UsePackage>vcl;rtl;vclx;vclimg;vclactnband;dbrtl;vcldb;vcldbx;bdertl;vcltouch;xmlrtl;dsnap;dsnapcon;TeeUI;TeeDB;Tee;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_100_140;Intraweb_100_140;VclSmp;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DbxClientDriver;DataSnapServer;DBXInterBaseDriver;DBXMySQLDriver;dbxcds;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver;Rave77VCL</DCC_UsePackage> + <DCC_ImageBase>00400000</DCC_ImageBase> + <DCC_SymbolReferenceInfo>1</DCC_SymbolReferenceInfo> + <DCC_DependencyCheckOutputName>delphidemo.exe</DCC_DependencyCheckOutputName> + <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias> + <DCC_Platform>x86</DCC_Platform> + <DCC_N>true</DCC_N> + <DCC_S>false</DCC_S> + <DCC_K>false</DCC_K> + <DCC_E>false</DCC_E> + <DCC_F>false</DCC_F> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_1)'!=''"> + <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> + <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> + <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> + <DCC_DebugInformation>false</DCC_DebugInformation> + </PropertyGroup> + <PropertyGroup Condition="'$(Cfg_2)'!=''"> + <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define> + </PropertyGroup> + <ItemGroup> + <DelphiCompile Include="delphidemo.dpr"> + <MainSource>MainSource</MainSource> + </DelphiCompile> + <DCCReference Include="demo1.pas"> + <Form>Form1</Form> + </DCCReference> + <BuildConfiguration Include="Base"> + <Key>Base</Key> + </BuildConfiguration> + <BuildConfiguration Include="Debug"> + <Key>Cfg_2</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + <BuildConfiguration Include="Release"> + <Key>Cfg_1</Key> + <CfgParent>Base</CfgParent> + </BuildConfiguration> + </ItemGroup> + <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/> + <ProjectExtensions> + <Borland.Personality>Delphi.Personality.12</Borland.Personality> + <Borland.ProjectType>VCLApplication</Borland.ProjectType> + <BorlandProject> + <Delphi.Personality> + <Source> + <Source Name="MainSource">delphidemo.dpr</Source> + </Source> + <Parameters> + <Parameters Name="UseLauncher">False</Parameters> + <Parameters Name="DebugCWD">d:\lcms-1.13\delphi</Parameters> + <Parameters Name="LoadAllSymbols">True</Parameters> + <Parameters Name="LoadUnspecifiedSymbols">False</Parameters> + </Parameters> + <VersionInfo> + <VersionInfo Name="IncludeVerInfo">False</VersionInfo> + <VersionInfo Name="AutoIncBuild">False</VersionInfo> + <VersionInfo Name="MajorVer">1</VersionInfo> + <VersionInfo Name="MinorVer">0</VersionInfo> + <VersionInfo Name="Release">0</VersionInfo> + <VersionInfo Name="Build">0</VersionInfo> + <VersionInfo Name="Debug">False</VersionInfo> + <VersionInfo Name="PreRelease">False</VersionInfo> + <VersionInfo Name="Special">False</VersionInfo> + <VersionInfo Name="Private">False</VersionInfo> + <VersionInfo Name="DLL">False</VersionInfo> + <VersionInfo Name="Locale">3082</VersionInfo> + <VersionInfo Name="CodePage">1252</VersionInfo> + </VersionInfo> + <VersionInfoKeys> + <VersionInfoKeys Name="CompanyName"/> + <VersionInfoKeys Name="FileDescription"/> + <VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys> + <VersionInfoKeys Name="InternalName"/> + <VersionInfoKeys Name="LegalCopyright"/> + <VersionInfoKeys Name="LegalTrademarks"/> + <VersionInfoKeys Name="OriginalFilename"/> + <VersionInfoKeys Name="ProductName"/> + <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys> + <VersionInfoKeys Name="Comments"/> + </VersionInfoKeys> + <Excluded_Packages> + <Excluded_Packages Name="$(BDS)\bin\dcloffice2k140.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages> + <Excluded_Packages Name="$(BDS)\bin\dclofficexp140.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages> + </Excluded_Packages> + </Delphi.Personality> + <ModelSupport>False</ModelSupport> + </BorlandProject> + <ProjectFileVersion>12</ProjectFileVersion> + </ProjectExtensions> + </Project> diff --git a/lcms2mt/utils/delphi/delphidemo.res b/lcms2mt/utils/delphi/delphidemo.res Binary files differnew file mode 100755 index 000000000..ca4824f8c --- /dev/null +++ b/lcms2mt/utils/delphi/delphidemo.res diff --git a/lcms2mt/utils/delphi/demo1.dfm b/lcms2mt/utils/delphi/demo1.dfm Binary files differnew file mode 100755 index 000000000..c7722534b --- /dev/null +++ b/lcms2mt/utils/delphi/demo1.dfm diff --git a/lcms2mt/utils/delphi/demo1.pas b/lcms2mt/utils/delphi/demo1.pas new file mode 100644 index 000000000..8b69c98e0 --- /dev/null +++ b/lcms2mt/utils/delphi/demo1.pas @@ -0,0 +1,322 @@ +unit demo1; + +interface + +uses + Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + ExtCtrls, StdCtrls, ExtDlgs, lcms2dll, ComCtrls; + +type + TForm1 = class(TForm) + + Image1: TImage; + Image2: TImage; + Panel1: TPanel; + Splitter1: TSplitter; + Button2: TButton; + ComboBoxInput: TComboBox; + ComboBoxOutput: TComboBox; + Label1: TLabel; + Label2: TLabel; + WBCompensation: TCheckBox; + NoTransform: TCheckBox; + RadioGroup1: TRadioGroup; + OpenPictureDialog1: TOpenPictureDialog; + Button1: TButton; + ProgressBar1: TProgressBar; + ComboBoxIntent: TComboBox; + Label3: TLabel; + Button3: TButton; + Button4: TButton; + OpenDialog1: TOpenDialog; + Label4: TLabel; + ScrollBar1: TScrollBar; + + procedure Button2Click(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure ComboBoxIntentChange(Sender: TObject); + procedure ScrollBar1Change(Sender: TObject); + private + { Private declarations } + function ComputeFlags: DWORD; + + public + constructor Create(Owner: TComponent); Override; + { Public declarations } + end; + +var + Form1: TForm1; + +implementation + +{$R *.DFM} + +CONST + IS_INPUT = $1; + IS_DISPLAY = $2; + IS_COLORSPACE = $4; + IS_OUTPUT = $8; + IS_ABSTRACT = $10; + +VAR + IntentCodes: array [0 .. 20] of cmsUInt32Number; + +FUNCTION InSignatures(Signature: cmsProfileClassSignature; dwFlags: DWORD): Boolean; +BEGIN + + if (((dwFlags AND IS_DISPLAY) <> 0) AND (Signature = cmsSigDisplayClass)) then + InSignatures := TRUE + else if (((dwFlags AND IS_OUTPUT) <> 0) AND (Signature = cmsSigOutputClass)) + then + InSignatures := TRUE + else if (((dwFlags AND IS_INPUT) <> 0) AND (Signature = cmsSigInputClass)) + then + InSignatures := TRUE + else if (((dwFlags AND IS_COLORSPACE) <> 0) AND + (Signature = cmsSigColorSpaceClass)) then + InSignatures := TRUE + else if (((dwFlags AND IS_ABSTRACT) <> 0) AND + (Signature = cmsSigAbstractClass)) then + InSignatures := TRUE + else + InSignatures := FALSE +END; + +PROCEDURE FillCombo(var Combo: TComboBox; Signatures: DWORD); +var + Files, Descriptions: TStringList; + Found: Integer; + SearchRec: TSearchRec; + Path, Profile: String; + Dir: ARRAY [0 .. 1024] OF Char; + hProfile: cmsHPROFILE; + Descrip: array [0 .. 256] of Char; +begin + Files := TStringList.Create; + Descriptions := TStringList.Create; + GetSystemDirectory(Dir, 1023); + Path := String(Dir) + '\SPOOL\DRIVERS\COLOR\'; + Found := FindFirst(Path + '*.ic?', faAnyFile, SearchRec); + while Found = 0 do + begin + Profile := Path + SearchRec.Name; + hProfile := cmsOpenProfileFromFile(PAnsiChar(AnsiString(Profile)), 'r'); + if (hProfile <> NIL) THEN + begin + + if ((cmsGetColorSpace(hProfile) = cmsSigRgbData) AND InSignatures + (cmsGetDeviceClass(hProfile), Signatures)) then + begin + cmsGetProfileInfo(hProfile, cmsInfoDescription, 'EN', 'us', Descrip, + 256); + Descriptions.Add(Descrip); + Files.Add(Profile); + end; + cmsCloseProfile(hProfile); + end; + + Found := FindNext(SearchRec); + + end; + FindClose(SearchRec); + Combo.Items := Descriptions; + Combo.Tag := Integer(Files); +end; + +// A rather simple Logger... note the "cdecl" convention +PROCEDURE ErrorLogger(ContextID: cmsContext; ErrorCode: cmsUInt32Number; + Text: PAnsiChar); Cdecl; +begin + MessageBox(0, PWideChar(WideString(Text)), 'Something is going wrong...', + MB_OK OR MB_ICONWARNING or MB_TASKMODAL); +end; + +constructor TForm1.Create(Owner: TComponent); +var + IntentNames: array [0 .. 20] of PAnsiChar; + i, n: Integer; +begin + inherited Create(Owner); + + // Set the logger + cmsSetLogErrorHandler(ErrorLogger); + + ScrollBar1.Min := 0; + ScrollBar1.Max := 100; + + FillCombo(ComboBoxInput, IS_INPUT OR IS_COLORSPACE OR IS_DISPLAY); + FillCombo(ComboBoxOutput, $FFFF ); + + + // Get the supported intents + n := cmsGetSupportedIntents(20, @IntentCodes, @IntentNames); + + + ComboBoxIntent.Items.BeginUpdate; + ComboBoxIntent.Items.Clear; + for i:= 0 TO n - 1 DO + ComboBoxIntent.Items.Add(String(IntentNames[i])); + + ComboBoxIntent.ItemIndex := 0; + ComboBoxIntent.Items.EndUpdate; +end; + + + +procedure TForm1.ScrollBar1Change(Sender: TObject); +var d: Integer; + s: String; +begin + d := ScrollBar1.Position; + Str(d, s); + Label4.Caption := 'Adaptation state '+s + '% (Abs. col only)'; +end; + +procedure TForm1.Button2Click(Sender: TObject); +begin + if OpenPictureDialog1.Execute then + begin + Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName); + Image1.Picture.Bitmap.PixelFormat := pf24bit; + + Image2.Picture.LoadFromFile(OpenPictureDialog1.FileName); + Image2.Picture.Bitmap.PixelFormat := pf24bit; + + end +end; + +function SelectedFile(var Combo: TComboBox): string; +var + List: TStringList; + n: Integer; +begin + + List := TStringList(Combo.Tag); + n := Combo.ItemIndex; + if (n >= 0) then + SelectedFile := List.Strings[n] + else + SelectedFile := Combo.Text; +end; + +procedure TForm1.ComboBoxIntentChange(Sender: TObject); +begin + ScrollBar1.Enabled := (ComboBoxIntent.itemIndex = 3); +end; + +function TForm1.ComputeFlags: DWORD; +var + dwFlags: DWORD; +begin + dwFlags := 0; + if (WBCompensation.Checked) then + begin + dwFlags := dwFlags OR cmsFLAGS_BLACKPOINTCOMPENSATION + end; + + if (NoTransform.Checked) then + begin + dwFlags := dwFlags OR cmsFLAGS_NULLTRANSFORM + end; + + case RadioGroup1.ItemIndex of + 0: + dwFlags := dwFlags OR cmsFLAGS_NOOPTIMIZE; + 1: + dwFlags := dwFlags OR cmsFLAGS_HIGHRESPRECALC; + 3: + dwFlags := dwFlags OR cmsFLAGS_LOWRESPRECALC; + end; + + ComputeFlags := dwFlags +end; + +procedure TForm1.Button1Click(Sender: TObject); +var + Source, Dest: String; + hSrc, hDest: cmsHPROFILE; + xform: cmsHTRANSFORM; + i, PicW, PicH: Integer; + Intent: Integer; + dwFlags: DWORD; +begin + + Source := SelectedFile(ComboBoxInput); + Dest := SelectedFile(ComboBoxOutput); + + dwFlags := ComputeFlags; + + Intent := IntentCodes[ComboBoxIntent.ItemIndex]; + + cmsSetAdaptationState( ScrollBar1.Position / 100.0 ); + + if (Source <> '') AND (Dest <> '') then + begin + hSrc := cmsOpenProfileFromFile(PAnsiChar(AnsiString(Source)), 'r'); + hDest := cmsOpenProfileFromFile(PAnsiChar(AnsiString(Dest)), 'r'); + + if (hSrc <> Nil) and (hDest <> Nil) then + begin + xform := cmsCreateTransform(hSrc, TYPE_BGR_8, hDest, TYPE_BGR_8, Intent, + dwFlags); + end + else + begin + xform := nil; + end; + + if hSrc <> nil then + begin + cmsCloseProfile(hSrc); + end; + + if hDest <> Nil then + begin + cmsCloseProfile(hDest); + end; + + if (xform <> nil) then + begin + + PicW := Image2.Picture.width; + PicH := Image2.Picture.height; + ProgressBar1.Min := 0; + ProgressBar1.Max := PicH; + ProgressBar1.Step := 1; + + for i := 0 TO (PicH - 1) do + begin + if ((i MOD 100) = 0) then + ProgressBar1.Position := i; + + cmsDoTransform(xform, Image1.Picture.Bitmap.Scanline[i], + Image2.Picture.Bitmap.Scanline[i], PicW); + + end; + ProgressBar1.Position := PicH; + + cmsDeleteTransform(xform); + + end; + + Image2.Repaint; + ProgressBar1.Position := 0; + end +end; + +procedure TForm1.Button3Click(Sender: TObject); +begin + if OpenDialog1.Execute then + ComboBoxInput.Text := OpenDialog1.FileName; +end; + +procedure TForm1.Button4Click(Sender: TObject); +begin + if OpenDialog1.Execute then + ComboBoxOutput.Text := OpenDialog1.FileName; +end; + +end. diff --git a/lcms2mt/utils/delphi/lcms2dll.pas b/lcms2mt/utils/delphi/lcms2dll.pas new file mode 100644 index 000000000..b8cccdc04 --- /dev/null +++ b/lcms2mt/utils/delphi/lcms2dll.pas @@ -0,0 +1,2156 @@ +// +// Little cms DELPHI wrapper +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2014 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// +// Version 2.6 +// + +UNIT lcms2dll; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +INTERFACE + +{$IFNDEF MSWINDOWS} + USES LCLType, types; + Type PWChar = PWideChar; +{$ELSE} + USES Windows; +{$ENDIF} + + CONST + + LCMS2_SO = {$IFDEF DARWIN} 'liblcms2.2.dylib'; {$ELSE} 'lcms2.dll'; {$ENDIF} + + TYPE + + Uint8 = Byte; + Int8 = Shortint; + UInt16 = Word; + Int16 = Smallint; + UInt32 = LongWord; + Int32 = Longint; + + TYPE + cmsUInt8Number = Uint8; + cmsInt8Number = Int8; + cmsUInt16Number = UInt16; + cmsInt16Number = Int16; + + cmsUInt32Number = UInt32; + cmsInt32Number = Int32; + cmsInt64Number = Int64; + cmsUInt64Number = UInt64; + + cmsFloat32Number = Single; + cmsFloat64Number = Double; + + LPcmsUInt8Number = ^cmsUInt8Number; + LPcmsInt8Number = ^cmsInt8Number; + LPcmsUInt16Number = ^cmsUInt16Number; + LPcmsInt16Number = ^cmsInt16Number; + + LPcmsUInt32Number = ^cmsUInt32Number; + LPcmsInt32Number = ^cmsInt32Number; + LPcmsInt64Number = ^cmsInt64Number; + LPcmsUInt64Number = ^cmsUInt64Number; + + LPcmsFloat32Number = ^cmsFloat32Number; + LPcmsFloat64Number = ^cmsFloat64Number; + + + // Derivative types + cmsSignature = cmsUInt32Number; + cmsU8Fixed8Number = cmsUInt16Number; + cmsS15Fixed16Number = cmsInt32Number; + cmsU16Fixed16Number = cmsUInt32Number; + + // Boolean type, which will be using the native integer + cmsBool = Boolean; + + CONST + + // Some common definitions + cmsMAX_PATH = 256; + + // D50 XYZ normalized to Y=1.0 + cmsD50X = 0.9642; + cmsD50Y = 1.0; + cmsD50Z = 0.8249; + + // V4 perceptual black + cmsPERCEPTUAL_BLACK_X = 0.00336; + cmsPERCEPTUAL_BLACK_Y = 0.0034731; + cmsPERCEPTUAL_BLACK_Z = 0.00287; + + // Definitions in ICC spec + cmsMagicNumber = $61637370; // 'acsp' + lcmsSignature = $6c636d73; // 'lcms' + + +TYPE + +// Base ICC type definitions +cmsTagTypeSignature = ( + cmsSigChromaticityType = $6368726D, // 'chrm' + cmsSigColorantOrderType = $636C726F, // 'clro' + cmsSigColorantTableType = $636C7274, // 'clrt' + cmsSigCrdInfoType = $63726469, // 'crdi' + cmsSigCurveType = $63757276, // 'curv' + cmsSigDataType = $64617461, // 'data' + cmsSigDictType = $64696374, // 'dict' + cmsSigDateTimeType = $6474696D, // 'dtim' + cmsSigDeviceSettingsType = $64657673, // 'devs' + cmsSigLut16Type = $6d667432, // 'mft2' + cmsSigLut8Type = $6d667431, // 'mft1' + cmsSigLutAtoBType = $6d414220, // 'mAB ' + cmsSigLutBtoAType = $6d424120, // 'mBA ' + cmsSigMeasurementType = $6D656173, // 'meas' + cmsSigMultiLocalizedUnicodeType = $6D6C7563, // 'mluc' + cmsSigMultiProcessElementType = $6D706574, // 'mpet' + cmsSigNamedColorType = $6E636f6C, // 'ncol' -- DEPRECATED! + cmsSigNamedColor2Type = $6E636C32, // 'ncl2' + cmsSigParametricCurveType = $70617261, // 'para' + cmsSigProfileSequenceDescType = $70736571, // 'pseq' + cmsSigProfileSequenceIdType = $70736964, // 'psid' + cmsSigResponseCurveSet16Type = $72637332, // 'rcs2' + cmsSigS15Fixed16ArrayType = $73663332, // 'sf32' + cmsSigScreeningType = $7363726E, // 'scrn' + cmsSigSignatureType = $73696720, // 'sig ' + cmsSigTextType = $74657874, // 'text' + cmsSigTextDescriptionType = $64657363, // 'desc' + cmsSigU16Fixed16ArrayType = $75663332, // 'uf32' + cmsSigUcrBgType = $62666420, // 'bfd ' + cmsSigUInt16ArrayType = $75693136, // 'ui16' + cmsSigUInt32ArrayType = $75693332, // 'ui32' + cmsSigUInt64ArrayType = $75693634, // 'ui64' + cmsSigUInt8ArrayType = $75693038, // 'ui08' + cmsSigViewingConditionsType = $76696577, // 'view' + cmsSigXYZType = $58595A20, // 'XYZ ' + cmsSigVcgtType = $76636774 // 'vcgt' + ); + +// Base ICC tag definitions +cmsTagSignature = ( + cmsSigAToB0Tag = $41324230, // 'A2B0' + cmsSigAToB1Tag = $41324231, // 'A2B1' + cmsSigAToB2Tag = $41324232, // 'A2B2' + cmsSigBlueColorantTag = $6258595A, // 'bXYZ' + cmsSigBlueMatrixColumnTag = $6258595A, // 'bXYZ' + cmsSigBlueTRCTag = $62545243, // 'bTRC' + cmsSigBToA0Tag = $42324130, // 'B2A0' + cmsSigBToA1Tag = $42324131, // 'B2A1' + cmsSigBToA2Tag = $42324132, // 'B2A2' + cmsSigCalibrationDateTimeTag = $63616C74, // 'calt' + cmsSigCharTargetTag = $74617267, // 'targ' + cmsSigChromaticAdaptationTag = $63686164, // 'chad' + cmsSigChromaticityTag = $6368726D, // 'chrm' + cmsSigColorantOrderTag = $636C726F, // 'clro' + cmsSigColorantTableTag = $636C7274, // 'clrt' + cmsSigColorantTableOutTag = $636C6F74, // 'clot' + cmsSigColorimetricIntentImageStateTag = $63696973, // 'ciis' + cmsSigCopyrightTag = $63707274, // 'cprt' + cmsSigCrdInfoTag = $63726469, // 'crdi' + cmsSigDataTag = $64617461, // 'data' + cmsSigDateTimeTag = $6474696D, // 'dtim' + cmsSigDeviceMfgDescTag = $646D6E64, // 'dmnd' + cmsSigDeviceModelDescTag = $646D6464, // 'dmdd' + cmsSigDeviceSettingsTag = $64657673, // 'devs' + cmsSigDToB0Tag = $44324230, // 'D2B0' + cmsSigDToB1Tag = $44324231, // 'D2B1' + cmsSigDToB2Tag = $44324232, // 'D2B2' + cmsSigDToB3Tag = $44324233, // 'D2B3' + cmsSigBToD0Tag = $42324430, // 'B2D0' + cmsSigBToD1Tag = $42324431, // 'B2D1' + cmsSigBToD2Tag = $42324432, // 'B2D2' + cmsSigBToD3Tag = $42324433, // 'B2D3' + cmsSigGamutTag = $67616D74, // 'gamt' + cmsSigGrayTRCTag = $6b545243, // 'kTRC' + cmsSigGreenColorantTag = $6758595A, // 'gXYZ' + cmsSigGreenMatrixColumnTag = $6758595A, // 'gXYZ' + cmsSigGreenTRCTag = $67545243, // 'gTRC' + cmsSigLuminanceTag = $6C756d69, // 'lumi' + cmsSigMeasurementTag = $6D656173, // 'meas' + cmsSigMediaBlackPointTag = $626B7074, // 'bkpt' + cmsSigMediaWhitePointTag = $77747074, // 'wtpt' + cmsSigNamedColorTag = $6E636f6C, // 'ncol' // Deprecated by the ICC + cmsSigNamedColor2Tag = $6E636C32, // 'ncl2' + cmsSigOutputResponseTag = $72657370, // 'resp' + cmsSigPerceptualRenderingIntentGamutTag = $72696730, // 'rig0' + cmsSigPreview0Tag = $70726530, // 'pre0' + cmsSigPreview1Tag = $70726531, // 'pre1' + cmsSigPreview2Tag = $70726532, // 'pre2' + cmsSigProfileDescriptionTag = $64657363, // 'desc' + cmsSigProfileSequenceDescTag = $70736571, // 'pseq' + cmsSigProfileSequenceIdTag = $70736964, // 'psid' + cmsSigPs2CRD0Tag = $70736430, // 'psd0' + cmsSigPs2CRD1Tag = $70736431, // 'psd1' + cmsSigPs2CRD2Tag = $70736432, // 'psd2' + cmsSigPs2CRD3Tag = $70736433, // 'psd3' + cmsSigPs2CSATag = $70733273, // 'ps2s' + cmsSigPs2RenderingIntentTag = $70733269, // 'ps2i' + cmsSigRedColorantTag = $7258595A, // 'rXYZ' + cmsSigRedMatrixColumnTag = $7258595A, // 'rXYZ' + cmsSigRedTRCTag = $72545243, // 'rTRC' + cmsSigSaturationRenderingIntentGamutTag = $72696732, // 'rig2' + cmsSigScreeningDescTag = $73637264, // 'scrd' + cmsSigScreeningTag = $7363726E, // 'scrn' + cmsSigTechnologyTag = $74656368, // 'tech' + cmsSigUcrBgTag = $62666420, // 'bfd ' + cmsSigViewingCondDescTag = $76756564, // 'vued' + cmsSigViewingConditionsTag = $76696577, // 'view' + cmsSigVcgtTag = $76636774, // 'vcgt' + cmsSigMetaTag = $6D657461 // 'meta' +); + +// ICC Technology tag +cmsTechnologySignature = ( + cmsSigDigitalCamera = $6463616D, // 'dcam' + cmsSigFilmScanner = $6673636E, // 'fscn' + cmsSigReflectiveScanner = $7273636E, // 'rscn' + cmsSigInkJetPrinter = $696A6574, // 'ijet' + cmsSigThermalWaxPrinter = $74776178, // 'twax' + cmsSigElectrophotographicPrinter = $6570686F, // 'epho' + cmsSigElectrostaticPrinter = $65737461, // 'esta' + cmsSigDyeSublimationPrinter = $64737562, // 'dsub' + cmsSigPhotographicPaperPrinter = $7270686F, // 'rpho' + cmsSigFilmWriter = $6670726E, // 'fprn' + cmsSigVideoMonitor = $7669646D, // 'vidm' + cmsSigVideoCamera = $76696463, // 'vidc' + cmsSigProjectionTelevision = $706A7476, // 'pjtv' + cmsSigCRTDisplay = $43525420, // 'CRT ' + cmsSigPMDisplay = $504D4420, // 'PMD ' + cmsSigAMDisplay = $414D4420, // 'AMD ' + cmsSigPhotoCD = $4B504344, // 'KPCD' + cmsSigPhotoImageSetter = $696D6773, // 'imgs' + cmsSigGravure = $67726176, // 'grav' + cmsSigOffsetLithography = $6F666673, // 'offs' + cmsSigSilkscreen = $73696C6B, // 'silk' + cmsSigFlexography = $666C6578, // 'flex' + cmsSigMotionPictureFilmScanner = $6D706673, // 'mpfs' + cmsSigMotionPictureFilmRecorder = $6D706672, // 'mpfr' + cmsSigDigitalMotionPictureCamera = $646D7063, // 'dmpc' + cmsSigDigitalCinemaProjector = $64636A70 // 'dcpj' +); + + +// ICC Color spaces +cmsColorSpaceSignature = ( + cmsSigXYZData = $58595A20, // 'XYZ ' + cmsSigLabData = $4C616220, // 'Lab ' + cmsSigLuvData = $4C757620, // 'Luv ' + cmsSigYCbCrData = $59436272, // 'YCbr' + cmsSigYxyData = $59787920, // 'Yxy ' + cmsSigRgbData = $52474220, // 'RGB ' + cmsSigGrayData = $47524159, // 'GRAY' + cmsSigHsvData = $48535620, // 'HSV ' + cmsSigHlsData = $484C5320, // 'HLS ' + cmsSigCmykData = $434D594B, // 'CMYK' + cmsSigCmyData = $434D5920, // 'CMY ' + cmsSigMCH1Data = $4D434831, // 'MCH1' + cmsSigMCH2Data = $4D434832, // 'MCH2' + cmsSigMCH3Data = $4D434833, // 'MCH3' + cmsSigMCH4Data = $4D434834, // 'MCH4' + cmsSigMCH5Data = $4D434835, // 'MCH5' + cmsSigMCH6Data = $4D434836, // 'MCH6' + cmsSigMCH7Data = $4D434837, // 'MCH7' + cmsSigMCH8Data = $4D434838, // 'MCH8' + cmsSigMCH9Data = $4D434839, // 'MCH9' + cmsSigMCHAData = $4D43483A, // 'MCHA' + cmsSigMCHBData = $4D43483B, // 'MCHB' + cmsSigMCHCData = $4D43483C, // 'MCHC' + cmsSigMCHDData = $4D43483D, // 'MCHD' + cmsSigMCHEData = $4D43483E, // 'MCHE' + cmsSigMCHFData = $4D43483F, // 'MCHF' + cmsSigNamedData = $6e6d636c, // 'nmcl' + cmsSig1colorData = $31434C52, // '1CLR' + cmsSig2colorData = $32434C52, // '2CLR' + cmsSig3colorData = $33434C52, // '3CLR' + cmsSig4colorData = $34434C52, // '4CLR' + cmsSig5colorData = $35434C52, // '5CLR' + cmsSig6colorData = $36434C52, // '6CLR' + cmsSig7colorData = $37434C52, // '7CLR' + cmsSig8colorData = $38434C52, // '8CLR' + cmsSig9colorData = $39434C52, // '9CLR' + cmsSig10colorData = $41434C52, // 'ACLR' + cmsSig11colorData = $42434C52, // 'BCLR' + cmsSig12colorData = $43434C52, // 'CCLR' + cmsSig13colorData = $44434C52, // 'DCLR' + cmsSig14colorData = $45434C52, // 'ECLR' + cmsSig15colorData = $46434C52, // 'FCLR' + cmsSigLuvKData = $4C75764B // 'LuvK' +); + +// ICC Profile Class +cmsProfileClassSignature = ( + cmsSigInputClass = $73636E72, // 'scnr' + cmsSigDisplayClass = $6D6E7472, // 'mntr' + cmsSigOutputClass = $70727472, // 'prtr' + cmsSigLinkClass = $6C696E6B, // 'link' + cmsSigAbstractClass = $61627374, // 'abst' + cmsSigColorSpaceClass = $73706163, // 'spac' + cmsSigNamedColorClass = $6e6d636c // 'nmcl' +); + + +// ICC Platforms +cmsPlatformSignature = ( + cmsSigMacintosh = $4150504C, // 'APPL' + cmsSigMicrosoft = $4D534654, // 'MSFT' + cmsSigSolaris = $53554E57, // 'SUNW' + cmsSigSGI = $53474920, // 'SGI ' + cmsSigTaligent = $54474E54, // 'TGNT' + cmsSigUnices = $2A6E6978 // '*nix' // From argyll -- Not official +); + +CONST + + // Reference gamut + cmsSigPerceptualReferenceMediumGamut = $70726d67; //'prmg' + + // For cmsSigColorimetricIntentImageStateTag + cmsSigSceneColorimetryEstimates = $73636F65; //'scoe' + cmsSigSceneAppearanceEstimates = $73617065; //'sape' + cmsSigFocalPlaneColorimetryEstimates = $66706365; //'fpce' + cmsSigReflectionHardcopyOriginalColorimetry = $72686F63; //'rhoc' + cmsSigReflectionPrintOutputColorimetry = $72706F63; //'rpoc' + +TYPE + +// Multi process elements types +cmsStageSignature = ( + cmsSigCurveSetElemType = $63767374, //'cvst' + cmsSigMatrixElemType = $6D617466, //'matf' + cmsSigCLutElemType = $636C7574, //'clut' + + cmsSigBAcsElemType = $62414353, // 'bACS' + cmsSigEAcsElemType = $65414353, // 'eACS' + + // Custom from here, not in the ICC Spec + cmsSigXYZ2LabElemType = $6C327820, // 'l2x ' + cmsSigLab2XYZElemType = $78326C20, // 'x2l ' + cmsSigNamedColorElemType = $6E636C20, // 'ncl ' + cmsSigLabV2toV4 = $32203420, // '2 4 ' + cmsSigLabV4toV2 = $34203220, // '4 2 ' + + // Identities + cmsSigIdentityElemType = $69646E20 // 'idn ' +); + +// Types of CurveElements +cmsCurveSegSignature = ( + + cmsSigFormulaCurveSeg = $70617266, // 'parf' + cmsSigSampledCurveSeg = $73616D66, // 'samf' + cmsSigSegmentedCurve = $63757266 // 'curf' +); + +CONST + + // Used in ResponseCurveType + cmsSigStatusA = $53746141; //'StaA' + cmsSigStatusE = $53746145; //'StaE' + cmsSigStatusI = $53746149; //'StaI' + cmsSigStatusT = $53746154; //'StaT' + cmsSigStatusM = $5374614D; //'StaM' + cmsSigDN = $444E2020; //'DN ' + cmsSigDNP = $444E2050; //'DN P' + cmsSigDNN = $444E4E20; //'DNN ' + cmsSigDNNP = $444E4E50; //'DNNP' + + // Device attributes, currently defined values correspond to the low 4 bytes + // of the 8 byte attribute quantity + cmsReflective = 0; + cmsTransparency = 1; + cmsGlossy = 0; + cmsMatte = 2; + +TYPE + +// Common structures in ICC tags +cmsICCData = PACKED RECORD + len : cmsUInt32Number; + flag : cmsUInt32Number; + data : Array [0..1] of cmsUInt8Number; + END; + +// ICC date time +cmsDateTimeNumber = PACKED RECORD + year: cmsUInt16Number; + month: cmsUInt16Number; + day: cmsUInt16Number; + hours: cmsUInt16Number; + minutes: cmsUInt16Number; + seconds: cmsUInt16Number; +END; + +// ICC XYZ + +cmsEncodedXYZNumber = PACKED RECORD + X: cmsS15Fixed16Number; + Y: cmsS15Fixed16Number; + Z: cmsS15Fixed16Number; +END; + + +// Profile ID as computed by MD5 algorithm +cmsProfileID = PACKED RECORD + CASE Integer OF + 1: (ID8: Array[0..15] OF cmsUInt8Number); + 2: (ID16: Array[0..7] OF cmsUInt16Number); + 3: (ID32: Array[0..3] OF cmsUInt32Number); +END; + + + +// ---------------------------------------------------------------------------------------------- +// ICC profile internal base types. Strictly, shouldn't be declared in this unit, but maybe +// somebody want to use this info for accessing profile header directly, so here it is. + +// Profile header -- it is 32-bit aligned, so no issues are expected on alignment +cmsICCHeader = PACKED RECORD + size: cmsUInt32Number; // Profile size in bytes + cmmId: cmsSignature; // CMM for this profile + version: cmsUInt32Number; // Format version number + deviceClass: cmsProfileClassSignature; // Type of profile + colorSpace: cmsColorSpaceSignature; // Color space of data + pcs: cmsColorSpaceSignature; // PCS, XYZ or Lab only + date: cmsDateTimeNumber; // Date profile was created + magic: cmsSignature; // Magic Number to identify an ICC profile + platform: cmsPlatformSignature; // Primary Platform + flags: cmsUInt32Number; // Various bit settings + manufacturer: cmsSignature; // Device manufacturer + model: cmsUInt32Number; // Device model number + attributes: cmsUInt64Number; // Device attributes + renderingIntent:cmsUInt32Number; // Rendering intent + illuminant: cmsEncodedXYZNumber; // Profile illuminant + creator: cmsSignature; // Profile creator + profileID: cmsProfileID; // Profile ID using MD5 + reserved: array [0..27] of cmsInt8Number; // Reserved for future use +END; + +// ICC base tag +cmsTagBase = PACKED RECORD + sig: cmsTagTypeSignature; + reserved: array[0..3] of cmsInt8Number; +END; + +// A tag entry in directory +cmsTagEntry = PACKED RECORD + sig: cmsTagSignature; // The tag signature + offset: cmsUInt32Number; // Start of tag + size: cmsUInt32Number; // Size in bytes +END; + + +cmsContext = Pointer; // Context identifier for multithreaded environments +cmsHANDLE = Pointer; // Generic handle +cmsHPROFILE = Pointer; // Opaque typedefs to hide internals +cmsHTRANSFORM = Pointer; + + +CONST + + cmsMAXCHANNELS = 16; // Maximum number of channels in ICC profiles + +// Format of pixel is defined by one cmsUInt32Number, using bit fields as follows +// +// A O TTTTT U Y F P X S EEE CCCC BBB +// +// A: Floating point -- With this flag we can differentiate 16 bits as float and as int +// O: Optimized -- previous optimization already returns the final 8-bit value +// T: Pixeltype +// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) +// P: Planar? 0=Chunky, 1=Planar +// X: swap 16 bps endianness? +// S: Do swap? ie, BGR, KYMC +// E: Extra samples +// C: Channels (Samples per pixel) +// B: bytes per sample +// Y: Swap first - changes ABGR to BGRA and KCMY to CMYK + + FUNCTION FLOAT_SH(a: cmsUInt32Number): cmsUInt32Number; + FUNCTION OPTIMIZED_SH(s: cmsUInt32Number): cmsUInt32Number; + FUNCTION COLORSPACE_SH(s: cmsUInt32Number):cmsUInt32Number; + FUNCTION SWAPFIRST_SH(s: cmsUInt32Number):cmsUInt32Number; + FUNCTION FLAVOR_SH(s: cmsUInt32Number):cmsUInt32Number; + FUNCTION PLANAR_SH(p: cmsUInt32Number):cmsUInt32Number; + FUNCTION ENDIAN16_SH(e: cmsUInt32Number):cmsUInt32Number; + FUNCTION DOSWAP_SH(e: cmsUInt32Number):cmsUInt32Number; + FUNCTION EXTRA_SH(e: cmsUInt32Number):cmsUInt32Number; + FUNCTION CHANNELS_SH(c: cmsUInt32Number):cmsUInt32Number; + FUNCTION BYTES_SH(b: cmsUInt32Number):cmsUInt32Number; + + + FUNCTION T_FLOAT(a: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_OPTIMIZED(o: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_COLORSPACE(s: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_SWAPFIRST(s: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_FLAVOR(s: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_PLANAR(p: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_ENDIAN16(e: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_DOSWAP(e: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_EXTRA(e: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_CHANNELS(c: cmsUInt32Number): cmsUInt32Number; + FUNCTION T_BYTES(b: cmsUInt32Number): cmsUInt32Number; + +CONST + + +// Pixel types + + PT_ANY = 0; // Don't check colorspace + // 1 & 2 are reserved + PT_GRAY = 3; + PT_RGB = 4; + PT_CMY = 5; + PT_CMYK = 6; + PT_YCbCr = 7; + PT_YUV = 8; // Lu'v' + PT_XYZ = 9; + PT_Lab = 10; + PT_YUVK = 11; // Lu'v'K + PT_HSV = 12; + PT_HLS = 13; + PT_Yxy = 14; + + PT_MCH1 = 15; + PT_MCH2 = 16; + PT_MCH3 = 17; + PT_MCH4 = 18; + PT_MCH5 = 19; + PT_MCH6 = 20; + PT_MCH7 = 21; + PT_MCH8 = 22; + PT_MCH9 = 23; + PT_MCH10 = 24; + PT_MCH11 = 25; + PT_MCH12 = 26; + PT_MCH13 = 27; + PT_MCH14 = 28; + PT_MCH15 = 29; + + PT_LabV2 = 30; // Identical to PT_Lab, but using the V2 old encoding + + + // Format descriptors + TYPE_GRAY_8 = $030009; + TYPE_GRAY_8_REV = $032009; + TYPE_GRAY_16 = $03000a; + TYPE_GRAY_16_REV = $03200a; + TYPE_GRAY_16_SE = $03080a; + TYPE_GRAYA_8 = $030089; + TYPE_GRAYA_16 = $03008a; + TYPE_GRAYA_16_SE = $03088a; + TYPE_GRAYA_8_PLANAR = $031089; + TYPE_GRAYA_16_PLANAR = $03108a; + TYPE_RGB_8 = $040019; + TYPE_RGB_8_PLANAR = $041019; + TYPE_BGR_8 = $040419; + TYPE_BGR_8_PLANAR = $041419; + TYPE_RGB_16 = $04001a; + TYPE_RGB_16_PLANAR = $04101a; + TYPE_RGB_16_SE = $04081a; + TYPE_BGR_16 = $04041a; + TYPE_BGR_16_PLANAR = $04141a; + TYPE_BGR_16_SE = $040c1a; + TYPE_RGBA_8 = $040099; + TYPE_RGBA_8_PLANAR = $041099; + TYPE_ARGB_8_PLANAR = $045099; + TYPE_ABGR_8_PLANAR = $041499; + TYPE_BGRA_8_PLANAR = $045499; + TYPE_RGBA_16 = $04009a; + TYPE_RGBA_16_PLANAR = $04109a; + TYPE_RGBA_16_SE = $04089a; + TYPE_ARGB_8 = $044099; + TYPE_ARGB_16 = $04409a; + TYPE_ABGR_8 = $040499; + TYPE_ABGR_16 = $04049a; + TYPE_ABGR_16_PLANAR = $04149a; + TYPE_ABGR_16_SE = $040c9a; + TYPE_BGRA_8 = $044499; + TYPE_BGRA_16 = $04449a; + TYPE_BGRA_16_SE = $04489a; + TYPE_CMY_8 = $050019; + TYPE_CMY_8_PLANAR = $051019; + TYPE_CMY_16 = $05001a; + TYPE_CMY_16_PLANAR = $05101a; + TYPE_CMY_16_SE = $05081a; + TYPE_CMYK_8 = $060021; + TYPE_CMYKA_8 = $0600a1; + TYPE_CMYK_8_REV = $062021; + TYPE_YUVK_8 = $062021; + TYPE_CMYK_8_PLANAR = $061021; + TYPE_CMYK_16 = $060022; + TYPE_CMYK_16_REV = $062022; + TYPE_YUVK_16 = $062022; + TYPE_CMYK_16_PLANAR = $061022; + TYPE_CMYK_16_SE = $060822; + TYPE_KYMC_8 = $060421; + TYPE_KYMC_16 = $060422; + TYPE_KYMC_16_SE = $060c22; + TYPE_KCMY_8 = $064021; + TYPE_KCMY_8_REV = $066021; + TYPE_KCMY_16 = $064022; + TYPE_KCMY_16_REV = $066022; + TYPE_KCMY_16_SE = $064822; + TYPE_CMYK5_8 = $130029; + TYPE_CMYK5_16 = $13002a; + TYPE_CMYK5_16_SE = $13082a; + TYPE_KYMC5_8 = $130429; + TYPE_KYMC5_16 = $13042a; + TYPE_KYMC5_16_SE = $130c2a; + TYPE_CMYK6_8 = $140031; + TYPE_CMYK6_8_PLANAR = $141031; + TYPE_CMYK6_16 = $140032; + TYPE_CMYK6_16_PLANAR = $141032; + TYPE_CMYK6_16_SE = $140832; + TYPE_CMYK7_8 = $150039; + TYPE_CMYK7_16 = $15003a; + TYPE_CMYK7_16_SE = $15083a; + TYPE_KYMC7_8 = $150439; + TYPE_KYMC7_16 = $15043a; + TYPE_KYMC7_16_SE = $150c3a; + TYPE_CMYK8_8 = $160041; + TYPE_CMYK8_16 = $160042; + TYPE_CMYK8_16_SE = $160842; + TYPE_KYMC8_8 = $160441; + TYPE_KYMC8_16 = $160442; + TYPE_KYMC8_16_SE = $160c42; + TYPE_CMYK9_8 = $170049; + TYPE_CMYK9_16 = $17004a; + TYPE_CMYK9_16_SE = $17084a; + TYPE_KYMC9_8 = $170449; + TYPE_KYMC9_16 = $17044a; + TYPE_KYMC9_16_SE = $170c4a; + TYPE_CMYK10_8 = $180051; + TYPE_CMYK10_16 = $180052; + TYPE_CMYK10_16_SE = $180852; + TYPE_KYMC10_8 = $180451; + TYPE_KYMC10_16 = $180452; + TYPE_KYMC10_16_SE = $180c52; + TYPE_CMYK11_8 = $190059; + TYPE_CMYK11_16 = $19005a; + TYPE_CMYK11_16_SE = $19085a; + TYPE_KYMC11_8 = $190459; + TYPE_KYMC11_16 = $19045a; + TYPE_KYMC11_16_SE = $190c5a; + TYPE_CMYK12_8 = $1a0061; + TYPE_CMYK12_16 = $1a0062; + TYPE_CMYK12_16_SE = $1a0862; + TYPE_KYMC12_8 = $1a0461; + TYPE_KYMC12_16 = $1a0462; + TYPE_KYMC12_16_SE = $1a0c62; + TYPE_XYZ_16 = $09001a; + TYPE_Lab_8 = $0a0019; + TYPE_ALab_8 = $0a0499; + TYPE_Lab_16 = $0a001a; + TYPE_Yxy_16 = $0e001a; + TYPE_YCbCr_8 = $070019; + TYPE_YCbCr_8_PLANAR = $071019; + TYPE_YCbCr_16 = $07001a; + TYPE_YCbCr_16_PLANAR = $07101a; + TYPE_YCbCr_16_SE = $07081a; + TYPE_YUV_8 = $080019; + TYPE_YUV_8_PLANAR = $081019; + TYPE_YUV_16 = $08001a; + TYPE_YUV_16_PLANAR = $08101a; + TYPE_YUV_16_SE = $08081a; + TYPE_HLS_8 = $0d0019; + TYPE_HLS_8_PLANAR = $0d1019; + TYPE_HLS_16 = $0d001a; + TYPE_HLS_16_PLANAR = $0d101a; + TYPE_HLS_16_SE = $0d081a; + TYPE_HSV_8 = $0c0019; + TYPE_HSV_8_PLANAR = $0c1019; + TYPE_HSV_16 = $0c001a; + TYPE_HSV_16_PLANAR = $0c101a; + TYPE_HSV_16_SE = $0c081a; + + TYPE_NAMED_COLOR_INDEX = $000A; + + TYPE_XYZ_FLT = $49001c; + TYPE_Lab_FLT = $4a001c; + TYPE_GRAY_FLT = $43000c; + TYPE_RGB_FLT = $44001c; + TYPE_CMYK_FLT = $460024; + TYPE_XYZA_FLT = $49009c; + TYPE_LabA_FLT = $4a009c; + TYPE_RGBA_FLT = $44009c; + + TYPE_XYZ_DBL = $490018; + TYPE_Lab_DBL = $4a0018; + TYPE_GRAY_DBL = $430008; + TYPE_RGB_DBL = $440018; + TYPE_CMYK_DBL = $460020; + TYPE_LabV2_8 = $1e0019; + TYPE_ALabV2_8 = $1e0499; + TYPE_LabV2_16 = $1e001a; + + TYPE_GRAY_HALF_FLT = $43000a; + TYPE_RGB_HALF_FLT = $44001a; + TYPE_RGBA_HALF_FLT = $44009a; + TYPE_CMYK_HALF_FLT = $460022; + + TYPE_ARGB_HALF_FLT = $44409a; + TYPE_BGR_HALF_FLT = $44041a; + TYPE_BGRA_HALF_FLT = $44449a; + TYPE_ABGR_HALF_FLT = $44041a; + +TYPE + + + // Colorimetric spaces + + cmsCIEXYZ = PACKED RECORD + X, Y, Z : cmsFloat64Number; + END; + LPcmsCIEXYZ = ^cmsCIEXYZ; + + cmsCIExyY = PACKED RECORD + x, y, YY : cmsFloat64Number + END; + LPcmsCIExyY = ^cmsCIEXYY; + + cmsCIELab = PACKED RECORD + L, a, b: cmsFloat64Number + END; + LPcmsCIELab = ^cmsCIELab; + + cmsCIELCh = PACKED RECORD + L, C, h : cmsFloat64Number + END; + LPcmsCIELCh = ^cmsCIELCh; + + cmsJCh = PACKED RECORD + J, C, h : cmsFloat64Number + END; + LPcmsJCh = ^cmsJCH; + + + cmsCIEXYZTRIPLE = PACKED RECORD + Red, Green, Blue : cmsCIEXYZ + END; + LPcmsCIEXYZTRIPLE = ^cmsCIEXYZTRIPLE; + + + cmsCIExyYTRIPLE = PACKED RECORD + Red, Green, Blue : cmsCIExyY + END; + LPcmsCIExyYTRIPLE = ^cmsCIExyYTRIPLE; + + +CONST + + // Illuminant types for structs below + cmsILLUMINANT_TYPE_UNKNOWN = $0000000; + cmsILLUMINANT_TYPE_D50 = $0000001; + cmsILLUMINANT_TYPE_D65 = $0000002; + cmsILLUMINANT_TYPE_D93 = $0000003; + cmsILLUMINANT_TYPE_F2 = $0000004; + cmsILLUMINANT_TYPE_D55 = $0000005; + cmsILLUMINANT_TYPE_A = $0000006; + cmsILLUMINANT_TYPE_E = $0000007; + cmsILLUMINANT_TYPE_F8 = $0000008; + +TYPE + + cmsICCMeasurementConditions = PACKED RECORD + + Observer: cmsUInt32Number; // 0 = unknown, 1=CIE 1931, 2=CIE 1964 + Backing: cmsCIEXYZ; // Value of backing + Geometry: cmsUInt32Number; // 0=unknown, 1=45/0, 0/45 2=0d, d/0 + Flare: cmsFloat64Number; // 0..1.0 + IlluminantType: cmsUInt32Number; + + END; + + cmsICCViewingConditions = PACKED RECORD + IlluminantXYZ: cmsCIEXYZ; // Not the same struct as CAM02, + SurroundXYZ: cmsCIEXYZ; // This is for storing the tag + IlluminantType: cmsUInt32Number; // viewing condition + END; + + +// Context -------------------------------------------------------------------------------------------------------------- + +FUNCTION cmsCreateContext(Plugin : Pointer; UserData : Pointer) : cmsContext; StdCall; +PROCEDURE cmsDeleteContext(ContextID: cmsContext); StdCall; +FUNCTION cmsDupContext(ContextID: cmsContext; NewUserData: Pointer): cmsContext; StdCall; +FUNCTION cmsGetContextUserData(ContextID: cmsContext): Pointer; StdCall; + +// Plug-In registering --------------------------------------------------------------------------------------------------- + +FUNCTION cmsPlugin(Plugin: Pointer): cmsBool; StdCall; +PROCEDURE cmsUnregisterPlugins; StdCall; + +// Error logging ---------------------------------------------------------------------------------------------------------- + +// There is no error handling at all. When a function fails, it returns proper value. +// For example, all create functions does return NULL on failure. Other may return FALSE. +// It may be interesting, for the developer, to know why the function is failing. +// for that reason, lcms2 does offer a logging function. This function will get +// an ENGLISH string with some clues on what is going wrong. You can show this +// info to the end user if you wish, or just create some sort of log on disk. +// The logging function should NOT terminate the program, as this obviously can leave +// unfreed resources. It is the programmer's responsibility to check each function +// return code to make sure it didn't fail. + +CONST + + cmsERROR_UNDEFINED = 0; + cmsERROR_FILE = 1; + cmsERROR_RANGE = 2; + cmsERROR_INTERNAL = 3; + cmsERROR_NULL = 4; + cmsERROR_READ = 5; + cmsERROR_SEEK = 6; + cmsERROR_WRITE = 7; + cmsERROR_UNKNOWN_EXTENSION = 8; + cmsERROR_COLORSPACE_CHECK = 9; + cmsERROR_ALREADY_DEFINED = 10; + cmsERROR_BAD_SIGNATURE = 11; + cmsERROR_CORRUPTION_DETECTED = 12; + cmsERROR_NOT_SUITABLE = 13; + +// Error logger is called with the ContextID when a message is raised. This gives the +// chance to know which thread is responsible of the warning and any environment associated +// with it. Non-multithreading applications may safely ignore this parameter. +// Note that under certain special circumstances, ContextID may be NULL. + +TYPE + + cmsLogErrorHandlerFunction = PROCEDURE( ContextID: cmsContext; ErrorCode: cmsUInt32Number; Text: PAnsiChar); CDecl; + + // Allows user to set any specific logger + PROCEDURE cmsSetLogErrorHandler(Fn: cmsLogErrorHandlerFunction); StdCall; + + +// Conversions -------------------------------------------------------------------------------------------------------------- + + +// Returns pointers to constant structs +FUNCTION cmsD50_XYZ: LPcmsCIEXYZ; StdCall; +FUNCTION cmsD50_xyY: LPcmsCIExyY; StdCall; + +// Colorimetric space conversions +PROCEDURE cmsXYZ2xyY(Dest: LPcmsCIExyY; Source: LPcmsCIEXYZ); StdCall; +PROCEDURE cmsxyY2XYZ(Dest: LPcmsCIEXYZ; Source: LPcmsCIExyY); StdCall; +PROCEDURE cmsLab2XYZ(WhitePoint: LPcmsCIEXYZ; xyz: LPcmsCIEXYZ; Lab: LPcmsCIELab); StdCall; +PROCEDURE cmsXYZ2Lab(WhitePoint: LPcmsCIEXYZ; Lab: LPcmsCIELab; xyz: LPcmsCIEXYZ); StdCall; +PROCEDURE cmsLab2LCh(LCh: LPcmsCIELCh; Lab: LPcmsCIELab); StdCall; +PROCEDURE cmsLCh2Lab(Lab: LPcmsCIELab; LCh: LPcmsCIELCh); StdCall; + +// Encoding /Decoding on PCS +PROCEDURE cmsLabEncoded2Float(Lab: LPcmsCIELab; wLab: Pointer); StdCall; +PROCEDURE cmsLabEncoded2FloatV2(Lab: LPcmsCIELab; wLab: Pointer); StdCall; +PROCEDURE cmsFloat2LabEncoded(wLab: Pointer; Lab: LPcmsCIELab); StdCall; +PROCEDURE cmsFloat2LabEncodedV2(wLab: Pointer; Lab: LPcmsCIELab); StdCall; +PROCEDURE cmsXYZEncoded2Float(fxyz : LPcmsCIEXYZ; XYZ: Pointer); StdCall; +PROCEDURE cmsFloat2XYZEncoded(XYZ: Pointer; fXYZ: LPcmsCIEXYZ); StdCall; + + +// DeltaE metrics +FUNCTION cmsDeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; +FUNCTION cmsCIE94DeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; +FUNCTION cmsBFDdeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; +FUNCTION cmsCMCdeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; +FUNCTION cmsCIE2000DeltaE(Lab1, Lab2: LPcmsCIELab; Kl, Kc, Kh: Double): Double; StdCall; + + +// Temperature <-> Chromaticity (Black body) +FUNCTION cmsWhitePointFromTemp(var WhitePoint: cmsCIExyY; TempK: cmsFloat64Number) : cmsBool; StdCall; +FUNCTION cmsTempFromWhitePoint(var TeampK: cmsFloat64Number; var WhitePoint: cmsCIExyY) : cmsBool; StdCall; + + +// Chromatic adaptation +FUNCTION cmsAdaptToIlluminant(Result: LPcmsCIEXYZ; SourceWhitePt: LPcmsCIEXYZ; + Illuminant: LPcmsCIEXYZ; Value: LPcmsCIEXYZ): cmsBool; StdCall; + + +// CIECAM02 --------------------------------------------------------------------------------------------------- + +// Viewing conditions. Please note those are CAM model viewing conditions, and not the ICC tag viewing +// conditions, which I'm naming cmsICCViewingConditions to make differences evident. Unfortunately, the tag +// cannot deal with surround La, Yb and D value so is basically useless to store CAM02 viewing conditions. + + CONST + + AVG_SURROUND = 1; + DIM_SURROUND = 2; + DARK_SURROUND = 3; + CUTSHEET_SURROUND = 4; + + D_CALCULATE = -1; + + TYPE + + cmsViewingConditions = PACKED RECORD + + WhitePoint: cmsCIEXYZ; + Yb : cmsFloat64Number; + La : cmsFloat64Number; + surround : Integer; + D_value : cmsFloat64Number + END; + + + LPcmsViewingConditions = ^cmsViewingConditions; + +FUNCTION cmsCIECAM02Init(pVC : LPcmsViewingConditions ) : Pointer; StdCall; +PROCEDURE cmsCIECAM02Done(hModel : Pointer); StdCall; +PROCEDURE cmsCIECAM02Forward(hModel: Pointer; pIn: LPcmsCIEXYZ; pOut: LPcmsJCh ); StdCall; +PROCEDURE cmsCIECAM02Reverse(hModel: Pointer; pIn: LPcmsJCh; pOut: LPcmsCIEXYZ ); StdCall; + +// Tone curves ----------------------------------------------------------------------------------------- + +// This describes a curve segment. For a table of supported types, see the manual. User can increase the number of +// available types by using a proper plug-in. Parametric segments allow 10 parameters at most + +TYPE +cmsCurveSegment = PACKED RECORD + x0, x1: cmsFloat32Number; // Domain; for x0 < x <= x1 + PType: cmsInt32Number; // Parametric type, Type == 0 means sampled segment. Negative values are reserved + Params: array [0..9] of cmsFloat64Number; // Parameters if Type != 0 + nGridPoints: cmsUInt32Number; // Number of grid points if Type == 0 + SampledPoints: LPcmsFloat32Number; // Points to an array of floats if Type == 0 +END; + +LPcmsToneCurve = Pointer; +LPcmsCurveSegmentArray = ^cmsCurveSegmentArray; +cmsCurveSegmentArray = array[0..0] of cmsCurveSegment; + +LPcmsFloat64NumberArray = ^cmsFloat64NumberArray; +cmsFloat64NumberArray = array[0..0] of cmsFloat64Number; + +LPcmsUInt16NumberArray = ^cmsUInt16NumberArray; +cmsUInt16NumberArray = array[0..0] of cmsUInt16Number; + +LPcmsFloat32NumberArray = ^cmsFloat32NumberArray; +cmsFloat32NumberArray = array[0..0] of cmsFloat32Number; + +LPLPcmsToneCurveArray = ^LPcmsToneCurveArray; +LPcmsToneCurveArray = array[0..0] of LPcmsToneCurve; + +LPcmsUInt32NumberArray = ^cmsUInt32NumberArray; +cmsUInt32NumberArray = array[0..0] of cmsUInt32Number; + +FUNCTION cmsBuildSegmentedToneCurve(ContextID: cmsContext; nSegments: cmsInt32Number; Segments: LPcmsCurveSegmentArray): LPcmsToneCurve; StdCall; +FUNCTION cmsBuildParametricToneCurve(ContextID: cmsContext; CType: cmsInt32Number; Params: LPcmsFloat64NumberArray): LPcmsToneCurve; StdCall; +FUNCTION cmsBuildGamma(ContextID: cmsContext; Gamma: cmsFloat64Number): LPcmsToneCurve; StdCall; +FUNCTION cmsBuildTabulatedToneCurve16(ContextID: cmsContext; nEntries: cmsInt32Number; values: LPcmsUInt16NumberArray): LPcmsToneCurve; StdCall; +FUNCTION cmsBuildTabulatedToneCurveFloat(ContextID: cmsContext; nEntries: cmsUInt32Number; values: LPcmsFloat32NumberArray): LPcmsToneCurve; StdCall; +PROCEDURE cmsFreeToneCurve(Curve: LPcmsToneCurve); StdCall; +PROCEDURE cmsFreeToneCurveTriple(Curve: LPLPcmsToneCurveArray); StdCall; +FUNCTION cmsDupToneCurve(Src: LPcmsToneCurve): LPcmsToneCurve; StdCall; +FUNCTION cmsReverseToneCurve(InGamma: LPcmsToneCurve): LPcmsToneCurve; StdCall; +FUNCTION cmsReverseToneCurveEx(nResultSamples: cmsInt32Number; InGamma: LPcmsToneCurve): LPcmsToneCurve; StdCall; +FUNCTION cmsJoinToneCurve(ContextID: cmsContext; X, Y: LPcmsToneCurve; nPoints: cmsUInt32Number ): LPcmsToneCurve; StdCall; +FUNCTION cmsSmoothToneCurve(Tab: LPcmsToneCurve; lambda: cmsFloat64Number): cmsBool; StdCall; +FUNCTION cmsEvalToneCurveFloat(Curve: LPcmsToneCurve; v: cmsFloat32Number):cmsFloat32Number; StdCall; +FUNCTION cmsEvalToneCurve16(Curve: LPcmsToneCurve; v:cmsUInt16Number):cmsUInt16Number; StdCall; +FUNCTION cmsIsToneCurveMultisegment(InGamma: LPcmsToneCurve):cmsBool; StdCall; +FUNCTION cmsIsToneCurveLinear(Curve: LPcmsToneCurve):cmsBool; StdCall; +FUNCTION cmsIsToneCurveMonotonic(t: LPcmsToneCurve):cmsBool; StdCall; +FUNCTION cmsIsToneCurveDescending(t: LPcmsToneCurve):cmsBool; StdCall; +FUNCTION cmsGetToneCurveParametricType(t: LPcmsToneCurve):cmsInt32Number; StdCall; +FUNCTION cmsEstimateGamma(t: LPcmsToneCurve; Precision:cmsFloat64Number):cmsFloat64Number; StdCall; +FUNCTION cmsGetToneCurveEstimatedTableEntries(t: LPcmsToneCurve): cmsUInt32Number; StdCall; +FUNCTION cmsGetToneCurveEstimatedTable(t: LPcmsToneCurve): LPcmsUInt16Number; StdCall; + + +// Implements pipelines of multi-processing elements ------------------------------------------------------------- + +TYPE + LPcmsPipeline = Pointer; + LPcmsStage = Pointer; + LPLPcmsStage = ^LPcmsStage; + +// Those are hi-level pipelines +FUNCTION cmsPipelineAlloc(ContextID: cmsContext; InputChannels, OutputChannels: cmsUInt32Number): LPcmsPipeline; StdCall; +PROCEDURE cmsPipelineFree(lut: LPcmsPipeline); StdCall; +FUNCTION cmsPipelineDup(Orig: LPcmsPipeline): LPcmsPipeline; StdCall; +FUNCTION cmsGetPipelineContextID(lut: LPcmsPipeline) : cmsContext; StdCall; +FUNCTION cmsPipelineInputChannels(lut: LPcmsPipeline): cmsUInt32Number; StdCall; +FUNCTION cmsPipelineOutputChannels(lut: LPcmsPipeline): cmsUInt32Number; StdCall; + +FUNCTION cmsPipelineStageCount(lut: LPcmsPipeline): cmsUInt32Number; StdCall; +FUNCTION cmsPipelineGetPtrToFirstStage(lut: LPcmsPipeline): LPcmsStage; StdCall; +FUNCTION cmsPipelineGetPtrToLastStage(lut: LPcmsPipeline): LPcmsStage; StdCall; + +PROCEDURE cmsPipelineEval16(Inv, Outv: LPcmsUInt16NumberArray; lut: LPcmsPipeline); StdCall; +PROCEDURE cmsPipelineEvalFloat(Inv, Outv: LPcmsFloat32NumberArray; lut: LPcmsPipeline); StdCall; + +FUNCTION cmsPipelineEvalReverseFloat(Target, Result, Hint: LPcmsFloat32NumberArray; lut: LPcmsPipeline): cmsBool; StdCall; +FUNCTION cmsPipelineCat(l1, l2: LPcmsPipeline): cmsBool; StdCall; +FUNCTION cmsPipelineSetSaveAs8bitsFlag(lut: LPcmsPipeline; On: cmsBool): cmsBool; StdCall; + +// Where to place/locate the stages in the pipeline chain +TYPE + cmsStageLoc = (cmsAT_BEGIN = 0, cmsAT_END = 1 ); + +PROCEDURE cmsPipelineInsertStage(lut: LPcmsPipeline; loc: cmsStageLoc; mpe: LPcmsStage); StdCall; +PROCEDURE cmsPipelineUnlinkStage(lut: LPcmsPipeline; loc: cmsStageLoc; mpe: LPLPcmsStage); StdCall; + +// This function is quite useful to analyze the structure of a Pipeline and retrieve the Stage elements +// that conform the Pipeline. It should be called with the Pipeline, the number of expected elements and +// then a list of expected types followed with a list of double pointers to Stage elements. If +// the function founds a match with current pipeline, it fills the pointers and returns TRUE +// if not, returns FALSE without touching anything. +// FUNCTION cmsPipelineCheckAndRetreiveStages(const cmsPipeline* Lut, n: cmsUInt32Number, ...): cmsBool; StdCall; + +// Matrix has double precision and CLUT has only float precision. That is because an ICC profile can encode +// matrices with far more precision that CLUTS +FUNCTION cmsStageAllocIdentity(ContextID: cmsContext; nChannels: cmsUInt32Number): LPcmsStage; StdCall; +FUNCTION cmsStageAllocToneCurves(ContextID: cmsContext; nChannels: cmsUInt32Number; Curves: LPLPcmsToneCurveArray): LPcmsStage; StdCall; +FUNCTION cmsStageAllocMatrix(ContextID: cmsContext; Rows, Cols: cmsUInt32Number; Matrix, Offset: LPcmsFloat64NumberArray): LPcmsStage; StdCall; + +FUNCTION cmsStageAllocCLut16bit(ContextID: cmsContext; nGridPoints: cmsUInt32Number; inputChan, outputChan: cmsUInt32Number; Table: LPcmsUInt16NumberArray): LPcmsStage; StdCall; +FUNCTION cmsStageAllocCLutFloat(ContextID: cmsContext; nGridPoints: cmsUInt32Number; inputChan, outputChan: cmsUInt32Number; Table: LPcmsFloat32NumberArray): LPcmsStage; StdCall; + +FUNCTION cmsStageAllocCLut16bitGranular(ContextID: cmsContext; nGridPoints: LPcmsUInt32NumberArray; inputChan, outputChan: cmsUInt32Number; Table: LPcmsUInt16NumberArray): LPcmsStage; StdCall; +FUNCTION cmsStageAllocCLutFloatGranular(ContextID: cmsContext; nGridPoints: LPcmsUInt32NumberArray; inputChan, outputChan: cmsUInt32Number; Table: LPcmsFloat32NumberArray): LPcmsStage; StdCall; + + +FUNCTION cmsStageDup(mpe: LPcmsStage): LPcmsStage; StdCall; +PROCEDURE cmsStageFree(mpe: LPcmsStage); StdCall; +FUNCTION cmsStageNext(mpe: LPcmsStage): LPcmsStage; StdCall; + +FUNCTION cmsStageInputChannels(mpe: LPcmsStage): cmsUInt32Number; StdCall; +FUNCTION cmsStageOutputChannels(mpe: LPcmsStage): cmsUInt32Number; StdCall; +FUNCTION cmsStageType(mpe: LPcmsStage): cmsStageSignature; StdCall; +FUNCTION cmsStageData(mpe: LPcmsStage): Pointer; StdCall; + +// Sampling + +Type + cmsSAMPLER16 = FUNCTION (Inp, Outp: LPcmsUInt16NumberArray; Cargo: Pointer): cmsInt32Number; CDecl; + cmsSAMPLERFLOAT = FUNCTION (Inp, Outp: LPcmsFloat32NumberArray; Cargo: Pointer): cmsInt32Number; CDecl; + +// Use this flag to prevent changes being written to destination + +Const + +SAMPLER_INSPECT = $01000000; + + +// For CLUT only +FUNCTION cmsStageSampleCLut16bit(mpe: LPcmsStage; Sampler: cmsSAMPLER16; Cargo: Pointer; dwFlags: cmsUInt32Number): cmsBool; StdCall; +FUNCTION cmsStageSampleCLutFloat(mpe: LPcmsStage; Sampler: cmsSAMPLERFLOAT; Cargo: Pointer; dwFlags: cmsUInt32Number): cmsBool; StdCall; + + +// Slicers +FUNCTION cmsSliceSpace16(nInputs: cmsUInt32Number; clutPoints: LPcmsUInt32NumberArray; + Sampler: cmsSAMPLER16; Cargo: Pointer): cmsBool; StdCall; + +FUNCTION cmsSliceSpaceFloat(nInputs: cmsUInt32Number; clutPoints: LPcmsUInt32NumberArray; + Sampler: cmsSAMPLERFLOAT; Cargo: Pointer): cmsBool; StdCall; + +// Multilocalized Unicode management --------------------------------------------------------------------------------------- + +Type + LPcmsMLU = Pointer; + +Const + +cmsNoLanguage = #0#0#0; +cmsNoCountry = #0#0#0; + + +FUNCTION cmsMLUalloc(ContextID: cmsContext; nItems: cmsUInt32Number): LPcmsMLU; StdCall; +PROCEDURE cmsMLUfree(mlu: LPcmsMLU); StdCall; +FUNCTION cmsMLUdup(mlu: LPcmsMLU): LPcmsMLU; StdCall; + +FUNCTION cmsMLUsetASCII(mlu: LPcmsMLU; LanguageCode, CountryCode, ASCIIString: PAnsiChar): cmsBool; StdCall; +FUNCTION cmsMLUsetWide(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; WideString: PWChar): cmsBool; StdCall; + +FUNCTION cmsMLUgetASCII(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; Buffer: PAnsiChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; + +FUNCTION cmsMLUgetWide(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; Buffer: PWChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; + +FUNCTION cmsMLUgetTranslation(mlu: LPcmsMLU; LanguageCode, CountryCode, ObtainedLanguage, ObtainedCountry: PAnsiChar): cmsBool; StdCall; + +// Undercolorremoval & black generation ------------------------------------------------------------------------------------- + +Type + +cmsUcrBg = PACKED RECORD + Ucr, Bg: LPcmsToneCurve; + Desc: LPcmsMLU; + END; + + +// Screening ---------------------------------------------------------------------------------------------------------------- + +Const + + cmsPRINTER_DEFAULT_SCREENS = $0001; + cmsFREQUENCE_UNITS_LINES_CM = $0000; + cmsFREQUENCE_UNITS_LINES_INCH = $0002; + + cmsSPOT_UNKNOWN = 0; + cmsSPOT_PRINTER_DEFAULT = 1; + cmsSPOT_ROUND = 2; + cmsSPOT_DIAMOND = 3; + cmsSPOT_ELLIPSE = 4; + cmsSPOT_LINE = 5; + cmsSPOT_SQUARE = 6; + cmsSPOT_CROSS = 7; + + +Type + +cmsScreeningChannel = PACKED RECORD + + Frequency, + ScreenAngle: cmsFloat64Number; + SpotShape: cmsUInt32Number; + +END; + +cmsScreening = PACKED RECORD + + Flag, + nChannels : cmsUInt32Number; + Channels: Array [0..cmsMAXCHANNELS-1] OF cmsScreeningChannel; +END; + + +// Named color ----------------------------------------------------------------------------------------------------------------- + + +LPcmsNAMEDCOLORLIST = Pointer; + +FUNCTION cmsAllocNamedColorList(ContextID: cmsContext; n, ColorantCount :cmsUInt32Number; + Prefix, Suffix: PAnsiChar): LPcmsNAMEDCOLORLIST; StdCall; + +PROCEDURE cmsFreeNamedColorList(v: LPcmsNAMEDCOLORLIST); StdCall; +FUNCTION cmsDupNamedColorList(v: LPcmsNAMEDCOLORLIST): LPcmsNAMEDCOLORLIST; StdCall; +FUNCTION cmsAppendNamedColor(v: LPcmsNAMEDCOLORLIST; Name: PAnsiChar; + PCS, Colorant : LPcmsUInt16NumberArray): cmsBool; StdCall; + +FUNCTION cmsNamedColorCount(v: LPcmsNAMEDCOLORLIST): cmsUInt32Number; StdCall; +FUNCTION cmsNamedColorIndex(v: LPcmsNAMEDCOLORLIST; Name: PAnsiChar): cmsInt32Number; StdCall; + +FUNCTION cmsNamedColorInfo(v: LPcmsNAMEDCOLORLIST; nColor : cmsUInt32Number; + Name,Prefix, Suffix : PAnsiChar; + PCS, Colorant : LPcmsUInt16NumberArray): cmsBool; StdCall; + +// Retrieve named color list from transform +FUNCTION cmsGetNamedColorList(xform: cmsHTRANSFORM ): LPcmsNAMEDCOLORLIST; StdCall; + +// Profile sequence ----------------------------------------------------------------------------------------------------- + +Type + +// Profile sequence descriptor. Some fields come from profile sequence descriptor tag, others +// come from Profile Sequence Identifier Tag + +cmsPSEQDESC = PACKED RECORD + deviceMfg, deviceModel: cmsSignature; + + attributes: cmsUInt64Number; + technology: cmsTechnologySignature; + ProfileID: cmsProfileID; + Manufacturer, + Model, + Description : LPcmsMLU; + END; + + LPcmsSEQDESC = ^cmsPSEQDESC; + +cmsSEQ = PACKED RECORD + + n: cmsUInt32Number; + ContextID: cmsContext; + seq: LPcmsSEQDESC; +END; + +LPcmsSEQ = ^cmsSEQ; + +FUNCTION cmsAllocProfileSequenceDescription(ContextID: cmsContext; n: cmsUInt32Number):LPcmsSEQ; StdCall; +FUNCTION cmsDupProfileSequenceDescription(pseq: LPcmsSEQ):LPcmsSEQ; StdCall; +PROCEDURE cmsFreeProfileSequenceDescription(pseq: LPcmsSEQ); StdCall; + +// Dictionaries -------------------------------------------------------------------------------------------------------- + +TYPE + + LPcmsDICTentry = ^cmsDICTentry; + +cmsDICTentry = PACKED RECORD + + Next: LPcmsDICTentry; + + DisplayName, DisplayValue: LPcmsMLU; + Name, Value : PWChar; +END; + +FUNCTION cmsDictAlloc(ContextID: cmsContext): cmsHANDLE; StdCall; +PROCEDURE cmsDictFree(hDict: cmsHANDLE); StdCall; +FUNCTION cmsDictDup(hDict: cmsHANDLE): cmsHANDLE; StdCall; + +FUNCTION cmsDictAddEntry(hDict: cmsHANDLE; Name, Value: PWChar; DisplayName, DisplayValue : LPcmsMLU): cmsBool; StdCall; +FUNCTION cmsDictGetEntryList(hDict: cmsHANDLE): LPcmsDICTentry; StdCall; +FUNCTION cmsDictNextEntry(e : LPcmsDICTentry): LPcmsDICTentry; StdCall; + +// Access to Profile data ---------------------------------------------------------------------------------------------- +FUNCTION cmsCreateProfilePlaceholder(ContextID: cmsContext): cmsHPROFILE; StdCall; + +FUNCTION cmsGetProfileContextID(hProfile: cmsHPROFILE):cmsContext; StdCall; +FUNCTION cmsGetTagCount(hProfile: cmsHPROFILE): cmsInt32Number; StdCall; +FUNCTION cmsGetTagSignature(hProfile: cmsHPROFILE; n: cmsUInt32Number): cmsTagSignature; StdCall; +FUNCTION cmsIsTag(hProfile: cmsHPROFILE; sig: cmsTagSignature ): cmsBool; StdCall; + +// Read and write pre-formatted data +FUNCTION cmsReadTag(hProfile: cmsHPROFILE; sig: cmsTagSignature ): Pointer; StdCall; +FUNCTION cmsWriteTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; data: Pointer): cmsBool; StdCall; +FUNCTION cmsLinkTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; dest: cmsTagSignature): cmsBool; StdCall; +FUNCTION cmsTagLinkedTo(hProfile: cmsHPROFILE; sig: cmsTagSignature):cmsTagSignature; StdCall; + +// Read and write raw data +FUNCTION cmsReadRawTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; Buffer: Pointer; BufferSize: cmsUInt32Number): cmsInt32Number; StdCall; +FUNCTION cmsWriteRawTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; data: Pointer; Size: cmsUInt32Number): cmsBool; StdCall; + +// Access header data +Const + + cmsEmbeddedProfileFalse = $00000000; + cmsEmbeddedProfileTrue = $00000001; + cmsUseAnywhere = $00000000; + cmsUseWithEmbeddedDataOnly = $00000002; + +FUNCTION cmsGetHeaderFlags(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; +PROCEDURE cmsGetHeaderAttributes(hProfile: cmsHPROFILE; Flags: LPcmsUInt64Number); StdCall; +PROCEDURE cmsGetHeaderProfileID(hProfile: cmsHPROFILE; ProfileID: LPcmsUInt8Number); StdCall; + +// TODO: +// FUNCTION cmsGetHeaderCreationDateTime(hProfile: cmsHPROFILE; struct tm *Dest): cmsBool; StdCall; + +FUNCTION cmsGetHeaderRenderingIntent(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; +PROCEDURE cmsSetHeaderFlags(hProfile: cmsHPROFILE; Flags: cmsUInt32Number); StdCall; +FUNCTION cmsGetHeaderManufacturer(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; +PROCEDURE cmsSetHeaderManufacturer(hProfile: cmsHPROFILE; manufacturer: cmsUInt32Number ); StdCall; +FUNCTION cmsGetHeaderModel(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; +PROCEDURE cmsSetHeaderModel(hProfile: cmsHPROFILE; model: cmsUInt32Number ); StdCall; +PROCEDURE cmsSetHeaderAttributes(hProfile: cmsHPROFILE; Flags: cmsUInt64Number); StdCall; +PROCEDURE cmsSetHeaderProfileID(hProfile: cmsHPROFILE; ProfileID: LPcmsUInt8Number); StdCall; +PROCEDURE cmsSetHeaderRenderingIntent(hProfile: cmsHPROFILE; RenderingIntent: cmsUInt32Number ); StdCall; + +FUNCTION cmsGetPCS(hProfile: cmsHPROFILE):cmsColorSpaceSignature; StdCall; +PROCEDURE cmsSetPCS(hProfile: cmsHPROFILE; pcs: cmsColorSpaceSignature); StdCall; +FUNCTION cmsGetColorSpace(hProfile: cmsHPROFILE): cmsColorSpaceSignature; StdCall; +PROCEDURE cmsSetColorSpace(hProfile: cmsHPROFILE; sig: cmsColorSpaceSignature); StdCall; +FUNCTION cmsGetDeviceClass(hProfile: cmsHPROFILE): cmsProfileClassSignature; StdCall; +PROCEDURE cmsSetDeviceClass(hProfile: cmsHPROFILE; sig: cmsProfileClassSignature); StdCall; +PROCEDURE cmsSetProfileVersion(hProfile: cmsHPROFILE; Version: cmsFloat64Number); StdCall; +FUNCTION cmsGetProfileVersion(hProfile: cmsHPROFILE): cmsFloat64Number; StdCall; + +FUNCTION cmsGetEncodedICCversion(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; +PROCEDURE cmsSetEncodedICCversion(hProfile: cmsHPROFILE; Version: cmsUInt32Number); StdCall; + + +Const + + // How profiles may be used + LCMS_USED_AS_INPUT = 0; + LCMS_USED_AS_OUTPUT = 1; + LCMS_USED_AS_PROOF = 2; + +FUNCTION cmsIsIntentSupported(hProfile: cmsHPROFILE; Intent: cmsUInt32Number; UsedDirection: cmsUInt32Number): cmsBool; StdCall; +FUNCTION cmsIsMatrixShaper(hProfile: cmsHPROFILE): cmsBool; StdCall; +FUNCTION cmsIsCLUT(hProfile: cmsHPROFILE; Intent: cmsUInt32Number; UsedDirection: cmsUInt32Number): cmsBool; StdCall; + +// Translate form/to our notation to ICC +FUNCTION _cmsICCcolorSpace(OurNotation: Integer): cmsColorSpaceSignature; StdCall; +FUNCTION _cmsLCMScolorSpace(ProfileSpace: cmsColorSpaceSignature): Integer; StdCall; + +FUNCTION cmsChannelsOf( ColorSpace: cmsColorSpaceSignature): cmsUInt32Number; StdCall; + +// Build a suitable formatter for the colorspace of this profile +FUNCTION cmsFormatterForColorspaceOfProfile(hProfile: cmsHPROFILE; nBytes: cmsUInt32Number; lIsFloat: cmsBool): cmsUInt32Number; StdCall; +FUNCTION cmsFormatterForPCSOfProfile(hProfile: cmsHPROFILE; nBytes: cmsUInt32Number; lIsFloat: cmsBool): cmsUInt32Number; StdCall; + +Type + +// Localized info +cmsInfoType = ( + cmsInfoDescription = 0, + cmsInfoManufacturer = 1, + cmsInfoModel = 2, + cmsInfoCopyright = 3 +); + +FUNCTION cmsGetProfileInfo(hProfile: cmsHPROFILE; Info: cmsInfoType; LanguageCode, CountryCode: PAnsiChar; + Buffer: PWChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; + +FUNCTION cmsGetProfileInfoASCII(hProfile: cmsHPROFILE; Info: cmsInfoType; LanguageCode, CountryCode: PAnsiChar; + Buffer: PAnsiChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; + +// IO handlers ---------------------------------------------------------------------------------------------------------- + +Type + +LPcmsIOHANDLER = Pointer; + +FUNCTION cmsOpenIOhandlerFromFile(ContextID: cmsContext; FileName, AccessMode: PAnsiChar): LPcmsIOHANDLER; StdCall; +// FUNCTION cmsOpenIOhandlerFromStream(ContextID: cmsContext; FILE* Stream): LPcmsIOHANDLER; StdCall; +FUNCTION cmsOpenIOhandlerFromMem(ContextID: cmsContext; Buffer: Pointer; size: cmsUInt32Number; AccessMode: PAnsiChar): LPcmsIOHANDLER; StdCall; +FUNCTION cmsOpenIOhandlerFromNULL(ContextID: cmsContext): LPcmsIOHANDLER; StdCall; +FUNCTION cmsCloseIOhandler(io: LPcmsIOHANDLER): cmsBool; StdCall; + +// MD5 message digest -------------------------------------------------------------------------------------------------- + +FUNCTION cmsMD5computeID(hProfile: cmsHPROFILE): cmsBool; StdCall; + +// Profile high level funtions ------------------------------------------------------------------------------------------ + +FUNCTION cmsOpenProfileFromFile(ICCProfile : PAnsiChar; sAccess: PAnsiChar): cmsHPROFILE; StdCall; +FUNCTION cmsOpenProfileFromFileTHR(ContextID: cmsContext; ICCProfile, sAccess: PAnsiChar): cmsHPROFILE; StdCall; +// FUNCTION CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char* sAccess): cmsHPROFILE; StdCall; +// FUNCTION CMSEXPORT cmsOpenProfileFromStreamTHR(ContextID: cmsContext; FILE* ICCProfile, const char* sAccess): cmsHPROFILE; StdCall; +FUNCTION cmsOpenProfileFromMem(MemPtr: Pointer; dwSize: cmsUInt32Number): cmsHPROFILE; StdCall; +FUNCTION cmsOpenProfileFromMemTHR(ContextID: cmsContext; MemPtr: Pointer; dwSize: cmsUInt32Number): cmsHPROFILE; StdCall; +FUNCTION cmsOpenProfileFromIOhandlerTHR(ContextID: cmsContext; io: LPcmsIOHANDLER): cmsHPROFILE; StdCall; +FUNCTION cmsCloseProfile(hProfile: cmsHPROFILE): cmsBool; StdCall; + +FUNCTION cmsSaveProfileToFile(hProfile: cmsHPROFILE; FileName: PAnsiChar): cmsBool; StdCall; +// FUNCTION CMSEXPORT cmsSaveProfileToStream(hProfile: cmsHPROFILE, FILE* Stream): cmsBool; StdCall; +FUNCTION cmsSaveProfileToMem(hProfile: cmsHPROFILE; MemPtr: Pointer; BytesNeeded: LPcmsUInt32Number): cmsBool; StdCall; +FUNCTION cmsSaveProfileToIOhandler(hProfile: cmsHPROFILE; io: LPcmsIOHANDLER):cmsUInt32Number; StdCall; + +// Predefined virtual profiles ------------------------------------------------------------------------------------------ + +FUNCTION cmsCreateRGBProfileTHR(ContextID: cmsContext; + WhitePoint: LPcmsCIExyY; + Primaries: LPcmsCIExyYTRIPLE; + TransferFunction: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateRGBProfile(WhitePoint: LPcmsCIExyY; + Primaries: LPcmsCIExyYTRIPLE; + TransferFunction: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateGrayProfileTHR(ContextID: cmsContext; + WhitePoint: LPcmsCIExyY; + TransferFunction: LPcmsToneCurve): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateGrayProfile(WhitePoint: LPcmsCIExyY; + TransferFunction: LPcmsToneCurve): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateLinearizationDeviceLinkTHR(ContextID: cmsContext; + ColorSpace: cmsColorSpaceSignature; + TransferFunctions: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateLinearizationDeviceLink(ColorSpace: cmsColorSpaceSignature; + TransferFunctions: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateInkLimitingDeviceLinkTHR(ContextID: cmsContext; + ColorSpace: cmsColorSpaceSignature; Limit: cmsFloat64Number): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateInkLimitingDeviceLink(ColorSpace: cmsColorSpaceSignature; Limit: cmsFloat64Number): cmsHPROFILE; StdCall; + + +FUNCTION cmsCreateLab2ProfileTHR(ContextID: cmsContext; WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; +FUNCTION cmsCreateLab2Profile(WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; +FUNCTION cmsCreateLab4ProfileTHR(ContextID: cmsContext; WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; +FUNCTION cmsCreateLab4Profile(WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateXYZProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; +FUNCTION cmsCreateXYZProfile: cmsHPROFILE; StdCall; + +FUNCTION cmsCreate_sRGBProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; +FUNCTION cmsCreate_sRGBProfile: cmsHPROFILE; StdCall; + +FUNCTION cmsCreateBCHSWabstractProfileTHR(ContextID: cmsContext; + nLUTPoints: Integer; + Bright, + Contrast, + Hue, + Saturation: cmsFloat64Number; + TempSrc, + TempDest: Integer): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateBCHSWabstractProfile( nLUTPoints: Integer; + Bright, + Contrast, + Hue, + Saturation: cmsFloat64Number; + TempSrc, + TempDest: Integer): cmsHPROFILE; StdCall; + +FUNCTION cmsCreateNULLProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; +FUNCTION cmsCreateNULLProfile: cmsHPROFILE; StdCall; + +// Converts a transform to a devicelink profile +FUNCTION cmsTransform2DeviceLink(hTransform: cmsHTRANSFORM; Version: cmsFloat64Number; dwFlags: cmsUInt32Number): cmsHPROFILE; StdCall; + +// Intents ---------------------------------------------------------------------------------------------- + +Const + +// ICC Intents +INTENT_PERCEPTUAL = 0; +INTENT_RELATIVE_COLORIMETRIC = 1; +INTENT_SATURATION = 2; +INTENT_ABSOLUTE_COLORIMETRIC = 3; + +// Non-ICC intents +INTENT_PRESERVE_K_ONLY_PERCEPTUAL = 10; +INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC = 11; +INTENT_PRESERVE_K_ONLY_SATURATION = 12; +INTENT_PRESERVE_K_PLANE_PERCEPTUAL = 13; +INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC = 14; +INTENT_PRESERVE_K_PLANE_SATURATION = 15; + +Type +LPPAnsiChar = ^PAnsiChar; + +// Call with NULL as parameters to get the intent count +FUNCTION cmsGetSupportedIntents(nMax: cmsUInt32Number; Codes: LPcmsUInt32Number; Descriptions: LPPAnsiChar): cmsUInt32Number; StdCall; + +Const + +// Flags + +cmsFLAGS_NOCACHE = $0040; // Inhibit 1-pixel cache +cmsFLAGS_NOOPTIMIZE = $0100; // Inhibit optimizations +cmsFLAGS_NULLTRANSFORM = $0200; // Don't transform anyway + +// Proofing flags +cmsFLAGS_GAMUTCHECK = $1000; // Out of Gamut alarm +cmsFLAGS_SOFTPROOFING = $4000; // Do softproofing + +// Misc +cmsFLAGS_BLACKPOINTCOMPENSATION = $2000; +cmsFLAGS_NOWHITEONWHITEFIXUP = $0004; // Don't fix scum dot +cmsFLAGS_HIGHRESPRECALC = $0400; // Use more memory to give better accurancy +cmsFLAGS_LOWRESPRECALC = $0800; // Use less memory to minimize resouces + +// For devicelink creation +cmsFLAGS_8BITS_DEVICELINK = $0008; // Create 8 bits devicelinks +cmsFLAGS_GUESSDEVICECLASS = $0020; // Guess device class (for transform2devicelink) +cmsFLAGS_KEEP_SEQUENCE = $0080; // Keep profile sequence for devicelink creation + +// Specific to a particular optimizations +cmsFLAGS_FORCE_CLUT = $0002; // Force CLUT optimization +cmsFLAGS_CLUT_POST_LINEARIZATION = $0001; // create postlinearization tables if possible +cmsFLAGS_CLUT_PRE_LINEARIZATION = $0010; // create prelinearization tables if possible + +// CRD special +cmsFLAGS_NODEFAULTRESOURCEDEF = $01000000; + +// Fine-tune control over number of gridpoints +FUNCTION cmsFLAGS_GRIDPOINTS(n: Integer): Integer; + + +// Transforms --------------------------------------------------------------------------------------------------- + +type + LPcmsHPROFILEArray = ^cmsHPROFILEArray; + cmsHPROFILEArray = array[0..0] of cmsHPROFILE; + + LPcmsBoolArray = ^cmsBoolArray; + cmsBoolArray = array[0..0] of cmsBool; + +FUNCTION cmsCreateTransformTHR(ContextID: cmsContext; + Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + +FUNCTION cmsCreateTransform(Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + +FUNCTION cmsCreateProofingTransformTHR(ContextID: cmsContext; + Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Proofing: cmsHPROFILE; + Intent: cmsUInt32Number; + ProofingIntent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + +FUNCTION cmsCreateProofingTransform(Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Proofing: cmsHPROFILE; + Intent: cmsUInt32Number; + ProofingIntent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + +FUNCTION cmsCreateMultiprofileTransformTHR(ContextID: cmsContext; + hProfiles: LPcmsHPROFILEArray; + nProfiles: cmsUInt32Number; + InputFormat: cmsUInt32Number; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + + +FUNCTION cmsCreateMultiprofileTransform( hProfiles: LPcmsHPROFILEArray; + nProfiles: cmsUInt32Number; + InputFormat: cmsUInt32Number; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + + +FUNCTION cmsCreateExtendedTransform(ContextID: cmsContext; + nProfiles: cmsUInt32Number; + hProfiles: LPcmsHPROFILEArray; + BPC: LPcmsBoolArray; + Intents: LPcmsUInt32NumberArray; + AdaptationStates: LPcmsFloat64NumberArray; + hGamutProfile: cmsHPROFILE; + nGamutPCSposition: cmsUInt32Number; + InputFormat, + OutputFormat: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; + +PROCEDURE cmsDeleteTransform(hTransform: cmsHTRANSFORM); StdCall; + +PROCEDURE cmsDoTransform(Transform: cmsHTRANSFORM; InputBuffer, OutputBuffer: Pointer; size: cmsUInt32Number); StdCall; +PROCEDURE cmsDoTransformStride(Transform: cmsHTRANSFORM; InputBuffer, OutputBuffer: Pointer; size: cmsUInt32Number; stride: cmsUInt32Number); StdCall; + + +PROCEDURE cmsSetAlarmCodes( NewAlarm: LPcmsUInt16NumberArray); StdCall; +PROCEDURE cmsGetAlarmCodes(NewAlarm: LPcmsUInt16NumberArray); StdCall; + +// Adaptation state for absolute colorimetric intent +FUNCTION cmsSetAdaptationState(d: cmsFloat64Number):cmsFloat64Number; StdCall; + +// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed +FUNCTION cmsGetTransformContextID(hTransform: cmsHTRANSFORM):cmsContext; StdCall; + +// For backwards compatibility +FUNCTION cmsChangeBuffersFormat(hTransform: cmsHTRANSFORM; InputFormat, OutputFormat: cmsUInt32Number): cmsBool; StdCall; + + + +// PostScript ColorRenderingDictionary and ColorSpaceArray ---------------------------------------------------- + +Type + +cmsPSResourceType = (cmsPS_RESOURCE_CSA, cmsPS_RESOURCE_CRD ) ; + +// lcms2 unified method to access postscript color resources +FUNCTION cmsGetPostScriptColorResource(ContextID: cmsContext; RType: cmsPSResourceType; + hProfile: cmsHPROFILE; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number; + io: LPcmsIOHANDLER): cmsUInt32Number; StdCall; + +FUNCTION cmsGetPostScriptCSA(ContextID: cmsContext; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number; Buffer: Pointer; dwBufferLen: cmsUInt32Number ): cmsUInt32Number; StdCall; +FUNCTION cmsGetPostScriptCRD(ContextID: cmsContext; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number; Buffer: Pointer; dwBufferLen: cmsUInt32Number): cmsUInt32Number; StdCall; + + +// IT8.7 / CGATS.17-20$ handling ----------------------------------------------------------------------------- + + +// CGATS.13 parser + +FUNCTION cmsIT8Alloc: cmsHANDLE; StdCall; +PROCEDURE cmsIT8Free(hIT8: cmsHANDLE); StdCall; + +// Tables + +FUNCTION cmsIT8TableCount(hIT8: cmsHANDLE): Integer; StdCall; +FUNCTION cmsIT8SetTable(hIT8: cmsHANDLE; nTable: Integer): Integer; StdCall; + +// Persistence +FUNCTION cmsIT8LoadFromFile(cFileName: PAnsiChar): cmsHANDLE; StdCall; +FUNCTION cmsIT8LoadFromMem(Ptr: Pointer; size :DWord): cmsHANDLE; StdCall; + +FUNCTION cmsIT8SaveToFile(hIT8: cmsHANDLE; cFileName: PAnsiChar): cmsBool; StdCall; +FUNCTION cmsIT8SaveToMem(hIT8: cmsHANDLE; MemPtr: Pointer; BytesNeeded: LPcmsUInt32Number): cmsBool; StdCall; +// Properties + +FUNCTION cmsIT8GetSheetType(hIT8: cmsHANDLE): PAnsiChar; StdCall; +FUNCTION cmsIT8SetSheetType(hIT8: cmsHANDLE; TheType: PAnsiChar): cmsBool; StdCall; + +FUNCTION cmsIT8SetComment(hIT8: cmsHANDLE; cComment: PAnsiChar): cmsBool; StdCall; + +FUNCTION cmsIT8SetPropertyStr(hIT8: cmsHANDLE; cProp, Str: PAnsiChar): cmsBool; StdCall; +FUNCTION cmsIT8SetPropertyDbl(hIT8: cmsHANDLE; cProp: PAnsiChar; Val: Double): cmsBool; StdCall; +FUNCTION cmsIT8SetPropertyHex(hIT8: cmsHANDLE; cProp: PAnsiChar; Val: Integer): cmsBool; StdCall; +FUNCTION cmsIT8SetPropertyUncooked(hIT8: cmsHANDLE; Key, Buffer: PAnsiChar): cmsBool; StdCall; + + +FUNCTION cmsIT8GetProperty(hIT8: cmsHANDLE; cProp: PAnsiChar): PAnsiChar; StdCall; +FUNCTION cmsIT8GetPropertyDbl(hIT8: cmsHANDLE; cProp: PAnsiChar): Double; StdCall; +FUNCTION cmsIT8EnumProperties(hIT8: cmsHANDLE; var PropertyNames: LPPAnsiChar): Integer; StdCall; + +// Datasets + +FUNCTION cmsIT8GetDataRowCol(hIT8: cmsHANDLE; row, col: Integer): PAnsiChar; StdCall; +FUNCTION cmsIT8GetDataRowColDbl(hIT8: cmsHANDLE; row, col: Integer): Double; StdCall; + +FUNCTION cmsIT8SetDataRowCol(hIT8: cmsHANDLE; row, col: Integer; Val: PAnsiChar): cmsBool; StdCall; +FUNCTION cmsIT8SetDataRowColDbl(hIT8: cmsHANDLE; row, col: Integer; Val: Double): cmsBool; StdCall; + +FUNCTION cmsIT8GetData(hIT8: cmsHANDLE; cPatch, cSample: PAnsiChar): PAnsiChar; StdCall; + +FUNCTION cmsIT8GetDataDbl(hIT8: cmsHANDLE;cPatch, cSample: PAnsiChar): Double; StdCall; + +FUNCTION cmsIT8SetData(hIT8: cmsHANDLE; cPatch, cSample, Val: PAnsiChar): cmsBool; StdCall; + +FUNCTION cmsIT8SetDataDbl(hIT8: cmsHANDLE; cPatch, cSample: PAnsiChar; Val: Double): cmsBool; StdCall; + +FUNCTION cmsIT8SetDataFormat(hIT8: cmsHANDLE; n: Integer; Sample: PAnsiChar): cmsBool; StdCall; +FUNCTION cmsIT8EnumDataFormat(hIT8: cmsHANDLE; var SampleNames: LPPAnsiChar): Integer; StdCall; +FUNCTION cmsIT8GetPatchName(hIT8: cmsHANDLE; nPatch: Integer; Buffer: PAnsiChar): PAnsiChar; StdCall; + +// The LABEL extension +FUNCTION cmsIT8SetTableByLabel(hIT8: cmsHANDLE; cSet, cField, ExpectedType: PAnsiChar): Integer; StdCall; + +FUNCTION cmsIT8FindDataFormat(hIT8: cmsHANDLE; cSample: PAnsiChar): Integer; StdCall; + +// Formatter for double +PROCEDURE cmsIT8DefineDblFormat(hIT8: cmsHANDLE; Formatter: PAnsiChar); StdCall; + +// Gamut boundary description routines ------------------------------------------------------------------------------ + +FUNCTION cmsGBDAlloc(ContextID: cmsContext):cmsHANDLE; StdCall; +PROCEDURE cmsGBDFree(hGBD: cmsHANDLE); StdCall; +FUNCTION cmsGDBAddPoint(hGBD: cmsHANDLE; Lab: LPcmsCIELab): cmsBool; StdCall; +FUNCTION cmsGDBCompute(hGDB: cmsHANDLE; dwFlags: cmsUInt32Number): cmsBool; StdCall; +FUNCTION cmsGDBCheckPoint(hGBD: cmsHANDLE; Lab: LPcmsCIELab): cmsBool; StdCall; + +// Feature detection ---------------------------------------------------------------------------------------------- + +// Estimate the black point +FUNCTION cmsDetectBlackPoint( BlackPoint: LPcmsCIEXYZ; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number): cmsBool; StdCall; +FUNCTION cmsDetectDestinationBlackPoint( BlackPoint: LPcmsCIEXYZ; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number): cmsBool; StdCall; + + +// Estimate total area coverage +FUNCTION cmsDetectTAC(hProfile: cmsHPROFILE): cmsFloat64Number; StdCall; + + +// Poor man's gamut mapping +FUNCTION cmsDesaturateLab(Lab: LPcmsCIELab; amax, amin, bmax, bmin: cmsFloat64Number): cmsBool; StdCall; + + +IMPLEMENTATION + + + + FUNCTION FLOAT_SH(a: cmsUInt32Number): cmsUInt32Number; begin FLOAT_SH := ((a) shl 22) end; + FUNCTION OPTIMIZED_SH(s: cmsUInt32Number): cmsUInt32Number; begin OPTIMIZED_SH := ((s) shl 21) end; + FUNCTION COLORSPACE_SH(s: cmsUInt32Number):cmsUInt32Number; begin COLORSPACE_SH := ((s) shl 16) end; + FUNCTION SWAPFIRST_SH(s: cmsUInt32Number):cmsUInt32Number; begin SWAPFIRST_SH := ((s) shl 14) end; + FUNCTION FLAVOR_SH(s: cmsUInt32Number):cmsUInt32Number; begin FLAVOR_SH := ((s) shl 13) end; + FUNCTION PLANAR_SH(p: cmsUInt32Number):cmsUInt32Number; begin PLANAR_SH := ((p) shl 12) end; + FUNCTION ENDIAN16_SH(e: cmsUInt32Number):cmsUInt32Number; begin ENDIAN16_SH := ((e) shl 11) end; + FUNCTION DOSWAP_SH(e: cmsUInt32Number):cmsUInt32Number; begin DOSWAP_SH := ((e) shl 10) end; + FUNCTION EXTRA_SH(e: cmsUInt32Number):cmsUInt32Number; begin EXTRA_SH := ((e) shl 7) end; + FUNCTION CHANNELS_SH(c: cmsUInt32Number):cmsUInt32Number; begin CHANNELS_SH := ((c) shl 3) end; + FUNCTION BYTES_SH(b: cmsUInt32Number):cmsUInt32Number; begin BYTES_SH := (b) end; + + + FUNCTION T_FLOAT(a: cmsUInt32Number): cmsUInt32Number; begin T_FLOAT := (((a) shr 22) and 1) end; + FUNCTION T_OPTIMIZED(o: cmsUInt32Number): cmsUInt32Number; begin T_OPTIMIZED := (((o) shr 21) and 1) end; + FUNCTION T_COLORSPACE(s: cmsUInt32Number): cmsUInt32Number; begin T_COLORSPACE := (((s) shr 16) and 31) end; + FUNCTION T_SWAPFIRST(s: cmsUInt32Number): cmsUInt32Number; begin T_SWAPFIRST := (((s) shr 14) and 1) end; + FUNCTION T_FLAVOR(s: cmsUInt32Number): cmsUInt32Number; begin T_FLAVOR := (((s) shr 13) and 1) end; + FUNCTION T_PLANAR(p: cmsUInt32Number): cmsUInt32Number; begin T_PLANAR := (((p) shr 12) and 1) end; + FUNCTION T_ENDIAN16(e: cmsUInt32Number): cmsUInt32Number; begin T_ENDIAN16 := (((e) shr 11) and 1) end; + FUNCTION T_DOSWAP(e: cmsUInt32Number): cmsUInt32Number; begin T_DOSWAP := (((e) shr 10) and 1) end; + FUNCTION T_EXTRA(e: cmsUInt32Number): cmsUInt32Number; begin T_EXTRA := (((e) shr 7) and 7) end; + FUNCTION T_CHANNELS(c: cmsUInt32Number): cmsUInt32Number; begin T_CHANNELS := (((c) shr 3) and 15) end; + FUNCTION T_BYTES(b: cmsUInt32Number): cmsUInt32Number; begin T_BYTES := ((b) and 7) end; + + + +// + +FUNCTION cmsCreateContext(Plugin : Pointer; UserData : Pointer) : cmsContext; StdCall; external LCMS2_SO; +PROCEDURE cmsDeleteContext(ContextID: cmsContext); StdCall; external LCMS2_SO; +FUNCTION cmsDupContext(ContextID: cmsContext; NewUserData: Pointer): cmsContext; StdCall; external LCMS2_SO; +FUNCTION cmsGetContextUserData(ContextID: cmsContext): Pointer; StdCall; external LCMS2_SO; + +FUNCTION cmsPlugin(Plugin: Pointer): cmsBool; StdCall; external LCMS2_SO; +PROCEDURE cmsUnregisterPlugins; StdCall; external LCMS2_SO; +PROCEDURE cmsSetLogErrorHandler(Fn: cmsLogErrorHandlerFunction); StdCall; external LCMS2_SO; +FUNCTION cmsD50_XYZ: LPcmsCIEXYZ; StdCall; external LCMS2_SO; +FUNCTION cmsD50_xyY: LPcmsCIExyY; StdCall; external LCMS2_SO; +PROCEDURE cmsXYZ2xyY(Dest: LPcmsCIExyY; Source: LPcmsCIEXYZ); StdCall; external LCMS2_SO; +PROCEDURE cmsxyY2XYZ(Dest: LPcmsCIEXYZ; Source: LPcmsCIExyY); StdCall; external LCMS2_SO; +PROCEDURE cmsLab2XYZ(WhitePoint: LPcmsCIEXYZ; xyz: LPcmsCIEXYZ; Lab: LPcmsCIELab); StdCall; external LCMS2_SO; +PROCEDURE cmsXYZ2Lab(WhitePoint: LPcmsCIEXYZ; Lab: LPcmsCIELab; xyz: LPcmsCIEXYZ); StdCall; external LCMS2_SO; +PROCEDURE cmsLab2LCh(LCh: LPcmsCIELCh; Lab: LPcmsCIELab); StdCall; external LCMS2_SO; +PROCEDURE cmsLCh2Lab(Lab: LPcmsCIELab; LCh: LPcmsCIELCh); StdCall; external LCMS2_SO; +PROCEDURE cmsLabEncoded2Float(Lab: LPcmsCIELab; wLab: Pointer); StdCall; external LCMS2_SO; +PROCEDURE cmsLabEncoded2FloatV2(Lab: LPcmsCIELab; wLab: Pointer); StdCall; external LCMS2_SO; +PROCEDURE cmsFloat2LabEncoded(wLab: Pointer; Lab: LPcmsCIELab); StdCall; external LCMS2_SO; +PROCEDURE cmsFloat2LabEncodedV2(wLab: Pointer; Lab: LPcmsCIELab); StdCall; external LCMS2_SO; +PROCEDURE cmsXYZEncoded2Float(fxyz : LPcmsCIEXYZ; XYZ: Pointer); StdCall; external LCMS2_SO; +PROCEDURE cmsFloat2XYZEncoded(XYZ: Pointer; fXYZ: LPcmsCIEXYZ); StdCall; external LCMS2_SO; +FUNCTION cmsDeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; external LCMS2_SO; +FUNCTION cmsCIE94DeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; external LCMS2_SO; +FUNCTION cmsBFDdeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; external LCMS2_SO; +FUNCTION cmsCMCdeltaE(Lab1, Lab2: LPcmsCIELab): Double; StdCall; external LCMS2_SO; +FUNCTION cmsCIE2000DeltaE(Lab1, Lab2: LPcmsCIELab; Kl, Kc, Kh: Double): Double; StdCall; external LCMS2_SO; +FUNCTION cmsWhitePointFromTemp(var WhitePoint: cmsCIExyY; TempK: cmsFloat64Number) : cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsTempFromWhitePoint(var TeampK: cmsFloat64Number; var WhitePoint: cmsCIExyY) : cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsAdaptToIlluminant(Result: LPcmsCIEXYZ; SourceWhitePt: LPcmsCIEXYZ; + Illuminant: LPcmsCIEXYZ; Value: LPcmsCIEXYZ): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsCIECAM02Init(pVC : LPcmsViewingConditions ) : Pointer; StdCall; external LCMS2_SO; +PROCEDURE cmsCIECAM02Done(hModel : Pointer); StdCall; external LCMS2_SO; +PROCEDURE cmsCIECAM02Forward(hModel: Pointer; pIn: LPcmsCIEXYZ; pOut: LPcmsJCh ); StdCall; external LCMS2_SO; +PROCEDURE cmsCIECAM02Reverse(hModel: Pointer; pIn: LPcmsJCh; pOut: LPcmsCIEXYZ ); StdCall; external LCMS2_SO; +FUNCTION cmsBuildSegmentedToneCurve(ContextID: cmsContext; nSegments: cmsInt32Number; Segments: LPcmsCurveSegmentArray): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsBuildParametricToneCurve(ContextID: cmsContext; CType: cmsInt32Number; Params: LPcmsFloat64NumberArray): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsBuildGamma(ContextID: cmsContext; Gamma: cmsFloat64Number): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsBuildTabulatedToneCurve16(ContextID: cmsContext; nEntries: cmsInt32Number; values: LPcmsUInt16NumberArray): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsBuildTabulatedToneCurveFloat(ContextID: cmsContext; nEntries: cmsUInt32Number; values: LPcmsFloat32NumberArray): LPcmsToneCurve; StdCall; external LCMS2_SO; +PROCEDURE cmsFreeToneCurve(Curve: LPcmsToneCurve); StdCall; external LCMS2_SO; +PROCEDURE cmsFreeToneCurveTriple(Curve: LPLPcmsToneCurveArray); StdCall; external LCMS2_SO; +FUNCTION cmsDupToneCurve(Src: LPcmsToneCurve): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsReverseToneCurve(InGamma: LPcmsToneCurve): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsReverseToneCurveEx(nResultSamples: cmsInt32Number; InGamma: LPcmsToneCurve): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsJoinToneCurve(ContextID: cmsContext; X, Y: LPcmsToneCurve; nPoints: cmsUInt32Number ): LPcmsToneCurve; StdCall; external LCMS2_SO; +FUNCTION cmsSmoothToneCurve(Tab: LPcmsToneCurve; lambda: cmsFloat64Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsEvalToneCurveFloat(Curve: LPcmsToneCurve; v: cmsFloat32Number):cmsFloat32Number; StdCall; external LCMS2_SO; +FUNCTION cmsEvalToneCurve16(Curve: LPcmsToneCurve; v:cmsUInt16Number):cmsUInt16Number; StdCall; external LCMS2_SO; +FUNCTION cmsIsToneCurveMultisegment(InGamma: LPcmsToneCurve):cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIsToneCurveLinear(Curve: LPcmsToneCurve):cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIsToneCurveMonotonic(t: LPcmsToneCurve):cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIsToneCurveDescending(t: LPcmsToneCurve):cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsGetToneCurveParametricType(t: LPcmsToneCurve):cmsInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsEstimateGamma(t: LPcmsToneCurve; Precision:cmsFloat64Number):cmsFloat64Number; StdCall; external LCMS2_SO; +FUNCTION cmsGetToneCurveEstimatedTableEntries(t: LPcmsToneCurve): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsGetToneCurveEstimatedTable(t: LPcmsToneCurve): LPcmsUInt16Number; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineAlloc(ContextID: cmsContext; InputChannels, OutputChannels: cmsUInt32Number): LPcmsPipeline; StdCall; external LCMS2_SO; +PROCEDURE cmsPipelineFree(lut: LPcmsPipeline); StdCall; external LCMS2_SO; +FUNCTION cmsPipelineDup(Orig: LPcmsPipeline): LPcmsPipeline; StdCall; external LCMS2_SO; +FUNCTION cmsGetPipelineContextID(lut: LPcmsPipeline) : cmsContext; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineInputChannels(lut: LPcmsPipeline): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineOutputChannels(lut: LPcmsPipeline): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineStageCount(lut: LPcmsPipeline): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineGetPtrToFirstStage(lut: LPcmsPipeline): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineGetPtrToLastStage(lut: LPcmsPipeline): LPcmsStage; StdCall; external LCMS2_SO; + +PROCEDURE cmsPipelineEval16(Inv, Outv: LPcmsUInt16NumberArray; lut: LPcmsPipeline); StdCall; external LCMS2_SO; +PROCEDURE cmsPipelineEvalFloat(Inv, Outv: LPcmsFloat32NumberArray; lut: LPcmsPipeline); StdCall; external LCMS2_SO; + +FUNCTION cmsPipelineEvalReverseFloat(Target, Result, Hint: LPcmsFloat32NumberArray; lut: LPcmsPipeline): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineCat(l1, l2: LPcmsPipeline): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsPipelineSetSaveAs8bitsFlag(lut: LPcmsPipeline; On: cmsBool): cmsBool; StdCall; external LCMS2_SO; +PROCEDURE cmsPipelineInsertStage(lut: LPcmsPipeline; loc: cmsStageLoc; mpe: LPcmsStage); StdCall; external LCMS2_SO; +PROCEDURE cmsPipelineUnlinkStage(lut: LPcmsPipeline; loc: cmsStageLoc; mpe: LPLPcmsStage); StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocIdentity(ContextID: cmsContext; nChannels: cmsUInt32Number): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocToneCurves(ContextID: cmsContext; nChannels: cmsUInt32Number; Curves: LPLPcmsToneCurveArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocMatrix(ContextID: cmsContext; Rows, Cols: cmsUInt32Number; Matrix, Offset: LPcmsFloat64NumberArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocCLut16bit(ContextID: cmsContext; nGridPoints: cmsUInt32Number; inputChan, outputChan: cmsUInt32Number; Table: LPcmsUInt16NumberArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocCLutFloat(ContextID: cmsContext; nGridPoints: cmsUInt32Number; inputChan, outputChan: cmsUInt32Number; Table: LPcmsFloat32NumberArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocCLut16bitGranular(ContextID: cmsContext; nGridPoints: LPcmsUInt32NumberArray; inputChan, outputChan: cmsUInt32Number; Table: LPcmsUInt16NumberArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageAllocCLutFloatGranular(ContextID: cmsContext; nGridPoints: LPcmsUInt32NumberArray; inputChan, outputChan: cmsUInt32Number; Table: LPcmsFloat32NumberArray): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageDup(mpe: LPcmsStage): LPcmsStage; StdCall; external LCMS2_SO; +PROCEDURE cmsStageFree(mpe: LPcmsStage); StdCall; external LCMS2_SO; +FUNCTION cmsStageNext(mpe: LPcmsStage): LPcmsStage; StdCall; external LCMS2_SO; +FUNCTION cmsStageInputChannels(mpe: LPcmsStage): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsStageOutputChannels(mpe: LPcmsStage): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsStageType(mpe: LPcmsStage): cmsStageSignature; StdCall; external LCMS2_SO; +FUNCTION cmsStageData(mpe: LPcmsStage): Pointer; StdCall; external LCMS2_SO; +FUNCTION cmsStageSampleCLut16bit(mpe: LPcmsStage; Sampler: cmsSAMPLER16; Cargo: Pointer; dwFlags: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsStageSampleCLutFloat(mpe: LPcmsStage; Sampler: cmsSAMPLERFLOAT; Cargo: Pointer; dwFlags: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsSliceSpace16(nInputs: cmsUInt32Number; clutPoints: LPcmsUInt32NumberArray; + Sampler: cmsSAMPLER16; Cargo: Pointer): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsSliceSpaceFloat(nInputs: cmsUInt32Number; clutPoints: LPcmsUInt32NumberArray; + Sampler: cmsSAMPLERFLOAT; Cargo: Pointer): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsMLUalloc(ContextID: cmsContext; nItems: cmsUInt32Number): LPcmsMLU; StdCall; external LCMS2_SO; +PROCEDURE cmsMLUfree(mlu: LPcmsMLU); StdCall; external LCMS2_SO; +FUNCTION cmsMLUdup(mlu: LPcmsMLU): LPcmsMLU; StdCall; external LCMS2_SO; + +FUNCTION cmsMLUsetASCII(mlu: LPcmsMLU; LanguageCode, CountryCode, ASCIIString: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsMLUsetWide(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; WideString: PWChar): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsMLUgetASCII(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; Buffer: PAnsiChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsMLUgetWide(mlu: LPcmsMLU; LanguageCode, CountryCode: PAnsiChar; Buffer: PWChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsMLUgetTranslation(mlu: LPcmsMLU; LanguageCode, CountryCode, ObtainedLanguage, ObtainedCountry: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsAllocNamedColorList(ContextID: cmsContext; n, ColorantCount :cmsUInt32Number; + Prefix, Suffix: PAnsiChar): LPcmsNAMEDCOLORLIST; StdCall; external LCMS2_SO; + +PROCEDURE cmsFreeNamedColorList(v: LPcmsNAMEDCOLORLIST); StdCall; external LCMS2_SO; +FUNCTION cmsDupNamedColorList(v: LPcmsNAMEDCOLORLIST): LPcmsNAMEDCOLORLIST; StdCall; external LCMS2_SO; +FUNCTION cmsAppendNamedColor(v: LPcmsNAMEDCOLORLIST; Name: PAnsiChar; + PCS, Colorant : LPcmsUInt16NumberArray): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsNamedColorCount(v: LPcmsNAMEDCOLORLIST): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsNamedColorIndex(v: LPcmsNAMEDCOLORLIST; Name: PAnsiChar): cmsInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsNamedColorInfo(v: LPcmsNAMEDCOLORLIST; nColor : cmsUInt32Number; + Name,Prefix, Suffix : PAnsiChar; + PCS, Colorant : LPcmsUInt16NumberArray): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsGetNamedColorList(xform: cmsHTRANSFORM ): LPcmsNAMEDCOLORLIST; StdCall; external LCMS2_SO; + +FUNCTION cmsAllocProfileSequenceDescription(ContextID: cmsContext; n: cmsUInt32Number):LPcmsSEQ; StdCall; external LCMS2_SO; +FUNCTION cmsDupProfileSequenceDescription(pseq: LPcmsSEQ):LPcmsSEQ; StdCall; external LCMS2_SO; +PROCEDURE cmsFreeProfileSequenceDescription(pseq: LPcmsSEQ); StdCall; external LCMS2_SO; + +FUNCTION cmsDictAlloc(ContextID: cmsContext): cmsHANDLE; StdCall; external LCMS2_SO; +PROCEDURE cmsDictFree(hDict: cmsHANDLE); StdCall; external LCMS2_SO; +FUNCTION cmsDictDup(hDict: cmsHANDLE): cmsHANDLE; StdCall; external LCMS2_SO; + +FUNCTION cmsDictAddEntry(hDict: cmsHANDLE; Name, Value: PWChar; DisplayName, DisplayValue : LPcmsMLU): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsDictGetEntryList(hDict: cmsHANDLE): LPcmsDICTentry; StdCall; external LCMS2_SO; +FUNCTION cmsDictNextEntry(e : LPcmsDICTentry): LPcmsDICTentry; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateProfilePlaceholder(ContextID: cmsContext): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsGetProfileContextID(hProfile: cmsHPROFILE):cmsContext; StdCall; external LCMS2_SO; +FUNCTION cmsGetTagCount(hProfile: cmsHPROFILE): cmsInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsGetTagSignature(hProfile: cmsHPROFILE; n: cmsUInt32Number): cmsTagSignature; StdCall; external LCMS2_SO; +FUNCTION cmsIsTag(hProfile: cmsHPROFILE; sig: cmsTagSignature ): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsReadTag(hProfile: cmsHPROFILE; sig: cmsTagSignature ): Pointer; StdCall; external LCMS2_SO; +FUNCTION cmsWriteTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; data: Pointer): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsLinkTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; dest: cmsTagSignature): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsTagLinkedTo(hProfile: cmsHPROFILE; sig: cmsTagSignature):cmsTagSignature; StdCall; external LCMS2_SO; + +FUNCTION cmsReadRawTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; Buffer: Pointer; BufferSize: cmsUInt32Number): cmsInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsWriteRawTag(hProfile: cmsHPROFILE; sig: cmsTagSignature; data: Pointer; Size: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsGetHeaderFlags(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; external LCMS2_SO; +PROCEDURE cmsGetHeaderAttributes(hProfile: cmsHPROFILE; Flags: LPcmsUInt64Number); StdCall; external LCMS2_SO; +PROCEDURE cmsGetHeaderProfileID(hProfile: cmsHPROFILE; ProfileID: LPcmsUInt8Number); StdCall; external LCMS2_SO; + +FUNCTION cmsGetHeaderRenderingIntent(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderFlags(hProfile: cmsHPROFILE; Flags: cmsUInt32Number); StdCall; external LCMS2_SO; +FUNCTION cmsGetHeaderManufacturer(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderManufacturer(hProfile: cmsHPROFILE; manufacturer: cmsUInt32Number ); StdCall; external LCMS2_SO; +FUNCTION cmsGetHeaderModel(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderModel(hProfile: cmsHPROFILE; model: cmsUInt32Number ); StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderAttributes(hProfile: cmsHPROFILE; Flags: cmsUInt64Number); StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderProfileID(hProfile: cmsHPROFILE; ProfileID: LPcmsUInt8Number); StdCall; external LCMS2_SO; +PROCEDURE cmsSetHeaderRenderingIntent(hProfile: cmsHPROFILE; RenderingIntent: cmsUInt32Number ); StdCall; external LCMS2_SO; + +FUNCTION cmsGetPCS(hProfile: cmsHPROFILE):cmsColorSpaceSignature; StdCall; external LCMS2_SO; +PROCEDURE cmsSetPCS(hProfile: cmsHPROFILE; pcs: cmsColorSpaceSignature); StdCall; external LCMS2_SO; +FUNCTION cmsGetColorSpace(hProfile: cmsHPROFILE): cmsColorSpaceSignature; StdCall; external LCMS2_SO; +PROCEDURE cmsSetColorSpace(hProfile: cmsHPROFILE; sig: cmsColorSpaceSignature); StdCall; external LCMS2_SO; +FUNCTION cmsGetDeviceClass(hProfile: cmsHPROFILE): cmsProfileClassSignature; StdCall; external LCMS2_SO; +PROCEDURE cmsSetDeviceClass(hProfile: cmsHPROFILE; sig: cmsProfileClassSignature); StdCall; external LCMS2_SO; +PROCEDURE cmsSetProfileVersion(hProfile: cmsHPROFILE; Version: cmsFloat64Number); StdCall; external LCMS2_SO; +FUNCTION cmsGetProfileVersion(hProfile: cmsHPROFILE): cmsFloat64Number; StdCall; external LCMS2_SO; + +FUNCTION cmsGetEncodedICCversion(hProfile: cmsHPROFILE): cmsUInt32Number; StdCall; external LCMS2_SO; +PROCEDURE cmsSetEncodedICCversion(hProfile: cmsHPROFILE; Version: cmsUInt32Number); StdCall; external LCMS2_SO; + + +FUNCTION cmsIsIntentSupported(hProfile: cmsHPROFILE; Intent: cmsUInt32Number; UsedDirection: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIsMatrixShaper(hProfile: cmsHPROFILE): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIsCLUT(hProfile: cmsHPROFILE; Intent: cmsUInt32Number; UsedDirection: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION _cmsICCcolorSpace(OurNotation: Integer): cmsColorSpaceSignature; StdCall; external LCMS2_SO; +FUNCTION _cmsLCMScolorSpace(ProfileSpace: cmsColorSpaceSignature): Integer; StdCall; external LCMS2_SO; + +FUNCTION cmsChannelsOf( ColorSpace: cmsColorSpaceSignature): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsFormatterForColorspaceOfProfile(hProfile: cmsHPROFILE; nBytes: cmsUInt32Number; lIsFloat: cmsBool): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsFormatterForPCSOfProfile(hProfile: cmsHPROFILE; nBytes: cmsUInt32Number; lIsFloat: cmsBool): cmsUInt32Number; StdCall; external LCMS2_SO; + + +FUNCTION cmsGetProfileInfo(hProfile: cmsHPROFILE; Info: cmsInfoType; LanguageCode, CountryCode: PAnsiChar; + Buffer: PWChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsGetProfileInfoASCII(hProfile: cmsHPROFILE; Info: cmsInfoType; LanguageCode, CountryCode: PAnsiChar; + Buffer: PAnsiChar; BufferSize: cmsUInt32Number): cmsUInt32Number; StdCall; external LCMS2_SO; + + +FUNCTION cmsOpenIOhandlerFromFile(ContextID: cmsContext; FileName, AccessMode: PAnsiChar): LPcmsIOHANDLER; StdCall; external LCMS2_SO; +// FUNCTION cmsOpenIOhandlerFromStream(ContextID: cmsContext; FILE* Stream): LPcmsIOHANDLER; StdCall; external LCMS2_SO; +FUNCTION cmsOpenIOhandlerFromMem(ContextID: cmsContext; Buffer: Pointer; size: cmsUInt32Number; AccessMode: PAnsiChar): LPcmsIOHANDLER; StdCall; external LCMS2_SO; +FUNCTION cmsOpenIOhandlerFromNULL(ContextID: cmsContext): LPcmsIOHANDLER; StdCall; external LCMS2_SO; +FUNCTION cmsCloseIOhandler(io: LPcmsIOHANDLER): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsMD5computeID(hProfile: cmsHPROFILE): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsOpenProfileFromFile(ICCProfile : PAnsiChar; sAccess: PAnsiChar): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsOpenProfileFromFileTHR(ContextID: cmsContext; ICCProfile, sAccess: PAnsiChar): cmsHPROFILE; StdCall; external LCMS2_SO; +// FUNCTION CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char* sAccess): cmsHPROFILE; StdCall; external LCMS2_SO; +// FUNCTION CMSEXPORT cmsOpenProfileFromStreamTHR(ContextID: cmsContext; FILE* ICCProfile, const char* sAccess): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsOpenProfileFromMem(MemPtr: Pointer; dwSize: cmsUInt32Number): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsOpenProfileFromMemTHR(ContextID: cmsContext; MemPtr: Pointer; dwSize: cmsUInt32Number): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsOpenProfileFromIOhandlerTHR(ContextID: cmsContext; io: LPcmsIOHANDLER): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCloseProfile(hProfile: cmsHPROFILE): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsSaveProfileToFile(hProfile: cmsHPROFILE; FileName: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +// FUNCTION CMSEXPORT cmsSaveProfileToStream(hProfile: cmsHPROFILE, FILE* Stream): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsSaveProfileToMem(hProfile: cmsHPROFILE; MemPtr: Pointer; BytesNeeded: LPcmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsSaveProfileToIOhandler(hProfile: cmsHPROFILE; io: LPcmsIOHANDLER):cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateRGBProfileTHR(ContextID: cmsContext; + WhitePoint: LPcmsCIExyY; + Primaries: LPcmsCIExyYTRIPLE; + TransferFunction: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateRGBProfile(WhitePoint: LPcmsCIExyY; + Primaries: LPcmsCIExyYTRIPLE; + TransferFunction: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateGrayProfileTHR(ContextID: cmsContext; + WhitePoint: LPcmsCIExyY; + TransferFunction: LPcmsToneCurve): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateGrayProfile(WhitePoint: LPcmsCIExyY; + TransferFunction: LPcmsToneCurve): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateLinearizationDeviceLinkTHR(ContextID: cmsContext; + ColorSpace: cmsColorSpaceSignature; + TransferFunctions: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateLinearizationDeviceLink(ColorSpace: cmsColorSpaceSignature; + TransferFunctions: LPLPcmsToneCurveArray): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateInkLimitingDeviceLinkTHR(ContextID: cmsContext; + ColorSpace: cmsColorSpaceSignature; Limit: cmsFloat64Number): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateInkLimitingDeviceLink(ColorSpace: cmsColorSpaceSignature; Limit: cmsFloat64Number): cmsHPROFILE; StdCall; external LCMS2_SO; + + +FUNCTION cmsCreateLab2ProfileTHR(ContextID: cmsContext; WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreateLab2Profile(WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreateLab4ProfileTHR(ContextID: cmsContext; WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreateLab4Profile(WhitePoint: LPcmsCIExyY): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateXYZProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreateXYZProfile: cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreate_sRGBProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreate_sRGBProfile: cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateBCHSWabstractProfileTHR(ContextID: cmsContext; + nLUTPoints: Integer; + Bright, + Contrast, + Hue, + Saturation: cmsFloat64Number; + TempSrc, + TempDest: Integer): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateBCHSWabstractProfile( nLUTPoints: Integer; + Bright, + Contrast, + Hue, + Saturation: cmsFloat64Number; + TempSrc, + TempDest: Integer): cmsHPROFILE; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateNULLProfileTHR(ContextID: cmsContext): cmsHPROFILE; StdCall; external LCMS2_SO; +FUNCTION cmsCreateNULLProfile: cmsHPROFILE; StdCall; external LCMS2_SO; + +// Converts a transform to a devicelink profile +FUNCTION cmsTransform2DeviceLink(hTransform: cmsHTRANSFORM; Version: cmsFloat64Number; dwFlags: cmsUInt32Number): cmsHPROFILE; StdCall; external LCMS2_SO; + +// Call with NULL as parameters to get the intent count +FUNCTION cmsGetSupportedIntents(nMax: cmsUInt32Number; Codes: LPcmsUInt32Number; Descriptions: LPPAnsiChar): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsFLAGS_GRIDPOINTS(n: Integer): Integer; begin cmsFLAGS_GRIDPOINTS := (((n) and $FF) shl 16) end; + + +FUNCTION cmsCreateTransformTHR(ContextID: cmsContext; + Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateTransform(Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateProofingTransformTHR(ContextID: cmsContext; + Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Proofing: cmsHPROFILE; + Intent: cmsUInt32Number; + ProofingIntent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateProofingTransform(Input: cmsHPROFILE; + InputFormat: cmsUInt32Number; + Output: cmsHPROFILE; + OutputFormat: cmsUInt32Number; + Proofing: cmsHPROFILE; + Intent: cmsUInt32Number; + ProofingIntent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + +FUNCTION cmsCreateMultiprofileTransformTHR(ContextID: cmsContext; + hProfiles: LPcmsHPROFILEArray; + nProfiles: cmsUInt32Number; + InputFormat: cmsUInt32Number; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + + +FUNCTION cmsCreateMultiprofileTransform( hProfiles: LPcmsHPROFILEArray; + nProfiles: cmsUInt32Number; + InputFormat: cmsUInt32Number; + OutputFormat: cmsUInt32Number; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + + +FUNCTION cmsCreateExtendedTransform(ContextID: cmsContext; + nProfiles: cmsUInt32Number; + hProfiles: LPcmsHPROFILEArray; + BPC: LPcmsBoolArray; + Intents: LPcmsUInt32NumberArray; + AdaptationStates: LPcmsFloat64NumberArray; + hGamutProfile: cmsHPROFILE; + nGamutPCSposition: cmsUInt32Number; + InputFormat, + OutputFormat: cmsUInt32Number; + dwFlags: cmsUInt32Number): cmsHTRANSFORM; StdCall; external LCMS2_SO; + +PROCEDURE cmsDeleteTransform(hTransform: cmsHTRANSFORM); StdCall; external LCMS2_SO; + +PROCEDURE cmsDoTransform(Transform: cmsHTRANSFORM; InputBuffer, OutputBuffer: Pointer; size: cmsUInt32Number); StdCall; external LCMS2_SO; +PROCEDURE cmsDoTransformStride(Transform: cmsHTRANSFORM; InputBuffer, OutputBuffer: Pointer; size: cmsUInt32Number; stride: cmsUInt32Number); StdCall; external LCMS2_SO; +PROCEDURE cmsSetAlarmCodes( NewAlarm: LPcmsUInt16NumberArray); StdCall; external LCMS2_SO; +PROCEDURE cmsGetAlarmCodes(NewAlarm: LPcmsUInt16NumberArray); StdCall; external LCMS2_SO; + +// Adaptation state for absolute colorimetric intent +FUNCTION cmsSetAdaptationState(d: cmsFloat64Number):cmsFloat64Number; StdCall; external LCMS2_SO; + +// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed +FUNCTION cmsGetTransformContextID(hTransform: cmsHTRANSFORM):cmsContext; StdCall; external LCMS2_SO; + +// For backwards compatibility +FUNCTION cmsChangeBuffersFormat(hTransform: cmsHTRANSFORM; InputFormat, OutputFormat: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; + + +// lcms2 unified method to access postscript color resources +FUNCTION cmsGetPostScriptColorResource(ContextID: cmsContext; RType: cmsPSResourceType; + hProfile: cmsHPROFILE; + Intent: cmsUInt32Number; + dwFlags: cmsUInt32Number; + io: LPcmsIOHANDLER): cmsUInt32Number; StdCall; external LCMS2_SO; + +FUNCTION cmsGetPostScriptCSA(ContextID: cmsContext; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number; Buffer: Pointer; dwBufferLen: cmsUInt32Number ): cmsUInt32Number; StdCall; external LCMS2_SO; +FUNCTION cmsGetPostScriptCRD(ContextID: cmsContext; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number; Buffer: Pointer; dwBufferLen: cmsUInt32Number): cmsUInt32Number; StdCall; external LCMS2_SO; + + +// CGATS.13 parser + +FUNCTION cmsIT8Alloc: cmsHANDLE; StdCall; external LCMS2_SO; +PROCEDURE cmsIT8Free(hIT8: cmsHANDLE); StdCall; external LCMS2_SO; + +// Tables + +FUNCTION cmsIT8TableCount(hIT8: cmsHANDLE): Integer; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetTable(hIT8: cmsHANDLE; nTable: Integer): Integer; StdCall; external LCMS2_SO; + +// Persistence +FUNCTION cmsIT8LoadFromFile(cFileName: PAnsiChar): cmsHANDLE; StdCall; external LCMS2_SO; +FUNCTION cmsIT8LoadFromMem(Ptr: Pointer; size :DWord): cmsHANDLE; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SaveToFile(hIT8: cmsHANDLE; cFileName: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SaveToMem(hIT8: cmsHANDLE; MemPtr: Pointer; BytesNeeded: LPcmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +// Properties + +FUNCTION cmsIT8GetSheetType(hIT8: cmsHANDLE): PAnsiChar; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetSheetType(hIT8: cmsHANDLE; TheType: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetComment(hIT8: cmsHANDLE; cComment: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetPropertyStr(hIT8: cmsHANDLE; cProp, Str: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetPropertyDbl(hIT8: cmsHANDLE; cProp: PAnsiChar; Val: Double): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetPropertyHex(hIT8: cmsHANDLE; cProp: PAnsiChar; Val: Integer): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetPropertyUncooked(hIT8: cmsHANDLE; Key, Buffer: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; + + +FUNCTION cmsIT8GetProperty(hIT8: cmsHANDLE; cProp: PAnsiChar): PAnsiChar; StdCall; external LCMS2_SO; +FUNCTION cmsIT8GetPropertyDbl(hIT8: cmsHANDLE; cProp: PAnsiChar): Double; StdCall; external LCMS2_SO; +FUNCTION cmsIT8EnumProperties(hIT8: cmsHANDLE; var PropertyNames: LPPAnsiChar): Integer; StdCall; external LCMS2_SO; + +// Datasets + +FUNCTION cmsIT8GetDataRowCol(hIT8: cmsHANDLE; row, col: Integer): PAnsiChar; StdCall; external LCMS2_SO; +FUNCTION cmsIT8GetDataRowColDbl(hIT8: cmsHANDLE; row, col: Integer): Double; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetDataRowCol(hIT8: cmsHANDLE; row, col: Integer; Val: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8SetDataRowColDbl(hIT8: cmsHANDLE; row, col: Integer; Val: Double): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8GetData(hIT8: cmsHANDLE; cPatch, cSample: PAnsiChar): PAnsiChar; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8GetDataDbl(hIT8: cmsHANDLE;cPatch, cSample: PAnsiChar): Double; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetData(hIT8: cmsHANDLE; cPatch, cSample, Val: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetDataDbl(hIT8: cmsHANDLE; cPatch, cSample: PAnsiChar; Val: Double): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8SetDataFormat(hIT8: cmsHANDLE; n: Integer; Sample: PAnsiChar): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsIT8EnumDataFormat(hIT8: cmsHANDLE; var SampleNames: LPPAnsiChar): Integer; StdCall; external LCMS2_SO; +FUNCTION cmsIT8GetPatchName(hIT8: cmsHANDLE; nPatch: Integer; Buffer: PAnsiChar): PAnsiChar; StdCall; external LCMS2_SO; + +// The LABEL extension + +FUNCTION cmsIT8SetTableByLabel(hIT8: cmsHANDLE; cSet, cField, ExpectedType: PAnsiChar): Integer; StdCall; external LCMS2_SO; + +FUNCTION cmsIT8FindDataFormat(hIT8: cmsHANDLE; cSample: PAnsiChar): Integer; StdCall; external LCMS2_SO; + +// Formatter for double +PROCEDURE cmsIT8DefineDblFormat(hIT8: cmsHANDLE; Formatter: PAnsiChar); StdCall; external LCMS2_SO; + +FUNCTION cmsGBDAlloc(ContextID: cmsContext):cmsHANDLE; StdCall; external LCMS2_SO; +PROCEDURE cmsGBDFree(hGBD: cmsHANDLE); StdCall; external LCMS2_SO; +FUNCTION cmsGDBAddPoint(hGBD: cmsHANDLE; Lab: LPcmsCIELab): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsGDBCompute(hGDB: cmsHANDLE; dwFlags: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsGDBCheckPoint(hGBD: cmsHANDLE; Lab: LPcmsCIELab): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsDetectBlackPoint( BlackPoint: LPcmsCIEXYZ; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; +FUNCTION cmsDetectDestinationBlackPoint( BlackPoint: LPcmsCIEXYZ; hProfile: cmsHPROFILE; Intent: cmsUInt32Number; dwFlags: cmsUInt32Number): cmsBool; StdCall; external LCMS2_SO; + +FUNCTION cmsDetectTAC(hProfile: cmsHPROFILE): cmsFloat64Number; StdCall; external LCMS2_SO; + +FUNCTION cmsDesaturateLab(Lab: LPcmsCIELab; amax, amin, bmax, bmin: cmsFloat64Number): cmsBool; StdCall; external LCMS2_SO; + +END. diff --git a/lcms2mt/utils/jpgicc/LICENSE_iccjpeg b/lcms2mt/utils/jpgicc/LICENSE_iccjpeg new file mode 100755 index 000000000..b77d4cbff --- /dev/null +++ b/lcms2mt/utils/jpgicc/LICENSE_iccjpeg @@ -0,0 +1,67 @@ + +THIS LICENSE APPLIES ONLY TO iccjpeg.c file +----- +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +The Unix configuration script "configure" was produced with GNU Autoconf. +It is copyright by the Free Software Foundation but is freely distributable. +The same holds for its supporting scripts (config.guess, config.sub, +ltmain.sh). Another support script, install-sh, is copyright by X Consortium +but is also freely distributable. + +The IJG distribution formerly included code to read and write GIF files. +To avoid entanglement with the Unisys LZW patent, GIF reading support has +been removed altogether, and the GIF writer has been simplified to produce +"uncompressed GIFs". This technique does not use the LZW algorithm; the +resulting GIF files are larger than usual, but are readable by all standard +GIF decoders. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." diff --git a/lcms2mt/utils/jpgicc/Makefile.am b/lcms2mt/utils/jpgicc/Makefile.am new file mode 100644 index 000000000..d0a0897f3 --- /dev/null +++ b/lcms2mt/utils/jpgicc/Makefile.am @@ -0,0 +1,22 @@ +# +# Makefile for building jpegicc +# Written by Bob Friesenhahn, June 2003 +# Bugs introduced by Marti Maria on October 2004 + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common +if HasJPEG +bin_PROGRAMS = jpgicc +else +bin_PROGRAMS = +endif + +jpgicc_LDADD = $(top_builddir)/src/liblcms2.la @JPEGICC_DEPLIBS@ +jpgicc_LDFLAGS = @LDFLAGS@ +jpgicc_SOURCES = jpgicc.c iccjpeg.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +man_MANS = jpgicc.1 + +EXTRA_DIST = iccjpeg.h $(man_MANS) diff --git a/lcms2mt/utils/jpgicc/Makefile.in b/lcms2mt/utils/jpgicc/Makefile.in new file mode 100644 index 000000000..69032832d --- /dev/null +++ b/lcms2mt/utils/jpgicc/Makefile.in @@ -0,0 +1,739 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building jpegicc +# Written by Bob Friesenhahn, June 2003 +# Bugs introduced by Marti Maria on October 2004 + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HasJPEG_TRUE@bin_PROGRAMS = jpgicc$(EXEEXT) +subdir = utils/jpgicc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_jpgicc_OBJECTS = jpgicc.$(OBJEXT) iccjpeg.$(OBJEXT) \ + ../common/xgetopt.$(OBJEXT) ../common/vprf.$(OBJEXT) +jpgicc_OBJECTS = $(am_jpgicc_OBJECTS) +jpgicc_DEPENDENCIES = $(top_builddir)/src/liblcms2.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +jpgicc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(jpgicc_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(jpgicc_SOURCES) +DIST_SOURCES = $(jpgicc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +jpgicc_LDADD = $(top_builddir)/src/liblcms2.la @JPEGICC_DEPLIBS@ +jpgicc_LDFLAGS = @LDFLAGS@ +jpgicc_SOURCES = jpgicc.c iccjpeg.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +man_MANS = jpgicc.1 +EXTRA_DIST = iccjpeg.h $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/jpgicc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign utils/jpgicc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../common/$(am__dirstamp): + @$(MKDIR_P) ../common + @: > ../common/$(am__dirstamp) +../common/xgetopt.$(OBJEXT): ../common/$(am__dirstamp) +../common/vprf.$(OBJEXT): ../common/$(am__dirstamp) + +jpgicc$(EXEEXT): $(jpgicc_OBJECTS) $(jpgicc_DEPENDENCIES) $(EXTRA_jpgicc_DEPENDENCIES) + @rm -f jpgicc$(EXEEXT) + $(AM_V_CCLD)$(jpgicc_LINK) $(jpgicc_OBJECTS) $(jpgicc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../common/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../common/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/jpgicc/iccjpeg.c b/lcms2mt/utils/jpgicc/iccjpeg.c new file mode 100644 index 000000000..d08b4bd08 --- /dev/null +++ b/lcms2mt/utils/jpgicc/iccjpeg.c @@ -0,0 +1,248 @@ +/* + * iccprofile.c + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. If you need to do that, + * change all the "unsigned int" variables to "INT32". You'll also need + * to find a malloc() replacement that can allocate more than 64K. + */ + +#include "iccjpeg.h" +#include <stdlib.h> /* define malloc() */ + + +/* + * Since an ICC profile can be larger than the maximum size of a JPEG marker + * (64K), we need provisions to split it into multiple markers. The format + * defined by the ICC specifies one or more APP2 markers containing the + * following data: + * Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte) + * Number of markers Total number of APP2's used (1 byte) + * Profile data (remainder of APP2 data) + * Decoders should use the marker sequence numbers to reassemble the profile, + * rather than assuming that the APP2 markers appear in the correct sequence. + */ + +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +void +write_icc_profile (j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len) +{ + unsigned int num_markers; /* total number of markers we'll write */ + int cur_marker = 1; /* per spec, counting starts at 1 */ + unsigned int length; /* number of bytes to write in this marker */ + + /* Calculate the number of markers we'll need, rounding up of course */ + num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER; + if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) + num_markers++; + + while (icc_data_len > 0) { + /* length of profile to put in this marker */ + length = icc_data_len; + if (length > MAX_DATA_BYTES_IN_MARKER) + length = MAX_DATA_BYTES_IN_MARKER; + icc_data_len -= length; + + /* Write the JPEG marker header (APP2 code and marker length) */ + jpeg_write_m_header(cinfo, ICC_MARKER, + (unsigned int) (length + ICC_OVERHEAD_LEN)); + + /* Write the marker identifying string "ICC_PROFILE" (null-terminated). + * We code it in this less-than-transparent way so that the code works + * even if the local character set is not ASCII. + */ + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x5F); + jpeg_write_m_byte(cinfo, 0x50); + jpeg_write_m_byte(cinfo, 0x52); + jpeg_write_m_byte(cinfo, 0x4F); + jpeg_write_m_byte(cinfo, 0x46); + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x4C); + jpeg_write_m_byte(cinfo, 0x45); + jpeg_write_m_byte(cinfo, 0x0); + + /* Add the sequencing info */ + jpeg_write_m_byte(cinfo, cur_marker); + jpeg_write_m_byte(cinfo, (int) num_markers); + + /* Add the profile data */ + while (length--) { + jpeg_write_m_byte(cinfo, *icc_data_ptr); + icc_data_ptr++; + } + cur_marker++; + } +} + + +/* + * Prepare for reading an ICC profile + */ + +void +setup_read_icc_profile (j_decompress_ptr cinfo) +{ + /* Tell the library to keep any APP2 data it may find */ + jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF); +} + + +/* + * Handy subroutine to test whether a saved marker is an ICC profile marker. + */ + +static boolean +marker_is_icc (jpeg_saved_marker_ptr marker) +{ + return + marker->marker == ICC_MARKER && + marker->data_length >= ICC_OVERHEAD_LEN && + /* verify the identifying string */ + GETJOCTET(marker->data[0]) == 0x49 && + GETJOCTET(marker->data[1]) == 0x43 && + GETJOCTET(marker->data[2]) == 0x43 && + GETJOCTET(marker->data[3]) == 0x5F && + GETJOCTET(marker->data[4]) == 0x50 && + GETJOCTET(marker->data[5]) == 0x52 && + GETJOCTET(marker->data[6]) == 0x4F && + GETJOCTET(marker->data[7]) == 0x46 && + GETJOCTET(marker->data[8]) == 0x49 && + GETJOCTET(marker->data[9]) == 0x4C && + GETJOCTET(marker->data[10]) == 0x45 && + GETJOCTET(marker->data[11]) == 0x0; +} + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + * + * NOTE: if the file contains invalid ICC APP2 markers, we just silently + * return FALSE. You might want to issue an error message instead. + */ + +boolean +read_icc_profile (j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len) +{ + jpeg_saved_marker_ptr marker; + int num_markers = 0; + int seq_no; + JOCTET *icc_data; + unsigned int total_length; +#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ + char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */ + unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */ + unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */ + + *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ + *icc_data_len = 0; + + /* This first pass over the saved markers discovers whether there are + * any ICC markers and verifies the consistency of the marker numbering. + */ + + for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) + marker_present[seq_no] = 0; + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + if (num_markers == 0) + num_markers = GETJOCTET(marker->data[13]); + else if (num_markers != GETJOCTET(marker->data[13])) + return FALSE; /* inconsistent num_markers fields */ + seq_no = GETJOCTET(marker->data[12]); + if (seq_no <= 0 || seq_no > num_markers) + return FALSE; /* bogus sequence number */ + if (marker_present[seq_no]) + return FALSE; /* duplicate sequence numbers */ + marker_present[seq_no] = 1; + data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + } + } + + if (num_markers == 0) + return FALSE; + + /* Check for missing markers, count total space needed, + * compute offset of each marker's part of the data. + */ + + total_length = 0; + for (seq_no = 1; seq_no <= num_markers; seq_no++) { + if (marker_present[seq_no] == 0) + return FALSE; /* missing sequence number */ + data_offset[seq_no] = total_length; + total_length += data_length[seq_no]; + } + + if (total_length == 0) + return FALSE; /* found only empty markers? */ + + /* Allocate space for assembled data */ + icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET)); + if (icc_data == NULL) + return FALSE; /* oops, out of memory */ + + /* and fill it in */ + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + JOCTET FAR *src_ptr; + JOCTET *dst_ptr; + unsigned int length; + seq_no = GETJOCTET(marker->data[12]); + dst_ptr = icc_data + data_offset[seq_no]; + src_ptr = marker->data + ICC_OVERHEAD_LEN; + length = data_length[seq_no]; + while (length--) { + *dst_ptr++ = *src_ptr++; + } + } + } + + *icc_data_ptr = icc_data; + *icc_data_len = total_length; + + return TRUE; +} diff --git a/lcms2mt/utils/jpgicc/iccjpeg.h b/lcms2mt/utils/jpgicc/iccjpeg.h new file mode 100644 index 000000000..5e1888d9e --- /dev/null +++ b/lcms2mt/utils/jpgicc/iccjpeg.h @@ -0,0 +1,73 @@ +/* + * iccprofile.h + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. See iccprofile.c + * for details. + */ + +#include <stdio.h> /* needed to define "FILE", "NULL" */ +#include "jpeglib.h" + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +extern void write_icc_profile JPP((j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len)); + + +/* + * Reading a JPEG file that may contain an ICC profile requires two steps: + * + * 1. After jpeg_create_decompress() but before jpeg_read_header(), + * call setup_read_icc_profile(). This routine tells the IJG library + * to save in memory any APP2 markers it may find in the file. + * + * 2. After jpeg_read_header(), call read_icc_profile() to find out + * whether there was a profile and obtain it if so. + */ + + +/* + * Prepare for reading an ICC profile + */ + +extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo)); + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + */ + +extern boolean read_icc_profile JPP((j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len)); diff --git a/lcms2mt/utils/jpgicc/jpgicc.1 b/lcms2mt/utils/jpgicc/jpgicc.1 new file mode 100644 index 000000000..44795a38e --- /dev/null +++ b/lcms2mt/utils/jpgicc/jpgicc.1 @@ -0,0 +1,122 @@ +.\"Shiju P. Nair September 30, 2004 +.\"Thomas Weber <tweber@debian.org> April 23, 2014 +.TH JPGICC 1 "September 30, 2004" +.SH NAME +jpgicc - little cms ICC profile applier for JPEG. +.SH SYNOPSIS +.B jpgicc +.RI [ options ] " input.jpg output.jpg" +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B jpgicc +is a little cms ICC profile applier for JPEG. +.SH OPTIONS +.TP +.B \-b +Black point compensation. +.TP +.BI \-c\ NUM +Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. +.TP +.BI \-d\ NUM +Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. +.TP +.B \-e +Embed destination profile. +.TP +.B \-g +Marks out-of-gamut colors on softproof. +.TP +.BI \-h\ NUM +Show summary of options and examples (0=help, 1=Examples, 2=Built-in profiles, 3=Contact information) +.TP +.BI \-i\ profile +Input profile (defaults to sRGB). +.TP +.BI \-l\ link +TODO: explain this option. +.TP +.BI \-m\ NUM +SoftProof intent (0,1,2,3) [defaults to 0]. +.TP +.B \-n +Ignore embedded profile. +.TP +.BI \-o\ profile +Output profile (defaults to sRGB). +.TP +.BI \-p\ profile +Soft proof profile. +.TP +.BI \-q\ NUM +Output JPEG quality, (0..100) [defaults to 75]. +.TP +.BI \-s\ newprofile +Save embedded profile as \fInewprofile\fR. +.TP +.BI \-t\ NUM +Rendering intent +.nf +.RS +0=Perceptual [default] +1=Relative colorimetric +2=Saturation +3=Absolute colorimetric +10=Perceptual preserving black ink +11=Relative colorimetric preserving black ink +12=Saturation preserving black ink +13=Perceptual preserving black plane +14=Relative colorimetric preserving black plane +15=Saturation preserving black plane +.RE +.fi +.TP +.B \-v +Verbose. +.TP +.BI \-!\ NUM,NUM,NUM +Out-of-gamut marker channel values (r,g,b) [defaults: 128,128,128]. +.SH BUILT-IN PROFILES +.nf + *Lab2 -- D50-based v2 CIEL*a*b + *Lab4 -- D50-based v4 CIEL*a*b + *Lab -- D50-based v4 CIEL*a*b + *XYZ -- CIE XYZ (PCS) + *sRGB -- sRGB color space + *Gray22 - Monochrome of Gamma 2.2 + *Gray30 - Monochrome of Gamma 3.0 + *null - Monochrome black for all input + *Lin2222- CMYK linearization of gamma 2.2 on each channel +.fi +.SH EXAMPLES +.nf +To color correct from scanner to sRGB: + jpgicc -iscanner.icm in.jpg out.jpg + +To convert from monitor1 to monitor2: + jpgicc -imon1.icm -omon2.icm in.jpg out.jpg + +To make a CMYK separation: + jpgicc -oprinter.icm inrgb.jpg outcmyk.jpg + +To recover sRGB from a CMYK separation: + jpgicc -iprinter.icm incmyk.jpg outrgb.jpg + +To convert from CIELab ITU/Fax JPEG to sRGB + jpgicc -iitufax.icm in.jpg out.jpg + +To convert from CIELab ITU/Fax JPEG to sRGB + jpgicc in.jpg out.jpg +.fi +.SH NOTES +For suggestions, comments, bug reports etc. send mail to +info@littlecms.com. +.SH SEE ALSO +.BR linkicc (1), +.BR psicc (1), +.BR tificc (1), +.BR transicc (1) +.SH AUTHOR +This manual page was written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. diff --git a/lcms2mt/utils/jpgicc/jpgicc.c b/lcms2mt/utils/jpgicc/jpgicc.c new file mode 100644 index 000000000..b4a880040 --- /dev/null +++ b/lcms2mt/utils/jpgicc/jpgicc.c @@ -0,0 +1,1263 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +// This program does apply profiles to (some) JPEG files + + +#include "utils.h" + +#include "jpeglib.h" +#include "iccjpeg.h" + +// Flags +static cmsBool BlackPointCompensation = FALSE; +static cmsBool IgnoreEmbedded = FALSE; +static cmsBool GamutCheck = FALSE; +static cmsBool lIsITUFax = FALSE; +static cmsBool lIsPhotoshopApp13 = FALSE; +static cmsBool lIsEXIF; +static cmsBool lIsDeviceLink = FALSE; +static cmsBool EmbedProfile = FALSE; + +static const char* SaveEmbedded = NULL; + +static int Intent = INTENT_PERCEPTUAL; +static int ProofingIntent = INTENT_PERCEPTUAL; +static int PrecalcMode = 1; + +static int jpegQuality = 75; + +static cmsFloat64Number ObserverAdaptationState = 0; + + +static char *cInpProf = NULL; +static char *cOutProf = NULL; +static char *cProofing = NULL; + +static FILE * InFile; +static FILE * OutFile; + +static struct jpeg_decompress_struct Decompressor; +static struct jpeg_compress_struct Compressor; + + +static struct my_error_mgr { + + struct jpeg_error_mgr pub; // "public" fields + void* Cargo; // "private" fields + +} ErrorHandler; + + +cmsUInt16Number Alarm[4] = {128,128,128,0}; + + +static +void my_error_exit (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + FatalError(buffer); +} + +/* +Definition of the APPn Markers Defined for continuous-tone G3FAX + +The application code APP1 initiates identification of the image as +a G3FAX application and defines the spatial resolution and subsampling. +This marker directly follows the SOI marker. The data format will be as follows: + +X'FFE1' (APP1), length, FAX identifier, version, spatial resolution. + +The above terms are defined as follows: + +Length: (Two octets) Total APP1 field octet count including the octet count itself, but excluding the APP1 +marker. + +FAX identifier: (Six octets) X'47', X'33', X'46', X'41', X'58', X'00'. This X'00'-terminated string "G3FAX" +uniquely identifies this APP1 marker. + +Version: (Two octets) X'07CA'. This string specifies the year of approval of the standard, for identification +in the case of future revision (for example, 1994). + +Spatial Resolution: (Two octets) Lightness pixel density in pels/25.4 mm. The basic value is 200. Allowed values are +100, 200, 300, 400, 600 and 1200 pels/25.4 mm, with square (or equivalent) pels. + +NOTE – The functional equivalence of inch-based and mm-based resolutions is maintained. For example, the 200 × 200 +*/ + +static +cmsBool IsITUFax(jpeg_saved_marker_ptr ptr) +{ + while (ptr) + { + if (ptr -> marker == (JPEG_APP0 + 1) && ptr -> data_length > 5) { + + const char* data = (const char*) ptr -> data; + + if (strcmp(data, "G3FAX") == 0) return TRUE; + } + + ptr = ptr -> next; + } + + return FALSE; +} + +// Save a ITU T.42/Fax marker with defaults on boundaries. This is the only mode we support right now. +static +void SetITUFax(j_compress_ptr cinfo) +{ + unsigned char Marker[] = "G3FAX\x00\0x07\xCA\x00\xC8"; + + jpeg_write_marker(cinfo, (JPEG_APP0 + 1), Marker, 10); +} + + +// Build a profile for decoding ITU T.42/Fax JPEG streams. +// The profile has an additional ability in the input direction of +// gamut compress values between 85 < a < -85 and -75 < b < 125. This conforms +// the default range for ITU/T.42 -- See RFC 2301, section 6.2.3 for details + +// L* = [0, 100] +// a* = [–85, 85] +// b* = [–75, 125] + + +// These functions does convert the encoding of ITUFAX to floating point +// and vice-versa. No gamut mapping is performed yet. + +static +void ITU2Lab(const cmsUInt16Number In[3], cmsCIELab* Lab) +{ + Lab -> L = (double) In[0] / 655.35; + Lab -> a = (double) 170.* (In[1] - 32768.) / 65535.; + Lab -> b = (double) 200.* (In[2] - 24576.) / 65535.; +} + +static +void Lab2ITU(const cmsCIELab* Lab, cmsUInt16Number Out[3]) +{ + Out[0] = (cmsUInt16Number) floor((double) (Lab -> L / 100.)* 65535. ); + Out[1] = (cmsUInt16Number) floor((double) (Lab -> a / 170.)* 65535. + 32768. ); + Out[2] = (cmsUInt16Number) floor((double) (Lab -> b / 200.)* 65535. + 24576. ); +} + +// These are the samplers-- They are passed as callbacks to cmsStageSampleCLut16bit() +// then, cmsSample3DGrid() will sweel whole Lab gamut calling these functions +// once for each node. In[] will contain the Lab PCS value to convert to ITUFAX +// on PCS2ITU, or the ITUFAX value to convert to Lab in ITU2PCS +// You can change the number of sample points if desired, the algorithm will +// remain same. 33 points gives good accurancy, but you can reduce to 22 or less +// is space is critical + +#define GRID_POINTS 33 + +static +int PCS2ITU(cmsContext ContextID, register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) +{ + cmsCIELab Lab; + + cmsLabEncoded2Float(NULL, &Lab, In); + cmsDesaturateLab(NULL, &Lab, 85, -85, 125, -75); // This function does the necessary gamut remapping + Lab2ITU(&Lab, Out); + return TRUE; + + UTILS_UNUSED_PARAMETER(Cargo); + UTILS_UNUSED_PARAMETER(ContextID); +} + + +static +int ITU2PCS(cmsContext ContextID, register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) +{ + cmsCIELab Lab; + + ITU2Lab(In, &Lab); + cmsFloat2LabEncoded(NULL, Out, &Lab); + return TRUE; + + UTILS_UNUSED_PARAMETER(Cargo); + UTILS_UNUSED_PARAMETER(ContextID); +} + +// This function does create the virtual input profile, which decodes ITU to the profile connection space +static +cmsHPROFILE CreateITU2PCS_ICC(void) +{ + cmsHPROFILE hProfile; + cmsPipeline* AToB0; + cmsStage* ColorMap; + + AToB0 = cmsPipelineAlloc(0, 3, 3); + if (AToB0 == NULL) return NULL; + + ColorMap = cmsStageAllocCLut16bit(0, GRID_POINTS, 3, 3, NULL); + if (ColorMap == NULL) return NULL; + + cmsPipelineInsertStage(NULL, AToB0, cmsAT_BEGIN, ColorMap); + cmsStageSampleCLut16bit(NULL, ColorMap, ITU2PCS, NULL, 0); + + hProfile = cmsCreateProfilePlaceholder(0); + if (hProfile == NULL) { + cmsPipelineFree(NULL, AToB0); + return NULL; + } + + cmsWriteTag(NULL, hProfile, cmsSigAToB0Tag, AToB0); + cmsSetColorSpace(NULL, hProfile, cmsSigLabData); + cmsSetPCS(NULL, hProfile, cmsSigLabData); + cmsSetDeviceClass(NULL, hProfile, cmsSigColorSpaceClass); + cmsPipelineFree(NULL, AToB0); + + return hProfile; +} + + +// This function does create the virtual output profile, with the necessary gamut mapping +static +cmsHPROFILE CreatePCS2ITU_ICC(void) +{ + cmsHPROFILE hProfile; + cmsPipeline* BToA0; + cmsStage* ColorMap; + + BToA0 = cmsPipelineAlloc(0, 3, 3); + if (BToA0 == NULL) return NULL; + + ColorMap = cmsStageAllocCLut16bit(0, GRID_POINTS, 3, 3, NULL); + if (ColorMap == NULL) return NULL; + + cmsPipelineInsertStage(NULL, BToA0, cmsAT_BEGIN, ColorMap); + cmsStageSampleCLut16bit(NULL, ColorMap, PCS2ITU, NULL, 0); + + hProfile = cmsCreateProfilePlaceholder(0); + if (hProfile == NULL) { + cmsPipelineFree(NULL, BToA0); + return NULL; + } + + cmsWriteTag(NULL, hProfile, cmsSigBToA0Tag, BToA0); + cmsSetColorSpace(NULL, hProfile, cmsSigLabData); + cmsSetPCS(NULL, hProfile, cmsSigLabData); + cmsSetDeviceClass(NULL, hProfile, cmsSigColorSpaceClass); + + cmsPipelineFree(NULL, BToA0); + + return hProfile; +} + + + +#define PS_FIXED_TO_FLOAT(h, l) ((float) (h) + ((float) (l)/(1<<16))) + +static +cmsBool ProcessPhotoshopAPP13(JOCTET FAR *data, int datalen) +{ + int i; + + for (i = 14; i < datalen; ) + { + long len; + unsigned int type; + + if (!(GETJOCTET(data[i] ) == 0x38 && + GETJOCTET(data[i+1]) == 0x42 && + GETJOCTET(data[i+2]) == 0x49 && + GETJOCTET(data[i+3]) == 0x4D)) break; // Not recognized + + i += 4; // identifying string + + type = (unsigned int) (GETJOCTET(data[i]<<8) + GETJOCTET(data[i+1])); + + i += 2; // resource type + + i += GETJOCTET(data[i]) + ((GETJOCTET(data[i]) & 1) ? 1 : 2); // resource name + + len = ((((GETJOCTET(data[i]<<8) + GETJOCTET(data[i+1]))<<8) + + GETJOCTET(data[i+2]))<<8) + GETJOCTET(data[i+3]); + + i += 4; // Size + + if (type == 0x03ED && len >= 16) { + + Decompressor.X_density = (UINT16) PS_FIXED_TO_FLOAT(GETJOCTET(data[i]<<8) + GETJOCTET(data[i+1]), + GETJOCTET(data[i+2]<<8) + GETJOCTET(data[i+3])); + Decompressor.Y_density = (UINT16) PS_FIXED_TO_FLOAT(GETJOCTET(data[i+8]<<8) + GETJOCTET(data[i+9]), + GETJOCTET(data[i+10]<<8) + GETJOCTET(data[i+11])); + + // Set the density unit to 1 since the + // Vertical and Horizontal resolutions + // are specified in Pixels per inch + + Decompressor.density_unit = 0x01; + return TRUE; + + } + + i += len + ((len & 1) ? 1 : 0); // Alignment + } + return FALSE; +} + + +static +cmsBool HandlePhotoshopAPP13(jpeg_saved_marker_ptr ptr) +{ + while (ptr) { + + if (ptr -> marker == (JPEG_APP0 + 13) && ptr -> data_length > 9) + { + JOCTET FAR* data = ptr -> data; + + if(GETJOCTET(data[0]) == 0x50 && + GETJOCTET(data[1]) == 0x68 && + GETJOCTET(data[2]) == 0x6F && + GETJOCTET(data[3]) == 0x74 && + GETJOCTET(data[4]) == 0x6F && + GETJOCTET(data[5]) == 0x73 && + GETJOCTET(data[6]) == 0x68 && + GETJOCTET(data[7]) == 0x6F && + GETJOCTET(data[8]) == 0x70) { + + ProcessPhotoshopAPP13(data, ptr -> data_length); + return TRUE; + } + } + + ptr = ptr -> next; + } + + return FALSE; +} + + +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +#define INTEL_BYTE_ORDER 0x4949 +#define XRESOLUTION 0x011a +#define YRESOLUTION 0x011b +#define RESOLUTION_UNIT 0x128 + +// Read a 16-bit word +static +uint16_t read16(uint8_t* arr, int pos, int swapBytes) +{ + uint8_t b1 = arr[pos]; + uint8_t b2 = arr[pos+1]; + + return (swapBytes) ? ((b2 << 8) | b1) : ((b1 << 8) | b2); +} + + +// Read a 32-bit word +static +uint32_t read32(uint8_t* arr, int pos, int swapBytes) +{ + + if(!swapBytes) { + + return (arr[pos] << 24) | + (arr[pos+1] << 16) | + (arr[pos+2] << 8) | + arr[pos+3]; + } + + return arr[pos] | + (arr[pos+1] << 8) | + (arr[pos+2] << 16) | + (arr[pos+3] << 24); +} + + + +static +int read_tag(uint8_t* arr, int pos, int swapBytes, void* dest) +{ + // Format should be 5 over here (rational) + uint32_t format = read16(arr, pos + 2, swapBytes); + // Components should be 1 + uint32_t components = read32(arr, pos + 4, swapBytes); + // Points to the value + uint32_t offset; + + // sanity + if (components != 1) return 0; + + if (format == 3) + offset = pos + 8; + else + offset = read32(arr, pos + 8, swapBytes); + + switch (format) { + + case 5: // Rational + { + double num = read32(arr, offset, swapBytes); + double den = read32(arr, offset + 4, swapBytes); + *(double *) dest = num / den; + } + break; + + case 3: // uint 16 + *(int*) dest = read16(arr, offset, swapBytes); + break; + + default: return 0; + } + + return 1; +} + + + +// Handler for EXIF data +static + cmsBool HandleEXIF(struct jpeg_decompress_struct* cinfo) +{ + jpeg_saved_marker_ptr ptr; + uint32_t ifd_ofs; + int pos = 0, swapBytes = 0; + uint32_t i, numEntries; + double XRes = -1, YRes = -1; + int Unit = 2; // Inches + + + for (ptr = cinfo ->marker_list; ptr; ptr = ptr ->next) { + + if ((ptr ->marker == JPEG_APP0+1) && ptr ->data_length > 6) { + JOCTET FAR* data = ptr -> data; + + if (memcmp(data, "Exif\0\0", 6) == 0) { + + data += 6; // Skip EXIF marker + + // 8 byte TIFF header + // first two determine byte order + pos = 0; + if (read16(data, pos, 0) == INTEL_BYTE_ORDER) { + swapBytes = 1; + } + + pos += 2; + + // next two bytes are always 0x002A (TIFF version) + pos += 2; + + // offset to Image File Directory (includes the previous 8 bytes) + ifd_ofs = read32(data, pos, swapBytes); + + // Search the directory for resolution tags + numEntries = read16(data, ifd_ofs, swapBytes); + + for (i=0; i < numEntries; i++) { + + uint32_t entryOffset = ifd_ofs + 2 + (12 * i); + uint32_t tag = read16(data, entryOffset, swapBytes); + + switch (tag) { + + case RESOLUTION_UNIT: + if (!read_tag(data, entryOffset, swapBytes, &Unit)) return FALSE; + break; + + case XRESOLUTION: + if (!read_tag(data, entryOffset, swapBytes, &XRes)) return FALSE; + break; + + case YRESOLUTION: + if (!read_tag(data, entryOffset, swapBytes, &YRes)) return FALSE; + break; + + default:; + } + + } + + // Proceed if all found + + if (XRes != -1 && YRes != -1) + { + + // 1 = None + // 2 = inches + // 3 = cm + + switch (Unit) { + + case 2: + + cinfo ->X_density = (UINT16) floor(XRes + 0.5); + cinfo ->Y_density = (UINT16) floor(YRes + 0.5); + break; + + case 1: + + cinfo ->X_density = (UINT16) floor(XRes * 2.54 + 0.5); + cinfo ->Y_density = (UINT16) floor(YRes * 2.54 + 0.5); + break; + + default: return FALSE; + } + + cinfo ->density_unit = 1; /* 1 for dots/inch, or 2 for dots/cm.*/ + + } + + + } + } + } + return FALSE; +} + + +static +cmsBool OpenInput(const char* FileName) +{ + int m; + + lIsITUFax = FALSE; + InFile = fopen(FileName, "rb"); + if (InFile == NULL) { + FatalError("Cannot open '%s'", FileName); + } + + // Now we can initialize the JPEG decompression object. + Decompressor.err = jpeg_std_error(&ErrorHandler.pub); + ErrorHandler.pub.error_exit = my_error_exit; + ErrorHandler.pub.output_message = my_error_exit; + + jpeg_create_decompress(&Decompressor); + jpeg_stdio_src(&Decompressor, InFile); + + for (m = 0; m < 16; m++) + jpeg_save_markers(&Decompressor, JPEG_APP0 + m, 0xFFFF); + + // setup_read_icc_profile(&Decompressor); + + fseek(InFile, 0, SEEK_SET); + jpeg_read_header(&Decompressor, TRUE); + + return TRUE; +} + + +static +cmsBool OpenOutput(const char* FileName) +{ + + OutFile = fopen(FileName, "wb"); + if (OutFile == NULL) { + FatalError("Cannot create '%s'", FileName); + + } + + Compressor.err = jpeg_std_error(&ErrorHandler.pub); + ErrorHandler.pub.error_exit = my_error_exit; + ErrorHandler.pub.output_message = my_error_exit; + + Compressor.input_components = Compressor.num_components = 4; + + jpeg_create_compress(&Compressor); + jpeg_stdio_dest(&Compressor, OutFile); + return TRUE; +} + +static +cmsBool Done(void) +{ + jpeg_destroy_decompress(&Decompressor); + jpeg_destroy_compress(&Compressor); + return fclose(InFile) + fclose(OutFile); + +} + + +// Build up the pixeltype descriptor + +static +cmsUInt32Number GetInputPixelType(void) +{ + int space, bps, extra, ColorChannels, Flavor; + + lIsITUFax = IsITUFax(Decompressor.marker_list); + lIsPhotoshopApp13 = HandlePhotoshopAPP13(Decompressor.marker_list); + lIsEXIF = HandleEXIF(&Decompressor); + + ColorChannels = Decompressor.num_components; + extra = 0; // Alpha = None + bps = 1; // 8 bits + Flavor = 0; // Vanilla + + if (lIsITUFax) { + + space = PT_Lab; + Decompressor.out_color_space = JCS_YCbCr; // Fake to don't touch + } + else + switch (Decompressor.jpeg_color_space) { + + case JCS_GRAYSCALE: // monochrome + space = PT_GRAY; + Decompressor.out_color_space = JCS_GRAYSCALE; + break; + + case JCS_RGB: // red/green/blue + space = PT_RGB; + Decompressor.out_color_space = JCS_RGB; + break; + + case JCS_YCbCr: // Y/Cb/Cr (also known as YUV) + space = PT_RGB; // Let IJG code to do the conversion + Decompressor.out_color_space = JCS_RGB; + break; + + case JCS_CMYK: // C/M/Y/K + space = PT_CMYK; + Decompressor.out_color_space = JCS_CMYK; + if (Decompressor.saw_Adobe_marker) // Adobe keeps CMYK inverted, so change flavor + Flavor = 1; // from vanilla to chocolate + break; + + case JCS_YCCK: // Y/Cb/Cr/K + space = PT_CMYK; + Decompressor.out_color_space = JCS_CMYK; + if (Decompressor.saw_Adobe_marker) // ditto + Flavor = 1; + break; + + default: + FatalError("Unsupported color space (0x%x)", Decompressor.jpeg_color_space); + return 0; + } + + return (EXTRA_SH(extra)|CHANNELS_SH(ColorChannels)|BYTES_SH(bps)|COLORSPACE_SH(space)|FLAVOR_SH(Flavor)); +} + + +// Rearrange pixel type to build output descriptor +static +cmsUInt32Number ComputeOutputFormatDescriptor(cmsUInt32Number dwInput, int OutColorSpace) +{ + int IsPlanar = T_PLANAR(dwInput); + int Channels = 0; + int Flavor = 0; + + switch (OutColorSpace) { + + case PT_GRAY: + Channels = 1; + break; + case PT_RGB: + case PT_CMY: + case PT_Lab: + case PT_YUV: + case PT_YCbCr: + Channels = 3; + break; + + case PT_CMYK: + if (Compressor.write_Adobe_marker) // Adobe keeps CMYK inverted, so change flavor to chocolate + Flavor = 1; + Channels = 4; + break; + default: + FatalError("Unsupported output color space"); + } + + return (COLORSPACE_SH(OutColorSpace)|PLANAR_SH(IsPlanar)|CHANNELS_SH(Channels)|BYTES_SH(1)|FLAVOR_SH(Flavor)); +} + + +// Equivalence between ICC color spaces and lcms color spaces +static +int GetProfileColorSpace(cmsHPROFILE hProfile) +{ + cmsColorSpaceSignature ProfileSpace = cmsGetColorSpace(NULL, hProfile); + + return _cmsLCMScolorSpace(NULL, ProfileSpace); +} + +static +int GetDevicelinkColorSpace(cmsHPROFILE hProfile) +{ + cmsColorSpaceSignature ProfileSpace = cmsGetPCS(NULL, hProfile); + + return _cmsLCMScolorSpace(NULL, ProfileSpace); +} + + +// From TRANSUPP + +static +void jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo) +{ + jpeg_saved_marker_ptr marker; + + /* In the current implementation, we don't actually need to examine the + * option flag here; we just copy everything that got saved. + * But to avoid confusion, we do not output JFIF and Adobe APP14 markers + * if the encoder library already wrote one. + */ + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + + if (dstinfo->write_JFIF_header && + marker->marker == JPEG_APP0 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x4A && + GETJOCTET(marker->data[1]) == 0x46 && + GETJOCTET(marker->data[2]) == 0x49 && + GETJOCTET(marker->data[3]) == 0x46 && + GETJOCTET(marker->data[4]) == 0) + continue; /* reject duplicate JFIF */ + + if (dstinfo->write_Adobe_marker && + marker->marker == JPEG_APP0+14 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x41 && + GETJOCTET(marker->data[1]) == 0x64 && + GETJOCTET(marker->data[2]) == 0x6F && + GETJOCTET(marker->data[3]) == 0x62 && + GETJOCTET(marker->data[4]) == 0x65) + continue; /* reject duplicate Adobe */ + + jpeg_write_marker(dstinfo, marker->marker, + marker->data, marker->data_length); + } +} + +static +void WriteOutputFields(int OutputColorSpace) +{ + J_COLOR_SPACE in_space, jpeg_space; + int components; + + switch (OutputColorSpace) { + + case PT_GRAY: in_space = jpeg_space = JCS_GRAYSCALE; + components = 1; + break; + + case PT_RGB: in_space = JCS_RGB; + jpeg_space = JCS_YCbCr; + components = 3; + break; // red/green/blue + + case PT_YCbCr: in_space = jpeg_space = JCS_YCbCr; + components = 3; + break; // Y/Cb/Cr (also known as YUV) + + case PT_CMYK: in_space = JCS_CMYK; + jpeg_space = JCS_YCCK; + components = 4; + break; // C/M/Y/components + + case PT_Lab: in_space = jpeg_space = JCS_YCbCr; + components = 3; + break; // Fake to don't touch + default: + FatalError("Unsupported output color space"); + return; + } + + + if (jpegQuality >= 100) { + + // avoid destructive conversion when asking for lossless compression + jpeg_space = in_space; + } + + Compressor.in_color_space = in_space; + Compressor.jpeg_color_space = jpeg_space; + Compressor.input_components = Compressor.num_components = components; + jpeg_set_defaults(&Compressor); + jpeg_set_colorspace(&Compressor, jpeg_space); + + + // Make sure to pass resolution through + if (OutputColorSpace == PT_CMYK) + Compressor.write_JFIF_header = 1; + + // Avoid subsampling on high quality factor + jpeg_set_quality(&Compressor, jpegQuality, 1); + if (jpegQuality >= 70) { + + int i; + for(i=0; i < Compressor.num_components; i++) { + + Compressor.comp_info[i].h_samp_factor = 1; + Compressor.comp_info[i].v_samp_factor = 1; + } + + } + +} + + +static +void DoEmbedProfile(const char* ProfileFile) +{ + FILE* f; + size_t size, EmbedLen; + cmsUInt8Number* EmbedBuffer; + + f = fopen(ProfileFile, "rb"); + if (f == NULL) return; + + size = cmsfilelength(f); + EmbedBuffer = (cmsUInt8Number*) malloc(size + 1); + EmbedLen = fread(EmbedBuffer, 1, size, f); + fclose(f); + EmbedBuffer[EmbedLen] = 0; + + write_icc_profile (&Compressor, EmbedBuffer, (unsigned int) EmbedLen); + free(EmbedBuffer); +} + + + +static +int DoTransform(cmsHTRANSFORM hXForm, int OutputColorSpace) +{ + JSAMPROW ScanLineIn; + JSAMPROW ScanLineOut; + + + //Preserve resolution values from the original + // (Thanks to Robert Bergs for finding out this bug) + Compressor.density_unit = Decompressor.density_unit; + Compressor.X_density = Decompressor.X_density; + Compressor.Y_density = Decompressor.Y_density; + + // Compressor.write_JFIF_header = 1; + + jpeg_start_decompress(&Decompressor); + jpeg_start_compress(&Compressor, TRUE); + + if (OutputColorSpace == PT_Lab) + SetITUFax(&Compressor); + + // Embed the profile if needed + if (EmbedProfile && cOutProf) + DoEmbedProfile(cOutProf); + + ScanLineIn = (JSAMPROW) malloc(Decompressor.output_width * Decompressor.num_components); + ScanLineOut = (JSAMPROW) malloc(Compressor.image_width * Compressor.num_components); + + while (Decompressor.output_scanline < + Decompressor.output_height) { + + jpeg_read_scanlines(&Decompressor, &ScanLineIn, 1); + + cmsDoTransform(NULL, hXForm, ScanLineIn, ScanLineOut, Decompressor.output_width); + + jpeg_write_scanlines(&Compressor, &ScanLineOut, 1); + } + + free(ScanLineIn); + free(ScanLineOut); + + jpeg_finish_decompress(&Decompressor); + jpeg_finish_compress(&Compressor); + + return TRUE; +} + + + +// Transform one image + +static +int TransformImage(char *cDefInpProf, char *cOutputProf) +{ + cmsHPROFILE hIn, hOut, hProof; + cmsHTRANSFORM xform; + cmsUInt32Number wInput, wOutput; + int OutputColorSpace; + cmsUInt32Number dwFlags = 0; + cmsUInt32Number EmbedLen; + cmsUInt8Number* EmbedBuffer; + + + cmsSetAdaptationState(ObserverAdaptationState); + + if (BlackPointCompensation) { + + dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + } + + + switch (PrecalcMode) { + + case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break; + case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; + case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; + default:; + } + + + if (GamutCheck) { + dwFlags |= cmsFLAGS_GAMUTCHECK; + cmsSetAlarmCodes(Alarm); + } + + // Take input color space + wInput = GetInputPixelType(); + + if (lIsDeviceLink) { + + hIn = cmsOpenProfileFromFile(cDefInpProf, "r"); + hOut = NULL; + hProof = NULL; + } + else { + + if (!IgnoreEmbedded && read_icc_profile(&Decompressor, &EmbedBuffer, &EmbedLen)) + { + hIn = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen); + + if (Verbose) { + + fprintf(stdout, " (Embedded profile found)\n"); + PrintProfileInformation(NULL, hIn); + fflush(stdout); + } + + if (hIn != NULL && SaveEmbedded != NULL) + SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded); + + free(EmbedBuffer); + } + else + { + // Default for ITU/Fax + if (cDefInpProf == NULL && T_COLORSPACE(wInput) == PT_Lab) + cDefInpProf = "*Lab"; + + if (cDefInpProf != NULL && cmsstrcasecmp(cDefInpProf, "*lab") == 0) + hIn = CreateITU2PCS_ICC(); + else + hIn = OpenStockProfile(0, cDefInpProf); + } + + if (cOutputProf != NULL && cmsstrcasecmp(cOutputProf, "*lab") == 0) + hOut = CreatePCS2ITU_ICC(); + else + hOut = OpenStockProfile(0, cOutputProf); + + hProof = NULL; + if (cProofing != NULL) { + + hProof = OpenStockProfile(0, cProofing); + if (hProof == NULL) { + FatalError("Proofing profile couldn't be read."); + } + dwFlags |= cmsFLAGS_SOFTPROOFING; + } + } + + if (!hIn) + FatalError("Input profile couldn't be read."); + if (!lIsDeviceLink && !hOut) + FatalError("Output profile couldn't be read."); + + // Assure both, input profile and input JPEG are on same colorspace + if (cmsGetColorSpace(NULL, hIn) != _cmsICCcolorSpace(NULL, T_COLORSPACE(wInput))) + FatalError("Input profile is not operating in proper color space"); + + + // Output colorspace is given by output profile + + if (lIsDeviceLink) { + OutputColorSpace = GetDevicelinkColorSpace(hIn); + } + else { + OutputColorSpace = GetProfileColorSpace(hOut); + } + + jpeg_copy_critical_parameters(&Decompressor, &Compressor); + + WriteOutputFields(OutputColorSpace); + + wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace); + + + xform = cmsCreateProofingTransform(hIn, wInput, + hOut, wOutput, + hProof, Intent, + ProofingIntent, dwFlags); + if (xform == NULL) + FatalError("Cannot transform by using the profiles"); + + DoTransform(xform, OutputColorSpace); + + + jcopy_markers_execute(&Decompressor, &Compressor); + + cmsDeleteTransform(NULL, xform); + cmsCloseProfile(NULL, hIn); + cmsCloseProfile(NULL, hOut); + if (hProof) cmsCloseProfile(NULL, hProof); + + return 1; +} + + +// Simply print help + +static +void Help(int level) +{ + fprintf(stderr, "little cms ICC profile applier for JPEG - v3.2 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0); + + switch(level) { + + default: + case 0: + + fprintf(stderr, "usage: jpgicc [flags] input.jpg output.jpg\n"); + + fprintf(stderr, "\nflags:\n\n"); + fprintf(stderr, "%cv - Verbose\n", SW); + fprintf(stderr, "%ci<profile> - Input profile (defaults to sRGB)\n", SW); + fprintf(stderr, "%co<profile> - Output profile (defaults to sRGB)\n", SW); + + PrintRenderingIntents(); + + + fprintf(stderr, "%cb - Black point compensation\n", SW); + fprintf(stderr, "%cd<0..1> - Observer adaptation state (abs.col. only)\n", SW); + fprintf(stderr, "%cn - Ignore embedded profile\n", SW); + fprintf(stderr, "%ce - Embed destination profile\n", SW); + fprintf(stderr, "%cs<new profile> - Save embedded profile as <new profile>\n", SW); + + fprintf(stderr, "\n"); + + fprintf(stderr, "%cc<0,1,2,3> - Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]\n", SW); + fprintf(stderr, "\n"); + + fprintf(stderr, "%cp<profile> - Soft proof profile\n", SW); + fprintf(stderr, "%cm<0,1,2,3> - SoftProof intent\n", SW); + fprintf(stderr, "%cg - Marks out-of-gamut colors on softproof\n", SW); + fprintf(stderr, "%c!<r>,<g>,<b> - Out-of-gamut marker channel values\n", SW); + + fprintf(stderr, "\n"); + fprintf(stderr, "%cq<0..100> - Output JPEG quality\n", SW); + + fprintf(stderr, "\n"); + fprintf(stderr, "%ch<0,1,2,3> - More help\n", SW); + break; + + case 1: + + fprintf(stderr, "Examples:\n\n" + "To color correct from scanner to sRGB:\n" + "\tjpgicc %ciscanner.icm in.jpg out.jpg\n" + "To convert from monitor1 to monitor2:\n" + "\tjpgicc %cimon1.icm %comon2.icm in.jpg out.jpg\n" + "To make a CMYK separation:\n" + "\tjpgicc %coprinter.icm inrgb.jpg outcmyk.jpg\n" + "To recover sRGB from a CMYK separation:\n" + "\tjpgicc %ciprinter.icm incmyk.jpg outrgb.jpg\n" + "To convert from CIELab ITU/Fax JPEG to sRGB\n" + "\tjpgicc in.jpg out.jpg\n\n", + SW, SW, SW, SW, SW); + break; + + case 2: + PrintBuiltins(); + break; + + case 3: + + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "marti@littlecms.com\n\n"); + break; + } + + exit(0); +} + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s=xgetopt(argc,argv,"bBnNvVGgh:H:i:I:o:O:P:p:t:T:c:C:Q:q:M:m:L:l:eEs:S:!:D:d:")) != EOF) { + + switch (s) + { + + case 'b': + case 'B': + BlackPointCompensation = TRUE; + break; + + case 'd': + case 'D': ObserverAdaptationState = atof(xoptarg); + if (ObserverAdaptationState < 0 || + ObserverAdaptationState > 1.0) + FatalError("Adaptation state should be 0..1"); + break; + + case 'v': + case 'V': + Verbose = TRUE; + break; + + case 'i': + case 'I': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + + cInpProf = xoptarg; + break; + + case 'o': + case 'O': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + + cOutProf = xoptarg; + break; + + case 'l': + case 'L': + if (cInpProf != NULL || cOutProf != NULL) + FatalError("input/output profiles already specified"); + + cInpProf = xoptarg; + lIsDeviceLink = TRUE; + break; + + case 'p': + case 'P': + cProofing = xoptarg; + break; + + case 't': + case 'T': + Intent = atoi(xoptarg); + break; + + case 'N': + case 'n': + IgnoreEmbedded = TRUE; + break; + + case 'e': + case 'E': + EmbedProfile = TRUE; + break; + + + case 'g': + case 'G': + GamutCheck = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 2) + FatalError("Unknown precalc mode '%d'", PrecalcMode); + break; + + case 'H': + case 'h': { + + int a = atoi(xoptarg); + Help(a); + } + break; + + case 'q': + case 'Q': + jpegQuality = atoi(xoptarg); + if (jpegQuality > 100) jpegQuality = 100; + if (jpegQuality < 0) jpegQuality = 0; + break; + + case 'm': + case 'M': + ProofingIntent = atoi(xoptarg); + break; + + case 's': + case 'S': SaveEmbedded = xoptarg; + break; + + case '!': + if (sscanf(xoptarg, "%hu,%hu,%hu", &Alarm[0], &Alarm[1], &Alarm[2]) == 3) { + int i; + for (i=0; i < 3; i++) { + Alarm[i] = (Alarm[i] << 8) | Alarm[i]; + } + } + break; + + default: + + FatalError("Unknown option - run without args to see valid ones"); + } + + } +} + + +int main(int argc, char* argv[]) +{ + InitUtils("jpgicc"); + + HandleSwitches(argc, argv); + + if ((argc - xoptind) != 2) { + Help(0); + } + + OpenInput(argv[xoptind]); + OpenOutput(argv[xoptind+1]); + + TransformImage(cInpProf, cOutProf); + + + if (Verbose) { fprintf(stdout, "\n"); fflush(stdout); } + + Done(); + + return 0; +} + + + diff --git a/lcms2mt/utils/linkicc/Makefile.am b/lcms2mt/utils/linkicc/Makefile.am new file mode 100644 index 000000000..3b9186970 --- /dev/null +++ b/lcms2mt/utils/linkicc/Makefile.am @@ -0,0 +1,19 @@ +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +bin_PROGRAMS = linkicc + +linkicc_LDADD = $(top_builddir)/src/liblcms2.la +linkicc_LDFLAGS = @LDFLAGS@ +linkicc_SOURCES = linkicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +linkicc_MANS = linkicc.1 + +EXTRA_DIST = $(man_MANS) diff --git a/lcms2mt/utils/linkicc/Makefile.in b/lcms2mt/utils/linkicc/Makefile.in new file mode 100644 index 000000000..2631ab879 --- /dev/null +++ b/lcms2mt/utils/linkicc/Makefile.in @@ -0,0 +1,663 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = linkicc$(EXEEXT) +subdir = utils/linkicc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_linkicc_OBJECTS = linkicc.$(OBJEXT) ../common/xgetopt.$(OBJEXT) \ + ../common/vprf.$(OBJEXT) +linkicc_OBJECTS = $(am_linkicc_OBJECTS) +linkicc_DEPENDENCIES = $(top_builddir)/src/liblcms2.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +linkicc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(linkicc_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(linkicc_SOURCES) +DIST_SOURCES = $(linkicc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +linkicc_LDADD = $(top_builddir)/src/liblcms2.la +linkicc_LDFLAGS = @LDFLAGS@ +linkicc_SOURCES = linkicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +linkicc_MANS = linkicc.1 +EXTRA_DIST = $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/linkicc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign utils/linkicc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../common/$(am__dirstamp): + @$(MKDIR_P) ../common + @: > ../common/$(am__dirstamp) +../common/xgetopt.$(OBJEXT): ../common/$(am__dirstamp) +../common/vprf.$(OBJEXT): ../common/$(am__dirstamp) + +linkicc$(EXEEXT): $(linkicc_OBJECTS) $(linkicc_DEPENDENCIES) $(EXTRA_linkicc_DEPENDENCIES) + @rm -f linkicc$(EXEEXT) + $(AM_V_CCLD)$(linkicc_LINK) $(linkicc_OBJECTS) $(linkicc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../common/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../common/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/linkicc/linkicc.1 b/lcms2mt/utils/linkicc/linkicc.1 new file mode 100644 index 000000000..56f73bb9a --- /dev/null +++ b/lcms2mt/utils/linkicc/linkicc.1 @@ -0,0 +1,123 @@ +.\"Shiju P. Nair September 30, 2004 +.\"Thomas Weber <tweber@debian.org> April 23, 2014 +.TH LINKICC 1 "September 30, 2004" +.SH NAME +linkicc - little cms device link generator. +.SH SYNOPSIS +.B linkicc +.RI [ options ] " profiles" +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B linkicc +is a little cms device link generator. +.P +Links two or more profiles into a single devicelink profile. +Colorspaces must be paired except Lab/XYZ, that can be interchanged. +.SH OPTIONS +.TP +.BR \-a\ NUM +Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 1.0]. +.TP +.B \-b +Black point compensation. +.TP +.BI \-c\ precision +Precision (0=LowRes, 1=Normal, 2=Hi-res) [defaults to 1]. +.TP +.BI \-d\ description +Description text (quotes can be used). +.TP +.BI \-h\ NUM +Show summary of options and examples (0=help, 1=Built-in profiles, 2=Examples, 3=Contact information) +.TP +.BI \-k\ inklimit +Ink-limiting in % (CMYK only), (0..400.0, float value) [default 400.0]. +.TP +.B \-l +Use linearization curves (may affect accuracy). +.TP +.BI \-n\ gridpoints +Alternate way to set precision, number of CLUT points. +.TP +.BI \-o\ profile +Output devicelink profile [defaults to 'devicelink.icm']. +.TP +.BI \-r\ profileversion +Profile version. (CAUTION: may change the profile implementation), (2.0..4.3, float value) [defaults to 4.3]. +.TP +.BI \-t\ NUM +Rendering intent +.nf +.RS +0=Perceptual [default] +1=Relative colorimetric +2=Saturation +3=Absolute colorimetric +10=Perceptual preserving black ink +11=Relative colorimetric preserving black ink +12=Saturation preserving black ink +13=Perceptual preserving black plane +14=Relative colorimetric preserving black plane +15=Saturation preserving black plane +.RE +.fi +.TP +.BI \-v\ verbosity +Verbosity level, (0=None, 1=Normal, 2=High, 3=Very High) [defaults to 0]. +.TP +.B \-x +Creatively, guess deviceclass of resulting profile. +.TP +.BI \-y\ copyright +Copyright notice (quotes can be used) ["No copyright, use freely"]. +.TP +.B \-8 +Creates 8-bit devicelink. +.SH BUILT-IN PROFILES +.nf + *Lab2 -- D50-based v2 CIEL*a*b + *Lab4 -- D50-based v4 CIEL*a*b + *Lab -- D50-based v4 CIEL*a*b + *XYZ -- CIE XYZ (PCS) + *sRGB -- sRGB color space + *Gray22 - Monochrome of Gamma 2.2 + *Gray30 - Monochrome of Gamma 3.0 + *null - Monochrome black for all input + *Lin2222- CMYK linearization of gamma 2.2 on each channel +.fi +.SH EXAMPLES +.nf +To create 'devicelink.icm' from a.icc to b.icc: + linkicc a.icc b.icc + +To create 'out.icc' from sRGB to cmyk.icc: + linkicc -o out.icc *sRGB cmyk.icc + +To create a sRGB input profile working in Lab: + linkicc -x -o sRGBLab.icc *sRGB *Lab + +To create a XYZ -> sRGB output profile: + linkicc -x -o sRGBLab.icc *XYZ *sRGB + +To create a abstract profile doing softproof for cmyk.icc: + linkicc -t1 -x -o softproof.icc *Lab cmyk.icc cmyk.icc *Lab + +To create a 'grayer' sRGB input profile: + linkicc -x -o grayer.icc *sRGB gray.icc gray.icc *Lab + +To embed ink limiting into a cmyk output profile: + linkicc -x -o cmyklimited.icc -k 250 cmyk.icc *Lab + +.fi +.SH NOTES +For suggestions, comments, bug reports etc. send mail to +info@littlecms.com. +.SH SEE ALSO +.BR jpgicc (1), +.BR psicc (1), +.BR tificc (1), +.BR transicc (1) +.SH AUTHOR +This manual page was written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. diff --git a/lcms2mt/utils/linkicc/linkicc.c b/lcms2mt/utils/linkicc/linkicc.c new file mode 100644 index 000000000..2104d8314 --- /dev/null +++ b/lcms2mt/utils/linkicc/linkicc.c @@ -0,0 +1,384 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- + +#include "utils.h" + +// --------------------------------------------------------------------------------- + +static char* Description = "Devicelink profile"; +static char* Copyright = "No copyright, use freely"; +static int Intent = INTENT_PERCEPTUAL; +static char* cOutProf = "devicelink.icc"; +static int PrecalcMode = 1; +static int NumOfGridPoints = 0; + +static cmsFloat64Number ObserverAdaptationState = 1.0; // According ICC 4.2 this is the default + +static cmsBool BlackPointCompensation = FALSE; + +static cmsFloat64Number InkLimit = 400; +static cmsBool lUse8bits = FALSE; +static cmsBool TagResult = FALSE; +static cmsBool KeepLinearization = FALSE; +static cmsFloat64Number Version = 4.3; + + +// The manual +static +int Help(int level) +{ + switch (level) { + + default: + case 0: + + fprintf(stderr, "\nlinkicc: Links profiles into a single devicelink.\n"); + + fprintf(stderr, "\n"); + fprintf(stderr, "usage: linkicc [flags] <profiles>\n\n"); + fprintf(stderr, "flags:\n\n"); + fprintf(stderr, "%co<profile> - Output devicelink profile. [defaults to 'devicelink.icc']\n", SW); + + PrintRenderingIntents(); + + fprintf(stderr, "%cc<0,1,2> - Precision (0=LowRes, 1=Normal, 2=Hi-res) [defaults to 1]\n", SW); + fprintf(stderr, "%cn<gridpoints> - Alternate way to set precision, number of CLUT points\n", SW); + fprintf(stderr, "%cd<description> - description text (quotes can be used)\n", SW); + fprintf(stderr, "%cy<copyright> - copyright notice (quotes can be used)\n", SW); + + fprintf(stderr, "\n%ck<0..400> - Ink-limiting in %% (CMYK only)\n", SW); + fprintf(stderr, "%c8 - Creates 8-bit devicelink\n", SW); + fprintf(stderr, "%cx - Creatively, guess deviceclass of resulting profile.\n", SW); + fprintf(stderr, "%cb - Black point compensation\n", SW); + fprintf(stderr, "%ca<0..1> - Observer adaptation state (abs.col. only)\n\n", SW); + fprintf(stderr, "%cl - Use linearization curves (may affect accuracy)\n", SW); + fprintf(stderr, "%cr<v.r> - Profile version. (CAUTION: may change the profile implementation)\n", SW); + fprintf(stderr, "\n"); + fprintf(stderr, "Colorspaces must be paired except Lab/XYZ, that can be interchanged.\n\n"); + + fprintf(stderr, "%ch<0,1,2,3> - More help\n", SW); + break; + + case 1: + PrintBuiltins(); + break; + + case 2: + + fprintf(stderr, "\nExamples:\n\n" + "To create 'devicelink.icm' from a.icc to b.icc:\n" + "\tlinkicc a.icc b.icc\n\n" + "To create 'out.icc' from sRGB to cmyk.icc:\n" + "\tlinkicc -o out.icc *sRGB cmyk.icc\n\n" + "To create a sRGB input profile working in Lab:\n" + "\tlinkicc -x -o sRGBLab.icc *sRGB *Lab\n\n" + "To create a XYZ -> sRGB output profile:\n" + "\tlinkicc -x -o sRGBLab.icc *XYZ *sRGB\n\n" + "To create a abstract profile doing softproof for cmyk.icc:\n" + "\tlinkicc -t1 -x -o softproof.icc *Lab cmyk.icc cmyk.icc *Lab\n\n" + "To create a 'grayer' sRGB input profile:\n" + "\tlinkicc -x -o grayer.icc *sRGB gray.icc gray.icc *Lab\n\n" + "To embed ink limiting into a cmyk output profile:\n" + "\tlinkicc -x -o cmyklimited.icc -k 250 cmyk.icc *Lab\n\n"); + break; + + case 3: + + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "info@littlecms.com\n\n"); + } + + exit(0); +} + +// The toggles stuff +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s = xgetopt(argc,argv,"a:A:BbC:c:D:d:h:H:k:K:lLn:N:O:o:r:R:T:t:V:v:xX8y:Y:")) != EOF) { + + switch (s) { + + + case 'a': + case 'A': + ObserverAdaptationState = atof(xoptarg); + if (ObserverAdaptationState < 0 || + ObserverAdaptationState > 1.0) + FatalError("Adaptation state should be 0..1"); + break; + + case 'b': + case 'B': + BlackPointCompensation = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 2) { + FatalError("Unknown precalc mode '%d'", PrecalcMode); + } + break; + + case 'd': + case 'D': + // Doing that is correct and safe: Description points to memory allocated in the command line. + // same for Copyright and output devicelink. + Description = xoptarg; + break; + + case 'h': + case 'H': + Help(atoi(xoptarg)); + return; + + case 'k': + case 'K': + InkLimit = atof(xoptarg); + if (InkLimit < 0.0 || InkLimit > 400.0) { + FatalError("Ink limit must be 0%%..400%%"); + } + break; + + + case 'l': + case 'L': KeepLinearization = TRUE; + break; + + case 'n': + case 'N': + if (PrecalcMode != 1) { + FatalError("Precalc mode already specified"); + } + NumOfGridPoints = atoi(xoptarg); + break; + + case 'o': + case 'O': + cOutProf = xoptarg; + break; + + + case 'r': + case 'R': + Version = atof(xoptarg); + if (Version < 2.0 || Version > 4.3) { + fprintf(stderr, "WARNING: lcms was not aware of this version, tag types may be wrong!\n"); + } + break; + + case 't': + case 'T': + Intent = atoi(xoptarg); // Will be validated latter on + break; + + case 'V': + case 'v': + Verbose = atoi(xoptarg); + if (Verbose < 0 || Verbose > 3) { + FatalError("Unknown verbosity level '%d'", Verbose); + } + break; + + case '8': + lUse8bits = TRUE; + break; + + + + case 'y': + case 'Y': + Copyright = xoptarg; + break; + + + + case 'x': + case 'X': TagResult = TRUE; + break; + + + + default: + + FatalError("Unknown option - run without args to see valid ones.\n"); + } + } +} + +// Set the copyright and description +static +cmsBool SetTextTags(cmsContext ContextID, cmsHPROFILE hProfile) +{ + cmsMLU *DescriptionMLU, *CopyrightMLU; + cmsBool rc = FALSE; + + DescriptionMLU = cmsMLUalloc(ContextID, 1); + CopyrightMLU = cmsMLUalloc(ContextID, 1); + + if (DescriptionMLU == NULL || CopyrightMLU == NULL) goto Error; + + if (!cmsMLUsetASCII(ContextID, DescriptionMLU, "en", "US", Description)) goto Error; + if (!cmsMLUsetASCII(ContextID, CopyrightMLU, "en", "US", Copyright)) goto Error; + + if (!cmsWriteTag(ContextID, hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error; + if (!cmsWriteTag(ContextID, hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error; + + rc = TRUE; + +Error: + + if (DescriptionMLU) + cmsMLUfree(ContextID, DescriptionMLU); + if (CopyrightMLU) + cmsMLUfree(ContextID, CopyrightMLU); + return rc; +} + + + +int main(int argc, char *argv[]) +{ + int i, nargs, rc; + cmsHPROFILE Profiles[257]; + cmsHPROFILE hProfile; + cmsUInt32Number dwFlags; + cmsHTRANSFORM hTransform = NULL; + cmsContext ContextID = NULL; + + // Here we are + fprintf(stderr, "little cms ICC device link generator - v2.2 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0); + fflush(stderr); + + // Initialize + InitUtils("linkicc"); + rc = 0; + + // Get the options + HandleSwitches(argc, argv); + + // How many profiles to link? + nargs = (argc - xoptind); + if (nargs < 1) + return Help(0); + + if (nargs > 255) { + FatalError("Holy profile! what are you trying to do with so many profiles!?"); + goto Cleanup; + } + + // Open all profiles + memset(Profiles, 0, sizeof(Profiles)); + for (i=0; i < nargs; i++) { + + Profiles[i] = OpenStockProfile(ContextID, argv[i + xoptind]); + if (Profiles[i] == NULL) goto Cleanup; + + if (Verbose >= 1) { + PrintProfileInformation(ContextID, Profiles[i]); + } + } + + // Ink limiting + if (InkLimit != 400.0) { + cmsColorSpaceSignature EndingColorSpace = cmsGetColorSpace(ContextID, Profiles[nargs-1]); + Profiles[nargs++] = cmsCreateInkLimitingDeviceLink(EndingColorSpace, InkLimit); + } + + // Set the flags + dwFlags = cmsFLAGS_KEEP_SEQUENCE; + switch (PrecalcMode) { + + case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; + case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; + case 1: + if (NumOfGridPoints > 0) + dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints); + break; + + default: + { + FatalError("Unknown precalculation mode '%d'", PrecalcMode); + goto Cleanup; + } + } + + if (BlackPointCompensation) + dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + + if (TagResult) + dwFlags |= cmsFLAGS_GUESSDEVICECLASS; + + if (KeepLinearization) + dwFlags |= cmsFLAGS_CLUT_PRE_LINEARIZATION|cmsFLAGS_CLUT_POST_LINEARIZATION; + + if (lUse8bits) dwFlags |= cmsFLAGS_8BITS_DEVICELINK; + + cmsSetAdaptationState(ObserverAdaptationState); + + // Create the color transform. Specify 0 for the format is safe as the transform + // is intended to be used only for the devicelink. + hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags|cmsFLAGS_NOOPTIMIZE); + if (hTransform == NULL) { + FatalError("Transform creation failed"); + goto Cleanup; + } + + hProfile = cmsTransform2DeviceLink(ContextID, hTransform, Version, dwFlags); + if (hProfile == NULL) { + FatalError("Devicelink creation failed"); + goto Cleanup; + } + + SetTextTags(ContextID, hProfile); + cmsSetHeaderRenderingIntent(ContextID, hProfile, Intent); + + if (cmsSaveProfileToFile(ContextID, hProfile, cOutProf)) { + + if (Verbose > 0) + fprintf(stderr, "Ok"); + } + else + FatalError("Error saving file!"); + + cmsCloseProfile(ContextID, hProfile); + + +Cleanup: + + if (hTransform != NULL) cmsDeleteTransform(ContextID, hTransform); + for (i=0; i < nargs; i++) { + + if (Profiles[i] != NULL) cmsCloseProfile(ContextID, Profiles[i]); + } + + return rc; +} diff --git a/lcms2mt/utils/matlab/icctrans.c b/lcms2mt/utils/matlab/icctrans.c new file mode 100644 index 000000000..1ed66d954 --- /dev/null +++ b/lcms2mt/utils/matlab/icctrans.c @@ -0,0 +1,724 @@ +// +// Little cms +// Copyright (C) 1998-2010 Marti Maria, Ignacio Ruiz de Conejo +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +#include "mex.h" + +#include "lcms2mt.h" +#include "string.h" +#include "stdarg.h" + +// xgetopt() interface ----------------------------------------------------- + +static int xoptind; +static char *xoptarg; +static int xopterr; +static char *letP; +static char SW = '-'; + +// ------------------------------------------------------------------------ + + +static int Verbose ; // Print some statistics +static char *cInProf; // Input profile +static char *cOutProf; // Output profile +static char *cProofing; // Softproofing profile + + +static int Intent; // Rendering Intent +static int ProofingIntent; // RI for proof + +static int PrecalcMode; // 0 = Not, 1=Normal, 2=Accurate, 3=Fast + +static cmsBool BlackPointCompensation; +static cmsBool lIsDeviceLink; +static cmsBool lMultiProfileChain; // Multiple profile chain + +static cmsHPROFILE hInput, hOutput, hProof; +static cmsHTRANSFORM hColorTransform; +static cmsHPROFILE hProfiles[255]; +static int nProfiles; + +static cmsColorSpaceSignature InputColorSpace, OutputColorSpace; +static int OutputChannels, InputChannels, nBytesDepth; + + +// Error. Print error message and abort + +static +cmsBool FatalError(const char *frm, ...) +{ + va_list args; + char Buffer[1024]; + + va_start(args, frm); + vsprintf(Buffer, frm, args); + mexErrMsgTxt(Buffer); + va_end(args); + + return FALSE; +} + +// This is the handler passed to lcms + +static +void MatLabErrorHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, + const char *Text) +{ + mexErrMsgTxt(Text); +} +// +// Parse the command line options, System V style. +// + +static +void xoptinit() +{ + xoptind = 1; + xopterr = 0; + letP = NULL; +} + + +static +int xgetopt(int argc, char *argv[], char *optionS) +{ + unsigned char ch; + char *optP; + + if (SW == 0) { + SW = '/'; + } + + if (argc > xoptind) { + if (letP == NULL) { + if ((letP = argv[xoptind]) == NULL || + *(letP++) != SW) goto gopEOF; + if (*letP == SW) { + xoptind++; goto gopEOF; + } + } + if (0 == (ch = *(letP++))) { + xoptind++; goto gopEOF; + } + if (':' == ch || (optP = strchr(optionS, ch)) == NULL) + goto gopError; + if (':' == *(++optP)) { + xoptind++; + if (0 == *letP) { + if (argc <= xoptind) goto gopError; + letP = argv[xoptind++]; + } + xoptarg = letP; + letP = NULL; + } else { + if (0 == *letP) { + xoptind++; + letP = NULL; + } + xoptarg = NULL; + } + return ch; + } +gopEOF: + xoptarg = letP = NULL; + return EOF; + +gopError: + xoptarg = NULL; + if (xopterr) + FatalError ("get command line option"); + return ('?'); +} + + +// Return Mathlab type by depth + +static +size_t SizeOfArrayType(const mxArray *Array) +{ + + switch (mxGetClassID(Array)) { + + case mxINT8_CLASS: return 1; + case mxUINT8_CLASS: return 1; + case mxINT16_CLASS: return 2; + case mxUINT16_CLASS: return 2; + case mxSINGLE_CLASS: return 4; + case mxDOUBLE_CLASS: return 0; // Special case -- lcms handles double as size=0 + + + default: + FatalError("Unsupported data type"); + return 0; + } +} + + +// Get number of pixels of input array. Supported arrays are +// organized as NxMxD, being N and M the size of image and D the +// number of components. + +static +size_t GetNumberOfPixels(const mxArray* In) +{ + int nDimensions = mxGetNumberOfDimensions(In); + const int *Dimensions = mxGetDimensions(In); + + switch (nDimensions) { + + case 1: return 1; // It is just a spot color + case 2: return Dimensions[0]; // A scanline + case 3: return Dimensions[0]*Dimensions[1]; // A image + + default: + FatalError("Unsupported array of %d dimensions", nDimensions); + return 0; + } +} + + +// Allocates the output array. Copies the input array modifying the pixel +// definition to match "OutputChannels". + +static +mxArray* AllocateOutputArray(const mxArray* In, int OutputChannels) +{ + + mxArray* Out = mxDuplicateArray(In); // Make a "deep copy" of Input array + int nDimensions = mxGetNumberOfDimensions(In); + const int* Dimensions = mxGetDimensions(In); + int InputChannels = Dimensions[nDimensions-1]; + + + // Modify pixel size only if needed + + if (InputChannels != OutputChannels) { + + + int i, NewSize; + int *ModifiedDimensions = (int*) mxMalloc(nDimensions * sizeof(int)); + + + memmove(ModifiedDimensions, Dimensions, nDimensions * sizeof(int)); + ModifiedDimensions[nDimensions - 1] = OutputChannels; + + switch (mxGetClassID(In)) { + + case mxINT8_CLASS: NewSize = sizeof(char); break; + case mxUINT8_CLASS: NewSize = sizeof(unsigned char); break; + case mxINT16_CLASS: NewSize = sizeof(short); break; + case mxUINT16_CLASS: NewSize = sizeof(unsigned short); break; + + default: + case mxDOUBLE_CLASS: NewSize = sizeof(double); break; + } + + + // NewSize = 1; + for (i=0; i < nDimensions; i++) + NewSize *= ModifiedDimensions[i]; + + + mxSetDimensions(Out, ModifiedDimensions, nDimensions); + mxFree(ModifiedDimensions); + + mxSetPr(Out, mxRealloc(mxGetPr(Out), NewSize)); + + } + + + return Out; +} + + + +// Does create a format descriptor. "Bytes" is the sizeof type in bytes +// +// Bytes Meaning +// ------ -------- +// 0 Floating point (double) +// 1 8-bit samples +// 2 16-bit samples + +static +cmsUInt32Number MakeFormatDescriptor(cmsColorSpaceSignature ColorSpace, int Bytes) +{ + int IsFloat = (Bytes == 0 || Bytes == 4) ? 1 : 0; + int Channels = cmsChannelsOf(ColorSpace); + return FLOAT_SH(IsFloat)|COLORSPACE_SH(_cmsLCMScolorSpace(ColorSpace))|BYTES_SH(Bytes)|CHANNELS_SH(Channels)|PLANAR_SH(1); +} + + +// Opens a profile or proper built-in + +static +cmsHPROFILE OpenProfile(const char* File) +{ + + cmsContext ContextID = 0; + + if (!File) + return cmsCreate_sRGBProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*Lab2") == 0) + return cmsCreateLab2ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*Lab4") == 0) + return cmsCreateLab4ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*Lab") == 0) + return cmsCreateLab4ProfileTHR(ContextID, NULL); + + if (cmsstrcasecmp(File, "*LabD65") == 0) { + + cmsCIExyY D65xyY; + + cmsWhitePointFromTemp( &D65xyY, 6504); + return cmsCreateLab4ProfileTHR(ContextID, &D65xyY); + } + + if (cmsstrcasecmp(File, "*XYZ") == 0) + return cmsCreateXYZProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*Gray22") == 0) { + + cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2); + cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve); + cmsFreeToneCurve(Curve); + return hProfile; + } + + if (cmsstrcasecmp(File, "*Gray30") == 0) { + + cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0); + cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve); + cmsFreeToneCurve(Curve); + return hProfile; + } + + if (cmsstrcasecmp(File, "*srgb") == 0) + return cmsCreate_sRGBProfileTHR(ContextID); + + if (cmsstrcasecmp(File, "*null") == 0) + return cmsCreateNULLProfileTHR(ContextID); + + + if (cmsstrcasecmp(File, "*Lin2222") == 0) { + + cmsToneCurve* Gamma = cmsBuildGamma(0, 2.2); + cmsToneCurve* Gamma4[4]; + cmsHPROFILE hProfile; + + Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma; + hProfile = cmsCreateLinearizationDeviceLink(cmsSigCmykData, Gamma4); + cmsFreeToneCurve(Gamma); + return hProfile; + } + + + return cmsOpenProfileFromFileTHR(ContextID, File, "r"); +} + + +static +cmsUInt32Number GetFlags() +{ + cmsUInt32Number dwFlags = 0; + + switch (PrecalcMode) { + + case 0: dwFlags = cmsFLAGS_NOOPTIMIZE; break; + case 2: dwFlags = cmsFLAGS_HIGHRESPRECALC; break; + case 3: dwFlags = cmsFLAGS_LOWRESPRECALC; break; + case 1: break; + + default: FatalError("Unknown precalculation mode '%d'", PrecalcMode); + } + + if (BlackPointCompensation) + dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + + return dwFlags; +} + +// Create transforms + +static +void OpenTransforms(int argc, char *argv[]) +{ + + cmsUInt32Number dwIn, dwOut, dwFlags; + + + if (lMultiProfileChain) { + + int i; + cmsHTRANSFORM hTmp; + + + nProfiles = argc - xoptind; + for (i=0; i < nProfiles; i++) { + + hProfiles[i] = OpenProfile(argv[i+xoptind]); + } + + + // Create a temporary devicelink + + hTmp = cmsCreateMultiprofileTransform(hProfiles, nProfiles, + 0, 0, Intent, GetFlags()); + + hInput = cmsTransform2DeviceLink(hTmp, 4.2, 0); + hOutput = NULL; + cmsDeleteTransform(hTmp); + + InputColorSpace = cmsGetColorSpace(hInput); + OutputColorSpace = cmsGetPCS(hInput); + lIsDeviceLink = TRUE; + + } + else + if (lIsDeviceLink) { + + hInput = cmsOpenProfileFromFile(cInProf, "r"); + hOutput = NULL; + InputColorSpace = cmsGetColorSpace(hInput); + OutputColorSpace = cmsGetPCS(hInput); + + + } + else { + + hInput = OpenProfile(cInProf); + hOutput = OpenProfile(cOutProf); + + InputColorSpace = cmsGetColorSpace(hInput); + OutputColorSpace = cmsGetColorSpace(hOutput); + + if (cmsGetDeviceClass(hInput) == cmsSigLinkClass || + cmsGetDeviceClass(hOutput) == cmsSigLinkClass) + FatalError("Use %cl flag for devicelink profiles!\n", SW); + + } + + + /* + + if (Verbose) { + + mexPrintf("From: %s\n", cmsTakeProductName(hInput)); + if (hOutput) mexPrintf("To : %s\n\n", cmsTakeProductName(hOutput)); + + } + */ + + + OutputChannels = cmsChannelsOf(OutputColorSpace); + InputChannels = cmsChannelsOf(InputColorSpace); + + + dwIn = MakeFormatDescriptor(InputColorSpace, nBytesDepth); + dwOut = MakeFormatDescriptor(OutputColorSpace, nBytesDepth); + + + dwFlags = GetFlags(); + + if (cProofing != NULL) { + + hProof = OpenProfile(cProofing); + dwFlags |= cmsFLAGS_SOFTPROOFING; + } + + + + + hColorTransform = cmsCreateProofingTransform(hInput, dwIn, + hOutput, dwOut, + hProof, Intent, + ProofingIntent, + dwFlags); + +} + + + +static +void ApplyTransforms(const mxArray *In, mxArray *Out) +{ + double *Input = mxGetPr(In); + double *Output = mxGetPr(Out); + size_t nPixels = GetNumberOfPixels(In);; + + cmsDoTransform(hColorTransform, Input, Output, nPixels ); + +} + + +static +void CloseTransforms(void) +{ + int i; + + if (hColorTransform) cmsDeleteTransform(hColorTransform); + if (hInput) cmsCloseProfile(hInput); + if (hOutput) cmsCloseProfile(hOutput); + if (hProof) cmsCloseProfile(hProof); + + for (i=0; i < nProfiles; i++) + cmsCloseProfile(hProfiles[i]); + + hColorTransform = NULL; hInput = NULL; hOutput = NULL; hProof = NULL; +} + + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + xoptinit(); + + while ((s = xgetopt(argc, argv,"C:c:VvbBI:i:O:o:T:t:L:l:r:r:P:p:Mm")) != EOF) { + + + switch (s){ + + case 'b': + case 'B': + BlackPointCompensation = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 3) + FatalError("Unknown precalc mode '%d'", PrecalcMode); + break; + + case 'v': + case 'V': + Verbose = TRUE; + break; + + case 'i': + case 'I': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + cInProf = xoptarg; + break; + + case 'o': + case 'O': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + cOutProf = xoptarg; + break; + + case 't': + case 'T': + Intent = atoi(xoptarg); + // if (Intent > 3) Intent = 3; + if (Intent < 0) Intent = 0; + break; + + + case 'l': + case 'L': + cInProf = xoptarg; + lIsDeviceLink = TRUE; + break; + + case 'p': + case 'P': + cProofing = xoptarg; + break; + + + + case 'r': + case 'R': + ProofingIntent = atoi(xoptarg); + // if (ProofingIntent > 3) ProofingIntent = 3; + if (ProofingIntent < 0) ProofingIntent = 0; + break; + + + case 'm': + case 'M': + lMultiProfileChain = TRUE; + break; + + default: + FatalError("Unknown option."); + } + } + + // For multiprofile, need to specify -m + + if (xoptind < argc) { + + if (!lMultiProfileChain) + FatalError("Use %cm for multiprofile transforms", SW); + } + +} + + + +// -------------------------------------------------- Print some fancy help +static +void PrintHelp(void) +{ + mexPrintf("(MX) little cms ColorSpace conversion tool - v2.0\n\n"); + + mexPrintf("usage: icctrans (mVar, flags)\n\n"); + + mexPrintf("mVar : Matlab array.\n"); + mexPrintf("flags: a string containing one or more of following options.\n\n"); + mexPrintf("\t%cv - Verbose\n", SW); + mexPrintf("\t%ci<profile> - Input profile (defaults to sRGB)\n", SW); + mexPrintf("\t%co<profile> - Output profile (defaults to sRGB)\n", SW); + mexPrintf("\t%cl<profile> - Transform by device-link profile\n", SW); + mexPrintf("\t%cm<profiles> - Apply multiprofile chain\n", SW); + + mexPrintf("\t%ct<n> - Rendering intent\n", SW); + + mexPrintf("\t%cb - Black point compensation\n", SW); + mexPrintf("\t%cc<0,1,2,3> - Optimize transform (0=Off, 1=Normal, 2=Hi-res, 3=Lo-Res) [defaults to 1]\n", SW); + + mexPrintf("\t%cp<profile> - Soft proof profile\n", SW); + mexPrintf("\t%cr<0,1,2,3> - Soft proof intent\n", SW); + + mexPrintf("\nYou can use following built-ins as profiles:\n\n"); + + mexPrintf("\t*Lab2 -- D50-based v2 CIEL*a*b\n" + "\t*Lab4 -- D50-based v4 CIEL*a*b\n" + "\t*Lab -- D50-based v4 CIEL*a*b\n" + "\t*XYZ -- CIE XYZ (PCS)\n" + "\t*sRGB -- IEC6 1996-2.1 sRGB color space\n" + "\t*Gray22 - Monochrome of Gamma 2.2\n" + "\t*Gray30 - Monochrome of Gamma 3.0\n" + "\t*null - Monochrome black for all input\n" + "\t*Lin2222- CMYK linearization of gamma 2.2 on each channel\n\n"); + + mexPrintf("For suggestions, comments, bug reports etc. send mail to info@littlecms.com\n\n"); + +} + + + +// Main entry point + +void mexFunction( + int nlhs, // Number of left hand side (output) arguments + mxArray *plhs[], // Array of left hand side arguments + int nrhs, // Number of right hand side (input) arguments + const mxArray *prhs[] // Array of right hand side arguments +) +{ + + char CommandLine[4096+1]; + char *pt, *argv[128]; + int argc = 1; + + + if (nrhs != 2) { + + PrintHelp(); + return; + } + + + if(nlhs > 1) { + FatalError("Too many output arguments."); + } + + + // Setup error handler + + cmsSetLogErrorHandler(MatLabErrorHandler); + + // Defaults + + Verbose = 0; + cInProf = NULL; + cOutProf = NULL; + cProofing = NULL; + + lMultiProfileChain = FALSE; + nProfiles = 0; + + Intent = INTENT_PERCEPTUAL; + ProofingIntent = INTENT_ABSOLUTE_COLORIMETRIC; + PrecalcMode = 1; + BlackPointCompensation = FALSE; + lIsDeviceLink = FALSE; + + // Check types. Fist parameter is array of values, second parameter is command line + + if (!mxIsNumeric(prhs[0])) + FatalError("Type mismatch on argument 1 -- Must be numeric"); + + if (!mxIsChar(prhs[1])) + FatalError("Type mismatch on argument 2 -- Must be string"); + + + + + // Unpack string to command line buffer + + if (mxGetString(prhs[1], CommandLine, 4096)) + FatalError("Cannot unpack command string"); + + // Separate to argv[] convention + + argv[0] = NULL; + for (pt = strtok(CommandLine, " "); + pt; + pt = strtok(NULL, " ")) { + + argv[argc++] = pt; + } + + + + // Parse arguments + HandleSwitches(argc, argv); + + + nBytesDepth = SizeOfArrayType(prhs[0]); + + OpenTransforms(argc, argv); + + + plhs[0] = AllocateOutputArray(prhs[0], OutputChannels); + + + ApplyTransforms(prhs[0], plhs[0]); + + CloseTransforms(); + + // Done! +} + + diff --git a/lcms2mt/utils/matlab/lcms_rsp b/lcms2mt/utils/matlab/lcms_rsp new file mode 100644 index 000000000..c2b8c8d3a --- /dev/null +++ b/lcms2mt/utils/matlab/lcms_rsp @@ -0,0 +1,27 @@ +-O +-I..\..\include +icctrans.c +..\..\src\cmscam02.c +..\..\src\cmscgats.c +..\..\src\cmscnvrt.c +..\..\src\cmserr.c +..\..\src\cmsgamma.c +..\..\src\cmsgmt.c +..\..\src\cmsintrp.c +..\..\src\cmsio0.c +..\..\src\cmsio1.c +..\..\src\cmslut.c +..\..\src\cmsmd5.c +..\..\src\cmsmtrx.c +..\..\src\cmsnamed.c +..\..\src\cmsopt.c +..\..\src\cmspack.c +..\..\src\cmspcs.c +..\..\src\cmsplugin.c +..\..\src\cmsps2.c +..\..\src\cmssamp.c +..\..\src\cmssm.c +..\..\src\cmstypes.c +..\..\src\cmsvirt.c +..\..\src\cmswtpnt.c +..\..\src\cmsxform.c diff --git a/lcms2mt/utils/psicc/Makefile.am b/lcms2mt/utils/psicc/Makefile.am new file mode 100644 index 000000000..99d9d5b3a --- /dev/null +++ b/lcms2mt/utils/psicc/Makefile.am @@ -0,0 +1,19 @@ +# +# Makefile for building psicc +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +bin_PROGRAMS = psicc + +psicc_LDADD = $(top_builddir)/src/liblcms2.la +psicc_LDFLAGS = @LDFLAGS@ +psicc_SOURCES = psicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +psicc_MANS = psicc.1 + +EXTRA_DIST = $(man_MANS) diff --git a/lcms2mt/utils/psicc/Makefile.in b/lcms2mt/utils/psicc/Makefile.in new file mode 100644 index 000000000..6fed47585 --- /dev/null +++ b/lcms2mt/utils/psicc/Makefile.in @@ -0,0 +1,663 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building psicc +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = psicc$(EXEEXT) +subdir = utils/psicc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_psicc_OBJECTS = psicc.$(OBJEXT) ../common/xgetopt.$(OBJEXT) \ + ../common/vprf.$(OBJEXT) +psicc_OBJECTS = $(am_psicc_OBJECTS) +psicc_DEPENDENCIES = $(top_builddir)/src/liblcms2.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +psicc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(psicc_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(psicc_SOURCES) +DIST_SOURCES = $(psicc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +psicc_LDADD = $(top_builddir)/src/liblcms2.la +psicc_LDFLAGS = @LDFLAGS@ +psicc_SOURCES = psicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +psicc_MANS = psicc.1 +EXTRA_DIST = $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/psicc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign utils/psicc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../common/$(am__dirstamp): + @$(MKDIR_P) ../common + @: > ../common/$(am__dirstamp) +../common/xgetopt.$(OBJEXT): ../common/$(am__dirstamp) +../common/vprf.$(OBJEXT): ../common/$(am__dirstamp) + +psicc$(EXEEXT): $(psicc_OBJECTS) $(psicc_DEPENDENCIES) $(EXTRA_psicc_DEPENDENCIES) + @rm -f psicc$(EXEEXT) + $(AM_V_CCLD)$(psicc_LINK) $(psicc_OBJECTS) $(psicc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../common/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../common/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/psicc/psicc.1 b/lcms2mt/utils/psicc/psicc.1 new file mode 100644 index 000000000..19868b513 --- /dev/null +++ b/lcms2mt/utils/psicc/psicc.1 @@ -0,0 +1,47 @@ +.\"Shiju P. Nair September 30, 2004 +.\"Thomas Weber <tweber@debian.org> April 23, 2014 +.TH PSICC 1 "September 30, 2004" +.SH NAME +psicc - little cms PostScript converter. +.SH SYNOPSIS +.B psicc +.RI [ options ] +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B psicc +is a little cms PostScript converter. +.SH OPTIONS +.TP +.B \-b +Black point compensation (CRD only). +.TP +.BI \-c\ precision +Precision (0=LowRes, 1=Normal, 2=Hi-res) (CRD only) [defaults to 1]. +.TP +.BI \-i\ profile +Input profile: Generates Color Space Array (CSA). +.TP +.BI \-n\ gridpoints +Alternate way to set precision, number of CLUT points (CRD only). +.TP +.BI \-o\ profile +.p +Output profile: Generates Color Rendering Dictionary(CRD). +.TP +.BI \-t\ intent +Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute) [defaults to 0]. +.TP +.B \-u +Do NOT generate resource name on CRD. +.SH NOTES +For suggestions, comments, bug reports etc. send mail to +info@littlecms.com. +.SH SEE ALSO +.BR jpgicc (1), +.BR linkicc (1), +.BR tificc (1), +.BR transicc (1) +.SH AUTHOR +This manual page was written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. diff --git a/lcms2mt/utils/psicc/psicc.c b/lcms2mt/utils/psicc/psicc.c new file mode 100644 index 000000000..60a8c9b9f --- /dev/null +++ b/lcms2mt/utils/psicc/psicc.c @@ -0,0 +1,233 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- + +#include "utils.h" + +// ------------------------------------------------------------------------ + +static char *cInProf = NULL; +static char *cOutProf = NULL; +static int Intent = INTENT_PERCEPTUAL; +static FILE* OutFile; +static int BlackPointCompensation = FALSE; +static int Undecorated = FALSE; +static int PrecalcMode = 1; +static int NumOfGridPoints = 0; + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s = xgetopt(argc,argv,"uUbBI:i:O:o:T:t:c:C:n:N:")) != EOF) { + + switch (s){ + + + case 'i': + case 'I': + cInProf = xoptarg; + break; + + case 'o': + case 'O': + cOutProf = xoptarg; + break; + + case 'b': + case 'B': BlackPointCompensation =TRUE; + break; + + + case 't': + case 'T': + Intent = atoi(xoptarg); + if (Intent > 3) Intent = 3; + if (Intent < 0) Intent = 0; + break; + + case 'U': + case 'u': + Undecorated = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 2) + FatalError("ERROR: Unknown precalc mode '%d'", PrecalcMode); + break; + + + case 'n': + case 'N': + if (PrecalcMode != 1) + FatalError("Precalc mode already specified"); + NumOfGridPoints = atoi(xoptarg); + break; + + + default: + + FatalError("Unknown option - run without args to see valid ones.\n"); + } + } +} + +static +void Help(void) +{ + fprintf(stderr, "little CMS ICC PostScript generator - v2.1 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0); + + fprintf(stderr, "usage: psicc [flags] [<Output file>]\n\n"); + + fprintf(stderr, "flags:\n\n"); + + fprintf(stderr, "%ci<profile> - Input profile: Generates Color Space Array (CSA)\n", SW); + fprintf(stderr, "%co<profile> - Output profile: Generates Color Rendering Dictionary(CRD)\n", SW); + + fprintf(stderr, "%ct<0,1,2,3> - Intent (0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute)\n", SW); + + fprintf(stderr, "%cb - Black point compensation (CRD only)\n", SW); + fprintf(stderr, "%cu - Do NOT generate resource name on CRD\n", SW); + fprintf(stderr, "%cc<0,1,2> - Precision (0=LowRes, 1=Normal (default), 2=Hi-res) (CRD only)\n", SW); + fprintf(stderr, "%cn<gridpoints> - Alternate way to set precission, number of CLUT points (CRD only)\n", SW); + + fprintf(stderr, "\n"); + fprintf(stderr, "If no output file is specified, output goes to stdout.\n\n"); + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "info@littlecms.com\n\n"); + exit(0); +} + + +static +void GenerateCSA(cmsContext ContextID) +{ + cmsHPROFILE hProfile = OpenStockProfile(ContextID, cInProf); + size_t n; + char* Buffer; + + if (hProfile == NULL) return; + + n = cmsGetPostScriptCSA(ContextID, hProfile, Intent, 0, NULL, 0); + if (n == 0) return; + + Buffer = (char*) malloc(n + 1); + if (Buffer != NULL) { + + cmsGetPostScriptCSA(ContextID, hProfile, Intent, 0, Buffer, (cmsUInt32Number) n); + Buffer[n] = 0; + + fprintf(OutFile, "%s", Buffer); + + free(Buffer); + } + + cmsCloseProfile(ContextID, hProfile); +} + + +static +void GenerateCRD(cmsContext ContextID) +{ + cmsHPROFILE hProfile = OpenStockProfile(ContextID, cOutProf); + size_t n; + char* Buffer; + cmsUInt32Number dwFlags = 0; + + if (hProfile == NULL) return; + + if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + if (Undecorated) dwFlags |= cmsFLAGS_NODEFAULTRESOURCEDEF; + + switch (PrecalcMode) { + + case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; + case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; + case 1: + if (NumOfGridPoints > 0) + dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints); + break; + + default: FatalError("ERROR: Unknown precalculation mode '%d'", PrecalcMode); + } + + n = cmsGetPostScriptCRD(ContextID, hProfile, Intent, dwFlags, NULL, 0); + if (n == 0) return; + + Buffer = (char*) malloc(n + 1); + if (Buffer == NULL) return; + cmsGetPostScriptCRD(ContextID, hProfile, Intent, dwFlags, Buffer, (cmsUInt32Number) n); + Buffer[n] = 0; + + fprintf(OutFile, "%s", Buffer); + free(Buffer); + cmsCloseProfile(ContextID, hProfile); +} + + +int main(int argc, char *argv[]) +{ + int nargs; + cmsContext ContextID = NULL; + + // Initialize + InitUtils("psicc"); + + HandleSwitches(argc, argv); + + nargs = (argc - xoptind); + if (nargs != 0 && nargs != 1) + Help(); + + if (cInProf == NULL && cOutProf == NULL) + Help(); + + if (nargs == 0) + OutFile = stdout; + else + OutFile = fopen(argv[xoptind], "wt"); + + if (cInProf != NULL) + GenerateCSA(ContextID); + + if (cOutProf != NULL) + GenerateCRD(ContextID); + + if (nargs == 1) { + fclose(OutFile); + } + + return 0; +} + + diff --git a/lcms2mt/utils/samples/Makefile.am b/lcms2mt/utils/samples/Makefile.am new file mode 100644 index 000000000..b3b620173 --- /dev/null +++ b/lcms2mt/utils/samples/Makefile.am @@ -0,0 +1,19 @@ +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +bin_PROGRAMS = wtpt + +wtpt_LDADD = $(top_builddir)/src/liblcms2.la +wtpt_LDFLAGS = @LDFLAGS@ +wtpt_SOURCES = wtpt.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +wtpt_MANS = wtpt.1 + +EXTRA_DIST = $(man_MANS) roundtrip.c mktiff8.c mkgrayer.c mkcmy.c itufax.c diff --git a/lcms2mt/utils/samples/Makefile.in b/lcms2mt/utils/samples/Makefile.in new file mode 100644 index 000000000..da52ca57b --- /dev/null +++ b/lcms2mt/utils/samples/Makefile.in @@ -0,0 +1,611 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria Oct 2004 + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = icctrans$(EXEEXT) wtpt$(EXEEXT) icc2ps$(EXEEXT) \ + icclink$(EXEEXT) +subdir = samples +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_icc2ps_OBJECTS = icc2ps.$(OBJEXT) xgetopt.$(OBJEXT) +icc2ps_OBJECTS = $(am_icc2ps_OBJECTS) +icc2ps_DEPENDENCIES = $(top_builddir)/src/liblcms.la +icc2ps_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(icc2ps_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_icclink_OBJECTS = icclink.$(OBJEXT) xgetopt.$(OBJEXT) \ + vprf.$(OBJEXT) +icclink_OBJECTS = $(am_icclink_OBJECTS) +icclink_DEPENDENCIES = $(top_builddir)/src/liblcms.la +icclink_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(icclink_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_icctrans_OBJECTS = icctrans.$(OBJEXT) xgetopt.$(OBJEXT) \ + vprf.$(OBJEXT) +icctrans_OBJECTS = $(am_icctrans_OBJECTS) +icctrans_DEPENDENCIES = $(top_builddir)/src/liblcms.la +icctrans_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(icctrans_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_wtpt_OBJECTS = wtpt.$(OBJEXT) xgetopt.$(OBJEXT) +wtpt_OBJECTS = $(am_wtpt_OBJECTS) +wtpt_DEPENDENCIES = $(top_builddir)/src/liblcms.la +wtpt_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(wtpt_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(icc2ps_SOURCES) $(icclink_SOURCES) $(icctrans_SOURCES) \ + $(wtpt_SOURCES) +DIST_SOURCES = $(icc2ps_SOURCES) $(icclink_SOURCES) \ + $(icctrans_SOURCES) $(wtpt_SOURCES) +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INT16_T = @INT16_T@ +INT32_T = @INT32_T@ +INT64_T = @INT64_T@ +INT8_T = @INT8_T@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LCMS_PYEXECDIR = @LCMS_PYEXECDIR@ +LCMS_PYINCLUDE = @LCMS_PYINCLUDE@ +LCMS_PYLIB = @LCMS_PYLIB@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +UINT16_T = @UINT16_T@ +UINT32_T = @UINT32_T@ +UINT64_T = @UINT64_T@ +UINT8_T = @UINT8_T@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include +icctrans_LDADD = $(top_builddir)/src/liblcms.la +icctrans_LDFLAGS = @LDFLAGS@ +icctrans_SOURCES = icctrans.c xgetopt.c vprf.c +icctrans_MANS = icctrans.1 +wtpt_LDADD = $(top_builddir)/src/liblcms.la +wtpt_LDFLAGS = @LDFLAGS@ +wtpt_SOURCES = wtpt.c xgetopt.c +icc2ps_LDADD = $(top_builddir)/src/liblcms.la +icc2ps_LDFLAGS = @LDFLAGS@ +icc2ps_SOURCES = icc2ps.c xgetopt.c +icclink_LDADD = $(top_builddir)/src/liblcms.la +icclink_LDFLAGS = @LDFLAGS@ +icclink_SOURCES = icclink.c xgetopt.c vprf.c +man_MANS = wtpt.1 icc2ps.1 icclink.1 +EXTRA_DIST = $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign samples/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign samples/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +icc2ps$(EXEEXT): $(icc2ps_OBJECTS) $(icc2ps_DEPENDENCIES) + @rm -f icc2ps$(EXEEXT) + $(icc2ps_LINK) $(icc2ps_OBJECTS) $(icc2ps_LDADD) $(LIBS) +icclink$(EXEEXT): $(icclink_OBJECTS) $(icclink_DEPENDENCIES) + @rm -f icclink$(EXEEXT) + $(icclink_LINK) $(icclink_OBJECTS) $(icclink_LDADD) $(LIBS) +icctrans$(EXEEXT): $(icctrans_OBJECTS) $(icctrans_DEPENDENCIES) + @rm -f icctrans$(EXEEXT) + $(icctrans_LINK) $(icctrans_OBJECTS) $(icctrans_LDADD) $(LIBS) +wtpt$(EXEEXT): $(wtpt_OBJECTS) $(wtpt_DEPENDENCIES) + @rm -f wtpt$(EXEEXT) + $(wtpt_LINK) $(wtpt_OBJECTS) $(wtpt_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icc2ps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icclink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icctrans.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vprf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wtpt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetopt.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man1 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-man \ + uninstall-man1 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/samples/itufax.c b/lcms2mt/utils/samples/itufax.c new file mode 100644 index 000000000..79c7c4400 --- /dev/null +++ b/lcms2mt/utils/samples/itufax.c @@ -0,0 +1,138 @@ +// +// Little cms +// Copyright (C) 1998-2003 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +#include "lcms.h" + +// This is a sample on how to build a profile for decoding ITU T.42/Fax JPEG +// streams. The profile has an additional ability in the input direction of +// gamut compress values between 85 < a < -85 and -75 < b < 125. This conforms +// the default range for ITU/T.42 -- See RFC 2301, section 6.2.3 for details + + +// L* = [0, 100] +// a* = [–85, 85] +// b* = [–75, 125] + + +// These functions does convert the encoding of ITUFAX to floating point + +static +void ITU2Lab(WORD In[3], LPcmsCIELab Lab) +{ + Lab -> L = (double) In[0] / 655.35; + Lab -> a = (double) 170.* (In[1] - 32768.) / 65535.; + Lab -> b = (double) 200.* (In[2] - 24576.) / 65535.; +} + + +static +void Lab2ITU(LPcmsCIELab Lab, WORD Out[3]) +{ + Out[0] = (WORD) floor((double) (Lab -> L / 100.)* 65535. + 0.5); + Out[1] = (WORD) floor((double) (Lab -> a / 170.)* 65535. + 32768. + 0.5); + Out[2] = (WORD) floor((double) (Lab -> b / 200.)* 65535. + 24576. + 0.5); +} + + +// These are the samplers-- They are passed as callbacks to cmsSample3DGrid() +// then, cmsSample3DGrid() will sweel whole Lab gamut calling these functions +// once for each node. In[] will contain the Lab PCS value to convert to ITUFAX +// on InputDirection, or the ITUFAX value to convert to Lab in OutputDirection +// You can change the number of sample points if desired, the algorithm will +// remain same. 33 points gives good accurancy, but you can reduce to 22 or less +// is space is critical + +#define GRID_POINTS 33 + +static +int InputDirection(register WORD In[], register WORD Out[], register LPVOID Cargo) +{ + cmsCIELab Lab; + + cmsLabEncoded2Float(&Lab, In); + cmsClampLab(&Lab, 85, -85, 125, -75); // This function does the necessary gamut remapping + Lab2ITU(&Lab, Out); + + return TRUE; +} + + +static +int OutputDirection(register WORD In[], register WORD Out[], register LPVOID Cargo) +{ + + cmsCIELab Lab; + + ITU2Lab(In, &Lab); + cmsFloat2LabEncoded(Out, &Lab); + + return TRUE; +} + + +// The main entry point. Just create a profile an populate it with required tags. +// note that cmsOpenProfileFromFile("itufax.icm", "w") will NOT delete the file +// if already exists. This is for obvious safety reasons. + + +int main(int argc, char *argv[]) +{ + LPLUT AToB0, BToA0; + cmsHPROFILE hProfile; + + fprintf(stderr, "Creating itufax.icm..."); + + unlink("itufax.icm"); + hProfile = cmsOpenProfileFromFile("itufax.icm", "w"); + + AToB0 = cmsAllocLUT(); + BToA0 = cmsAllocLUT(); + + cmsAlloc3DGrid(AToB0, GRID_POINTS, 3, 3); + cmsAlloc3DGrid(BToA0, GRID_POINTS, 3, 3); + + cmsSample3DGrid(AToB0, InputDirection, NULL, 0); + cmsSample3DGrid(BToA0, OutputDirection, NULL, 0); + + cmsAddTag(hProfile, icSigAToB0Tag, AToB0); + cmsAddTag(hProfile, icSigBToA0Tag, BToA0); + + + cmsSetColorSpace(hProfile, icSigLabData); + cmsSetPCS(hProfile, icSigLabData); + cmsSetDeviceClass(hProfile, icSigColorSpaceClass); + + cmsAddTag(hProfile, icSigProfileDescriptionTag, "ITU T.42/Fax JPEG CIEL*a*b*"); + cmsAddTag(hProfile, icSigCopyrightTag, "No Copyright, use freely."); + cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); + cmsAddTag(hProfile, icSigDeviceModelDescTag, "ITU T.42/Fax JPEG CIEL*a*b*"); + + cmsCloseProfile(hProfile); + + cmsFreeLUT(AToB0); + cmsFreeLUT(BToA0); + + fprintf(stderr, "Done.\n"); + + return 0; +} diff --git a/lcms2mt/utils/samples/mkcmy.c b/lcms2mt/utils/samples/mkcmy.c new file mode 100644 index 000000000..1b0755f17 --- /dev/null +++ b/lcms2mt/utils/samples/mkcmy.c @@ -0,0 +1,170 @@ +// +// Little cms +// Copyright (C) 1998-2003 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +// +// IN NO EVENT SHALL MARTI MARIA BE LIABLE FOR ANY SPECIAL, INCIDENTAL, +// INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +// LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +// OF THIS SOFTWARE. +// +// Version 1.12 + + +#include "lcms.h" + + +typedef struct { + cmsHPROFILE hLab; + cmsHPROFILE hRGB; + cmsHTRANSFORM Lab2RGB; + cmsHTRANSFORM RGB2Lab; + + } CARGO, FAR* LPCARGO; + + + + + +// Our space will be CIE primaries plus a gamma of 4.5 + +static +int Forward(register WORD In[], register WORD Out[], register LPVOID Cargo) +{ + LPCARGO C = (LPCARGO) Cargo; + WORD RGB[3]; + cmsCIELab Lab; + + cmsLabEncoded2Float(&Lab, In); + + printf("%g %g %g\n", Lab.L, Lab.a, Lab.b); + + cmsDoTransform(C ->Lab2RGB, In, &RGB, 1); + + + Out[0] = 0xFFFF - RGB[0]; // Our CMY is negative of RGB + Out[1] = 0xFFFF - RGB[1]; + Out[2] = 0xFFFF - RGB[2]; + + + return TRUE; + +} + + +static +int Reverse(register WORD In[], register WORD Out[], register LPVOID Cargo) +{ + + LPCARGO C = (LPCARGO) Cargo; + WORD RGB[3]; + + RGB[0] = 0xFFFF - In[0]; + RGB[1] = 0xFFFF - In[1]; + RGB[2] = 0xFFFF - In[2]; + + cmsDoTransform(C ->RGB2Lab, &RGB, Out, 1); + + return TRUE; + +} + + + +static +void InitCargo(LPCARGO Cargo) +{ + + + Cargo -> hLab = cmsCreateLabProfile(NULL); + Cargo -> hRGB = cmsCreate_sRGBProfile(); + + Cargo->Lab2RGB = cmsCreateTransform(Cargo->hLab, TYPE_Lab_16, + Cargo ->hRGB, TYPE_RGB_16, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOTPRECALC); + + Cargo->RGB2Lab = cmsCreateTransform(Cargo ->hRGB, TYPE_RGB_16, + Cargo ->hLab, TYPE_Lab_16, + INTENT_RELATIVE_COLORIMETRIC, + cmsFLAGS_NOTPRECALC); +} + + + + +static +void FreeCargo(LPCARGO Cargo) +{ + cmsDeleteTransform(Cargo ->Lab2RGB); + cmsDeleteTransform(Cargo ->RGB2Lab); + cmsCloseProfile(Cargo ->hLab); + cmsCloseProfile(Cargo ->hRGB); +} + + + + +int main(void) +{ + LPLUT AToB0, BToA0; + CARGO Cargo; + cmsHPROFILE hProfile; + + fprintf(stderr, "Creating lcmscmy.icm..."); + + InitCargo(&Cargo); + + hProfile = cmsCreateLabProfile(NULL); + + + AToB0 = cmsAllocLUT(); + BToA0 = cmsAllocLUT(); + + cmsAlloc3DGrid(AToB0, 25, 3, 3); + cmsAlloc3DGrid(BToA0, 25, 3, 3); + + + cmsSample3DGrid(AToB0, Reverse, &Cargo, 0); + cmsSample3DGrid(BToA0, Forward, &Cargo, 0); + + + cmsAddTag(hProfile, icSigAToB0Tag, AToB0); + cmsAddTag(hProfile, icSigBToA0Tag, BToA0); + + cmsSetColorSpace(hProfile, icSigCmyData); + cmsSetDeviceClass(hProfile, icSigOutputClass); + + cmsAddTag(hProfile, icSigProfileDescriptionTag, "CMY "); + cmsAddTag(hProfile, icSigCopyrightTag, "Copyright (c) HP, 2007. All rights reserved."); + cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); + cmsAddTag(hProfile, icSigDeviceModelDescTag, "CMY space"); + + _cmsSaveProfile(hProfile, "lcmscmy.icm"); + + + cmsFreeLUT(AToB0); + cmsFreeLUT(BToA0); + cmsCloseProfile(hProfile); + FreeCargo(&Cargo); + fprintf(stderr, "Done.\n"); + + + + return 0; +} diff --git a/lcms2mt/utils/samples/mkgrayer.c b/lcms2mt/utils/samples/mkgrayer.c new file mode 100644 index 000000000..46e928618 --- /dev/null +++ b/lcms2mt/utils/samples/mkgrayer.c @@ -0,0 +1,93 @@ +// +// Little cms +// Copyright (C) 1998-2003 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +#include "lcms.h" + + + +static +int Forward(register WORD In[], register WORD Out[], register LPVOID Cargo) +{ + cmsCIELab Lab; + + + cmsLabEncoded2Float(&Lab, In); + + if (fabs(Lab.a) < 3 && fabs(Lab.b) < 3) { + + double L_01 = Lab.L / 100.0; + WORD K; + + if (L_01 > 1) L_01 = 1; + K = (WORD) floor(L_01* 65535.0 + 0.5); + + Out[0] = Out[1] = Out[2] = K; + } + else { + Out[0] = 0xFFFF; Out[1] = 0; Out[2] = 0; + } + + return TRUE; +} + + + + + +int main(int argc, char *argv[]) +{ + LPLUT BToA0; + cmsHPROFILE hProfile; + + fprintf(stderr, "Creating interpol2.icc..."); + + unlink("interpol2.icc"); + hProfile = cmsOpenProfileFromFile("interpol2.icc", "w8"); + + + BToA0 = cmsAllocLUT(); + + cmsAlloc3DGrid(BToA0, 17, 3, 3); + + cmsSample3DGrid(BToA0, Forward, NULL, 0); + + cmsAddTag(hProfile, icSigBToA0Tag, BToA0); + + cmsSetColorSpace(hProfile, icSigRgbData); + cmsSetPCS(hProfile, icSigLabData); + cmsSetDeviceClass(hProfile, icSigOutputClass); + + cmsAddTag(hProfile, icSigProfileDescriptionTag, "Interpolation test"); + cmsAddTag(hProfile, icSigCopyrightTag, "Copyright (c) HP 2007. All rights reserved."); + cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); + cmsAddTag(hProfile, icSigDeviceModelDescTag, "Interpolation test profile"); + + + cmsCloseProfile(hProfile); + + cmsFreeLUT(BToA0); + + fprintf(stderr, "Done.\n"); + + return 0; +} diff --git a/lcms2mt/utils/samples/mktiff8.c b/lcms2mt/utils/samples/mktiff8.c new file mode 100644 index 000000000..d6045cf11 --- /dev/null +++ b/lcms2mt/utils/samples/mktiff8.c @@ -0,0 +1,150 @@ +// +// Little cms +// Copyright (C) 1998-2010 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Creates a devicelink that decodes TIFF8 Lab files + +#include "lcms2mt.h" +#include <stdlib.h> +#include <math.h> + +static +double DecodeAbTIFF(double ab) +{ + if (ab <= 128.) + ab += 127.; + else + ab -= 127.; + + return ab; +} + +static +cmsToneCurve* CreateStep(void) +{ + cmsToneCurve* Gamma; + cmsUInt16Number* Table; + int i; + double a; + + Table = calloc(4096, sizeof(cmsUInt16Number)); + if (Table == NULL) return NULL; + + for (i=0; i < 4096; i++) { + + a = (double) i * 255. / 4095.; + + a = DecodeAbTIFF(a); + + Table[i] = (cmsUInt16Number) floor(a * 257. + 0.5); + } + + Gamma = cmsBuildTabulatedToneCurve16(0, 4096, Table); + free(Table); + + return Gamma; +} + + +static +cmsToneCurve* CreateLinear(void) +{ + cmsUInt16Number Linear[2] = { 0, 0xffff }; + + return cmsBuildTabulatedToneCurve16(0, 2, Linear); +} + + + +// Set the copyright and description +static +cmsBool SetTextTags(cmsHPROFILE hProfile) +{ + cmsMLU *DescriptionMLU, *CopyrightMLU; + cmsBool rc = FALSE; + + DescriptionMLU = cmsMLUalloc(0, 1); + CopyrightMLU = cmsMLUalloc(0, 1); + + if (DescriptionMLU == NULL || CopyrightMLU == NULL) goto Error; + + if (!cmsMLUsetASCII(DescriptionMLU, "en", "US", "Little cms Tiff8 CIELab")) goto Error; + if (!cmsMLUsetASCII(CopyrightMLU, "en", "US", "Copyright (c) Marti Maria, 2010. All rights reserved.")) goto Error; + + if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error; + if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error; + + rc = TRUE; + +Error: + + if (DescriptionMLU) + cmsMLUfree(DescriptionMLU); + if (CopyrightMLU) + cmsMLUfree(CopyrightMLU); + return rc; +} + + +int main(int argc, char *argv[]) +{ + cmsHPROFILE hProfile; + cmsPipeline *AToB0; + cmsToneCurve* PreLinear[3]; + cmsToneCurve *Lin, *Step; + + fprintf(stderr, "Creating lcmstiff8.icm..."); + + remove("lcmstiff8.icm"); + hProfile = cmsOpenProfileFromFile("lcmstiff8.icm", "w"); + + // Create linearization + Lin = CreateLinear(); + Step = CreateStep(); + + PreLinear[0] = Lin; + PreLinear[1] = Step; + PreLinear[2] = Step; + + AToB0 = cmsPipelineAlloc(0, 3, 3); + + cmsPipelineInsertStage(AToB0, + cmsAT_BEGIN, cmsStageAllocToneCurves(0, 3, PreLinear)); + + cmsSetColorSpace(hProfile, cmsSigLabData); + cmsSetPCS(hProfile, cmsSigLabData); + cmsSetDeviceClass(hProfile, cmsSigLinkClass); + cmsSetProfileVersion(hProfile, 4.2); + + cmsWriteTag(hProfile, cmsSigAToB0Tag, AToB0); + + SetTextTags(hProfile); + + cmsCloseProfile(hProfile); + + cmsFreeToneCurve(Lin); + cmsFreeToneCurve(Step); + cmsPipelineFree(AToB0); + + fprintf(stderr, "Done.\n"); + + return 0; +} diff --git a/lcms2mt/utils/samples/roundtrip.c b/lcms2mt/utils/samples/roundtrip.c new file mode 100644 index 000000000..a0ea4c1f0 --- /dev/null +++ b/lcms2mt/utils/samples/roundtrip.c @@ -0,0 +1,99 @@ +// +// Little cms +// Copyright (C) 1998-2011 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + +#include "lcms2mt.h" +#include <math.h> + + + +static +double VecDist(cmsUInt8Number bin[3], cmsUInt8Number bout[3]) +{ + double rdist, gdist, bdist; + + rdist = fabs((double) bout[0] - bin[0]); + gdist = fabs((double) bout[1] - bin[1]); + bdist = fabs((double) bout[2] - bin[2]); + + return (sqrt((rdist*rdist + gdist*gdist + bdist*bdist))); +} + + +int main(int argc, char* argv[]) +{ + + int r, g, b; + cmsUInt8Number RGB[3], RGB_OUT[3]; + cmsHTRANSFORM xform; + cmsHPROFILE hProfile; + double err, SumX=0, SumX2=0, Peak = 0, n = 0; + + + if (argc != 2) { + printf("roundtrip <RGB icc profile>\n"); + return 1; + } + + hProfile = cmsOpenProfileFromFile(argv[1], "r"); + if (hProfile == NULL) + { + printf("invalid profile\n"); + return 1; + } + + xform = cmsCreateTransform(hProfile,TYPE_RGB_8, hProfile, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); + if (xform == NULL) + { + printf("Not a valid RGB profile\n"); + return 1; + } + + for (r=0; r< 256; r++) { + printf("%d \r", r); + for (g=0; g < 256; g++) { + for (b=0; b < 256; b++) { + + RGB[0] = r; + RGB[1] = g; + RGB[2] = b; + + cmsDoTransform(xform, RGB, RGB_OUT, 1); + + err = VecDist(RGB, RGB_OUT); + + SumX += err; + SumX2 += err * err; + n += 1.0; + if (err > Peak) + Peak = err; + + } + } + } + + printf("Average %g\n", SumX / n); + printf("Max %g\n", Peak); + printf("Std %g\n", sqrt((n*SumX2 - SumX * SumX) / (n*(n-1)))); + cmsCloseProfile(hProfile); + cmsDeleteTransform(xform); + + return 0; +} diff --git a/lcms2mt/utils/samples/vericc.c b/lcms2mt/utils/samples/vericc.c new file mode 100644 index 000000000..05263a5fa --- /dev/null +++ b/lcms2mt/utils/samples/vericc.c @@ -0,0 +1,65 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2010 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "lcms2mt.h" +#include <string.h> +#include <math.h> + +static +int PrintUsage(void) +{ + fprintf(stderr, "Sets profile version\n\nUsage: vericc --r<version> iccprofile.icc\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + cmsHPROFILE hProfile; + char* ptr; + cmsFloat64Number Version; + + if (argc != 3) return PrintUsage(); + + ptr = argv[1]; + if (strncmp(ptr, "--r", 3) != 0) return PrintUsage(); + ptr += 3; + if (!*ptr) { fprintf(stderr, "Wrong version number\n"); return 1; } + + Version = atof(ptr); + + hProfile = cmsOpenProfileFromFile(argv[2], "r"); + if (hProfile == NULL) { fprintf(stderr, "'%s': cannot open\n", argv[2]); return 1; } + + cmsSetProfileVersion(hProfile, Version); + cmsSaveProfileToFile(hProfile, "$$tmp.icc"); + cmsCloseProfile(hProfile); + + remove(argv[2]); + rename("$$tmp.icc", argv[2]); + return 0; + + +} diff --git a/lcms2mt/utils/samples/wtpt.1 b/lcms2mt/utils/samples/wtpt.1 new file mode 100644 index 000000000..fbd37ac2b --- /dev/null +++ b/lcms2mt/utils/samples/wtpt.1 @@ -0,0 +1,28 @@ +.\"Shiju P. Nair September 30, 2004 +.TH WTPT 1 "September 30, 2004" +.SH NAME +wtpt - Show media white of profiles, identifying black body locus. +.SH SYNOPSIS +.B wtpt +.RI [ profile ] +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B wtpt +shows media white of profiles, identifying black body locus. +.P +If no parameters are given, then this program will +ask for XYZ value of media white. If parameter given, it must be +the profile to inspect. +.SH NOTES +For suggestions, comments, bug reports etc. send mail to +info@littlecms.com +.SH SEE ALSO +.BR jpegicc (1), +.BR tifficc (1), +.BR icc2ps (1), +.BR icclink (1), +.BR icctrans (1) +.SH AUTHOR +This manual page was written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. diff --git a/lcms2mt/utils/samples/wtpt.c b/lcms2mt/utils/samples/wtpt.c new file mode 100644 index 000000000..45602f796 --- /dev/null +++ b/lcms2mt/utils/samples/wtpt.c @@ -0,0 +1,144 @@ +// +// Little cms +// Copyright (C) 1998-2015 Marti Maria +// +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2014 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- + +#include "utils.h" + + +// The toggles stuff + +static cmsBool lShowXYZ = TRUE; +static cmsBool lShowLab = FALSE; +static cmsBool lShowLCh = FALSE; + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s = xgetopt(argc, argv, "lcx")) != EOF) { + + switch (s){ + + + case 'l': + lShowLab = TRUE; + break; + + case 'c': + lShowLCh = TRUE; + break; + + case 'x': + lShowXYZ = FALSE; + break; + + default: + + FatalError("Unknown option - run without args to see valid ones.\n"); + } + } +} + +static +void Help(void) +{ + fprintf(stderr, "little CMS ICC white point utility - v3 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0); + + fprintf(stderr, "usage: wtpt [flags] [<ICC profile>]\n\n"); + + fprintf(stderr, "flags:\n\n"); + + fprintf(stderr, "%cl - CIE Lab\n", SW); + fprintf(stderr, "%cc - CIE LCh\n", SW); + fprintf(stderr, "%cx - Don't show XYZ\n", SW); + + fprintf(stderr, "\nIf no parameters are given, then this program will\n"); + fprintf(stderr, "ask for XYZ value of media white. If parameter given, it must be\n"); + fprintf(stderr, "the profile to inspect.\n\n"); + + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "info@littlecms.com\n\n"); + exit(0); +} + + + +static +void ShowWhitePoint(cmsCIEXYZ* WtPt) +{ + cmsCIELab Lab; + cmsCIELCh LCh; + cmsCIExyY xyY; + + + cmsXYZ2Lab(NULL, &Lab, WtPt); + cmsLab2LCh(&LCh, &Lab); + cmsXYZ2xyY(&xyY, WtPt); + + + if (lShowXYZ) printf("XYZ=(%3.1f, %3.1f, %3.1f)\n", WtPt->X, WtPt->Y, WtPt->Z); + if (lShowLab) printf("Lab=(%3.3f, %3.3f, %3.3f)\n", Lab.L, Lab.a, Lab.b); + if (lShowLCh) printf("LCh=(%3.3f, %3.3f, %3.3f)\n", LCh.L, LCh.C, LCh.h); + { + double Ssens = (LCh.C * 100.0 )/ sqrt(LCh.C*LCh.C + LCh.L * LCh.L) ; + printf("Sens = %f\n", Ssens); + } + +} + + +int main(int argc, char *argv[]) +{ + int nargs; + + InitUtils("wtpt"); + + HandleSwitches(argc, argv); + + nargs = (argc - xoptind); + + if (nargs != 1) + Help(); + + else { + cmsCIEXYZ* WtPt; + cmsHPROFILE hProfile = cmsOpenProfileFromFile(argv[xoptind], "r"); + if (hProfile == NULL) return 1; + + WtPt = cmsReadTag(hProfile, cmsSigMediaWhitePointTag); + ShowWhitePoint(WtPt); + cmsCloseProfile(hProfile); + } + + return 0; +} + diff --git a/lcms2mt/utils/tificc/Makefile.am b/lcms2mt/utils/tificc/Makefile.am new file mode 100644 index 000000000..50f5dc441 --- /dev/null +++ b/lcms2mt/utils/tificc/Makefile.am @@ -0,0 +1,25 @@ +# +# Makefile for building tificc +# Originally written by Bob Friesenhahn, June 2003 +# bugs introduced by Marti Maria + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + + +if HasTIFF +bin_PROGRAMS = tificc +else +bin_PROGRAMS = +endif + +tificc_LDADD = $(top_builddir)/src/liblcms2.la @TIFFICC_DEPLIBS@ +tificc_LDFLAGS = @LDFLAGS@ +tificc_SOURCES = tificc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +man_MANS = tificc.1 + + +EXTRA_DIST = $(man_MANS) diff --git a/lcms2mt/utils/tificc/Makefile.in b/lcms2mt/utils/tificc/Makefile.in new file mode 100644 index 000000000..de4d9c296 --- /dev/null +++ b/lcms2mt/utils/tificc/Makefile.in @@ -0,0 +1,739 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building tificc +# Originally written by Bob Friesenhahn, June 2003 +# bugs introduced by Marti Maria + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HasTIFF_TRUE@bin_PROGRAMS = tificc$(EXEEXT) +subdir = utils/tificc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_tificc_OBJECTS = tificc.$(OBJEXT) ../common/xgetopt.$(OBJEXT) \ + ../common/vprf.$(OBJEXT) +tificc_OBJECTS = $(am_tificc_OBJECTS) +tificc_DEPENDENCIES = $(top_builddir)/src/liblcms2.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +tificc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(tificc_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(tificc_SOURCES) +DIST_SOURCES = $(tificc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +tificc_LDADD = $(top_builddir)/src/liblcms2.la @TIFFICC_DEPLIBS@ +tificc_LDFLAGS = @LDFLAGS@ +tificc_SOURCES = tificc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +man_MANS = tificc.1 +EXTRA_DIST = $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/tificc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign utils/tificc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../common/$(am__dirstamp): + @$(MKDIR_P) ../common + @: > ../common/$(am__dirstamp) +../common/xgetopt.$(OBJEXT): ../common/$(am__dirstamp) +../common/vprf.$(OBJEXT): ../common/$(am__dirstamp) + +tificc$(EXEEXT): $(tificc_OBJECTS) $(tificc_DEPENDENCIES) $(EXTRA_tificc_DEPENDENCIES) + @rm -f tificc$(EXEEXT) + $(AM_V_CCLD)$(tificc_LINK) $(tificc_OBJECTS) $(tificc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../common/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../common/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/tificc/tifdiff.c b/lcms2mt/utils/tificc/tifdiff.c new file mode 100644 index 000000000..214e84544 --- /dev/null +++ b/lcms2mt/utils/tificc/tifdiff.c @@ -0,0 +1,708 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "utils.h" +#include "tiffio.h" + + +// ------------------------------------------------------------------------ + +static TIFF *Tiff1, *Tiff2, *TiffDiff; +static const char* TiffDiffFilename; +static const char* CGATSout; + +typedef struct { + double n, x, x2; + double Min, Peak; + + } STAT, *LPSTAT; + + +static STAT ColorantStat[4]; +static STAT EuclideanStat; +static STAT ColorimetricStat; + +static uint16 Channels; + +static cmsHPROFILE hLab; + + +static +void ConsoleWarningHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + if (module != NULL) + strcat(strcpy(e, module), ": "); + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + if (Verbose) { + + fprintf(stderr, "\nWarning"); + fprintf(stderr, " %s\n", e); + fflush(stderr); + } +} + +static +void ConsoleErrorHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + + if (module != NULL) + strcat(strcpy(e, module), ": "); + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + fprintf(stderr, "\nError"); + fprintf(stderr, " %s\n", e); + fflush(stderr); +} + + + +static +void Help() +{ + fprintf(stderr, "Little cms TIFF compare utility. v1.0\n\n"); + + fprintf(stderr, "usage: tiffdiff [flags] input.tif output.tif\n"); + + fprintf(stderr, "\nflags:\n\n"); + + + fprintf(stderr, "%co<tiff> - Output TIFF file\n", SW); + fprintf(stderr, "%cg<CGATS> - Output results in CGATS file\n", SW); + + fprintf(stderr, "\n"); + + fprintf(stderr, "%cv - Verbose (show warnings)\n", SW); + fprintf(stderr, "%ch - This help\n", SW); + + + fflush(stderr); + exit(0); +} + + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s=xgetopt(argc,argv,"o:O:hHvVg:G:")) != EOF) { + + switch (s) { + + + case 'v': + case 'V': + Verbose = TRUE; + break; + + case 'o': + case 'O': + TiffDiffFilename = xoptarg; + break; + + + case 'H': + case 'h': + Help(); + break; + + case 'g': + case 'G': + CGATSout = xoptarg; + break; + + default: + + FatalError("Unknown option - run without args to see valid ones"); + } + } +} + + +static +void ClearStatistics(LPSTAT st) +{ + + st ->n = st ->x = st->x2 = st->Peak = 0; + st ->Min = 1E10; + +} + + +static +void AddOnePixel(LPSTAT st, double dE) +{ + + st-> x += dE; st ->x2 += (dE * dE); st->n += 1.0; + if (dE > st ->Peak) st ->Peak = dE; + if (dE < st ->Min) st ->Min= dE; +} + +static +double Std(LPSTAT st) +{ + return sqrt((st->n * st->x2 - st->x * st->x) / (st->n*(st->n-1))); +} + +static +double Mean(LPSTAT st) +{ + return st ->x/st ->n; +} + + +// Build up the pixeltype descriptor + +static +cmsUInt32Number GetInputPixelType(TIFF *Bank) +{ + uint16 Photometric, bps, spp, extra, PlanarConfig, *info; + uint16 Compression, reverse = 0; + int ColorChannels, IsPlanar = 0, pt = 0; + + TIFFGetField(Bank, TIFFTAG_PHOTOMETRIC, &Photometric); + TIFFGetFieldDefaulted(Bank, TIFFTAG_BITSPERSAMPLE, &bps); + + if (bps == 1) + FatalError("Sorry, bilevel TIFFs has nothig to do with ICC profiles"); + + if (bps != 8 && bps != 16) + FatalError("Sorry, 8 or 16 bits per sample only"); + + TIFFGetFieldDefaulted(Bank, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetFieldDefaulted(Bank, TIFFTAG_PLANARCONFIG, &PlanarConfig); + + switch (PlanarConfig) + { + case PLANARCONFIG_CONTIG: IsPlanar = 0; break; + case PLANARCONFIG_SEPARATE: FatalError("Planar TIFF are not supported"); + default: + + FatalError("Unsupported planar configuration (=%d) ", (int) PlanarConfig); + } + + // If Samples per pixel == 1, PlanarConfiguration is irrelevant and need + // not to be included. + + if (spp == 1) IsPlanar = 0; + + + // Any alpha? + + TIFFGetFieldDefaulted(Bank, TIFFTAG_EXTRASAMPLES, &extra, &info); + + + ColorChannels = spp - extra; + + switch (Photometric) { + + case PHOTOMETRIC_MINISWHITE: + + reverse = 1; + + case PHOTOMETRIC_MINISBLACK: + + pt = PT_GRAY; + break; + + case PHOTOMETRIC_RGB: + + pt = PT_RGB; + break; + + + case PHOTOMETRIC_PALETTE: + + FatalError("Sorry, palette images not supported (at least on this version)"); + + case PHOTOMETRIC_SEPARATED: + pt = PixelTypeFromChanCount(ColorChannels); + break; + + case PHOTOMETRIC_YCBCR: + TIFFGetField(Bank, TIFFTAG_COMPRESSION, &Compression); + { + uint16 subx, suby; + + pt = PT_YCbCr; + TIFFGetFieldDefaulted(Bank, TIFFTAG_YCBCRSUBSAMPLING, &subx, &suby); + if (subx != 1 || suby != 1) + FatalError("Sorry, subsampled images not supported"); + + } + break; + + case 9: + case PHOTOMETRIC_CIELAB: + pt = PT_Lab; + break; + + + case PHOTOMETRIC_LOGLUV: /* CIE Log2(L) (u',v') */ + + TIFFSetField(Bank, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT); + pt = PT_YUV; // *ICCSpace = icSigLuvData; + bps = 16; // 16 bits forced by LibTiff + break; + + default: + FatalError("Unsupported TIFF color space (Photometric %d)", Photometric); + } + + // Convert bits per sample to bytes per sample + + bps >>= 3; + + return (COLORSPACE_SH(pt)|PLANAR_SH(IsPlanar)|EXTRA_SH(extra)|CHANNELS_SH(ColorChannels)|BYTES_SH(bps)|FLAVOR_SH(reverse)); +} + + + +static +cmsUInt32Number OpenEmbedded(TIFF* tiff, cmsHPROFILE* PtrProfile, cmsHTRANSFORM* PtrXform) +{ + + cmsUInt32Number EmbedLen, dwFormat = 0; + cmsUInt8Number* EmbedBuffer; + + *PtrProfile = NULL; + *PtrXform = NULL; + + if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) { + + *PtrProfile = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen); + + if (Verbose) { + + fprintf(stdout, "Embedded profile found:\n"); + PrintProfileInformation(NULL, *PtrProfile); + + } + + dwFormat = GetInputPixelType(tiff); + *PtrXform = cmsCreateTransform(*PtrProfile, dwFormat, + hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, 0); + + } + + return dwFormat; +} + + +static +size_t PixelSize(cmsUInt32Number dwFormat) +{ + return T_BYTES(dwFormat) * (T_CHANNELS(dwFormat) + T_EXTRA(dwFormat)); +} + + +static +int CmpImages(TIFF* tiff1, TIFF* tiff2, TIFF* diff) +{ + cmsUInt8Number* buf1, *buf2, *buf3=NULL; + int row, cols, imagewidth = 0, imagelength = 0; + uint16 Photometric; + double dE = 0; + double dR, dG, dB, dC, dM, dY, dK; + int rc = 0; + cmsHPROFILE hProfile1 = 0, hProfile2 = 0; + cmsHTRANSFORM xform1 = 0, xform2 = 0; + cmsUInt32Number dwFormat1, dwFormat2; + + + + TIFFGetField(tiff1, TIFFTAG_PHOTOMETRIC, &Photometric); + TIFFGetField(tiff1, TIFFTAG_IMAGEWIDTH, &imagewidth); + TIFFGetField(tiff1, TIFFTAG_IMAGELENGTH, &imagelength); + TIFFGetField(tiff1, TIFFTAG_SAMPLESPERPIXEL, &Channels); + + dwFormat1 = OpenEmbedded(tiff1, &hProfile1, &xform1); + dwFormat2 = OpenEmbedded(tiff2, &hProfile2, &xform2); + + + + buf1 = (cmsUInt8Number*)_TIFFmalloc(TIFFScanlineSize(tiff1)); + buf2 = (cmsUInt8Number*)_TIFFmalloc(TIFFScanlineSize(tiff2)); + + if (diff) { + + TIFFSetField(diff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(diff, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField(diff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + + TIFFSetField(diff, TIFFTAG_IMAGEWIDTH, imagewidth); + TIFFSetField(diff, TIFFTAG_IMAGELENGTH, imagelength); + + TIFFSetField(diff, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(diff, TIFFTAG_BITSPERSAMPLE, 8); + + buf3 = (cmsUInt8Number*)_TIFFmalloc(TIFFScanlineSize(diff)); + } + + + + for (row = 0; row < imagelength; row++) { + + if (TIFFReadScanline(tiff1, buf1, row, 0) < 0) goto Error; + if (TIFFReadScanline(tiff2, buf2, row, 0) < 0) goto Error; + + + for (cols = 0; cols < imagewidth; cols++) { + + + switch (Photometric) { + + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + + dE = fabs(buf2[cols] - buf1[cols]); + + AddOnePixel(&ColorantStat[0], dE); + AddOnePixel(&EuclideanStat, dE); + break; + + case PHOTOMETRIC_RGB: + + { + int index = 3 * cols; + + dR = fabs(buf2[index+0] - buf1[index+0]); + dG = fabs(buf2[index+1] - buf1[index+1]); + dB = fabs(buf2[index+2] - buf1[index+2]); + + dE = sqrt(dR * dR + dG * dG + dB * dB) / sqrt(3.); + } + + AddOnePixel(&ColorantStat[0], dR); + AddOnePixel(&ColorantStat[1], dG); + AddOnePixel(&ColorantStat[2], dB); + AddOnePixel(&EuclideanStat, dE); + break; + + case PHOTOMETRIC_SEPARATED: + + { + int index = 4 * cols; + + dC = fabs(buf2[index+0] - buf1[index+0]); + dM = fabs(buf2[index+1] - buf1[index+1]); + dY = fabs(buf2[index+2] - buf1[index+2]); + dK = fabs(buf2[index+3] - buf1[index+3]); + + dE = sqrt(dC * dC + dM * dM + dY * dY + dK * dK) / 2.; + } + AddOnePixel(&ColorantStat[0], dC); + AddOnePixel(&ColorantStat[1], dM); + AddOnePixel(&ColorantStat[2], dY); + AddOnePixel(&ColorantStat[3], dK); + AddOnePixel(&EuclideanStat, dE); + break; + + default: + FatalError("Unsupported channels: %d", Channels); + } + + + if (xform1 && xform2) { + + + cmsCIELab Lab1, Lab2; + size_t index1 = cols * PixelSize(dwFormat1); + size_t index2 = cols * PixelSize(dwFormat2); + + cmsDoTransform(NULL, xform1, &buf1[index1], &Lab1, 1); + cmsDoTransform(NULL, xform2, &buf2[index2], &Lab2, 1); + + dE = cmsDeltaE(NULL, &Lab1, &Lab2); + AddOnePixel(&ColorimetricStat, dE); + } + + + if (diff) { + buf3[cols] = (cmsUInt8Number) floor(dE + 0.5); + } + + } + + if (diff) { + + if (TIFFWriteScanline(diff, buf3, row, 0) < 0) goto Error; + } + + + } + + rc = 1; + +Error: + + if (hProfile1) cmsCloseProfile(NULL, hProfile1); + if (hProfile2) cmsCloseProfile(NULL, hProfile2); + if (xform1) cmsDeleteTransform(NULL, xform1); + if (xform2) cmsDeleteTransform(NULL, xform2); + _TIFFfree(buf1); _TIFFfree(buf2); + if (diff) { + TIFFWriteDirectory(diff); + if (buf3 != NULL) _TIFFfree(buf3); + } + return rc; +} + + +static +void AssureShortTagIs(TIFF* tif1, TIFF* tiff2, int tag, int Val, const char* Error) +{ + uint16 v1; + + + if (!TIFFGetField(tif1, tag, &v1)) goto Err; + if (v1 != Val) goto Err; + + if (!TIFFGetField(tiff2, tag, &v1)) goto Err; + if (v1 != Val) goto Err; + + return; +Err: + FatalError("%s is not proper", Error); +} + + +static +int CmpShortTag(TIFF* tif1, TIFF* tif2, int tag) +{ + uint16 v1, v2; + + if (!TIFFGetField(tif1, tag, &v1)) return 0; + if (!TIFFGetField(tif2, tag, &v2)) return 0; + + return v1 == v2; +} + +static +int CmpLongTag(TIFF* tif1, TIFF* tif2, int tag) +{ + uint32 v1, v2; + + if (!TIFFGetField(tif1, tag, &v1)) return 0; + if (!TIFFGetField(tif2, tag, &v2)) return 0; + + return v1 == v2; +} + + +static +void EqualShortTag(TIFF* tif1, TIFF* tif2, int tag, const char* Error) +{ + if (!CmpShortTag(tif1, tif2, tag)) + FatalError("%s is different", Error); +} + + + +static +void EqualLongTag(TIFF* tif1, TIFF* tif2, int tag, const char* Error) +{ + if (!CmpLongTag(tif1, tif2, tag)) + FatalError("%s is different", Error); +} + + + +static +void AddOneCGATSRow(cmsHANDLE hIT8, char *Name, LPSTAT st) +{ + + double Per100 = 100.0 * ((255.0 - Mean(st)) / 255.0); + + cmsIT8SetData(NULL, hIT8, Name, "SAMPLE_ID", Name); + cmsIT8SetDataDbl(NULL, hIT8, Name, "PER100_EQUAL", Per100); + cmsIT8SetDataDbl(NULL, hIT8, Name, "MEAN_DE", Mean(st)); + cmsIT8SetDataDbl(NULL, hIT8, Name, "STDEV_DE", Std(st)); + cmsIT8SetDataDbl(NULL, hIT8, Name, "MIN_DE", st ->Min); + cmsIT8SetDataDbl(NULL, hIT8, Name, "MAX_DE", st ->Peak); + +} + + +static +void CreateCGATS(const char* TiffName1, const char* TiffName2) +{ + cmsHANDLE hIT8 = cmsIT8Alloc(0); + time_t ltime; + char Buffer[256]; + + cmsIT8SetSheetType(NULL, hIT8, "TIFFDIFF"); + + + sprintf(Buffer, "Differences between %s and %s", TiffName1, TiffName2); + + cmsIT8SetComment(NULL, hIT8, Buffer); + + cmsIT8SetPropertyStr(NULL, hIT8, "ORIGINATOR", "TIFFDIFF"); + time( <ime ); + strcpy(Buffer, ctime(<ime)); + Buffer[strlen(Buffer)-1] = 0; // Remove the nasty "\n" + + cmsIT8SetPropertyStr(NULL, hIT8, "CREATED", Buffer); + + cmsIT8SetComment(NULL, hIT8, " "); + + cmsIT8SetPropertyDbl(NULL, hIT8, "NUMBER_OF_FIELDS", 6); + + + cmsIT8SetDataFormat(NULL, hIT8, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(NULL, hIT8, 1, "PER100_EQUAL"); + cmsIT8SetDataFormat(NULL, hIT8, 2, "MEAN_DE"); + cmsIT8SetDataFormat(NULL, hIT8, 3, "STDEV_DE"); + cmsIT8SetDataFormat(NULL, hIT8, 4, "MIN_DE"); + cmsIT8SetDataFormat(NULL, hIT8, 5, "MAX_DE"); + + + switch (Channels) { + + case 1: + cmsIT8SetPropertyDbl(NULL, hIT8, "NUMBER_OF_SETS", 3); + AddOneCGATSRow(hIT8, "GRAY_PLANE", &ColorantStat[0]); + break; + + case 3: + cmsIT8SetPropertyDbl(NULL, hIT8, "NUMBER_OF_SETS", 5); + AddOneCGATSRow(hIT8, "R_PLANE", &ColorantStat[0]); + AddOneCGATSRow(hIT8, "G_PLANE", &ColorantStat[1]); + AddOneCGATSRow(hIT8, "B_PLANE", &ColorantStat[2]); + break; + + + case 4: + cmsIT8SetPropertyDbl(NULL, hIT8, "NUMBER_OF_SETS", 6); + AddOneCGATSRow(hIT8, "C_PLANE", &ColorantStat[0]); + AddOneCGATSRow(hIT8, "M_PLANE", &ColorantStat[1]); + AddOneCGATSRow(hIT8, "Y_PLANE", &ColorantStat[2]); + AddOneCGATSRow(hIT8, "K_PLANE", &ColorantStat[3]); + break; + + default: FatalError("Internal error: Bad ColorSpace"); + + } + + AddOneCGATSRow(hIT8, "EUCLIDEAN", &EuclideanStat); + AddOneCGATSRow(hIT8, "COLORIMETRIC", &ColorimetricStat); + + cmsIT8SaveToFile(NULL, hIT8, CGATSout); + cmsIT8Free(NULL, hIT8); +} + +int main(int argc, char* argv[]) +{ + int i; + + Tiff1 = Tiff2 = TiffDiff = NULL; + + InitUtils("tiffdiff"); + + HandleSwitches(argc, argv); + + if ((argc - xoptind) != 2) { + + Help(); + } + + TIFFSetErrorHandler(ConsoleErrorHandler); + TIFFSetWarningHandler(ConsoleWarningHandler); + + Tiff1 = TIFFOpen(argv[xoptind], "r"); + if (Tiff1 == NULL) FatalError("Unable to open '%s'", argv[xoptind]); + + Tiff2 = TIFFOpen(argv[xoptind+1], "r"); + if (Tiff2 == NULL) FatalError("Unable to open '%s'", argv[xoptind+1]); + + if (TiffDiffFilename) { + + TiffDiff = TIFFOpen(TiffDiffFilename, "w"); + if (TiffDiff == NULL) FatalError("Unable to create '%s'", TiffDiffFilename); + + } + + + AssureShortTagIs(Tiff1, Tiff2, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG, "Planar Config"); + AssureShortTagIs(Tiff1, Tiff2, TIFFTAG_BITSPERSAMPLE, 8, "8 bit per sample"); + + EqualLongTag(Tiff1, Tiff2, TIFFTAG_IMAGEWIDTH, "Image width"); + EqualLongTag(Tiff1, Tiff2, TIFFTAG_IMAGELENGTH, "Image length"); + + EqualShortTag(Tiff1, Tiff2, TIFFTAG_SAMPLESPERPIXEL, "Samples per pixel"); + + + hLab = cmsCreateLab4Profile(NULL); + + ClearStatistics(&EuclideanStat); + for (i=0; i < 4; i++) + ClearStatistics(&ColorantStat[i]); + + if (!CmpImages(Tiff1, Tiff2, TiffDiff)) + FatalError("Error comparing images"); + + if (CGATSout) { + CreateCGATS(argv[xoptind], argv[xoptind+1]); + } + else { + + double Per100 = 100.0 * ((255.0 - Mean(&EuclideanStat)) / 255.0); + + printf("Digital counts %g%% equal. mean %g, min %g, max %g, Std %g\n", Per100, Mean(&EuclideanStat), + EuclideanStat.Min, + EuclideanStat.Peak, + Std(&EuclideanStat)); + + if (ColorimetricStat.n > 0) { + + Per100 = 100.0 * ((255.0 - Mean(&ColorimetricStat)) / 255.0); + + printf("dE Colorimetric %g%% equal. mean %g, min %g, max %g, Std %g\n", Per100, Mean(&ColorimetricStat), + ColorimetricStat.Min, + ColorimetricStat.Peak, + Std(&ColorimetricStat)); + } + + } + + if (hLab) cmsCloseProfile(NULL, hLab); + if (Tiff1) TIFFClose(Tiff1); + if (Tiff2) TIFFClose(Tiff2); + if (TiffDiff) TIFFClose(TiffDiff); + + return 0; +} + + diff --git a/lcms2mt/utils/tificc/tificc.1 b/lcms2mt/utils/tificc/tificc.1 new file mode 100644 index 000000000..9af0d8688 --- /dev/null +++ b/lcms2mt/utils/tificc/tificc.1 @@ -0,0 +1,117 @@ +.\"Shiju P. Nair September 30, 2004 +.\"Thomas Weber <tweber@debian.org> April 23, 2014 +.TH TIFICC 1 "October 23, 2004" +.SH NAME +tificc - little cms ICC profile applier for TIFF. +.SH SYNOPSIS +.B tificc +.RI [ options ] " input.tif output.tif" +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B tificc +is a little cms ICC profile applier for TIFF. +.SH OPTIONS +.TP +.B \-a +Handle channels > 4 as alpha. +.TP +.B \-b +Black point compensation. +.TP +.BI \-c\ NUM +Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. +.TP +.BI \-d\ NUM +Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. +.TP +.B \-e +Embed destination profile. +.TP +.B \-g +Marks out-of-gamut colors on softproof. +.TP +.BI \-h\ NUM +Show summary of options and examples (0=help, 1=Examples, 2=Built-in profiles, 3=Contact information) +.TP +.BI \-i\ profile +Input profile (defaults to sRGB). +.TP +.BI \-k\ inklimit +Ink-limiting in % (CMYK only), (0..400.0, float value) [default 400.0]. +.TP +.BI \-l\ profile +Transform by device-link profile. +.TP +.B \-m TODO: check if values outside 0..3 are possible +SoftProof intent [defaults to 0]. +.TP +.B \-n +Ignore embedded profile on input. +.TP +.BI \-o\ profile +Output profile (defaults to sRGB). +.TP +.BI \-p\ profile +Soft proof profile. +.TP +.BI \-s\ newprofile +Save embedded profile as \fInewprofile\fR. +.TP +.BI \-t\ NUM +Rendering intent +.nf +.RS +0=Perceptual [default] +1=Relative colorimetric +2=Saturation +3=Absolute colorimetric +10=Perceptual preserving black ink +11=Relative colorimetric preserving black ink +12=Saturation preserving black ink +13=Perceptual preserving black plane +14=Relative colorimetric preserving black plane +15=Saturation preserving black plane +.RE +.fi +.TP +.B \-v +Verbose. +.TP +.BI \-w\ NUM +Output depth (8, 16 or 32). Use 32 for floating-point. +.SH BUILT-IN PROFILES +.nf + *Lab2 -- D50-based v2 CIEL*a*b + *Lab4 -- D50-based v4 CIEL*a*b + *Lab -- D50-based v4 CIEL*a*b + *XYZ -- CIE XYZ (PCS) + *sRGB -- sRGB color space + *Gray22 - Monochrome of Gamma 2.2 + *Gray30 - Monochrome of Gamma 3.0 + *null - Monochrome black for all input + *Lin2222- CMYK linearization of gamma 2.2 on each channel +.fi +.SH EXAMPLES +.nf +To color correct from scanner to sRGB: + tificc -iscanner.icm in.tif out.tif +To convert from monitor1 to monitor2: + tificc -imon1.icm -omon2.icm in.tif out.tif +To make a CMYK separation: + tificc -oprinter.icm inrgb.tif outcmyk.tif +To recover sRGB from a CMYK separation: + tificc -iprinter.icm incmyk.tif outrgb.tif +To convert from CIELab TIFF to sRGB + tificc -i*Lab in.tif out.tif +.fi +.SH NOTES +For suggestions, comments, bug reports etc. send mail to info@littlecms.com. +.SH SEE ALSO +.BR jpgicc (1), +.BR linkicc (1), +.BR psicc (1), +.BR transicc (1) +.SH AUTHOR +This manual page was originally written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. Modified by Marti Maria to reflect further changes. diff --git a/lcms2mt/utils/tificc/tificc.c b/lcms2mt/utils/tificc/tificc.c new file mode 100644 index 000000000..538c30cc0 --- /dev/null +++ b/lcms2mt/utils/tificc/tificc.c @@ -0,0 +1,1180 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- + +// This program does apply profiles to (some) TIFF files + +#include "lcms2_plugin.h" +#include "tiffio.h" +#include "utils.h" + + +// Flags + +static cmsBool BlackWhiteCompensation = FALSE; +static cmsBool IgnoreEmbedded = FALSE; +static cmsBool EmbedProfile = FALSE; +static int Width = 8; +static cmsBool GamutCheck = FALSE; +static cmsBool lIsDeviceLink = FALSE; +static cmsBool StoreAsAlpha = FALSE; + +static int Intent = INTENT_PERCEPTUAL; +static int ProofingIntent = INTENT_PERCEPTUAL; +static int PrecalcMode = 1; +static cmsFloat64Number InkLimit = 400; + +static cmsFloat64Number ObserverAdaptationState = 1.0; // According ICC 4.3 this is the default + +static const char *cInpProf = NULL; +static const char *cOutProf = NULL; +static const char *cProofing = NULL; + +static const char* SaveEmbedded = NULL; + +// Console error & warning +static +void ConsoleWarningHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + if (module != NULL) + strcat(strcpy(e, module), ": "); + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + if (Verbose) { + + fprintf(stderr, "\nWarning"); + fprintf(stderr, " %s\n", e); + fflush(stderr); + } +} + +static +void ConsoleErrorHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + + if (module != NULL) { + if (strlen(module) < 500) + strcat(strcpy(e, module), ": "); + } + + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + fprintf(stderr, "\nError"); + fprintf(stderr, " %s\n", e); + fflush(stderr); +} + + +// Issue a warning +static +void Warning(const char *frm, ...) +{ + va_list args; + + va_start(args, frm); + ConsoleWarningHandler("[tificc]", frm, args); + va_end(args); +} + + + +// Out of mememory is a fatal error +static +void OutOfMem(cmsUInt32Number size) +{ + FatalError("Out of memory on allocating %d bytes.", size); +} + + +// ----------------------------------------------------------------------------------------------- + +// In TIFF, Lab is encoded in a different way, so let's use the plug-in +// capabilities of lcms2 to change the meaning of TYPE_Lab_8. + +// * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256 +static int FromLabV2ToLabV4(int x) +{ + int a; + + a = ((x << 8) | x) >> 8; // * 257 / 256 + if ( a > 0xffff) return 0xffff; + return a; +} + +// * 0xf00 / 0xffff = * 256 / 257 +static int FromLabV4ToLabV2(int x) +{ + return ((x << 8) + 0x80) / 257; +} + + +// Formatter for 8bit Lab TIFF (photometric 8) +static +unsigned char* UnrollTIFFLab8(cmsContext ContextID, struct _cmstransform_struct* CMMcargo, + register cmsUInt16Number wIn[], + register cmsUInt8Number* accum, + register cmsUInt32Number Stride) +{ + wIn[0] = (cmsUInt16Number) FromLabV2ToLabV4((accum[0]) << 8); + wIn[1] = (cmsUInt16Number) FromLabV2ToLabV4(((accum[1] > 127) ? (accum[1] - 128) : (accum[1] + 128)) << 8); + wIn[2] = (cmsUInt16Number) FromLabV2ToLabV4(((accum[2] > 127) ? (accum[2] - 128) : (accum[2] + 128)) << 8); + + return accum + 3; + + UTILS_UNUSED_PARAMETER(Stride); + UTILS_UNUSED_PARAMETER(CMMcargo); +} + +// Formatter for 16bit Lab TIFF (photometric 8) +static +unsigned char* UnrollTIFFLab16(cmsContext ContextID, struct _cmstransform_struct* CMMcargo, + register cmsUInt16Number wIn[], + register cmsUInt8Number* accum, + register cmsUInt32Number Stride ) +{ + cmsUInt16Number* accum16 = (cmsUInt16Number*) accum; + + wIn[0] = (cmsUInt16Number) FromLabV2ToLabV4(accum16[0]); + wIn[1] = (cmsUInt16Number) FromLabV2ToLabV4(((accum16[1] > 0x7f00) ? (accum16[1] - 0x8000) : (accum16[1] + 0x8000)) ); + wIn[2] = (cmsUInt16Number) FromLabV2ToLabV4(((accum16[2] > 0x7f00) ? (accum16[2] - 0x8000) : (accum16[2] + 0x8000)) ); + + return accum + 3 * sizeof(cmsUInt16Number); + + UTILS_UNUSED_PARAMETER(Stride); + UTILS_UNUSED_PARAMETER(CMMcargo); +} + + +static +unsigned char* PackTIFFLab8(cmsContext ContextID, struct _cmstransform_struct* CMMcargo, + register cmsUInt16Number wOut[], + register cmsUInt8Number* output, + register cmsUInt32Number Stride) +{ + int a, b; + + *output++ = (cmsUInt8Number) (FromLabV4ToLabV2(wOut[0] + 0x0080) >> 8); + + a = (FromLabV4ToLabV2(wOut[1]) + 0x0080) >> 8; + b = (FromLabV4ToLabV2(wOut[2]) + 0x0080) >> 8; + + *output++ = (cmsUInt8Number) ((a < 128) ? (a + 128) : (a - 128)); + *output++ = (cmsUInt8Number) ((b < 128) ? (b + 128) : (b - 128)); + + return output; + + UTILS_UNUSED_PARAMETER(Stride); + UTILS_UNUSED_PARAMETER(CMMcargo); +} + +static +unsigned char* PackTIFFLab16(cmsContext ContextID, struct _cmstransform_struct* CMMcargo, + register cmsUInt16Number wOut[], + register cmsUInt8Number* output, + register cmsUInt32Number Stride) +{ + int a, b; + cmsUInt16Number* output16 = (cmsUInt16Number*) output; + + *output16++ = (cmsUInt16Number) FromLabV4ToLabV2(wOut[0]); + + a = FromLabV4ToLabV2(wOut[1]); + b = FromLabV4ToLabV2(wOut[2]); + + *output16++ = (cmsUInt16Number) ((a < 0x7f00) ? (a + 0x8000) : (a - 0x8000)); + *output16++ = (cmsUInt16Number) ((b < 0x7f00) ? (b + 0x8000) : (b - 0x8000)); + + return (cmsUInt8Number*) output16; + + UTILS_UNUSED_PARAMETER(Stride); + UTILS_UNUSED_PARAMETER(CMMcargo); +} + + +static +cmsFormatter TiffFormatterFactory(cmsContext ContextID, cmsUInt32Number Type, + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags) +{ + cmsFormatter Result = { NULL }; + int bps = T_BYTES(Type); + int IsTiffSpecial = (Type >> 23) & 1; + + if (IsTiffSpecial && !(dwFlags & CMS_PACK_FLAGS_FLOAT)) + { + if (Dir == cmsFormatterInput) + { + Result.Fmt16 = (bps == 1) ? UnrollTIFFLab8 : UnrollTIFFLab16; + } + else + Result.Fmt16 = (bps == 1) ? PackTIFFLab8 : PackTIFFLab16; + } + + return Result; +} + +static cmsPluginFormatters TiffLabPlugin = { {cmsPluginMagicNumber, 2000, cmsPluginFormattersSig, NULL}, TiffFormatterFactory }; + + + +// Build up the pixeltype descriptor +static +cmsUInt32Number GetInputPixelType(TIFF *Bank) +{ + uint16 Photometric, bps, spp, extra, PlanarConfig, *info; + uint16 Compression, reverse = 0; + int ColorChannels, IsPlanar = 0, pt = 0, IsFlt; + int labTiffSpecial = FALSE; + + TIFFGetField(Bank, TIFFTAG_PHOTOMETRIC, &Photometric); + TIFFGetFieldDefaulted(Bank, TIFFTAG_BITSPERSAMPLE, &bps); + + if (bps == 1) + FatalError("Sorry, bilevel TIFFs has nothing to do with ICC profiles"); + + if (bps != 8 && bps != 16 && bps != 32) + FatalError("Sorry, 8, 16 or 32 bits per sample only"); + + TIFFGetFieldDefaulted(Bank, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetFieldDefaulted(Bank, TIFFTAG_PLANARCONFIG, &PlanarConfig); + + switch (PlanarConfig) { + + case PLANARCONFIG_CONTIG: IsPlanar = 0; break; + case PLANARCONFIG_SEPARATE: IsPlanar = 1; break; + default: + + FatalError("Unsupported planar configuration (=%d) ", (int) PlanarConfig); + } + + // If Samples per pixel == 1, PlanarConfiguration is irrelevant and need + // not to be included. + + if (spp == 1) IsPlanar = 0; + + // Any alpha? + + TIFFGetFieldDefaulted(Bank, TIFFTAG_EXTRASAMPLES, &extra, &info); + + // Read alpha channels as colorant + + if (StoreAsAlpha) { + + ColorChannels = spp; + extra = 0; + } + else + ColorChannels = spp - extra; + + switch (Photometric) { + + case PHOTOMETRIC_MINISWHITE: + + reverse = 1; + + // ... fall through ... + + case PHOTOMETRIC_MINISBLACK: + pt = PT_GRAY; + break; + + case PHOTOMETRIC_RGB: + pt = PT_RGB; + break; + + + case PHOTOMETRIC_PALETTE: + FatalError("Sorry, palette images not supported"); + break; + + case PHOTOMETRIC_SEPARATED: + + pt = PixelTypeFromChanCount(ColorChannels); + break; + + case PHOTOMETRIC_YCBCR: + TIFFGetField(Bank, TIFFTAG_COMPRESSION, &Compression); + { + uint16 subx, suby; + + pt = PT_YCbCr; + TIFFGetFieldDefaulted(Bank, TIFFTAG_YCBCRSUBSAMPLING, &subx, &suby); + if (subx != 1 || suby != 1) + FatalError("Sorry, subsampled images not supported"); + + } + break; + + case PHOTOMETRIC_ICCLAB: + pt = PT_LabV2; + break; + + case PHOTOMETRIC_CIELAB: + pt = PT_Lab; + labTiffSpecial = TRUE; + break; + + + case PHOTOMETRIC_LOGLUV: // CIE Log2(L) (u',v') + + TIFFSetField(Bank, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT); + pt = PT_YUV; // *ICCSpace = icSigLuvData; + bps = 16; // 16 bits forced by LibTiff + break; + + default: + FatalError("Unsupported TIFF color space (Photometric %d)", Photometric); + } + + // Convert bits per sample to bytes per sample + + bps >>= 3; + IsFlt = (bps == 0) || (bps == 4); + + return (FLOAT_SH(IsFlt)|COLORSPACE_SH(pt)|PLANAR_SH(IsPlanar)|EXTRA_SH(extra)|CHANNELS_SH(ColorChannels)|BYTES_SH(bps)|FLAVOR_SH(reverse) | (labTiffSpecial << 23) ); +} + + + +// Rearrange pixel type to build output descriptor +static +cmsUInt32Number ComputeOutputFormatDescriptor(cmsUInt32Number dwInput, int OutColorSpace, int bps) +{ + int IsPlanar = T_PLANAR(dwInput); + int Channels = ChanCountFromPixelType(OutColorSpace); + int IsFlt = (bps == 0) || (bps == 4); + + return (FLOAT_SH(IsFlt)|COLORSPACE_SH(OutColorSpace)|PLANAR_SH(IsPlanar)|CHANNELS_SH(Channels)|BYTES_SH(bps)); +} + + + +// Tile based transforms +static +int TileBasedXform(cmsHTRANSFORM hXForm, TIFF* in, TIFF* out, int nPlanes) +{ + tsize_t BufSizeIn = TIFFTileSize(in); + tsize_t BufSizeOut = TIFFTileSize(out); + unsigned char *BufferIn, *BufferOut; + ttile_t i, TileCount = TIFFNumberOfTiles(in) / nPlanes; + uint32 tw, tl; + int PixelCount, j; + + + TIFFGetFieldDefaulted(in, TIFFTAG_TILEWIDTH, &tw); + TIFFGetFieldDefaulted(in, TIFFTAG_TILELENGTH, &tl); + + PixelCount = (int) tw * tl; + + BufferIn = (unsigned char *) _TIFFmalloc(BufSizeIn * nPlanes); + if (!BufferIn) OutOfMem(BufSizeIn * nPlanes); + + BufferOut = (unsigned char *) _TIFFmalloc(BufSizeOut * nPlanes); + if (!BufferOut) OutOfMem(BufSizeOut * nPlanes); + + + for (i = 0; i < TileCount; i++) { + + for (j=0; j < nPlanes; j++) { + + if (TIFFReadEncodedTile(in, i + (j* TileCount), + BufferIn + (j*BufSizeIn), BufSizeIn) < 0) goto cleanup; + } + + cmsDoTransform(NULL, hXForm, BufferIn, BufferOut, PixelCount); + + for (j=0; j < nPlanes; j++) { + + if (TIFFWriteEncodedTile(out, i + (j*TileCount), + BufferOut + (j*BufSizeOut), BufSizeOut) < 0) goto cleanup; + } + + } + + _TIFFfree(BufferIn); + _TIFFfree(BufferOut); + return 1; + + +cleanup: + + _TIFFfree(BufferIn); + _TIFFfree(BufferOut); + return 0; +} + + +// Strip based transforms + +static +int StripBasedXform(cmsHTRANSFORM hXForm, TIFF* in, TIFF* out, int nPlanes) +{ + tsize_t BufSizeIn = TIFFStripSize(in); + tsize_t BufSizeOut = TIFFStripSize(out); + unsigned char *BufferIn, *BufferOut; + ttile_t i, StripCount = TIFFNumberOfStrips(in) / nPlanes; + uint32 sw; + uint32 sl; + uint32 iml; + int j; + int PixelCount; + + TIFFGetFieldDefaulted(in, TIFFTAG_IMAGEWIDTH, &sw); + TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &sl); + TIFFGetFieldDefaulted(in, TIFFTAG_IMAGELENGTH, &iml); + + // It is possible to get infinite rows per strip + if (sl == 0 || sl > iml) + sl = iml; // One strip for whole image + + BufferIn = (unsigned char *) _TIFFmalloc(BufSizeIn * nPlanes); + if (!BufferIn) OutOfMem(BufSizeIn * nPlanes); + + BufferOut = (unsigned char *) _TIFFmalloc(BufSizeOut * nPlanes); + if (!BufferOut) OutOfMem(BufSizeOut * nPlanes); + + + for (i = 0; i < StripCount; i++) { + + for (j=0; j < nPlanes; j++) { + + if (TIFFReadEncodedStrip(in, i + (j * StripCount), + BufferIn + (j * BufSizeIn), BufSizeIn) < 0) goto cleanup; + } + + PixelCount = (int) sw * (iml < sl ? iml : sl); + iml -= sl; + + cmsDoTransform(NULL, hXForm, BufferIn, BufferOut, PixelCount); + + for (j=0; j < nPlanes; j++) { + if (TIFFWriteEncodedStrip(out, i + (j * StripCount), + BufferOut + j * BufSizeOut, BufSizeOut) < 0) goto cleanup; + } + + } + + _TIFFfree(BufferIn); + _TIFFfree(BufferOut); + return 1; + +cleanup: + + _TIFFfree(BufferIn); + _TIFFfree(BufferOut); + return 0; +} + + +// Creates minimum required tags +static +void WriteOutputTags(TIFF *out, int Colorspace, int BytesPerSample) +{ + int BitsPerSample = (8 * BytesPerSample); + int nChannels = ChanCountFromPixelType(Colorspace); + + uint16 Extra[] = { EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA, + EXTRASAMPLE_UNASSALPHA + }; + + + switch (Colorspace) { + + case PT_GRAY: + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); + break; + + case PT_RGB: + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); + break; + + case PT_CMY: + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(out, TIFFTAG_INKSET, 2); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); + break; + + case PT_CMYK: + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 4); + TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); + break; + + case PT_Lab: + if (BitsPerSample == 16) + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, 9); + else + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CIELAB); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); // Needed by TIFF Spec + break; + + + // Multi-ink separations + case PT_MCH2: + case PT_MCH3: + case PT_MCH4: + case PT_MCH5: + case PT_MCH6: + case PT_MCH7: + case PT_MCH8: + case PT_MCH9: + case PT_MCH10: + case PT_MCH11: + case PT_MCH12: + case PT_MCH13: + case PT_MCH14: + case PT_MCH15: + + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, nChannels); + + if (StoreAsAlpha && nChannels >= 4) { + // CMYK plus extra alpha + TIFFSetField(out, TIFFTAG_EXTRASAMPLES, nChannels - 4, Extra); + TIFFSetField(out, TIFFTAG_INKSET, 1); + TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4); + } + else { + TIFFSetField(out, TIFFTAG_INKSET, 2); + TIFFSetField(out, TIFFTAG_NUMBEROFINKS, nChannels); + } + + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample); + break; + + + default: + FatalError("Unsupported output colorspace"); + } + + if (Width == 32) + TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); +} + + +// Copies a bunch of tages + +static +void CopyOtherTags(TIFF* in, TIFF* out) +{ +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) + + + short shortv; + uint32 ow, ol; + cmsFloat32Number floatv; + char *stringv; + uint32 longv; + + CopyField(TIFFTAG_SUBFILETYPE, longv); + + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &ow); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &ol); + + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, ow); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, ol); + + CopyField(TIFFTAG_PLANARCONFIG, shortv); + CopyField(TIFFTAG_COMPRESSION, shortv); + + if (Width != 32) + CopyField(TIFFTAG_PREDICTOR, shortv); + + CopyField(TIFFTAG_THRESHHOLDING, shortv); + CopyField(TIFFTAG_FILLORDER, shortv); + CopyField(TIFFTAG_ORIENTATION, shortv); + CopyField(TIFFTAG_MINSAMPLEVALUE, shortv); + CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv); + CopyField(TIFFTAG_XRESOLUTION, floatv); + CopyField(TIFFTAG_YRESOLUTION, floatv); + CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); + CopyField(TIFFTAG_ROWSPERSTRIP, longv); + CopyField(TIFFTAG_XPOSITION, floatv); + CopyField(TIFFTAG_YPOSITION, floatv); + CopyField(TIFFTAG_IMAGEDEPTH, longv); + CopyField(TIFFTAG_TILEDEPTH, longv); + + CopyField(TIFFTAG_TILEWIDTH, longv); + CopyField(TIFFTAG_TILELENGTH, longv); + + CopyField(TIFFTAG_ARTIST, stringv); + CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv); + CopyField(TIFFTAG_MAKE, stringv); + CopyField(TIFFTAG_MODEL, stringv); + + CopyField(TIFFTAG_DATETIME, stringv); + CopyField(TIFFTAG_HOSTCOMPUTER, stringv); + CopyField(TIFFTAG_PAGENAME, stringv); + CopyField(TIFFTAG_DOCUMENTNAME, stringv); + +} + +// A replacement for (the nonstandard) filelength + + +static +void DoEmbedProfile(TIFF* Out, const char* ProfileFile) +{ + FILE* f; + cmsInt32Number size; + cmsUInt32Number EmbedLen; + cmsUInt8Number* EmbedBuffer; + + f = fopen(ProfileFile, "rb"); + if (f == NULL) return; + + size = cmsfilelength(f); + if (size < 0) return; + + EmbedBuffer = (cmsUInt8Number*) malloc(size + 1); + if (EmbedBuffer == NULL) { + OutOfMem(size+1); + return; + } + + EmbedLen = (cmsUInt32Number) fread(EmbedBuffer, 1, (size_t) size, f); + + if (EmbedLen != size) + FatalError("Cannot read %ld bytes to %s", size, ProfileFile); + + fclose(f); + EmbedBuffer[EmbedLen] = 0; + + TIFFSetField(Out, TIFFTAG_ICCPROFILE, EmbedLen, EmbedBuffer); + free(EmbedBuffer); +} + + + +static +cmsHPROFILE GetTIFFProfile(TIFF* in) +{ + cmsCIExyYTRIPLE Primaries; + cmsFloat32Number* chr; + cmsCIExyY WhitePoint; + cmsFloat32Number* wp; + int i; + cmsToneCurve* Curve[3]; + cmsUInt16Number *gmr, *gmg, *gmb; + cmsHPROFILE hProfile; + cmsUInt32Number EmbedLen; + cmsUInt8Number* EmbedBuffer; + + if (IgnoreEmbedded) return NULL; + + if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) { + + hProfile = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen); + + // Print description found in the profile + if (Verbose && (hProfile != NULL)) { + + fprintf(stdout, "\n[Embedded profile]\n"); + PrintProfileInformation(NULL, hProfile); + fflush(stdout); + } + + if (hProfile != NULL && SaveEmbedded != NULL) + SaveMemoryBlock(EmbedBuffer, EmbedLen, SaveEmbedded); + + if (hProfile) return hProfile; + } + + // Try to see if "colorimetric" tiff + + if (TIFFGetField(in, TIFFTAG_PRIMARYCHROMATICITIES, &chr)) { + + Primaries.Red.x = chr[0]; + Primaries.Red.y = chr[1]; + Primaries.Green.x = chr[2]; + Primaries.Green.y = chr[3]; + Primaries.Blue.x = chr[4]; + Primaries.Blue.y = chr[5]; + + Primaries.Red.Y = Primaries.Green.Y = Primaries.Blue.Y = 1.0; + + if (TIFFGetField(in, TIFFTAG_WHITEPOINT, &wp)) { + + WhitePoint.x = wp[0]; + WhitePoint.y = wp[1]; + WhitePoint.Y = 1.0; + + // Transferfunction is a bit harder.... + + TIFFGetFieldDefaulted(in, TIFFTAG_TRANSFERFUNCTION, + &gmr, + &gmg, + &gmb); + + Curve[0] = cmsBuildTabulatedToneCurve16(NULL, 256, gmr); + Curve[1] = cmsBuildTabulatedToneCurve16(NULL, 256, gmg); + Curve[2] = cmsBuildTabulatedToneCurve16(NULL, 256, gmb); + + hProfile = cmsCreateRGBProfileTHR(NULL, &WhitePoint, &Primaries, Curve); + + for (i=0; i < 3; i++) + cmsFreeToneCurve(NULL, Curve[i]); + + if (Verbose) { + fprintf(stdout, "\n[Colorimetric TIFF]\n"); + } + + + return hProfile; + } + } + + return NULL; +} + + +// Transform one image +static +int TransformImage(TIFF* in, TIFF* out, const char *cDefInpProf) +{ + cmsHPROFILE hIn, hOut, hProof, hInkLimit = NULL; + cmsHTRANSFORM xform; + cmsUInt32Number wInput, wOutput; + int OutputColorSpace; + int bps = Width / 8; + cmsUInt32Number dwFlags = 0; + int nPlanes; + + // Observer adaptation state (only meaningful on absolute colorimetric intent) + + cmsSetAdaptationState(ObserverAdaptationState); + + if (EmbedProfile && cOutProf) + DoEmbedProfile(out, cOutProf); + + if (BlackWhiteCompensation) + dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + + + switch (PrecalcMode) { + + case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break; + case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; + case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; + case 1: break; + + default: FatalError("Unknown precalculation mode '%d'", PrecalcMode); + } + + + if (GamutCheck) + dwFlags |= cmsFLAGS_GAMUTCHECK; + + hProof = NULL; + hOut = NULL; + + if (lIsDeviceLink) { + + hIn = cmsOpenProfileFromFile(cDefInpProf, "r"); + } + else { + + hIn = GetTIFFProfile(in); + + if (hIn == NULL) + hIn = OpenStockProfile(NULL, cDefInpProf); + + hOut = OpenStockProfile(NULL, cOutProf); + + if (cProofing != NULL) { + + hProof = OpenStockProfile(NULL, cProofing); + dwFlags |= cmsFLAGS_SOFTPROOFING; + } + } + + // Take input color space + + wInput = GetInputPixelType(in); + + // Assure both, input profile and input TIFF are on same colorspace + + if (_cmsLCMScolorSpace(NULL, cmsGetColorSpace(NULL, hIn)) != (int) T_COLORSPACE(wInput)) + FatalError("Input profile is not operating in proper color space"); + + + if (!lIsDeviceLink) + OutputColorSpace = _cmsLCMScolorSpace(NULL, cmsGetColorSpace(NULL, hOut)); + else + OutputColorSpace = _cmsLCMScolorSpace(NULL, cmsGetPCS(NULL, hIn)); + + wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, bps); + + WriteOutputTags(out, OutputColorSpace, bps); + CopyOtherTags(in, out); + + // Ink limit + if (InkLimit != 400.0 && + (OutputColorSpace == PT_CMYK || OutputColorSpace == PT_CMY)) { + + cmsHPROFILE hProfiles[10]; + int nProfiles = 0; + + + hInkLimit = cmsCreateInkLimitingDeviceLink(cmsGetColorSpace(NULL, hOut), InkLimit); + + hProfiles[nProfiles++] = hIn; + if (hProof) { + hProfiles[nProfiles++] = hProof; + hProfiles[nProfiles++] = hProof; + } + + hProfiles[nProfiles++] = hOut; + hProfiles[nProfiles++] = hInkLimit; + + xform = cmsCreateMultiprofileTransform(hProfiles, nProfiles, + wInput, wOutput, Intent, dwFlags); + + } + else { + + xform = cmsCreateProofingTransform(hIn, wInput, + hOut, wOutput, + hProof, Intent, + ProofingIntent, + dwFlags); + } + + cmsCloseProfile(NULL, hIn); + cmsCloseProfile(NULL, hOut); + + if (hInkLimit) + cmsCloseProfile(NULL, hInkLimit); + if (hProof) + cmsCloseProfile(NULL, hProof); + + if (xform == NULL) return 0; + + // Planar stuff + if (T_PLANAR(wInput)) + nPlanes = T_CHANNELS(wInput) + T_EXTRA(wInput); + else + nPlanes = 1; + + + // Handle tile by tile or strip by strip + if (TIFFIsTiled(in)) { + + TileBasedXform(xform, in, out, nPlanes); + } + else { + StripBasedXform(xform, in, out, nPlanes); + } + + + cmsDeleteTransform(NULL, xform); + + TIFFWriteDirectory(out); + + return 1; +} + + +// Print help +static +void Help(int level) +{ + fprintf(stderr, "little cms ICC profile applier for TIFF - v6.2 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0); + fflush(stderr); + + switch(level) { + + default: + case 0: + + fprintf(stderr, "usage: tificc [flags] input.tif output.tif\n"); + + fprintf(stderr, "\nflags:\n\n"); + fprintf(stderr, "%cv - Verbose\n", SW); + fprintf(stderr, "%ci<profile> - Input profile (defaults to sRGB)\n", SW); + fprintf(stderr, "%co<profile> - Output profile (defaults to sRGB)\n", SW); + fprintf(stderr, "%cl<profile> - Transform by device-link profile\n", SW); + + PrintRenderingIntents(); + + fprintf(stderr, "%cb - Black point compensation\n", SW); + fprintf(stderr, "%cd<0..1> - Observer adaptation state (abs.col. only)\n", SW); + + fprintf(stderr, "%cc<0,1,2,3> - Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes)\n", SW); + fprintf(stderr, "\n"); + + fprintf(stderr, "%cw<8,16,32> - Output depth. Use 32 for floating-point\n\n", SW); + fprintf(stderr, "%ca - Handle channels > 4 as alpha\n", SW); + + fprintf(stderr, "%cn - Ignore embedded profile on input\n", SW); + fprintf(stderr, "%ce - Embed destination profile\n", SW); + fprintf(stderr, "%cs<new profile> - Save embedded profile as <new profile>\n", SW); + fprintf(stderr, "\n"); + + + fprintf(stderr, "%cp<profile> - Soft proof profile\n", SW); + fprintf(stderr, "%cm<n> - Soft proof intent\n", SW); + fprintf(stderr, "%cg - Marks out-of-gamut colors on softproof\n", SW); + + fprintf(stderr, "\n"); + + fprintf(stderr, "%ck<0..400> - Ink-limiting in %% (CMYK only)\n", SW); + fprintf(stderr, "\n"); + fprintf(stderr, "%ch<0,1,2,3> - More help\n", SW); + break; + + case 1: + + fprintf(stderr, "Examples:\n\n" + "To color correct from scanner to sRGB:\n" + "\ttificc %ciscanner.icm in.tif out.tif\n" + "To convert from monitor1 to monitor2:\n" + "\ttificc %cimon1.icm %comon2.icm in.tif out.tif\n" + "To make a CMYK separation:\n" + "\ttificc %coprinter.icm inrgb.tif outcmyk.tif\n" + "To recover sRGB from a CMYK separation:\n" + "\ttificc %ciprinter.icm incmyk.tif outrgb.tif\n" + "To convert from CIELab TIFF to sRGB\n" + "\ttificc %ci*Lab in.tif out.tif\n\n", + SW, SW, SW, SW, SW, SW); + break; + + case 2: + PrintBuiltins(); + break; + + case 3: + + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "info@littlecms.com\n\n"); + + break; + } + + fflush(stderr); + exit(0); +} + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s=xgetopt(argc,argv,"aAeEbBw:W:nNvVGgh:H:i:I:o:O:P:p:t:T:c:C:l:L:M:m:K:k:S:s:D:d:")) != EOF) { + + switch (s) { + + case 'a': + case 'A': + StoreAsAlpha = TRUE; + break; + case 'b': + case 'B': + BlackWhiteCompensation = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 3) + FatalError("Unknown precalc mode '%d'", PrecalcMode); + break; + + case 'd': + case 'D': ObserverAdaptationState = atof(xoptarg); + if (ObserverAdaptationState < 0 || + ObserverAdaptationState > 1.0) + Warning("Adaptation state should be 0..1"); + break; + + case 'e': + case 'E': + EmbedProfile = TRUE; + break; + + case 'g': + case 'G': + GamutCheck = TRUE; + break; + + case 'v': + case 'V': + Verbose = TRUE; + break; + + case 'i': + case 'I': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + + cInpProf = xoptarg; + break; + + case 'o': + case 'O': + if (lIsDeviceLink) + FatalError("Device-link already specified"); + + cOutProf = xoptarg; + break; + + case 'l': + case 'L': + if (cInpProf != NULL || cOutProf != NULL) + FatalError("input/output profiles already specified"); + + cInpProf = xoptarg; + lIsDeviceLink = TRUE; + break; + + case 'p': + case 'P': + cProofing = xoptarg; + break; + + case 't': + case 'T': + Intent = atoi(xoptarg); + break; + + case 'm': + case 'M': + ProofingIntent = atoi(xoptarg); + break; + + case 'N': + case 'n': + IgnoreEmbedded = TRUE; + break; + + case 'W': + case 'w': + Width = atoi(xoptarg); + if (Width != 8 && Width != 16 && Width != 32) + FatalError("Only 8, 16 and 32 bps are supported"); + break; + + case 'k': + case 'K': + InkLimit = atof(xoptarg); + if (InkLimit < 0.0 || InkLimit > 400.0) + FatalError("Ink limit must be 0%%..400%%"); + break; + + + case 's': + case 'S': SaveEmbedded = xoptarg; + break; + + case 'H': + case 'h': { + + int a = atoi(xoptarg); + Help(a); + } + break; + + default: + + FatalError("Unknown option - run without args to see valid ones"); + } + + } +} + + +// The main sink + +int main(int argc, char* argv[]) +{ + TIFF *in, *out; + + cmsPlugin(&TiffLabPlugin); + + InitUtils("tificc"); + + HandleSwitches(argc, argv); + + if ((argc - xoptind) != 2) { + + Help(0); + } + + + TIFFSetErrorHandler(ConsoleErrorHandler); + TIFFSetWarningHandler(ConsoleWarningHandler); + + in = TIFFOpen(argv[xoptind], "r"); + if (in == NULL) FatalError("Unable to open '%s'", argv[xoptind]); + + out = TIFFOpen(argv[xoptind+1], "w"); + + if (out == NULL) { + + TIFFClose(in); + FatalError("Unable to write '%s'", argv[xoptind+1]); + } + + do { + + TransformImage(in, out, cInpProf); + + + } while (TIFFReadDirectory(in)); + + + if (Verbose) { fprintf(stdout, "\n"); fflush(stdout); } + + TIFFClose(in); + TIFFClose(out); + + return 0; +} + diff --git a/lcms2mt/utils/transicc/Makefile.am b/lcms2mt/utils/transicc/Makefile.am new file mode 100644 index 000000000..05e8b6936 --- /dev/null +++ b/lcms2mt/utils/transicc/Makefile.am @@ -0,0 +1,19 @@ +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies + +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +bin_PROGRAMS = transicc + +transicc_LDADD = $(top_builddir)/src/liblcms2.la +transicc_LDFLAGS = @LDFLAGS@ +transicc_SOURCES = transicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +transicc_MANS = transicc.1 + +EXTRA_DIST = $(man_MANS) diff --git a/lcms2mt/utils/transicc/Makefile.in b/lcms2mt/utils/transicc/Makefile.in new file mode 100644 index 000000000..ce93e538a --- /dev/null +++ b/lcms2mt/utils/transicc/Makefile.in @@ -0,0 +1,663 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building lcms sample programs +# Originally Written by Bob Friesenhahn, June 2003 +# Additions and bugs by Marti Maria + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = transicc$(EXEEXT) +subdir = utils/transicc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_transicc_OBJECTS = transicc.$(OBJEXT) ../common/xgetopt.$(OBJEXT) \ + ../common/vprf.$(OBJEXT) +transicc_OBJECTS = $(am_transicc_OBJECTS) +transicc_DEPENDENCIES = $(top_builddir)/src/liblcms2.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +transicc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(transicc_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(transicc_SOURCES) +DIST_SOURCES = $(transicc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign no-dependencies +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_srcdir)/utils/common -I$(top_builddir)/utils/common + +transicc_LDADD = $(top_builddir)/src/liblcms2.la +transicc_LDFLAGS = @LDFLAGS@ +transicc_SOURCES = transicc.c ../common/xgetopt.c ../common/vprf.c ../common/utils.h +transicc_MANS = transicc.1 +EXTRA_DIST = $(man_MANS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign utils/transicc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign utils/transicc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../common/$(am__dirstamp): + @$(MKDIR_P) ../common + @: > ../common/$(am__dirstamp) +../common/xgetopt.$(OBJEXT): ../common/$(am__dirstamp) +../common/vprf.$(OBJEXT): ../common/$(am__dirstamp) + +transicc$(EXEEXT): $(transicc_OBJECTS) $(transicc_DEPENDENCIES) $(EXTRA_transicc_DEPENDENCIES) + @rm -f transicc$(EXEEXT) + $(AM_V_CCLD)$(transicc_LINK) $(transicc_OBJECTS) $(transicc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../common/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../common/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lcms2mt/utils/transicc/transicc.1 b/lcms2mt/utils/transicc/transicc.1 new file mode 100644 index 000000000..0c50a9039 --- /dev/null +++ b/lcms2mt/utils/transicc/transicc.1 @@ -0,0 +1,90 @@ +.\"Shiju P. Nair September 30, 2004 +.\"Thomas Weber <tweber@debian.org> April 23, 2014 +.TH TRANSICC 1 "MAY 30, 2011" +.SH NAME +transicc - little cms ColorSpace conversion calculator. +.SH SYNOPSIS +.B transicc +.RI [ options ]\ [ CGATSINPUT ]\ [ CGATSOUTPUT ] +.SH DESCRIPTION +lcms is a standalone CMM engine, which deals with the color management. +It implements a fast transformation between ICC profiles. +.B transicc +is a lcms ColorSpace conversion calculator. +.SH OPTIONS +.TP +.B \-b +Black point compensation. +.TP +.BI \-c\ NUM +Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes) [defaults to 1]. +.TP +.BI \-d\ NUM +Observer adaptation state (abs.col. only), (0..1.0, float value) [defaults to 0.0]. +.TP +.B \-e +Encoded representation of numbers is not float (Option \fB\-w\fR=use 16 bits, Option \fB\-x\fR=hexadecimal). +.TP +.B \-g +Marks out-of-gamut colors on softproof. +.TP +.BI \-i\ profile +Input profile (defaults to sRGB). +.TP +.B \-l +Transform by device-link profile. +.TP +.BI \-m\ NUM +SoftProof intent (0,1,2,3) [defaults to 0]. +.TP +.B \-n +Terse output, intended for pipe usage. +.TP +.BI \-o\ profile +.p +Output profile (defaults to sRGB). +.TP +.B \-q +Quantize CGATS to 8 bits. +.TP +.BI \-s +Bounded mode. +.TP +.BI \-t\ NUM +Rendering intent +.nf +.RS +0=Perceptual [default] +1=Relative colorimetric +2=Saturation +3=Absolute colorimetric +10=Perceptual preserving black ink +11=Relative colorimetric preserving black ink +12=Saturation preserving black ink +13=Perceptual preserving black plane +14=Relative colorimetric preserving black plane +15=Saturation preserving black plane +.RE +.fi +.TP +.BI \-v\ verbosity +Verbosity level, (0=None, 1=Normal, 2=High, 3=Very High) [defaults to 1]. +.TP +.B \-w +Use 16 bits. +.TP +.B \-x +Hexadecimal. +.TP +You can use '*Lab' and '*xyz' as built-in profiles. +.SH NOTES +For suggestions, comments, bug reports etc. send mail to +info@littlecms.com. +.SH SEE ALSO +.BR jpgicc (1), +.BR linkicc (1), +.BR psicc (1), +.BR tificc (1) +.SH AUTHOR +This manual page was written by Shiju p. Nair <shiju.p@gmail.com>, +for the Debian project. diff --git a/lcms2mt/utils/transicc/transicc.c b/lcms2mt/utils/transicc/transicc.c new file mode 100644 index 000000000..bdb27e794 --- /dev/null +++ b/lcms2mt/utils/transicc/transicc.c @@ -0,0 +1,1317 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System +// Copyright (c) 1998-2017 Marti Maria Saguer +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +//--------------------------------------------------------------------------------- +// + +#include "utils.h" + +#ifndef _MSC_VER +# include <unistd.h> +#endif + +#ifdef CMS_IS_WINDOWS_ +# include <io.h> +#endif + +#define MAX_INPUT_BUFFER 4096 + +// Global options + +static cmsBool InHexa = FALSE; +static cmsBool GamutCheck = FALSE; +static cmsBool Width16 = FALSE; +static cmsBool BlackPointCompensation = FALSE; +static cmsBool lIsDeviceLink = FALSE; +static cmsBool lQuantize = FALSE; +static cmsBool lUnbounded = TRUE; +static cmsBool lIsFloat = TRUE; + +static cmsUInt32Number Intent = INTENT_PERCEPTUAL; +static cmsUInt32Number ProofingIntent = INTENT_PERCEPTUAL; + +static int PrecalcMode = 0; + +// -------------------------------------------------------------- + +static char *cInProf = NULL; +static char *cOutProf = NULL; +static char *cProofing = NULL; + +static char *IncludePart = NULL; + +static cmsHANDLE hIT8in = NULL; // CGATS input +static cmsHANDLE hIT8out = NULL; // CGATS output + +static char CGATSPatch[1024]; // Actual Patch Name +static char CGATSoutFilename[cmsMAX_PATH]; + +static int nMaxPatches; + +static cmsHTRANSFORM hTrans, hTransXYZ, hTransLab; +static cmsBool InputNamedColor = FALSE; + +static cmsColorSpaceSignature InputColorSpace, OutputColorSpace; + +static cmsNAMEDCOLORLIST* InputColorant = NULL; +static cmsNAMEDCOLORLIST* OutputColorant = NULL; + +static cmsFloat64Number InputRange, OutputRange; + + +// isatty replacement +#ifdef _MSC_VER +#define xisatty(x) _isatty( _fileno( (x) ) ) +#else +#define xisatty(x) isatty( fileno( (x) ) ) +#endif + +//--------------------------------------------------------------------------------------------------- + +// Print usage to stderr +static +void Help(void) +{ + + fprintf(stderr, "usage: transicc [flags] [CGATS input] [CGATS output]\n\n"); + + fprintf(stderr, "flags:\n\n"); + fprintf(stderr, "%cv<0..3> - Verbosity level\n", SW); + + fprintf(stderr, "%ce[op] - Encoded representation of numbers\n", SW); + fprintf(stderr, "\t%cw - use 16 bits\n", SW); + fprintf(stderr, "\t%cx - Hexadecimal\n\n", SW); + + fprintf(stderr, "%cs - bounded mode (clip negatives and highliths)\n", SW); + fprintf(stderr, "%cq - Quantize (round decimals)\n\n", SW); + + fprintf(stderr, "%ci<profile> - Input profile (defaults to sRGB)\n", SW); + fprintf(stderr, "%co<profile> - Output profile (defaults to sRGB)\n", SW); + fprintf(stderr, "%cl<profile> - Transform by device-link profile\n", SW); + + fprintf(stderr, "\nYou can use '*Lab', '*xyz' and others as built-in profiles\n\n"); + + PrintRenderingIntents(); + + fprintf(stderr, "\n"); + + fprintf(stderr, "%cd<0..1> - Observer adaptation state (abs.col. only)\n\n", SW); + + fprintf(stderr, "%cb - Black point compensation\n", SW); + + fprintf(stderr, "%cc<0,1,2,3> Precalculates transform (0=Off, 1=Normal, 2=Hi-res, 3=LoRes)\n\n", SW); + fprintf(stderr, "%cn - Terse output, intended for pipe usage\n", SW); + + fprintf(stderr, "%cp<profile> - Soft proof profile\n", SW); + fprintf(stderr, "%cm<0,1,2,3> - Soft proof intent\n", SW); + fprintf(stderr, "%cg - Marks out-of-gamut colors on softproof\n\n", SW); + + + + fprintf(stderr, "This program is intended to be a demo of the little cms\n" + "engine. Both lcms and this program are freeware. You can\n" + "obtain both in source code at http://www.littlecms.com\n" + "For suggestions, comments, bug reports etc. send mail to\n" + "info@littlecms.com\n\n"); +} + + + +// The toggles stuff + +static +void HandleSwitches(int argc, char *argv[]) +{ + int s; + + while ((s = xgetopt(argc, argv, + "bBC:c:d:D:eEgGI:i:L:l:m:M:nNO:o:p:P:QqSsT:t:V:v:WwxX!:")) != EOF) { + + switch (s){ + + case '!': + IncludePart = xoptarg; + break; + + case 'b': + case 'B': + BlackPointCompensation = TRUE; + break; + + case 'c': + case 'C': + PrecalcMode = atoi(xoptarg); + if (PrecalcMode < 0 || PrecalcMode > 3) + FatalError("Unknown precalc mode '%d'", PrecalcMode); + break; + + case 'd': + case 'D': { + cmsFloat64Number ObserverAdaptationState = atof(xoptarg); + if (ObserverAdaptationState < 0 || + ObserverAdaptationState > 1.0) + FatalError("Adaptation states should be between 0 and 1"); + + cmsSetAdaptationState(ObserverAdaptationState); + } + break; + + case 'e': + case 'E': + lIsFloat = FALSE; + break; + + case 'g': + case 'G': + GamutCheck = TRUE; + break; + + case 'i': + case 'I': + if (lIsDeviceLink) + FatalError("icctrans: Device-link already specified"); + + cInProf = xoptarg; + break; + + case 'l': + case 'L': + cInProf = xoptarg; + lIsDeviceLink = TRUE; + break; + + // No extra intents for proofing + case 'm': + case 'M': + ProofingIntent = atoi(xoptarg); + if (ProofingIntent > 3) + FatalError("Unknown Proofing Intent '%d'", ProofingIntent); + break; + + // For compatibility + case 'n': + case 'N': + Verbose = 0; + break; + + // Output profile + case 'o': + case 'O': + if (lIsDeviceLink) + FatalError("icctrans: Device-link already specified"); + cOutProf = xoptarg; + break; + + // Proofing profile + case 'p': + case 'P': + cProofing = xoptarg; + break; + + // Quantize (get rid of decimals) + case 'q': + case 'Q': + lQuantize = TRUE; + break; + + // Inhibit unbounded mode + case 's': + case 'S': + lUnbounded = FALSE; + break; + + // The intent + case 't': + case 'T': + Intent = atoi(xoptarg); + break; + + // Verbosity level + case 'V': + case 'v': + Verbose = atoi(xoptarg); + if (Verbose < 0 || Verbose > 3) { + FatalError("Unknown verbosity level '%d'", Verbose); + } + break; + + // Wide (16 bits) + case 'W': + case 'w': + Width16 = TRUE; + break; + + // Hexadecimal + case 'x': + case 'X': + InHexa = TRUE; + break; + + default: + FatalError("Unknown option - run without args to see valid ones.\n"); + } + } + + + // If output CGATS involved, switch to float + if ((argc - xoptind) > 2) { + lIsFloat = TRUE; + } +} + + + +static +void SetRange(cmsFloat64Number range, cmsBool IsInput) +{ + if (IsInput) + InputRange = range; + else + OutputRange = range; +} + +// Populate a named color list with usual component names. +// I am using the first Colorant channel to store the range, but it works since +// this space is not used anyway. +static +cmsNAMEDCOLORLIST* ComponentNames(cmsContext ContextID, cmsColorSpaceSignature space, cmsBool IsInput) +{ + cmsNAMEDCOLORLIST* out; + int i, n; + char Buffer[cmsMAX_PATH]; + + out = cmsAllocNamedColorList(0, 12, cmsMAXCHANNELS, "", ""); + if (out == NULL) return NULL; + + switch (space) { + + case cmsSigXYZData: + SetRange(100, IsInput); + cmsAppendNamedColor(ContextID, out, "X", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "Y", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "Z", NULL, NULL); + break; + + case cmsSigLabData: + SetRange(1, IsInput); + cmsAppendNamedColor(ContextID, out, "L*", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "a*", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "b*", NULL, NULL); + break; + + case cmsSigLuvData: + SetRange(1, IsInput); + cmsAppendNamedColor(ContextID, out, "L", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "u", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "v", NULL, NULL); + break; + + case cmsSigYCbCrData: + SetRange(255, IsInput); + cmsAppendNamedColor(ContextID, out, "Y", NULL, NULL ); + cmsAppendNamedColor(ContextID, out, "Cb", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "Cr", NULL, NULL); + break; + + + case cmsSigYxyData: + SetRange(1, IsInput); + cmsAppendNamedColor(ContextID, out, "Y", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "x", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "y", NULL, NULL); + break; + + case cmsSigRgbData: + SetRange(255, IsInput); + cmsAppendNamedColor(ContextID, out, "R", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "G", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "B", NULL, NULL); + break; + + case cmsSigGrayData: + SetRange(255, IsInput); + cmsAppendNamedColor(ContextID, out, "G", NULL, NULL); + break; + + case cmsSigHsvData: + SetRange(255, IsInput); + cmsAppendNamedColor(ContextID, out, "H", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "s", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "v", NULL, NULL); + break; + + case cmsSigHlsData: + SetRange(255, IsInput); + cmsAppendNamedColor(ContextID, out, "H", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "l", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "s", NULL, NULL); + break; + + case cmsSigCmykData: + SetRange(1, IsInput); + cmsAppendNamedColor(ContextID, out, "C", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "M", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "Y", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "K", NULL, NULL); + break; + + case cmsSigCmyData: + SetRange(1, IsInput); + cmsAppendNamedColor(ContextID, out, "C", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "M", NULL, NULL); + cmsAppendNamedColor(ContextID, out, "Y", NULL, NULL); + break; + + default: + + SetRange(1, IsInput); + + n = cmsChannelsOf(ContextID, space); + + for (i=0; i < n; i++) { + + sprintf(Buffer, "Channel #%d", i + 1); + cmsAppendNamedColor(ContextID, out, Buffer, NULL, NULL); + } + } + + return out; + +} + + +// Creates all needed color transforms +static +cmsBool OpenTransforms(cmsContext ContextID) +{ + cmsHPROFILE hInput, hOutput, hProof; + cmsUInt32Number dwIn, dwOut, dwFlags; + cmsNAMEDCOLORLIST* List; + int i; + + // We don't need cache + dwFlags = cmsFLAGS_NOCACHE; + + if (lIsDeviceLink) { + + hInput = OpenStockProfile(0, cInProf); + if (hInput == NULL) return FALSE; + hOutput = NULL; + hProof = NULL; + + if (cmsGetDeviceClass(ContextID, hInput) == cmsSigNamedColorClass) { + OutputColorSpace = cmsGetColorSpace(ContextID, hInput); + InputColorSpace = cmsGetPCS(ContextID, hInput); + } + else { + InputColorSpace = cmsGetColorSpace(ContextID, hInput); + OutputColorSpace = cmsGetPCS(ContextID, hInput); + } + + // Read colorant tables if present + if (cmsIsTag(ContextID, hInput, cmsSigColorantTableTag)) { + List = cmsReadTag(ContextID, hInput, cmsSigColorantTableTag); + InputColorant = cmsDupNamedColorList(ContextID, List); + InputRange = 1; + } + else InputColorant = ComponentNames(ContextID, InputColorSpace, TRUE); + + if (cmsIsTag(ContextID, hInput, cmsSigColorantTableOutTag)){ + + List = cmsReadTag(ContextID, hInput, cmsSigColorantTableOutTag); + OutputColorant = cmsDupNamedColorList(ContextID, List); + OutputRange = 1; + } + else OutputColorant = ComponentNames(ContextID, OutputColorSpace, FALSE); + + } + else { + + hInput = OpenStockProfile(0, cInProf); + if (hInput == NULL) return FALSE; + + hOutput = OpenStockProfile(0, cOutProf); + if (hOutput == NULL) return FALSE; + hProof = NULL; + + + if (cmsGetDeviceClass(ContextID, hInput) == cmsSigLinkClass || + cmsGetDeviceClass(ContextID, hOutput) == cmsSigLinkClass) + FatalError("Use %cl flag for devicelink profiles!\n", SW); + + + InputColorSpace = cmsGetColorSpace(ContextID, hInput); + OutputColorSpace = cmsGetColorSpace(ContextID, hOutput); + + // Read colorant tables if present + if (cmsIsTag(ContextID, hInput, cmsSigColorantTableTag)) { + List = cmsReadTag(ContextID, hInput, cmsSigColorantTableTag); + InputColorant = cmsDupNamedColorList(ContextID, List); + if (cmsNamedColorCount(ContextID, InputColorant) <= 3) + SetRange(255, TRUE); + else + SetRange(1, TRUE); // Inks are already divided by 100 in the formatter + + } + else InputColorant = ComponentNames(ContextID, InputColorSpace, TRUE); + + if (cmsIsTag(ContextID, hOutput, cmsSigColorantTableTag)){ + + List = cmsReadTag(ContextID, hOutput, cmsSigColorantTableTag); + OutputColorant = cmsDupNamedColorList(ContextID, List); + if (cmsNamedColorCount(ContextID, OutputColorant) <= 3) + SetRange(255, FALSE); + else + SetRange(1, FALSE); // Inks are already divided by 100 in the formatter + } + else OutputColorant = ComponentNames(ContextID, OutputColorSpace, FALSE); + + + if (cProofing != NULL) { + + hProof = OpenStockProfile(0, cProofing); + if (hProof == NULL) return FALSE; + dwFlags |= cmsFLAGS_SOFTPROOFING; + } + } + + // Print information on profiles + if (Verbose > 2) { + + printf("Profile:\n"); + PrintProfileInformation(ContextID, hInput); + + if (hOutput) { + + printf("Output profile:\n"); + PrintProfileInformation(ContextID, hOutput); + } + + if (hProof != NULL) { + printf("Proofing profile:\n"); + PrintProfileInformation(ContextID, hProof); + } + } + + + // Input is always in floating point + dwIn = cmsFormatterForColorspaceOfProfile(ContextID, hInput, 0, TRUE); + + if (lIsDeviceLink) { + + dwOut = cmsFormatterForPCSOfProfile(ContextID, hInput, lIsFloat ? 0 : 2, lIsFloat); + } + else { + + // 16 bits or floating point (only on output) + dwOut = cmsFormatterForColorspaceOfProfile(ContextID, hOutput, lIsFloat ? 0 : 2, lIsFloat); + } + + // For named color, there is a specialized formatter + if (cmsGetDeviceClass(ContextID, hInput) == cmsSigNamedColorClass) { + + dwIn = TYPE_NAMED_COLOR_INDEX; + InputNamedColor = TRUE; + } + + // Precision mode + switch (PrecalcMode) { + + case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break; + case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; + case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; + case 1: break; + + default: + FatalError("Unknown precalculation mode '%d'", PrecalcMode); + } + + + if (BlackPointCompensation) + dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + + + if (GamutCheck) { + + cmsUInt16Number Alarm[cmsMAXCHANNELS]; + + if (hProof == NULL) + FatalError("I need proofing profile -p for gamut checking!"); + + for (i=0; i < cmsMAXCHANNELS; i++) + Alarm[i] = 0xFFFF; + + cmsSetAlarmCodes(Alarm); + dwFlags |= cmsFLAGS_GAMUTCHECK; + } + + + // The main transform + hTrans = cmsCreateProofingTransform(hInput, dwIn, hOutput, dwOut, hProof, Intent, ProofingIntent, dwFlags); + + if (hProof) cmsCloseProfile(ContextID, hProof); + + if (hTrans == NULL) return FALSE; + + + // PCS Dump if requested + hTransXYZ = NULL; hTransLab = NULL; + + if (hOutput && Verbose > 1) { + + cmsHPROFILE hXYZ = cmsCreateXYZProfile(); + cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); + + hTransXYZ = cmsCreateTransform(hInput, dwIn, hXYZ, lIsFloat ? TYPE_XYZ_DBL : TYPE_XYZ_16, Intent, cmsFLAGS_NOCACHE); + if (hTransXYZ == NULL) return FALSE; + + hTransLab = cmsCreateTransform(hInput, dwIn, hLab, lIsFloat? TYPE_Lab_DBL : TYPE_Lab_16, Intent, cmsFLAGS_NOCACHE); + if (hTransLab == NULL) return FALSE; + + cmsCloseProfile(ContextID, hXYZ); + cmsCloseProfile(ContextID, hLab); + } + + if (hInput) cmsCloseProfile(ContextID, hInput); + if (hOutput) cmsCloseProfile(ContextID, hOutput); + + return TRUE; +} + + +// Free open resources +static +void CloseTransforms(cmsContext ContextID) +{ + if (InputColorant) cmsFreeNamedColorList(ContextID, InputColorant); + if (OutputColorant) cmsFreeNamedColorList(ContextID, OutputColorant); + + if (hTrans) cmsDeleteTransform(ContextID, hTrans); + if (hTransLab) cmsDeleteTransform(ContextID, hTransLab); + if (hTransXYZ) cmsDeleteTransform(ContextID, hTransXYZ); + +} + +// --------------------------------------------------------------------------------------------------- + +// Get input from user +static +void GetLine(cmsContext ContextID, char* Buffer, const char* frm, ...) +{ + int res; + va_list args; + + va_start(args, frm); + + do { + if (xisatty(stdin)) + vfprintf(stderr, frm, args); + + res = scanf("%4095s", Buffer); + + if (res < 0 || toupper(Buffer[0]) == 'Q') { // Quit? + + CloseTransforms(ContextID); + + if (xisatty(stdin)) + fprintf(stderr, "Done.\n"); + + exit(0); + } + } while (res == 0); + + va_end(args); +} + + +// Print a value which is given in double floating point +static +void PrintFloatResults(cmsContext ContextID, cmsFloat64Number Value[]) +{ + cmsUInt32Number i, n; + char ChannelName[cmsMAX_PATH]; + cmsFloat64Number v; + + n = cmsChannelsOf(ContextID, OutputColorSpace); + for (i=0; i < n; i++) { + + if (OutputColorant != NULL) { + + cmsNamedColorInfo(ContextID, OutputColorant, i, ChannelName, NULL, NULL, NULL, NULL); + } + else { + OutputRange = 1; + sprintf(ChannelName, "Channel #%u", i + 1); + } + + v = (cmsFloat64Number) Value[i]* OutputRange; + + if (lQuantize) + v = floor(v + 0.5); + + if (!lUnbounded) { + + if (v < 0) + v = 0; + if (v > OutputRange) + v = OutputRange; + } + + if (Verbose <= 0) + printf("%.4f ", v); + else + printf("%s=%.4f ", ChannelName, v); + } + + printf("\n"); +} + + +// Get a named-color index +static +cmsUInt16Number GetIndex(cmsContext ContextID) +{ + char Buffer[4096], Name[cmsMAX_PATH], Prefix[40], Suffix[40]; + int index, max; + const cmsNAMEDCOLORLIST* NamedColorList; + + NamedColorList = cmsGetNamedColorList(hTrans); + if (NamedColorList == NULL) return 0; + + max = cmsNamedColorCount(ContextID, NamedColorList)-1; + + GetLine(ContextID, Buffer, "Color index (0..%d)? ", max); + index = atoi(Buffer); + + if (index > max) + FatalError("Named color %d out of range!", index); + + cmsNamedColorInfo(ContextID, NamedColorList, index, Name, Prefix, Suffix, NULL, NULL); + + printf("\n%s %s %s\n", Prefix, Name, Suffix); + + return (cmsUInt16Number) index; +} + +// Read values from a text file or terminal +static +void TakeFloatValues(cmsContext ContextID, cmsFloat64Number Float[]) +{ + cmsUInt32Number i, n; + char ChannelName[cmsMAX_PATH]; + char Buffer[4096]; + + if (xisatty(stdin)) + fprintf(stderr, "\nEnter values, 'q' to quit\n"); + + if (InputNamedColor) { + + // This is named color index, which is always cmsUInt16Number + cmsUInt16Number index = GetIndex(ContextID); + memcpy(Float, &index, sizeof(cmsUInt16Number)); + return; + } + + n = cmsChannelsOf(ContextID, InputColorSpace); + for (i=0; i < n; i++) { + + if (InputColorant) { + cmsNamedColorInfo(ContextID, InputColorant, i, ChannelName, NULL, NULL, NULL, NULL); + } + else { + InputRange = 1; + sprintf(ChannelName, "Channel #%u", i+1); + } + + GetLine(ContextID, Buffer, "%s? ", ChannelName); + + Float[i] = (cmsFloat64Number) atof(Buffer) / InputRange; + } + + if (xisatty(stdin)) + fprintf(stderr, "\n"); +} + +static +void PrintPCSFloat(cmsContext ContextID, cmsFloat64Number Input[]) +{ + if (Verbose > 1 && hTransXYZ && hTransLab) { + + cmsCIEXYZ XYZ = { 0, 0, 0 }; + cmsCIELab Lab = { 0, 0, 0 }; + + if (hTransXYZ) cmsDoTransform(ContextID, hTransXYZ, Input, &XYZ, 1); + if (hTransLab) cmsDoTransform(ContextID, hTransLab, Input, &Lab, 1); + + printf("[PCS] Lab=(%.4f,%.4f,%.4f) XYZ=(%.4f,%.4f,%.4f)\n", Lab.L, Lab.a, Lab.b, + XYZ.X * 100.0, XYZ.Y * 100.0, XYZ.Z * 100.0); + + } +} + + + + +// ----------------------------------------------------------------------------------------------- + +static +void PrintEncodedResults(cmsContext ContextID, cmsUInt16Number Encoded[]) +{ + cmsUInt32Number i, n; + char ChannelName[cmsMAX_PATH]; + cmsUInt32Number v; + + n = cmsChannelsOf(ContextID, OutputColorSpace); + for (i=0; i < n; i++) { + + if (OutputColorant != NULL) { + + cmsNamedColorInfo(ContextID, OutputColorant, i, ChannelName, NULL, NULL, NULL, NULL); + } + else { + sprintf(ChannelName, "Channel #%u", i + 1); + } + + if (Verbose > 0) + printf("%s=", ChannelName); + + v = Encoded[i]; + + if (InHexa) { + + if (Width16) + printf("0x%04X ", (int) floor(v + .5)); + else + printf("0x%02X ", (int) floor(v / 257. + .5)); + + } else { + + if (Width16) + printf("%d ", (int) floor(v + .5)); + else + printf("%d ", (int) floor(v / 257. + .5)); + } + + } + + printf("\n"); +} + +// Print XYZ/Lab values on verbose mode + +static +void PrintPCSEncoded(cmsContext ContextID, cmsFloat64Number Input[]) +{ + if (Verbose > 1 && hTransXYZ && hTransLab) { + + cmsUInt16Number XYZ[3], Lab[3]; + + if (hTransXYZ) cmsDoTransform(ContextID, hTransXYZ, Input, XYZ, 1); + if (hTransLab) cmsDoTransform(ContextID, hTransLab, Input, Lab, 1); + + printf("[PCS] Lab=(0x%04X,0x%04X,0x%04X) XYZ=(0x%04X,0x%04X,0x%04X)\n", Lab[0], Lab[1], Lab[2], + XYZ[0], XYZ[1], XYZ[2]); + + } +} + + +// -------------------------------------------------------------------------------------- + + + +// Take a value from IT8 and scale it accordly to fill a cmsUInt16Number (0..FFFF) + +static +cmsFloat64Number GetIT8Val(cmsContext ContextID, const char* Name, cmsFloat64Number Max) +{ + const char* Val = cmsIT8GetData(ContextID, hIT8in, CGATSPatch, Name); + + if (Val == NULL) + FatalError("Field '%s' not found", Name); + + return atof(Val) / Max; + +} + + +// Read input values from CGATS file. + +static + void TakeCGATSValues(cmsContext ContextID, int nPatch, cmsFloat64Number Float[]) +{ + + // At first take the name if SAMPLE_ID is present + if (cmsIT8GetPatchName(ContextID, hIT8in, nPatch, CGATSPatch) == NULL) { + FatalError("Sorry, I need 'SAMPLE_ID' on input CGATS to operate."); + } + + + // Special handling for named color profiles. + // Lookup the name in the names database (the transform) + + if (InputNamedColor) { + + const cmsNAMEDCOLORLIST* NamedColorList; + int index; + + NamedColorList = cmsGetNamedColorList(hTrans); + if (NamedColorList == NULL) + FatalError("Malformed named color profile"); + + index = cmsNamedColorIndex(ContextID, NamedColorList, CGATSPatch); + if (index < 0) + FatalError("Named color '%s' not found in the profile", CGATSPatch); + + Float[0] = index; + return; + } + + // Color is not a spot color, proceed. + + switch (InputColorSpace) { + + // Encoding should follow CGATS specification. + + case cmsSigXYZData: + Float[0] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "XYZ_X") / 100.0; + Float[1] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "XYZ_Y") / 100.0; + Float[2] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "XYZ_Z") / 100.0; + break; + + case cmsSigLabData: + Float[0] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "LAB_L"); + Float[1] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "LAB_A"); + Float[2] = cmsIT8GetDataDbl(ContextID, hIT8in, CGATSPatch, "LAB_B"); + break; + + + case cmsSigRgbData: + Float[0] = GetIT8Val(ContextID, "RGB_R", 255.0); + Float[1] = GetIT8Val(ContextID, "RGB_G", 255.0); + Float[2] = GetIT8Val(ContextID, "RGB_B", 255.0); + break; + + case cmsSigGrayData: + Float[0] = GetIT8Val(ContextID, "GRAY", 255.0); + break; + + case cmsSigCmykData: + Float[0] = GetIT8Val(ContextID, "CMYK_C", 1.0); + Float[1] = GetIT8Val(ContextID, "CMYK_M", 1.0); + Float[2] = GetIT8Val(ContextID, "CMYK_Y", 1.0); + Float[3] = GetIT8Val(ContextID, "CMYK_K", 1.0); + break; + + case cmsSigCmyData: + Float[0] = GetIT8Val(ContextID, "CMY_C", 1.0); + Float[1] = GetIT8Val(ContextID, "CMY_M", 1.0); + Float[2] = GetIT8Val(ContextID, "CMY_Y", 1.0); + break; + + case cmsSig1colorData: + case cmsSig2colorData: + case cmsSig3colorData: + case cmsSig4colorData: + case cmsSig5colorData: + case cmsSig6colorData: + case cmsSig7colorData: + case cmsSig8colorData: + case cmsSig9colorData: + case cmsSig10colorData: + case cmsSig11colorData: + case cmsSig12colorData: + case cmsSig13colorData: + case cmsSig14colorData: + case cmsSig15colorData: + { + cmsUInt32Number i, n; + + n = cmsChannelsOf(ContextID, InputColorSpace); + for (i=0; i < n; i++) { + + char Buffer[255]; + + sprintf(Buffer, "%uCLR_%u", n, i+1); + Float[i] = GetIT8Val(ContextID, Buffer, 100.0); + } + + } + break; + + default: + { + cmsUInt32Number i, n; + + n = cmsChannelsOf(ContextID, InputColorSpace); + for (i=0; i < n; i++) { + + char Buffer[255]; + + sprintf(Buffer, "CHAN_%u", i+1); + Float[i] = GetIT8Val(ContextID, Buffer, 1.0); + } + + } + } + +} + +static +void SetCGATSfld(cmsContext ContextID, const char* Col, cmsFloat64Number Val) +{ + if (lQuantize) + Val = floor(Val + 0.5); + + if (!cmsIT8SetDataDbl(ContextID, hIT8out, CGATSPatch, Col, Val)) { + FatalError("couldn't set '%s' on output cgats '%s'", Col, CGATSoutFilename); + } +} + + + +static +void PutCGATSValues(cmsContext ContextID, cmsFloat64Number Float[]) +{ + cmsIT8SetData(ContextID, hIT8out, CGATSPatch, "SAMPLE_ID", CGATSPatch); + switch (OutputColorSpace) { + + + // Encoding should follow CGATS specification. + + case cmsSigXYZData: + + SetCGATSfld(ContextID, "XYZ_X", Float[0] * 100.0); + SetCGATSfld(ContextID, "XYZ_Y", Float[1] * 100.0); + SetCGATSfld(ContextID, "XYZ_Z", Float[2] * 100.0); + break; + + case cmsSigLabData: + + SetCGATSfld(ContextID, "LAB_L", Float[0]); + SetCGATSfld(ContextID, "LAB_A", Float[1]); + SetCGATSfld(ContextID, "LAB_B", Float[2]); + break; + + + case cmsSigRgbData: + SetCGATSfld(ContextID, "RGB_R", Float[0] * 255.0); + SetCGATSfld(ContextID, "RGB_G", Float[1] * 255.0); + SetCGATSfld(ContextID, "RGB_B", Float[2] * 255.0); + break; + + case cmsSigGrayData: + SetCGATSfld(ContextID, "GRAY", Float[0] * 255.0); + break; + + case cmsSigCmykData: + SetCGATSfld(ContextID, "CMYK_C", Float[0]); + SetCGATSfld(ContextID, "CMYK_M", Float[1]); + SetCGATSfld(ContextID, "CMYK_Y", Float[2]); + SetCGATSfld(ContextID, "CMYK_K", Float[3]); + break; + + case cmsSigCmyData: + SetCGATSfld(ContextID, "CMY_C", Float[0]); + SetCGATSfld(ContextID, "CMY_M", Float[1]); + SetCGATSfld(ContextID, "CMY_Y", Float[2]); + break; + + case cmsSig1colorData: + case cmsSig2colorData: + case cmsSig3colorData: + case cmsSig4colorData: + case cmsSig5colorData: + case cmsSig6colorData: + case cmsSig7colorData: + case cmsSig8colorData: + case cmsSig9colorData: + case cmsSig10colorData: + case cmsSig11colorData: + case cmsSig12colorData: + case cmsSig13colorData: + case cmsSig14colorData: + case cmsSig15colorData: + { + + cmsUInt32Number i, n; + + n = cmsChannelsOf(ContextID, InputColorSpace); + for (i=0; i < n; i++) { + + char Buffer[255]; + + sprintf(Buffer, "%uCLR_%u", n, i+1); + + SetCGATSfld(ContextID, Buffer, Float[i] * 100.0); + } + } + break; + + default: + { + + cmsUInt32Number i, n; + + n = cmsChannelsOf(ContextID, InputColorSpace); + for (i=0; i < n; i++) { + + char Buffer[255]; + + sprintf(Buffer, "CHAN_%u", i+1); + + SetCGATSfld(ContextID, Buffer, Float[i]); + } + } + } +} + + + +// Create data format +static +void SetOutputDataFormat(cmsContext ContextID) +{ + cmsIT8DefineDblFormat(ContextID, hIT8out, "%.4g"); + cmsIT8SetPropertyStr(ContextID, hIT8out, "ORIGINATOR", "icctrans"); + + if (IncludePart != NULL) + cmsIT8SetPropertyStr(ContextID, hIT8out, ".INCLUDE", IncludePart); + + cmsIT8SetComment(ContextID, hIT8out, "Data follows"); + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_SETS", nMaxPatches); + + + switch (OutputColorSpace) { + + + // Encoding should follow CGATS specification. + + case cmsSigXYZData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 4); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "XYZ_X"); + cmsIT8SetDataFormat(ContextID, hIT8out, 2, "XYZ_Y"); + cmsIT8SetDataFormat(ContextID, hIT8out, 3, "XYZ_Z"); + break; + + case cmsSigLabData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 4); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "LAB_L"); + cmsIT8SetDataFormat(ContextID, hIT8out, 2, "LAB_A"); + cmsIT8SetDataFormat(ContextID, hIT8out, 3, "LAB_B"); + break; + + + case cmsSigRgbData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 4); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "RGB_R"); + cmsIT8SetDataFormat(ContextID, hIT8out, 2, "RGB_G"); + cmsIT8SetDataFormat(ContextID, hIT8out, 3, "RGB_B"); + break; + + case cmsSigGrayData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 2); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "GRAY"); + break; + + case cmsSigCmykData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 5); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "CMYK_C"); + cmsIT8SetDataFormat(ContextID, hIT8out, 2, "CMYK_M"); + cmsIT8SetDataFormat(ContextID, hIT8out, 3, "CMYK_Y"); + cmsIT8SetDataFormat(ContextID, hIT8out, 4, "CMYK_K"); + break; + + case cmsSigCmyData: + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", 4); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + cmsIT8SetDataFormat(ContextID, hIT8out, 1, "CMY_C"); + cmsIT8SetDataFormat(ContextID, hIT8out, 2, "CMY_M"); + cmsIT8SetDataFormat(ContextID, hIT8out, 3, "CMY_Y"); + break; + + case cmsSig1colorData: + case cmsSig2colorData: + case cmsSig3colorData: + case cmsSig4colorData: + case cmsSig5colorData: + case cmsSig6colorData: + case cmsSig7colorData: + case cmsSig8colorData: + case cmsSig9colorData: + case cmsSig10colorData: + case cmsSig11colorData: + case cmsSig12colorData: + case cmsSig13colorData: + case cmsSig14colorData: + case cmsSig15colorData: + { + int i, n; + char Buffer[255]; + + n = cmsChannelsOf(ContextID, OutputColorSpace); + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", n+1); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + + for (i=1; i <= n; i++) { + sprintf(Buffer, "%dCLR_%d", n, i); + cmsIT8SetDataFormat(ContextID, hIT8out, i, Buffer); + } + } + break; + + default: { + + int i, n; + char Buffer[255]; + + n = cmsChannelsOf(ContextID, OutputColorSpace); + cmsIT8SetPropertyDbl(ContextID, hIT8out, "NUMBER_OF_FIELDS", n+1); + cmsIT8SetDataFormat(ContextID, hIT8out, 0, "SAMPLE_ID"); + + for (i=1; i <= n; i++) { + sprintf(Buffer, "CHAN_%d", i); + cmsIT8SetDataFormat(ContextID, hIT8out, i, Buffer); + } + } + } +} + +// Open CGATS if specified + +static +void OpenCGATSFiles(cmsContext ContextID, int argc, char *argv[]) +{ + int nParams = argc - xoptind; + + if (nParams >= 1) { + + hIT8in = cmsIT8LoadFromFile(0, argv[xoptind]); + + if (hIT8in == NULL) + FatalError("'%s' is not recognized as a CGATS file", argv[xoptind]); + + nMaxPatches = (int) cmsIT8GetPropertyDbl(ContextID, hIT8in, "NUMBER_OF_SETS"); + } + + if (nParams == 2) { + + hIT8out = cmsIT8Alloc(NULL); + SetOutputDataFormat(ContextID); + strncpy(CGATSoutFilename, argv[xoptind+1], cmsMAX_PATH-1); + } + + if (nParams > 2) FatalError("Too many CGATS files"); +} + + + +// The main sink +int main(int argc, char *argv[]) +{ + cmsUInt16Number Output[cmsMAXCHANNELS]; + cmsFloat64Number OutputFloat[cmsMAXCHANNELS]; + cmsFloat64Number InputFloat[cmsMAXCHANNELS]; + cmsContext ContextID = NULL; + + int nPatch = 0; + + fprintf(stderr, "LittleCMS ColorSpace conversion calculator - 4.3 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0); + + InitUtils("transicc"); + + Verbose = 1; + + if (argc == 1) { + + Help(); + return 0; + } + + HandleSwitches(argc, argv); + + // Open profiles, create transforms + if (!OpenTransforms(ContextID)) return 1; + + // Open CGATS input if specified + OpenCGATSFiles(ContextID, argc, argv); + + // Main loop: read all values and convert them + for(;;) { + + if (hIT8in != NULL) { + + if (nPatch >= nMaxPatches) break; + TakeCGATSValues(ContextID, nPatch++, InputFloat); + + } else { + + if (feof(stdin)) break; + TakeFloatValues(ContextID, InputFloat); + + } + + if (lIsFloat) + cmsDoTransform(ContextID, hTrans, InputFloat, OutputFloat, 1); + else + cmsDoTransform(ContextID, hTrans, InputFloat, Output, 1); + + + if (hIT8out != NULL) { + + PutCGATSValues(ContextID, OutputFloat); + } + else { + + if (lIsFloat) { + PrintFloatResults(ContextID, OutputFloat); PrintPCSFloat(ContextID, InputFloat); + } + else { + PrintEncodedResults(ContextID, Output); PrintPCSEncoded(ContextID, InputFloat); + } + + } + } + + + // Cleanup + CloseTransforms(ContextID); + + if (hIT8in) + cmsIT8Free(ContextID, hIT8in); + + if (hIT8out) { + cmsIT8SaveToFile(ContextID, hIT8out, CGATSoutFilename); + cmsIT8Free(ContextID, hIT8out); + } + + // All is ok + return 0; +} + + |