Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
iccApplyToLink.cpp File Reference
#include <stdio.h>
#include <string>
#include "IccCmm.h"
#include "IccUtil.h"
#include "IccDefs.h"
#include "IccApplyBPC.h"
#include "IccEnvVar.h"
#include "IccProfLibVer.h"
#include "IccProfile.h"
#include "IccTagBasic.h"
#include "IccTagLut.h"
#include "IccTagMPE.h"
#include "IccMpeBasic.h"
+ Include dependency graph for iccApplyToLink.cpp:

Go to the source code of this file.

Classes

class  CCubeWriter
 
class  CDevLinkWriter
 
class  ILinkWriter
 

Typedefs

typedef std::list< CIccProfile * > IccProfilePtrList
 
typedef std::shared_ptr< ILinkWriterLinkWriterPtr
 

Functions

int main (int argc, icChar *argv[])
 
void Usage ()
 

Typedef Documentation

◆ IccProfilePtrList

typedef std::list<CIccProfile*> IccProfilePtrList

Definition at line 576 of file iccApplyToLink.cpp.

◆ LinkWriterPtr

typedef std::shared_ptr<ILinkWriter> LinkWriterPtr

Definition at line 113 of file iccApplyToLink.cpp.

Function Documentation

◆ main()

int main ( int argc,
icChar * argv[] )

Definition at line 639 of file iccApplyToLink.cpp.

