Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
CIccMpeXmlCalculator Class Reference

#include <IccMpeXml.h>

+ Inheritance diagram for CIccMpeXmlCalculator:
+ Collaboration diagram for CIccMpeXmlCalculator:

Public Member Functions

 CIccMpeXmlCalculator ()
 
virtual const char * GetClassName () const
 
virtual IIccExtensionMpeGetExtension ()
 
bool ParseImport (xmlNode *pNode, std::string importPath, std::string &parseStr)
 
virtual bool ParseXml (xmlNode *pNode, std::string &parseStr)
 
virtual bool ToXml (std::string &xml, std::string blanks="")
 
virtual ~CIccMpeXmlCalculator ()
 
- Public Member Functions inherited from CIccMpeCalculator
virtual void Apply (CIccApplyMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
 Name: CIccMpeCalculator::Apply.
 
virtual bool Begin (icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
 Name: CIccMpeCalculator::Begin.
 
 CIccMpeCalculator (const CIccMpeCalculator &curveSet)
 Name: CIccMpeCalculator::CIccMpeCalculator.
 
 CIccMpeCalculator (icUInt16Number nInputChannels=0, icUInt16Number nOutputChannels=0)
 Name: CIccMpeCalculator::CIccMpeCalculator.
 
virtual void Describe (std::string &sDescription, int nVerboseness)
 Name: CIccMpeCalculator::Describe.
 
CIccMultiProcessElementGetElem (icSigCalcOp op, icUInt16Number index)
 Name: CIccMpeCalculator::GetSubApply.
 
virtual CIccApplyMpeGetNewApply (CIccApplyTagMpe *pApplyTag)
 Name: CIccMpeCalculator::Begin.
 
virtual icElemTypeSignature GetType () const
 
virtual bool IsLateBinding () const
 Name: CIccMpeCalculator::IsLateBinding.
 
virtual bool IsLateBindingReflectance () const
 Name: CIccMpeCalculator::IsLateBindingReflectance.
 
virtual CIccMpeCalculatorNewCopy () const
 
CIccMpeCalculatoroperator= (const CIccMpeCalculator &curveSet)
 Name: &CIccMpeCalculator::operator=.
 
virtual bool Read (icUInt32Number size, CIccIO *pIO)
 Name: CIccMpeCalculator::Read.
 
void Reset ()
 
icFuncParseStatus SetCalcFunc (const char *szFuncDef, std::string &sReport)
 Name: CIccMpeCalculator::SetCalcFunc.
 
icFuncParseStatus SetCalcFunc (icCalculatorFuncPtr newFunc)
 Name: CIccMpeCalculator::SetCalcFunc.
 
void SetSize (icUInt16Number nInputChannels, icUInt16Number nOutputChannels)
 Name: CIccMpeCalculator::SetSize.
 
bool SetSubElem (icUInt32Number idx, CIccMultiProcessElement *pElem)
 
virtual icValidateStatus Validate (std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
 Name: CIccMpeCalculator::Validate.
 
virtual bool Write (CIccIO *pIO)
 Name: CIccMpeCalculator::Write.
 
virtual ~CIccMpeCalculator ()
 Name: CIccMpeCalculator::~CIccMpeCalculator.
 
- Public Member Functions inherited from CIccMultiProcessElement
 CIccMultiProcessElement ()
 
virtual icAcsSignature GetBAcsSig ()
 
virtual icAcsSignature GetEAcsSig ()
 
virtual bool IsAcs ()
 
virtual bool IsSupported ()
 
virtual icUInt16Number NumInputChannels () const
 
virtual icUInt16Number NumOutputChannels () const
 
virtual ~CIccMultiProcessElement ()
 
- Public Member Functions inherited from CIccMpeXml
virtual const char * GetExtClassName ()
 
virtual ~CIccMpeXml (void)
 

Protected Member Functions

void clean ()
 
bool Flatten (std::string &flatStr, std::string macroName, const char *szFunc, std::string &parseStr, icUInt32Number nLocalsOffset=0)
 
bool ParseChanMap (ChanVarMap &chanMap, const char *szNames, int nChannels)
 
bool UpdateLocals (std::string &func, std::string szFunc, std::string &parseStr, int nLocalsOffset)
 
bool ValidateMacroCalls (std::string &parseStr) const
 
bool ValidMacroCalls (const char *szMacroText, std::string macroStack, std::string &parseStr) const
 
- Protected Member Functions inherited from CIccMpeCalculator
bool SetElem (icUInt32Number idx, CIccMultiProcessElement *pElem, icUInt32Number &count, CIccMultiProcessElement ***pArray)
 Name: CIccMpeCalculator::GetSubApply.
 

Static Protected Member Functions

static bool validName (const char *saName)
 
static bool validNameChar (char c, bool bFirst)
 

Protected Attributes

TempDeclVarMap m_declVarMap
 
ChanVarMap m_inputMap
 
TempDeclVarMap m_macroLocalMap
 
MacroMap m_macroMap
 
MpePtrList m_mpeList
 
MpePtrMap m_mpeMap
 
int m_nNextMpe
 
int m_nNextVar
 
ChanVarMap m_outputMap
 
std::string m_sImport
 
TempVarMap m_varMap
 
- Protected Attributes inherited from CIccMpeCalculator
bool m_bNeedTempReset
 
icCalculatorFuncPtr m_calcFunc
 
icUInt32Number m_nSubElem
 
icUInt32Number m_nTempChannels
 
IIccCmmEnvVarLookupm_pCmmEnvVarLookup
 
CIccMultiProcessElement ** m_SubElem
 
- Protected Attributes inherited from CIccMultiProcessElement
icUInt16Number m_nInputChannels
 
icUInt16Number m_nOutputChannels
 

Additional Inherited Members

- Static Public Member Functions inherited from CIccMultiProcessElement
static CIccMultiProcessElementCreate (icElemTypeSignature sig)
 Name: CIccMultiProcessElement::Create.
 
- Public Attributes inherited from CIccMultiProcessElement
icUInt32Number m_nReserved
 

Detailed Description

Definition at line 301 of file IccMpeXml.h.

Constructor & Destructor Documentation

◆ CIccMpeXmlCalculator()

CIccMpeXmlCalculator::CIccMpeXmlCalculator ( )
inline

Definition at line 304 of file IccMpeXml.h.

304{ m_sImport = "*"; }
std::string m_sImport
Definition IccMpeXml.h:329

References m_sImport.

◆ ~CIccMpeXmlCalculator()

virtual CIccMpeXmlCalculator::~CIccMpeXmlCalculator ( )
inlinevirtual

Definition at line 305 of file IccMpeXml.h.

305{ clean(); }

References clean().

+ Here is the call graph for this function:

Member Function Documentation

◆ clean()

void CIccMpeXmlCalculator::clean ( )
protected

Definition at line 3000 of file IccMpeXml.cpp.

3001{
3002 m_sImport = "*";
3003 m_declVarMap.clear();
3004 m_varMap.clear();
3005 m_macroMap.clear();
3006
3007 MpePtrList::iterator ml;
3008 for (ml = m_mpeList.begin(); ml != m_mpeList.end(); ml++) {
3009 if (ml->m_ptr)
3010 delete ml->m_ptr;
3011 }
3012 m_mpeList.clear();
3013
3014 MpePtrMap::iterator mm;
3015 for (mm = m_mpeMap.begin(); mm != m_mpeMap.end(); mm++) {
3016 if (mm->second.m_ptr)
3017 delete mm->second.m_ptr;
3018 }
3019 m_mpeMap.clear();
3020 m_nNextVar = 0;
3021 m_nNextMpe = 0;
3022}
TempDeclVarMap m_declVarMap
Definition IccMpeXml.h:331
TempVarMap m_varMap
Definition IccMpeXml.h:333
MpePtrList m_mpeList
Definition IccMpeXml.h:337

Referenced by ~CIccMpeXmlCalculator().

+ Here is the caller graph for this function:

◆ Flatten()

bool CIccMpeXmlCalculator::Flatten ( std::string & flatStr,
std::string macroName,
const char * szFunc,
std::string & parseStr,
icUInt32Number nLocalsOffset = 0 )
protected

Definition at line 2654 of file IccMpeXml.cpp.

2655{
2656 CIccFuncTokenizer parse(szFunc, true);
2657
2658 while (parse.GetNext()) {
2659 std::string token = parse.GetLast();
2660 const char *tok = token.c_str();
2661 if (!strncmp(tok, "call{", 5) ||
2662 tok[0] == '#') {
2663 std::string nameiter;
2664 std::string name;
2665
2666 if (tok[0] == '#')
2667 nameiter = token.substr(1);
2668 else
2669 nameiter = parse.GetReference();
2670
2671 const char *ptr;
2672 for (ptr = nameiter.c_str(); *ptr && *ptr != '[' && *ptr != '('; ptr++) name += *ptr;
2673 int iter = 1;
2674// if (*ptr) {
2675// iter = atoi(ptr + 1);
2676// if (iter < 1)
2677// iter = 1;
2678// else if (iter>1024)
2679// iter = 1024;
2680// }
2681
2682 MacroMap::iterator m = m_macroMap.find(name.c_str());
2683 if (m != m_macroMap.end()) {
2684 icUInt16Number nLocalsSize = 0;
2685 TempDeclVarMap::iterator locals = m_macroLocalMap.find(macroName);
2686 if (locals != m_macroLocalMap.end()) {
2687 nLocalsSize = locals->second.m_size;
2688 }
2689
2690 int i;
2691 for (i = 0; i < iter; i++) {
2692 Flatten(flatStr, name, m->second.c_str(), parseStr, nLocalsOffset+nLocalsSize);
2693 }
2694 }
2695 else {
2696 parseStr += "Call to undefined macro '" + name + "'\n";
2697 return false;
2698 }
2699 }
2700 else if (!strncmp(tok, "in{", 3) ||
2701 !strncmp(tok, "out{", 4)) {
2702 std::string op = parse.GetName();
2703 std::string ref = parse.GetReference();
2704 std::string refroot;
2705 for (const char *ptr = ref.c_str(); *ptr && *ptr != ',' && *ptr != '(' && *ptr != '['; ptr++) refroot += *ptr;
2706
2707 ChanVarMap *pMap;
2708 int nChan;
2709 if (op == "in") {
2710 pMap = &m_inputMap;
2711 nChan = m_nInputChannels;
2712 }
2713 else {
2714 pMap = &m_outputMap;
2715 nChan = m_nOutputChannels;
2716 }
2717
2718 ChanVarMap::iterator ci = pMap->find(refroot);
2719 if (ci == pMap->end()) {
2720 parseStr += "Invalid '" + op + "' operation channel reference '" + refroot + "'\n";
2721 return false;
2722 }
2723 if (refroot != ref) {
2724 std::string select = ref.substr(refroot.size());
2725 int offset = 0;
2726 int size = 1;
2727
2728 if (select[0] == '[' || select[1] == '(') {
2729 const char *ptr;
2730 offset = atoi(select.c_str() + 1);
2731 for (ptr = select.c_str() + 1; *ptr && *ptr != ')' && *ptr != ']'; ptr++);
2732 select = ptr + 1;
2733 }
2734
2735 if (select[0]==',')
2736 size = atoi(select.c_str() + 1);
2737
2738 if (size < 0 || offset<0 || ci->second.first + offset + size > m_nInputChannels) {
2739 parseStr += "Invalid '" + op + "' operation channel offset or size '" + refroot + "'\n";
2740 return false;
2741 }
2742 char index[80];
2743 sprintf(index, "(%d,%d)", ci->second.first+offset, size);
2744 flatStr += op + index + " ";
2745 }
2746 else if (ci->second.second>1) {
2747 char index[80];
2748 sprintf(index, "(%d,%d)", ci->second.first, ci->second.second);
2749 flatStr += op + index + " ";
2750 }
2751 else {
2752 char index[80];
2753 sprintf(index, "(%d)", ci->second.first);
2754 flatStr += op + index + " ";
2755 }
2756 }
2757 else if (!strncmp(tok, "tget{", 5) ||
2758 !strncmp(tok, "tput{", 5) ||
2759 !strncmp(tok, "tsav{", 5)) {
2760 std::string op = parse.GetName();
2761 std::string ref = parse.GetReference();
2762 std::string refroot;
2763 for (const char *ptr = ref.c_str(); *ptr && *ptr != '[' && *ptr != '('; ptr++) refroot += *ptr;
2764
2765 if (macroName.size() && refroot.size() && refroot[0] == '@') {
2766 std::string localName = refroot.substr(1);
2767 TempDeclVarMap::iterator locals = m_macroLocalMap.find(macroName);
2768 if (locals == m_macroLocalMap.end()) {
2769 parseStr += "Reference to undeclared local variable '" + localName + "' in macro '" + macroName + "'\n";
2770 return false;
2771 }
2772
2773 unsigned long nLocalOffset = 0;
2774 unsigned long nLocalSize = 0;
2775 TempVarList::iterator m = locals->second.m_members.begin();
2776 for (; m != locals->second.m_members.end(); m++) {
2777 if (localName == m->m_name) {
2778 nLocalOffset = m->m_pos;
2779 nLocalSize = m->m_size;
2780 break;
2781 }
2782 }
2783 if (m == locals->second.m_members.end()) {
2784 parseStr += "Reference to undeclared local variable '" + localName + "' in macro '" + macroName + "'\n";
2785 return false;
2786 }
2787 int voffset, vsize;
2788
2789 if (ref != refroot) {
2790 CIccFuncTokenizer p2(ref.c_str());
2791 p2.GetNext();
2792 icUInt16Number _voffset = 0, _vsize = 1;
2793 p2.GetIndex(_voffset, _vsize, 0, 1);
2794 voffset = _voffset;
2795 vsize = _vsize + 1;
2796 }
2797 else {
2798 voffset = 0;
2799 vsize = (int)nLocalSize;
2800 }
2801
2802 if (voffset + vsize > (int)nLocalSize) {
2803 parseStr += "Out of bounds indexing of local '" + refroot + "' in macro '" + macroName + "'\n";
2804 return false;
2805 }
2806
2807 if (nLocalsOffset + nLocalOffset + voffset + vsize > 65536) {
2808 parseStr += "Temporary variable addressing out of bounds\n";
2809 return false;
2810 }
2811 char idx[80];
2812 if (vsize == 1) {
2813 sprintf(idx, "[%lu]", nLocalsOffset + nLocalOffset + voffset);
2814 }
2815 else {
2816 sprintf(idx, "[%lu,%d]", nLocalsOffset + nLocalOffset + voffset, vsize);
2817 }
2818 flatStr += "l";
2819 flatStr += op.substr(1);
2820 flatStr += idx;
2821 flatStr += " ";
2822 }
2823 else {
2824 TempVarMap::iterator var = m_varMap.find(refroot);
2825 if (var == m_varMap.end()) {
2826 std::string root;
2827 for (const char *ptr = refroot.c_str(); *ptr && *ptr != '.'; ptr++) root += *ptr;
2828
2829 TempVarMap::iterator rootVar = m_varMap.find(root);
2830 if (refroot != root && rootVar == m_varMap.end()) {
2831 parseStr += "Reference to undeclared variable '" + ref + "'\n";
2832 return false;
2833 }
2834
2835 TempDeclVarMap::iterator decl = m_declVarMap.find(root);
2836 if (decl == m_declVarMap.end()) {
2837 parseStr += "Reference to undeclared variable '" + ref + "'\n";
2838 return false;
2839 }
2840
2841 if (decl->second.m_pos < 0) {
2842 m_varMap[root] = CIccTempVar(root, m_nNextVar, decl->second.m_size);
2843 decl->second.m_pos = m_nNextVar;
2844
2845 if (strchr(refroot.c_str(), '.')) {
2846 TempVarList::iterator m = decl->second.m_members.begin();
2847 for (; m != decl->second.m_members.end(); m++) {
2848 std::string vm = root + "." + m->m_name;
2849 m_varMap[vm] = CIccTempVar(vm, m_nNextVar + m->m_pos, m->m_size);
2850 }
2851 }
2852
2853 if (m_nNextVar + decl->second.m_size > 65536) {
2854 parseStr += "Temporary variable addressing out of bounds\n";
2855 return false;
2856 }
2857 m_nNextVar += decl->second.m_size;
2858 }
2859 else {
2860 m_varMap[root] = CIccTempVar(root, decl->second.m_pos, decl->second.m_size);
2861
2862 if (strchr(refroot.c_str(), '.')) {
2863 TempVarList::iterator m = decl->second.m_members.begin();
2864 for (; m != decl->second.m_members.end(); m++) {
2865 std::string vm = root + "." + m->m_name;
2866 m_varMap[vm] = CIccTempVar(vm, decl->second.m_pos + m->m_pos, m->m_size);
2867 }
2868 }
2869 if (decl->second.m_pos + decl->second.m_size > 65536) {
2870 parseStr += "Temporary variable addressing out of bounds\n";
2871 return false;
2872 }
2873 }
2874
2875 var = m_varMap.find(refroot);
2876 if (var == m_varMap.end()) {
2877 parseStr += "Reference to undeclared variable '" + refroot + "'\n";
2878 return false;
2879 }
2880 }
2881 int voffset, vsize;
2882
2883 if (ref != refroot) {
2884 CIccFuncTokenizer p2(ref.c_str());
2885 p2.GetNext();
2886 icUInt16Number _voffset = 0, _vsize = 1;
2887 p2.GetIndex(_voffset, _vsize, 0, 1);
2888 voffset = _voffset;
2889 vsize = _vsize + 1;
2890 }
2891 else {
2892 voffset = 0;
2893 vsize = var->second.m_size;
2894 }
2895
2896 if (voffset + vsize > var->second.m_size) {
2897 parseStr += "Out of bounds indexing of '" + refroot + "'\n";
2898 return false;
2899 }
2900 if (var->second.m_pos + voffset + vsize > 65536) {
2901 parseStr += "Temporary variable addressing out of bounds\n";
2902 return false;
2903 }
2904 char idx[80];
2905 if (vsize == 1) {
2906 sprintf(idx, "[%d]", var->second.m_pos + voffset);
2907 }
2908 else {
2909 sprintf(idx, "[%d,%d]", var->second.m_pos + voffset, vsize);
2910 }
2911 flatStr += op + idx + " ";
2912 }
2913 }
2914 else if (!strncmp(tok, "elem{", 5) ||
2915 !strncmp(tok, "curv{", 5) ||
2916 !strncmp(tok, "clut{", 5) ||
2917 !strncmp(tok, "mtx{", 4) ||
2918 !strncmp(tok, "fJab{", 5) ||
2919 !strncmp(tok, "tJab{", 5) ||
2920 !strncmp(tok, "calc{", 5) ||
2921 !strncmp(tok, "tint{", 5)) {
2922 std::string op = parse.GetName();
2923 std::string ref = parse.GetReference();
2924 MpePtrMap::iterator e = m_mpeMap.find(ref);
2925 if (e == m_mpeMap.end()) {
2926 parseStr += "Unknown sub element reference to " + token + "\n";
2927 return false;
2928 }
2929 if (e->second.m_nIndex<0) {
2930 if (e->second.m_ptr) {
2931 m_mpeList.push_back(CIccMpePtr(e->second.m_ptr, m_nNextMpe));
2932 e->second.m_ptr = NULL;
2933 e->second.m_nIndex = m_nNextMpe;
2934 m_nNextMpe++;
2935 }
2936 else {
2937 parseStr += "Invalid sub-element reference: " + token + "\n";
2938 return false;
2939 }
2940 }
2941 char idx[80];
2942 sprintf(idx, "(%d)", e->second.m_nIndex);
2943 flatStr += op + idx + " ";
2944 }
2945 else {
2946 flatStr += tok;
2947 flatStr += " ";
2948 }
2949 }
2950
2951 return true;
2952}
std::map< std::string, IndexSizePair > ChanVarMap
Definition IccMpeXml.h:283
ChanVarMap m_outputMap
Definition IccMpeXml.h:327
TempDeclVarMap m_macroLocalMap
Definition IccMpeXml.h:340
bool Flatten(std::string &flatStr, std::string macroName, const char *szFunc, std::string &parseStr, icUInt32Number nLocalsOffset=0)
ChanVarMap m_inputMap
Definition IccMpeXml.h:326
icUInt16Number m_nOutputChannels
Definition IccTagMPE.h:192
icUInt16Number m_nInputChannels
Definition IccTagMPE.h:191
unsigned short icUInt16Number

References CIccFuncTokenizer::GetIndex(), CIccFuncTokenizer::GetLast(), CIccFuncTokenizer::GetName(), CIccFuncTokenizer::GetNext(), and CIccFuncTokenizer::GetReference().

+ Here is the call graph for this function:

◆ GetClassName()

virtual const char * CIccMpeXmlCalculator::GetClassName ( ) const
inlinevirtual

Reimplemented from CIccMpeCalculator.

Definition at line 307 of file IccMpeXml.h.

307{ return "CIccMpeXmlCalculator"; }

◆ GetExtension()

virtual IIccExtensionMpe * CIccMpeXmlCalculator::GetExtension ( )
inlinevirtual

Reimplemented from CIccMultiProcessElement.

Definition at line 309 of file IccMpeXml.h.

309{ return this; }

◆ ParseChanMap()

bool CIccMpeXmlCalculator::ParseChanMap ( ChanVarMap & chanMap,
const char * szNames,
int nChannels )
protected

Definition at line 3024 of file IccMpeXml.cpp.

3025{
3026 chanMap.clear();
3027
3028 if (!szNames)
3029 return false;
3030
3031 int i;
3032 const char *ptr;
3033 std::string name;
3034 IndexSizePair isp;
3035 int size = 1;
3036
3037 for (i = 0, ptr = szNames; *ptr && i < nChannels; ptr++) {
3038 bool bFirst = name.empty();
3039 if (*ptr == ' ') {
3040 if (!bFirst) {
3041 isp.first = i;
3042 isp.second = size;
3043 chanMap[name] = isp;
3044 name.clear();
3045 i += size;
3046 size = 1;
3047 }
3048 }
3049 else if (*ptr == '[' || *ptr == '(') {
3050 size = atoi(ptr + 1);
3051 if (size<0 || i + size>nChannels)
3052 return 0;
3053
3054 for (; *ptr && *ptr != ']' && *ptr != ')'; ptr++);
3055 if (!*ptr)
3056 ptr--;
3057 }
3058 else if (validNameChar(*ptr, bFirst)) {
3059 name += *ptr;
3060 }
3061 else {
3062 return false;
3063 }
3064 }
3065
3066 if (!name.empty() && i < nChannels) {
3067 isp.first = i;
3068 isp.second = size;
3069 chanMap[name] = isp;
3070 }
3071
3072 return true;
3073}
std::pair< int, int > IndexSizePair
Definition IccMpeXml.h:282
static bool validNameChar(char c, bool bFirst)

◆ ParseImport()

bool CIccMpeXmlCalculator::ParseImport ( xmlNode * pNode,
std::string importPath,
std::string & parseStr )

Definition at line 2336 of file IccMpeXml.cpp.

2337{
2338 xmlNode *pChild, *pNext;
2339 xmlAttr *attr;
2340
2341 pChild = icXmlFindNode(pNode->children, "Imports");
2342 if (pChild) {
2343 for (pNext = pChild->children; pNext; pNext = pNext->next) {
2344 if (pNext->type == XML_ELEMENT_NODE) {
2345 if (!strcmp((icChar*)pNext->name, "Import")) {
2346 if ((attr = icXmlFindAttr(pNext, "Filename"))) {
2347 std::string file = icXmlAttrValue(attr);
2348 xmlDoc *doc = NULL;
2349 xmlNode *root_element = NULL;
2350
2351 std::string look = "*";
2352 look += file;
2353 look += "*";
2354
2355 if (strstr(importPath.c_str(), look.c_str())) {
2356 //Already imported this file
2357 continue;
2358 }
2359
2360 /*parse the file and get the DOM */
2361 doc = xmlReadFile(file.c_str(), NULL, 0);
2362
2363 if (doc == NULL) {
2364 parseStr += "Unable to import '";
2365 parseStr += file;
2366 parseStr += '\n';
2367 return false;
2368 }
2369
2370 /*Get the root element node */
2371 root_element = xmlDocGetRootElement(doc);
2372 if (strcmp((icChar*)root_element->name, "IccCalcImport")) {
2373 parseStr += "Invalid calc element import file '" + file + "'\n";
2374 return false;
2375 }
2376
2377 bool rv = ParseImport(root_element, importPath+file+"*", parseStr);
2378
2379 xmlFreeDoc(doc);
2380 }
2381 else {
2382 parseStr += "Missing import file specifier\n";
2383 return false;
2384 }
2385 }
2386 else {
2387 parseStr += "Invalid import specifier\n";
2388 return false;
2389 }
2390 }
2391 }
2392 }
2393
2394 pChild = icXmlFindNode(pNode->children, "Variables");
2395 if (pChild) {
2396 for (pNext = pChild->children; pNext; pNext = pNext->next) {
2397 if (pNext->type == XML_ELEMENT_NODE) {
2398 if (!strcmp((icChar*)pNext->name, "Declare")) {
2399 if ((attr = icXmlFindAttr(pNext, "Name"))) {
2400 std::string name = icXmlAttrValue(attr);
2401 if (!validName(name.c_str())) {
2402 parseStr += "Invalid calc element variable name '" + name + "'\n'";
2403 return false;
2404 }
2405
2406 TempDeclVarMap::iterator v = m_declVarMap.find(name);
2407 if (v != m_declVarMap.end()) {
2408 parseStr += "Calc element variable '" + name + "' was previously declared\n";
2409 return false;
2410 }
2411 int offset = -1;
2412 icUInt16Number size = 1;
2413
2414 if ((attr = icXmlFindAttr(pNext, "Position"))) {
2415 offset = atoi(icXmlAttrValue(attr));
2416 if (offset && importPath != "*") {
2417 parseStr += "Position cannot be specified for imported variables";
2418 return false;
2419 }
2420 }
2421 if ((attr = icXmlFindAttr(pNext, "Size"))) {
2422 size = (icUInt16Number)atoi(icXmlAttrValue(attr));
2423 }
2424 if (size < 1) size = 1;
2425
2426 CIccTempDeclVar var = CIccTempDeclVar(name, offset, size);
2427 if (pNext->children && pNext->children->content) {
2428 CIccFuncTokenizer parse((icChar*)pNext->children->content);
2429 offset = 0;
2430
2431 while (parse.GetNext()) {
2432 icUInt16Number extra = 0;
2433 std::string member = parse.GetName();
2434 if (!validName(member.c_str())) {
2435 parseStr += "Invalid member name '" + member + "' for calc element variable '" + name + "'\n";
2436 return false;
2437 }
2438 size = 0; extra = 0;
2439 parse.GetIndex(size, extra, 1, 0);
2440 size++;
2441 if (size < 1)
2442 size = 1;
2443
2444 var.m_members.push_back(CIccTempVar(member, offset, size));
2445 offset += size;
2446 }
2447 if (var.m_size < offset)
2448 var.m_size = offset;
2449 }
2450 m_declVarMap[name] = var;
2451 }
2452 else {
2453 parseStr += "Missing calc element variable name definition\n";
2454 return false;
2455 }
2456 }
2457 else {
2458 parseStr += "Invalid calc element variable declaration\n";
2459 return false;
2460 }
2461 }
2462 }
2463 }
2464
2465 pChild = icXmlFindNode(pNode->children, "Macros");
2466 if (pChild) {
2467 for (pNext = pChild->children; pNext; pNext = pNext->next) {
2468 if (pNext->type == XML_ELEMENT_NODE) {
2469 if (!strcmp((icChar*)pNext->name, "Macro")) {
2470 if ((attr = icXmlFindAttr(pNext, "Name"))) {
2471 std::string name = icXmlAttrValue(attr);
2472 if (!validName(name.c_str())) {
2473 parseStr += "Invalid Macro name '" + name + "'\n'";
2474 return false;
2475 }
2476 if (!pNext->children || !pNext->children->content || !pNext->children->content[0]) {
2477 parseStr += "Missing content for macro '" + name + "'\n'";
2478 return false;
2479 }
2480 MacroMap::iterator m = m_macroMap.find(name);
2481 if (m != m_macroMap.end()) {
2482 if (!strcmp(m->second.c_str(), (icChar*)pNext->children->content))
2483 continue;
2484 parseStr += "Calc Element macro '" + name + "' was previously defined differently\n";
2485 return false;
2486 }
2487 m_macroMap[name] = (icChar*)(pNext->children->content);
2488
2489 if ((attr = icXmlFindAttr(pNext, "Local"))) {
2490 icUInt16Number offset, size;
2491 CIccTempDeclVar var = CIccTempDeclVar(name, 0, 0);
2492 std::string locals = icXmlAttrValue(attr);
2493 CIccFuncTokenizer parse(locals.c_str());
2494 offset = 0;
2495
2496 while (parse.GetNext()) {
2497 icUInt16Number extra = 0;
2498 std::string member = parse.GetName();
2499 if (!validName(member.c_str())) {
2500 parseStr += "Invalid local name '" + member + "' for calc element macro '" + name + "'\n";
2501 return false;
2502 }
2503 size = 0; extra = 0;
2504 parse.GetIndex(size, extra, 1, 0);
2505 size++;
2506 if (size < 1)
2507 size = 1;
2508
2509 var.m_members.push_back(CIccTempVar(member, offset, size));
2510 offset += size;
2511 }
2512 if (var.m_size < offset)
2513 var.m_size = offset;
2514
2515 m_macroLocalMap[name] = var;
2516 }
2517 }
2518 else {
2519 parseStr += "Missing macro name\n";
2520 return false;
2521 }
2522 }
2523 else {
2524 parseStr += "Invalid macro declaration\n";
2525 return false;
2526 }
2527 }
2528 }
2529 }
2530
2531 pChild = icXmlFindNode(pNode->children, "SubElements");
2532 if (pChild) {
2533 for (pNext = pChild->children; pNext; pNext = pNext->next) {
2534 if (pNext->type == XML_ELEMENT_NODE) {
2535 std::string name;
2536
2537 if ((attr = icXmlFindAttr(pNext, "Name"))) {
2538 name = icXmlAttrValue(attr);
2539 if (!validName(name.c_str())) {
2540 parseStr += "Invalid SubElement name '" + name + "'\n'";
2541 return false;
2542 }
2543 }
2544 if (name.empty()) {
2545 if (importPath != "*") {
2546 parseStr += "Imported Calc SubElments must be named.";
2547 return false;
2548 }
2549 }
2550 else {
2551 MpePtrMap::iterator se = m_mpeMap.find(name);
2552 if (se != m_mpeMap.end()) {
2553 parseStr += "Duplicate declaration of SubElement '" + name + "'\n";
2554 return false;
2555 }
2556 }
2557
2559
2560 if (!pMpe) {
2561 parseStr += std::string("Unknown Sub-Element Type (") + (const icChar*)pNext->name + ")\n";
2562 return false;
2563 }
2564
2565 if (!strcmp(pMpe->GetClassName(), "CIccMpeXmlCalculator")) {
2566 CIccMpeXmlCalculator *pSubCalc = (CIccMpeXmlCalculator*)pMpe;
2567 pSubCalc->m_sImport = importPath;
2568 }
2569
2570 xmlAttr *attr;
2571 IIccExtensionMpe *pExt = pMpe->GetExtension();
2572
2573 if (pExt) {
2574 if (!strcmp(pExt->GetExtClassName(), "CIccMpeXml")) {
2575 CIccMpeXml* pXmlMpe = (CIccMpeXml*)pExt;
2576
2577 if (pXmlMpe->ParseXml(pNext, parseStr)) {
2578 if ((attr = icXmlFindAttr(pNode, "Reserved"))) {
2579 sscanf(icXmlAttrValue(attr), "%u", &pMpe->m_nReserved);
2580 }
2581
2582 if (name.empty()) {
2583 m_mpeList.push_back(CIccMpePtr(pMpe, m_nNextMpe));
2584 m_nNextMpe++;
2585 }
2586 else {
2587 m_mpeMap[name] = CIccMpePtr(pMpe);
2588 }
2589 }
2590 else {
2591 char str[100];
2592 sprintf(str, " starting on line %d", pNext->line);
2593 parseStr += std::string("Unable to parse element of type ") + pMpe->GetClassName() + str + "\n";
2594 delete pMpe;
2595 return false;
2596 }
2597 }
2598 else {
2599 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
2600 delete pMpe;
2601 return false;
2602 }
2603 }
2604 else {
2605 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
2606 delete pMpe;
2607 return false;
2608 }
2609 }
2610 }
2611 }
2612 return true;
2613}
char icChar
Definition IccDefs.h:109
xmlAttr * icXmlFindAttr(xmlNode *pNode, const char *szAttrName)
xmlNode * icXmlFindNode(xmlNode *pNode, const char *szNodeName)
const char * icXmlAttrValue(xmlAttr *attr, const char *szDefault)
bool ParseImport(xmlNode *pNode, std::string importPath, std::string &parseStr)
static bool validName(const char *saName)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)=0
Class: CIccMultiProcessElement.
Definition IccTagMPE.h:146
virtual IIccExtensionMpe * GetExtension()
Definition IccTagMPE.h:182
virtual const icChar * GetClassName() const =0
icUInt32Number m_nReserved
Definition IccTagMPE.h:188
static CIccMultiProcessElement * CreateElement(const icChar *szElementNodeName)
icUInt16Number m_size
Definition IccMpeXml.h:292
TempVarList m_members
Definition IccMpeXml.h:294
virtual const char * GetExtClassName()=0

References CIccTagXmlMultiProcessElement::CreateElement(), CIccMultiProcessElement::GetClassName(), IIccExtensionMpe::GetExtClassName(), CIccMultiProcessElement::GetExtension(), CIccFuncTokenizer::GetIndex(), CIccFuncTokenizer::GetName(), CIccFuncTokenizer::GetNext(), icXmlAttrValue(), icXmlFindAttr(), icXmlFindNode(), CIccTempDeclVar::m_members, CIccMultiProcessElement::m_nReserved, m_sImport, CIccTempDeclVar::m_size, and CIccMpeXml::ParseXml().

+ Here is the call graph for this function:

◆ ParseXml()

bool CIccMpeXmlCalculator::ParseXml ( xmlNode * pNode,
std::string & parseStr )
virtual

Implements CIccMpeXml.

Definition at line 3075 of file IccMpeXml.cpp.

3076{
3077 xmlNode *pChild;
3078
3079 SetSize(atoi(icXmlAttrValue(pNode, "InputChannels")),
3080 atoi(icXmlAttrValue(pNode, "OutputChannels")));
3081
3082 clean();
3083
3084 if (!ParseChanMap(m_inputMap, icXmlAttrValue(pNode, "InputNames"), m_nInputChannels)) {
3085 parseStr += "Invalid name for InputChannels";
3086 return false;
3087 }
3088
3089 if (!ParseChanMap(m_outputMap, icXmlAttrValue(pNode, "OutputNames"), m_nOutputChannels)) {
3090 parseStr += "Invalid name for InputChannels";
3091 return false;
3092 }
3093
3094 if (!ParseImport(pNode, "*", parseStr))
3095 return false;
3096
3097 if (!ValidateMacroCalls(parseStr)) {
3098 return false;
3099 }
3100
3101 pChild = icXmlFindNode(pNode->children, "MainFunction");
3102 if (pChild && pNode->children && pChild->children->content) {
3103 char *content = (char*)pChild->children->content;
3104 std::string flatFunc;
3105
3106 //Move new variables to after allocated variables
3107 TempDeclVarMap::iterator declVar;
3108 for (declVar = m_declVarMap.begin(); declVar != m_declVarMap.end(); declVar++) {
3109 if (declVar->second.m_pos >= 0) {
3110 int next = declVar->second.m_pos + declVar->second.m_size;
3111 if (next > m_nNextVar)
3112 m_nNextVar = next;
3113 }
3114 }
3115
3116 if (!Flatten(flatFunc, "", content, parseStr, 0)) {
3117 return false;
3118 }
3119
3120 if (m_macroLocalMap.size()) {
3121 std::string localFunc;
3122 if (!UpdateLocals(localFunc, flatFunc, parseStr, m_nNextVar)) {
3123 return false;
3124 }
3125 flatFunc = localFunc;
3126 }
3127 //copy MPE subelmeents used by Main Function to returned object
3128 int n;
3129 MpePtrList::iterator m;
3130 for (m = m_mpeList.begin(), n = 0; m != m_mpeList.end(); m++, n++) {
3131 this->SetSubElem(n, m->m_ptr);
3132 m->m_ptr = NULL;
3133 }
3134
3135#if 0
3136 FILE *ff = fopen("flatfunc.txt", "wb");
3137 fwrite(flatFunc.c_str(), flatFunc.size(), 1, ff);
3138 fclose(ff);
3139#endif
3140
3141 icFuncParseStatus stat = SetCalcFunc(flatFunc.c_str(), parseStr);
3142 if (stat!=icFuncParseNoError) {
3143 char buf[65];
3144 int len = icIntMin(64, (int)strlen(flatFunc.c_str()));
3145 strncpy(buf, flatFunc.c_str(), len);
3146 buf[len]=0;
3147
3148 switch(stat) {
3150 parseStr += "Syntax Error occurred while parsing Main Calculator Function from \"";
3151 break;
3153 parseStr += "Invalid Operation found while parsing Main Calculator Function from \"";
3154 break;
3156 parseStr += "Stack underflow detected while parsing Main Calculator Function from \"";
3157 break;
3159 parseStr += "Invalid Channel detected while parsing Main Calculator Function from \"";
3160 break;
3161 default:
3162 parseStr += "Unable to parse Main Calculator Function from \"";
3163 }
3164 parseStr += buf;
3165 parseStr += "\"\n";
3166 return false;
3167 }
3168 }
3169 clean();
3170
3171 return true;
3172}
icFuncParseStatus
Definition IccMpeCalc.h:308
@ icFuncParseSyntaxError
Definition IccMpeCalc.h:310
@ icFuncParseNoError
Definition IccMpeCalc.h:309
@ icFuncParseStackUnderflow
Definition IccMpeCalc.h:312
@ icFuncParseInvalidOperation
Definition IccMpeCalc.h:311
@ icFuncParseInvalidChannel
Definition IccMpeCalc.h:314
icUInt32Number icIntMin(icUInt32Number v1, icUInt32Number v2)
Definition IccUtil.cpp:908
icFuncParseStatus SetCalcFunc(icCalculatorFuncPtr newFunc)
Name: CIccMpeCalculator::SetCalcFunc.
void SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels)
Name: CIccMpeCalculator::SetSize.
bool SetSubElem(icUInt32Number idx, CIccMultiProcessElement *pElem)
Definition IccMpeCalc.h:461
bool ParseChanMap(ChanVarMap &chanMap, const char *szNames, int nChannels)
bool UpdateLocals(std::string &func, std::string szFunc, std::string &parseStr, int nLocalsOffset)
bool ValidateMacroCalls(std::string &parseStr) const

References icFuncParseInvalidChannel, icFuncParseInvalidOperation, icFuncParseNoError, icFuncParseStackUnderflow, icFuncParseSyntaxError, icIntMin(), icXmlAttrValue(), and icXmlFindNode().

Referenced by CIccSampledCalculatorCurveXml::ParseXml().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ToXml()

bool CIccMpeXmlCalculator::ToXml ( std::string & xml,
std::string blanks = "" )
virtual

Implements CIccMpeXml.

Definition at line 2260 of file IccMpeXml.cpp.

2261{
2262 char line[256];
2263 std::string blanks2 = blanks + " ";
2264
2265 sprintf(line, "<CalculatorElement InputChannels=\"%d\" OutputChannels=\"%d\"", NumInputChannels(), NumOutputChannels());
2266 xml += blanks + line;
2267
2268 if (m_nReserved) {
2269 sprintf(line, " Reserved=\"%u\"", m_nReserved);
2270 xml += line;
2271 }
2272 xml += ">\n";
2273
2274 int i;
2275
2276 if (m_SubElem && m_nSubElem) {
2277 xml += blanks2 + "<SubElements>\n";
2278 for (i=0; i<(int)m_nSubElem; i++) {
2279 if (m_SubElem[i]) {
2281 if (pExt && !strcmp(pExt->GetExtClassName(), "CIccMpeXml")) {
2282 CIccMpeXml *pMpe = (CIccMpeXml*)pExt;
2283 pMpe->ToXml(xml, blanks2+" ");
2284 }
2285 else {
2286 return false;
2287 }
2288 }
2289 else {
2290 return false;
2291 }
2292 }
2293 xml += blanks2 + "</SubElements>\n";
2294 }
2295
2296 if (m_calcFunc) {
2297 std::string desc;
2298
2299 xml += blanks2 + "<MainFunction>\n";
2300
2301 m_calcFunc->Describe(desc, 100, (int)blanks2.size()+2);
2302 xml += desc;
2303
2304 xml+= blanks2 + "</MainFunction>\n";
2305 }
2306
2307 xml += blanks + "</CalculatorElement>\n";
2308 return true;
2309}
virtual void Describe(std::string &sDescription, int nVerboseness=0, int nBlanks=0)
Name: CIccCalculatorFunc::Describe.
icCalculatorFuncPtr m_calcFunc
Definition IccMpeCalc.h:491
icUInt32Number m_nSubElem
Definition IccMpeCalc.h:488
CIccMultiProcessElement ** m_SubElem
Definition IccMpeCalc.h:489
virtual bool ToXml(std::string &xml, std::string blanks="")=0
virtual icUInt16Number NumInputChannels() const
Definition IccTagMPE.h:159
virtual icUInt16Number NumOutputChannels() const
Definition IccTagMPE.h:160

References IIccExtensionMpe::GetExtClassName(), and CIccMpeXml::ToXml().

Referenced by CIccSampledCalculatorCurveXml::ToXml().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ UpdateLocals()

bool CIccMpeXmlCalculator::UpdateLocals ( std::string & func,
std::string szFunc,
std::string & parseStr,
int nLocalsOffset )
protected

Definition at line 2954 of file IccMpeXml.cpp.

2955{
2956 func.clear();
2957 CIccFuncTokenizer parse(sFunc.c_str(), true);
2958
2959 while (parse.GetNext()) {
2960 std::string token = parse.GetLast();
2961 const char *tok = token.c_str();
2962
2963 if (!strncmp(tok, "lget[", 5) ||
2964 !strncmp(tok, "lput[", 5) ||
2965 !strncmp(tok, "lsav[", 5)) {
2966 std::string op = parse.GetName();
2967 int voffset, vsize;
2968
2969 CIccFuncTokenizer p2(tok+4);
2970 icUInt16Number _voffset = 0, _vsize = 1;
2971 p2.GetIndex(_voffset, _vsize, 0, 1);
2972 voffset = _voffset + nLocalsOffset;
2973 vsize = _vsize + 1;
2974
2975 if (voffset + vsize > 65535) {
2976 parseStr += "Local variable out of bounds - too many variables.\n";
2977 return false;
2978 }
2979
2980 char idx[80];
2981 if (vsize == 1) {
2982 sprintf(idx, "[%d]", voffset);
2983 }
2984 else {
2985 sprintf(idx, "[%d,%d]", voffset, vsize);
2986 }
2987 func +="t";
2988 func += op.substr(1);
2989 func += idx;
2990 func += " ";
2991 }
2992 else {
2993 func += tok;
2994 func += " ";
2995 }
2996 }
2997
2998 return true;
2999}

References CIccFuncTokenizer::GetIndex(), CIccFuncTokenizer::GetLast(), CIccFuncTokenizer::GetName(), and CIccFuncTokenizer::GetNext().

+ Here is the call graph for this function:

◆ ValidateMacroCalls()

bool CIccMpeXmlCalculator::ValidateMacroCalls ( std::string & parseStr) const
protected

Definition at line 2642 of file IccMpeXml.cpp.

2643{
2644 MacroMap::const_iterator m;
2645
2646 for (m = m_macroMap.begin(); m != m_macroMap.end(); m++) {
2647 if (!ValidMacroCalls(m->second.c_str(), "*", parseStr)) {
2648 return false;
2649 }
2650 }
2651 return true;
2652}
bool ValidMacroCalls(const char *szMacroText, std::string macroStack, std::string &parseStr) const

◆ ValidMacroCalls()

bool CIccMpeXmlCalculator::ValidMacroCalls ( const char * szMacroText,
std::string macroStack,
std::string & parseStr ) const
protected

Definition at line 2615 of file IccMpeXml.cpp.

2616{
2617 const char *ptr;
2618 for (ptr = strstr(szMacroText, "call{"); ptr; ptr = strstr(ptr, "call{")) {
2619 CIccFuncTokenizer parse(ptr, true);
2620 parse.GetNext();
2621
2622 std::string name = parse.GetReference();
2623 MacroMap::const_iterator m = m_macroMap.find(name);
2624 if (m == m_macroMap.end()) {
2625 parseStr += "Call to undefined macro '" + name + "'\n";
2626 return false;
2627 }
2628 std::string sm = "*";
2629 sm += name + "*";
2630 if (strstr(macroStack.c_str(), sm.c_str())) {
2631 parseStr += "Macro recursion detected in call to '" + name + "'\n";
2632 return false;
2633 }
2634 if (!ValidMacroCalls(m->second.c_str(), macroStack + name + "*", parseStr)) {
2635 return false;
2636 }
2637 ptr++;
2638 }
2639 return true;
2640}

References CIccFuncTokenizer::GetNext(), and CIccFuncTokenizer::GetReference().

+ Here is the call graph for this function:

◆ validName()

bool CIccMpeXmlCalculator::validName ( const char * saName)
staticprotected

Definition at line 2321 of file IccMpeXml.cpp.

2322{
2323 const char *ptr;
2324 if (!szName || !*szName) {
2325 return false;
2326 }
2327
2328 for (ptr = szName; *ptr; ptr++) {
2329 if (!validNameChar(*ptr, ptr == szName))
2330 return false;
2331 }
2332
2333 return true;
2334}
const icChar * szName

References szName.

◆ validNameChar()

bool CIccMpeXmlCalculator::validNameChar ( char c,
bool bFirst )
staticprotected

Definition at line 2311 of file IccMpeXml.cpp.

2312{
2313 if (bFirst && !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')))
2314 return false;
2315 else if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '_')))
2316 return false;
2317
2318 return true;
2319}

Member Data Documentation

◆ m_declVarMap

TempDeclVarMap CIccMpeXmlCalculator::m_declVarMap
protected

Definition at line 331 of file IccMpeXml.h.

◆ m_inputMap

ChanVarMap CIccMpeXmlCalculator::m_inputMap
protected

Definition at line 326 of file IccMpeXml.h.

◆ m_macroLocalMap

TempDeclVarMap CIccMpeXmlCalculator::m_macroLocalMap
protected

Definition at line 340 of file IccMpeXml.h.

◆ m_macroMap

MacroMap CIccMpeXmlCalculator::m_macroMap
protected

Definition at line 339 of file IccMpeXml.h.

◆ m_mpeList

MpePtrList CIccMpeXmlCalculator::m_mpeList
protected

Definition at line 337 of file IccMpeXml.h.

◆ m_mpeMap

MpePtrMap CIccMpeXmlCalculator::m_mpeMap
protected

Definition at line 335 of file IccMpeXml.h.

◆ m_nNextMpe

int CIccMpeXmlCalculator::m_nNextMpe
protected

Definition at line 336 of file IccMpeXml.h.

◆ m_nNextVar

int CIccMpeXmlCalculator::m_nNextVar
protected

Definition at line 332 of file IccMpeXml.h.

◆ m_outputMap

ChanVarMap CIccMpeXmlCalculator::m_outputMap
protected

Definition at line 327 of file IccMpeXml.h.

◆ m_sImport

std::string CIccMpeXmlCalculator::m_sImport
protected

Definition at line 329 of file IccMpeXml.h.

Referenced by CIccMpeXmlCalculator(), and ParseImport().

◆ m_varMap

TempVarMap CIccMpeXmlCalculator::m_varMap
protected

Definition at line 333 of file IccMpeXml.h.


The documentation for this class was generated from the following files: