示例#1
0
icStatusCMM CIccEvalCompare::EvaluateProfile(CIccProfile *pProfile, icUInt8Number nGran/* =0 */,
        icRenderingIntent nIntent/* =icUnknownIntent */, icXformInterp nInterp/* =icInterpLinear */,
        bool buseMpeTags/* =true */)
{
    if (!pProfile)
    {
        return icCmmStatCantOpenProfile;
    }

    if (pProfile->m_Header.deviceClass!=icSigInputClass &&
            pProfile->m_Header.deviceClass!=icSigDisplayClass &&
            pProfile->m_Header.deviceClass!=icSigOutputClass &&
            pProfile->m_Header.deviceClass!=icSigColorSpaceClass)
    {
        return icCmmStatInvalidProfile;
    }

    CIccCmm dev2Lab(icSigUnknownData, icSigLabData);
    CIccCmm Lab2Dev2Lab(icSigLabData, icSigLabData, false);

    icStatusCMM result;

    result = dev2Lab.AddXform(*pProfile, nIntent, nInterp, icXformLutColor, buseMpeTags);

    if (result!=icCmmStatOk) {
        return result;
    }

    result = dev2Lab.Begin();
    if (result != icCmmStatOk) {
        return result;
    }

    result = Lab2Dev2Lab.AddXform(*pProfile, nIntent, nInterp, icXformLutColor, buseMpeTags);
    if (result != icCmmStatOk) {
        return result;
    }

    result = Lab2Dev2Lab.AddXform(*pProfile, nIntent, nInterp, icXformLutColor, buseMpeTags);
    if (result != icCmmStatOk) {
        return result;
    }

    result = Lab2Dev2Lab.Begin();
    if (result != icCmmStatOk) {
        return result;
    }

    icFloatNumber sPixel[15];
    icFloatNumber devPcs[15], roundPcs1[15], roundPcs2[15];

    int ndim = icGetSpaceSamples(pProfile->m_Header.colorSpace);
    int ndim1 = ndim+1;

    // determine granularity
    if (!nGran)
    {
        CIccTagLutAtoB* pTag = (CIccTagLutAtoB*)pProfile->FindTag(icSigAToB0Tag+(nIntent==icAbsoluteColorimetric ? icRelativeColorimetric : nIntent));
        if (!pTag || ndim==3)
        {
            nGran = 33;
        }
        else {
            CIccCLUT* pClut = pTag->GetCLUT();
            if (pClut)
                nGran = pClut->GridPoints()+2;
            else
                nGran = 33;
        }
    }

    int i, j;
    icFloatNumber stepsize = (icFloatNumber)(1.0/(icFloatNumber)(nGran-1));
    icFloatNumber* steps = new icFloatNumber[ndim1];
    icFloatNumber nstart = 0.0;
    icFloatNumber nEnd = (icFloatNumber)(1.0+stepsize/2.0);
    for(j=0; j<ndim1; j++) {
        steps[j] = nstart;
    }

    while(steps[0]==nstart) {
        for(j=0; j<ndim; j++) {
            sPixel[j] = icMin(steps[j+1],1.0);
        }
        steps[ndim] = (steps[ndim]+stepsize);
        for(i=ndim; i>=0; i--) {
            if(steps[i]>nEnd) {
                steps[i] = nstart;
                steps[i-1] = (steps[i-1]+stepsize);
            }
            else break;
        }

        dev2Lab.Apply(devPcs, sPixel); //Convert device value to pcs from input table
        Lab2Dev2Lab.Apply(roundPcs1, devPcs);  //First round trip gets color into output gamut
        Lab2Dev2Lab.Apply(roundPcs2, roundPcs1);  //Second round trip find reproducibility error

        icLabFromPcs(devPcs);
        icLabFromPcs(roundPcs1);
        icLabFromPcs(roundPcs2);

        Compare(sPixel, devPcs, roundPcs1, roundPcs2);
    }

    delete[] steps;

    return icCmmStatOk;
}
int main(int argc, icChar* argv[])
{
	int minargs = 4; // minimum number of arguments
  if(argc<minargs) {
		Usage();
    return -1;
  }

  int nNumProfiles, temp;
  temp = argc - minargs;

  if(temp%2 != 0) {
    printf("\nMissing arguments!\n");
		Usage();
    return -1;
  }

  nNumProfiles = temp/2;

  std::ifstream InputData(argv[1]);

  if(!InputData) {
    printf("\nFile [%s] cannot be opened.\n", argv[1]);
    return false;
  }

  icChar ColorSig[7], tempBuf[5000];
  InputData.getline(tempBuf, sizeof(tempBuf));

  int i;
  for (i = 0; (i<4 || tempBuf[i+1]!='\'') && i < 6; i++) {
    ColorSig[i] = tempBuf[i+1];
  }
  for (;i<7; i++)
    ColorSig[i] = '\0';


  icColorSpaceSignature SrcspaceSig = (icColorSpaceSignature)icGetSigVal(ColorSig);
  int nSamples = icGetSpaceSamples(SrcspaceSig);

  if(SrcspaceSig != icSigNamedData) {
    if(!nSamples) {
      printf("Source color space signature not recognized.\n");
      return -1;
    }
  }

  InputData.getline(tempBuf, sizeof(tempBuf));
  sscanf(tempBuf, "%s", tempBuf);

  icFloatColorEncoding srcEncoding, destEncoding;

  srcEncoding = CIccCmm::GetFloatColorEncoding(tempBuf);

  if(srcEncoding == icEncodeUnknown) {
    printf("Source color data encoding not recognized.\n");
    return false;
  }

  destEncoding = (icFloatColorEncoding)atoi(argv[2]);
	icXformInterp nInterp = (icXformInterp)atoi(argv[3]);

  int nIntent, nType;
  CIccNamedColorCmm namedCmm(SrcspaceSig, icSigUnknownData, !IsSpacePCS(SrcspaceSig));
  IccProfilePtrList pccList;

  int nCount;
  bool bUseMPE;
  icCmmEnvSigMap sigMap;

  for(i = 0, nCount=minargs; i<nNumProfiles; i++, nCount+=2) {
    if (!strnicmp(argv[nCount], "-ENV:", 5)) {  //check for -ENV: to allow for Cmm Environment variables to be defined for next transform
      icSignature sig = icGetSigVal(argv[nCount]+5);
      icFloatNumber val = (icFloatNumber)atof(argv[nCount+1]);
      
      sigMap[sig]=val;
    }
    else if (stricmp(argv[nCount], "-PCC")) {      //check for -PCC arg to allow for profile connection conditions to be defined
      bUseMPE = true;
      nIntent = atoi(argv[nCount+1]);
      nType = abs(nIntent) / 10;
      nIntent = nIntent % 10;
      CIccProfile *pPccProfile = NULL;

      CIccCreateXformHintManager Hint;

      switch(nType) {
        case 1:
          nType = 0;
          bUseMPE = false;
          break;
        case 4:
          nType = 0;
          Hint.AddHint(new CIccApplyBPCHint());
          break;
      }

      if (i+1<nNumProfiles && !stricmp(argv[nCount+2], "-PCC")) {
        pPccProfile = OpenIccProfile(argv[nCount+3]);
        if (!pPccProfile) {
          printf("Unable to open Profile Connections Conditions from '%s'\n", argv[nCount+3]);
          return -1;
        }
        //Keep track of pPccProfile for until after cmm.Begin is called
        pccList.push_back(pPccProfile);
      }

      if (sigMap.size()>0) {
        Hint.AddHint(new CIccCmmEnvVarHint(sigMap));
      }

      if (namedCmm.AddXform(argv[nCount], nIntent<0 ? icUnknownIntent : (icRenderingIntent)nIntent, nInterp, pPccProfile, (icXformLutType)nType, bUseMPE, &Hint)) {
        printf("Invalid Profile:  %s\n", argv[nCount]);
        return -1;
      }
      sigMap.clear();
    }
  }

  icStatusCMM stat;
  if((stat=namedCmm.Begin())) {
    printf("Error %d - Unable to begin profile application - Possibly invalid or incompatible profiles\n", stat);
    return -1;
  }

  //Now we can release the pccProfile nodes.
  IccProfilePtrList::iterator pcc;

  for (pcc=pccList.begin(); pcc!=pccList.end(); pcc++) {
    CIccProfile *pPccProfile = *pcc;
    delete pPccProfile;
  }
  pccList.clear();

  SrcspaceSig = namedCmm.GetSourceSpace();
  int nSrcSamples = icGetSpaceSamples(SrcspaceSig);

  icColorSpaceSignature DestspaceSig = namedCmm.GetDestSpace();
  int nDestSamples = icGetSpaceSamples(DestspaceSig);
  
  std::string OutPutData;
  char SrcNameBuf[256], DestNameBuf[256];
  CIccPixelBuf SrcPixel(nSrcSamples+16), DestPixel(nDestSamples+16), Pixel(icIntMax(nSrcSamples, nDestSamples)+16);

  sprintf(tempBuf,"%s\t; ", icGetColorSig(tempBuf, DestspaceSig, false));
  OutPutData += tempBuf;
  OutPutData += "Data Format\n";

  if(DestspaceSig==icSigNamedData)
    destEncoding = icEncodeValue;
  sprintf(tempBuf, "%s\t; ", CIccCmm::GetFloatColorEncoding(destEncoding));
  OutPutData += tempBuf;
  OutPutData += "Encoding\n\n";

  OutPutData += ";Source Data Format: ";
  sprintf(tempBuf,"%s\n", icGetColorSig(tempBuf, SrcspaceSig, false));
  OutPutData += tempBuf;

  if(SrcspaceSig==icSigNamedData)
    srcEncoding = icEncodeValue;
  OutPutData += ";Source Data Encoding: ";
  sprintf(tempBuf, "%s\n", CIccCmm::GetFloatColorEncoding(srcEncoding));
  OutPutData += tempBuf;

  OutPutData += ";Source data is after semicolon\n";
  
  OutPutData += "\n;Profiles applied\n";
  for(i = 0, nCount=minargs; i<nNumProfiles; i++, nCount+=2) {
    OutPutData += "; ";
    if (stricmp(argv[nCount], "-PCC") && strnicmp(argv[nCount], "-ENV:", 5)) {
      if (i+1<nNumProfiles && !stricmp(argv[nCount+2], "-PCC")) {
        sprintf(tempBuf, "%s -PCC %s\n", argv[nCount], argv[nCount+3]);
        OutPutData += tempBuf;
        nCount += 2;
        nNumProfiles--;
      }
      else {
        sprintf(tempBuf, "%s\n", argv[nCount]);
        OutPutData += tempBuf;
      }
    }
  }
  OutPutData += "\n";
  
  fwrite(OutPutData.c_str(), 1, OutPutData.length(), stdout);

  while(!InputData.eof()) {

    if(SrcspaceSig==icSigNamedData) {
      InputData.getline(tempBuf, sizeof(tempBuf));
      if(!ParseName(SrcNameBuf, tempBuf))
        continue;

      icChar *numptr = strstr(tempBuf, "\" }");
      if (numptr)
        numptr+=3;

      icFloatNumber tint;
      if (!ParseNextNumber(tint, &numptr))
        tint = 1.0;

      OutPutData.erase();

      switch(namedCmm.GetInterface()) {
        case icApplyNamed2Pixel:
          {

            if(namedCmm.Apply(DestPixel, SrcNameBuf, tint)) {
              printf("Profile application failed.\n");
              return -1;
            }

            if(CIccCmm::FromInternalEncoding(DestspaceSig, destEncoding, DestPixel, DestPixel, destEncoding!=icEncodeFloat)) {
              printf("Invalid final data encoding\n");
              return -1;
            }

            for(i = 0; i<nDestSamples; i++) {
              sprintf(tempBuf, "%9.4lf ", DestPixel[i]);
              OutPutData += tempBuf;
            }
            OutPutData += "\t; ";
            
            break;
          }
        case icApplyNamed2Named:
          {
            if(namedCmm.Apply(DestNameBuf, SrcNameBuf, tint)) {
              printf("Profile application failed.\n");
              return -1;
            }
            
            sprintf(tempBuf, "{ \"%s\" }\t; ", DestNameBuf);
            OutPutData += tempBuf;

            break;
          }
        case icApplyPixel2Pixel:
        case icApplyPixel2Named:
        default:
          printf("Incorrect interface.\n");
          return -1;
      }      

      if (tint==1.0)
        sprintf(tempBuf, "{ \"%s\" }\n", SrcNameBuf);
      else
        sprintf(tempBuf, "{ \"%s\" } %.4f\n", SrcNameBuf, tint);

      OutPutData += tempBuf;
    }
    else {
      InputData.getline(tempBuf, sizeof(tempBuf));
      if(!ParseNumbers(Pixel, tempBuf, nSamples))
        continue;

      OutPutData.erase();
      if(CIccCmm::ToInternalEncoding(SrcspaceSig, srcEncoding, SrcPixel, Pixel)) {
        printf("Invalid source data encoding\n");
        return -1;
      }

      switch(namedCmm.GetInterface()) {
        case icApplyPixel2Pixel:
          {
            if(namedCmm.Apply(DestPixel, SrcPixel)) {
              printf("Profile application failed.\n");
              return -1;
            }
            if(CIccCmm::FromInternalEncoding(DestspaceSig, destEncoding, DestPixel, DestPixel)) {
              printf("Invalid final data encoding\n");
              return -1;
            }

            for(i = 0; i<nDestSamples; i++) {
              sprintf(tempBuf, "%9.4lf ", DestPixel[i]);
              OutPutData += tempBuf;
            }
            OutPutData += "\t; ";
            break;
          }
        case icApplyPixel2Named:
          {
            if(namedCmm.Apply(DestNameBuf, SrcPixel)) {
              printf("Profile application failed.\n");
              return -1;
            }
            sprintf(tempBuf, "{ \"%s\" }\t; ", DestNameBuf);
            OutPutData += tempBuf;
            break;
          }
        case icApplyNamed2Pixel:
        case icApplyNamed2Named:
        default:
          printf("Incorrect interface.\n");
          return -1;
      }      


      for(i = 0; i<nSamples; i++) {
        sprintf(tempBuf, "%9.4lf ", Pixel[i]);
        OutPutData += tempBuf;
      }

      OutPutData += "\n";
    }

    fwrite(OutPutData.c_str(), 1, OutPutData.length(), stdout);
  }


  return 0;
}