640{
641 int minargs = 10; // minimum number of arguments
642 if(argc<minargs) {
643 Usage();
644 return -1;
645 }
646
647 int nNumProfiles, temp;
648 temp = argc - minargs;
649
650 //remaining arguments must be in pairs
651 if(temp%2 != 0) {
652 printf("\nMissing arguments!\n");
653 Usage();
654 return -1;
655 }
656
657 nNumProfiles = temp/2;
658
659 ILinkWriter* pLinkWriter;
660 if (atoi(argv[2])) {
661 pLinkWriter = new CCubeWriter();
662 }
663 else {
664 pLinkWriter = new CDevLinkWriter();
665 }
666
667 if (!pLinkWriter) {
668 printf("Unable to allocate writer\n");
669 return -1;
670 }
671
672 LinkWriterPtr pWriter(pLinkWriter);
673
674 pWriter->setFile(argv[1]);
675
676 int nLutSize = atoi(argv[3]);
677 pWriter->setLutSize(nLutSize);
678
679 pWriter->setOption(atoi(argv[4]));
680
681 pWriter->setTitle(argv[5]);
682
683 icFloatNumber loRange = (icFloatNumber)atof(argv[6]);
684 icFloatNumber hiRange = (icFloatNumber)atof(argv[7]);
685 icFloatNumber sizeRange = hiRange - loRange;
686 pWriter->setInputRange(loRange, hiRange);
687
688 //Retrieve command line arguments
689 bool bFirstTransform = atoi(argv[8]) != 0;
690 icXformInterp nInterp = (icXformInterp)atoi(argv[9]);
691
692 int nIntent, nType, nLuminance;
693
694 //Allocate a CIccCmm to use to apply profiles.
695 //Let profiles determine starting and ending color spaces.
696 //Third argument indicates that Input transform from first profile should be used.
697 CIccCmm theCmm(icSigUnknownData, icSigUnknownData, bFirstTransform);
698
699 //PCC profiles need to stay around until the CMM has been completely initialized to apply transforms.
700 //TheCmm doesn't own them so keep a list so they can be released when they aren't needed any more.
701 IccProfilePtrList pccList;
702
703 int i, nCount;
704 bool bUseD2BxB2DxTags;
705 icStatusCMM stat; //status variable for CMM operations
706 icCmmEnvSigMap sigMap; //Keep track of CMM Environment for each profile
707 bool bUseSubProfile;
708
709 //Remaining arguments define a sequence of profiles to be applied.
710 //Add them to theCmm one at a time providing CMM environment variables and PCC overrides as provided.
711 for(i = 0, nCount=minargs; i<nNumProfiles; i++, nCount+=2) {
712#if defined(_WIN32) || defined(_WIN64)
713 if (!strnicmp(argv[nCount], "-ENV:", 5)) { //check for -ENV: to allow for CMM Environment variables to be defined for next transform
714#else
715 if (!strncasecmp(argv[nCount], "-ENV:", 5)) {
716#endif
717 icSignature sig = icGetSigVal(argv[nCount]+5);
718 icFloatNumber val = (icFloatNumber)atof(argv[nCount+1]);
719
720 sigMap[sig]=val;
721 }
722 else if (stricmp(argv[nCount], "-PCC")) { //Attach profile while ignoring -PCC (this are handled below as profiles are attached)
723 bUseD2BxB2DxTags = true;
724 nIntent = atoi(argv[nCount+1]);
725 bUseSubProfile = (nIntent / 1000) > 0;
726 nIntent = nIntent % 1000;
727 nLuminance = nIntent / 100;
728 nIntent = nIntent % 100;
729 nType = abs(nIntent) / 10;
730 nIntent = nIntent % 10;
731 CIccProfile *pPccProfile = NULL;
732
733 //Adjust type and hint information based on rendering intent
734 CIccCreateXformHintManager Hint;
735 switch(nType) {
736 case 1:
737 nType = 0;
738 bUseD2BxB2DxTags = false;
739 break;
740 case 4:
741 nType = 0;
742 Hint.AddHint(new CIccApplyBPCHint());
743 break;
744 }
745
746 if (nLuminance) {
747 Hint.AddHint(new CIccLuminanceMatchingHint());
748 }
749
750 // Use of following -PCC arg allows for profile connection conditions to be defined
751 if (i+1<nNumProfiles && !stricmp(argv[nCount+2], "-PCC")) {
752 pPccProfile = OpenIccProfile(argv[nCount+3]);
753 if (!pPccProfile) {
754 printf("Unable to open Profile Connections Conditions from '%s'\n", argv[nCount+3]);
755 return -1;
756 }
757 //Keep track of pPccProfile for until after cmm.Begin is called
758 pccList.push_back(pPccProfile);
759 }
760
761
762 //CMM Environment variables are passed in as a Hint to the Xform associated with the profile
763 if (sigMap.size()>0) {
764 Hint.AddHint(new CIccCmmEnvVarHint(sigMap));
765 }
766
767 //Read profile from path and add it to theCmm
768 CIccProfile* pXformProfile = ReadIccProfile(argv[nCount], bUseSubProfile); //We need all tags in profile for providing information to link
769 stat = theCmm.AddXform(pXformProfile, nIntent<0 ? icUnknownIntent : (icRenderingIntent)nIntent, nInterp, pPccProfile,
770 (icXformLutType)nType, bUseD2BxB2DxTags, &Hint);
771 if (stat) {
772 printf("Invalid Profile(%d): %s\n", stat, argv[nCount]);
773 return -1;
774 }
775 sigMap.clear();
776
777 }
778 }
779
780 //All profiles have been added to CMM. Tell CMM that we are ready to begin applying colors/pixels
781 if((stat=theCmm.Begin())) {
782 printf("Error %d - Unable to begin profile application - Possibly invalid or incompatible profiles\n", stat);
783 return -1;
784 }
785
786 pWriter->setCmm(&theCmm);
787
788 //Now we can release the pccProfile nodes.
789 IccProfilePtrList::iterator pcc;
790 for (pcc=pccList.begin(); pcc!=pccList.end(); pcc++) {
791 CIccProfile *pPccProfile = *pcc;
792 delete pPccProfile;
793 }
794 pccList.clear();
795
796 if (!pWriter->begin(theCmm.GetSourceSpace(), theCmm.GetDestSpace())) {
797 printf("Unable to begin writing LUT\n");
798 return -1;
799 }
800
801 //Get and validate the source color space from the Cmm.
802 icColorSpaceSignature SrcspaceSig = theCmm.GetSourceSpace();
803 int nSrcSamples = icGetSpaceSamples(SrcspaceSig);
804
805 //Get and validate the destination color space from theCmm.
806 icColorSpaceSignature DestspaceSig = theCmm.GetDestSpace();
807 int nDestSamples = icGetSpaceSamples(DestspaceSig);
808
809 int* idx = new int[nSrcSamples];
810 icFloatNumber* srcPixel = new icFloatNumber[nSrcSamples];
811 icFloatNumber* dstPixel = new icFloatNumber[nDestSamples];
812
813 icUInt32Number maxLut = nLutSize - 1;
814
815 int curPer, lastPer = -1;
816
817 //init idx;
818 int lutCount = 1;
819 for (auto i = 0; i < nSrcSamples; i++) {
820 idx[i] = 0;
821 lutCount *= nLutSize;
822 }
823
824 int j = 0;
825 for (int c = 0; j >= 0; c++) {
826
827 for (auto i = 0; i < nSrcSamples; i++) {
828 srcPixel[i] = sizeRange * (icFloatNumber)idx[i] / maxLut + loRange;
829 }
830
831 //Use CMM to convert SrcPixel to DestPixel
832 theCmm.Apply(dstPixel, srcPixel);
833
834 pWriter->setNextNode(dstPixel);
835
836 for (j = nSrcSamples - 1; j >= 0;) {
837 idx[j]++;
838 if (idx[j] >= nLutSize) {
839 idx[j] = 0;
840 j--;
841 }
842 else
843 break;
844 }
845
846 //Display status of how much we have accomplished
847 curPer = (int)((float)(c + 1) * 100.0f / (float)lutCount);
848 if (curPer != lastPer) {
849 printf("\r%d%%", curPer);
850 lastPer = curPer;
851 }
852 }
853
854 delete[] dstPixel;
855 delete[] srcPixel;
856 delete[] idx;
857
858 if (pWriter->finish()) {
859 printf("\nLUT successfully written to '%s'\n", argv[1]);
860 }
861 else {
862 printf("\nUnable to write LUT to '%s'\n", argv[1]);
863 }
864
865 return 0;
866}
icArraySignature sig
icXformLutType
CMM Xform LUT types.
Definition IccCmm.h:125
icXformInterp
CMM Interpolation types.
Definition IccCmm.h:113
icStatusCMM
CMM return status values.
Definition IccCmm.h:90
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
std::map< icSignature, icFloatNumber > icCmmEnvSigMap
Definition IccEnvVar.h:83
#define strnicmp
#define stricmp
CIccProfile * ReadIccProfile(const icChar *szFilename, bool bUseSubProfile)
Name: ReadIccProfile.
CIccProfile * OpenIccProfile(const icChar *szFilename, bool bUseSubProfile)
Name: OpenIccProfile.
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
icUInt32Number icGetSigVal(const icChar *pBuf)
Definition IccUtil.cpp:1258
unsigned int icUInt32Number
Type: Class.
Definition IccApplyBPC.h:89
#define icUnknownIntent
Convenience Enum Definitions - Not defined in ICC specification.
icColorSpaceSignature
Color Space Signatures.
icUInt32Number icSignature
#define icSigUnknownData
icRenderingIntent
Rendering Intents, used in the profile header.
std::list< CIccProfile * > IccProfilePtrList

References icGetSigVal(), icGetSpaceSamples(), icSigUnknownData, icUnknownIntent, OpenIccProfile(), ReadIccProfile(), sig, stricmp, strnicmp, and Usage().

+ Here is the call graph for this function:

◆ Usage()

void Usage ( )

Definition at line 579 of file iccApplyToLink.cpp.

580{
581 printf("iccApplyToLink built with IccProfLib version " ICCPROFLIBVER "\n\n");
582
583 printf("Usage: iccApplyToLink dst_link_file link_type lut_size option title range_min range_max first_transform interp {{-ENV:sig value} profile_file_path rendering_intent {-PCC connection_conditions_path}}\n\n");
584 printf(" dst_link_file is path of file to create\n\n");
585
586 printf(" For link_type:\n");
587 printf(" 0 - Device Link\n");
588 printf(" 1 - .cube text file\n\n");
589
590 printf(" Where lut_size represents the number of grid entries for each lut dimension.\n\n");
591
592 printf(" For option when link_type is 0:\n");
593 printf(" option represents the digits of precision for lut for .cube files\n");
594 printf(" For option when link_type is 1:\n");
595 printf(" 0 - version 4 profile with 16-bit table\n");
596 printf(" 1 - version 5 profile\n\n");
597
598 printf(" title is the title/description for the dest_link_file\n\n");
599
600 printf(" range_min specifies the minimum input value (usually 0.0)\n");
601 printf(" range_max specifies the maximum input value (usually 1.0)\n\n");
602
603 printf(" For first_transform:\n");
604 printf(" 0 - use source transform from first profile\n");
605 printf(" 1 - use destination transform from first profile\n\n");
606
607 printf(" For interp:\n");
608 printf(" 0 - linear interpolation\n");
609 printf(" 1 - tetrahedral interpolation\n\n");
610
611 printf(" For rendering_intent:\n");
612 printf(" 0 - Perceptual\n");
613 printf(" 1 - Relative\n");
614 printf(" 2 - Saturation\n");
615 printf(" 3 - Absolute\n");
616 printf(" 10 - Perceptual without D2Bx/B2Dx\n");
617 printf(" 11 - Relative without D2Bx/B2Dx\n");
618 printf(" 12 - Saturation without D2Bx/B2Dx\n");
619 printf(" 13 - Absolute without D2Bx/B2Dx\n");
620 printf(" 20 - Preview Perceptual\n");
621 printf(" 21 - Preview Relative\n");
622 printf(" 22 - Preview Saturation\n");
623 printf(" 23 - Preview Absolute\n");
624 printf(" 30 - Gamut\n");
625 printf(" 33 - Gamut Absolute\n");
626 printf(" 40 - Perceptual with BPC\n");
627 printf(" 41 - Relative Colorimetric with BPC\n");
628 printf(" 42 - Saturation with BPC\n");
629 printf(" 50 - BDRF Parameters\n");
630 printf(" 60 - BDRF Direct\n");
631 printf(" 70 - BDRF MCS Parameters\n");
632 printf(" 80 - MCS connection\n");
633 printf(" +100 - Use Luminance based PCS adjustment\n");
634 printf(" +1000 - Use V5 sub-profile if present\n");
635}
#define ICCPROFLIBVER

References ICCPROFLIBVER.

Referenced by main().

+ Here is the caller graph for this function: