ScColorProfile ScLcmsColorMgmtEngineImpl::createProfile_Lab(ScColorMgmtEngine& engine)
{
	QString internalProfilePath("memprofile://Internal Lab profile");
	ScColorProfile profile = m_profileCache->profile(internalProfilePath);
	if (!profile.isNull())
		return profile;

	cmsHPROFILE lcmsProf = NULL;
	cmsSetErrorHandler(&cmsErrorHandler);
	try
	{
		lcmsProf = cmsCreateLabProfile(NULL);
		if (lcmsProf)
		{
			ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
			profData->m_profilePath = internalProfilePath;
			profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
			m_profileCache->addProfile(profile);
		}
		if (profile.isNull() && lcmsProf)
		{
			cmsCloseProfile(lcmsProf);
			lcmsProf = NULL;
		}
	}
	catch (lcmsException& e)
	{
		std::cerr << e.what() << std::endl;
		if (profile.isNull() && lcmsProf)
			cmsCloseProfile(lcmsProf);
		profile = ScColorProfile();
	}
	cmsSetErrorHandler(NULL);
	return profile;
}
ScColorProfile ScLcmsColorMgmtEngineImpl::openProfileFromMem(ScColorMgmtEngine& engine, const QByteArray& data)
{
	ScColorProfile profile;
	cmsHPROFILE lcmsProf = NULL;
	cmsSetErrorHandler(&cmsErrorHandler);
	try
	{
		lcmsProf = cmsOpenProfileFromMem((LPVOID) data.data(), data.size());
		if (lcmsProf)
		{
			ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
			QString desc = profData->productDescription();
			if (!desc.isEmpty())
				profData->m_profilePath = QString("memprofile://%1").arg(desc);
			profData->m_profileData = data;
			profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
		}
		if (profile.isNull() && lcmsProf)
		{
			cmsCloseProfile(lcmsProf);
			lcmsProf = NULL;
		}
	}
	catch (lcmsException& e)
	{
		std::cerr << e.what() << std::endl;
		if (profile.isNull() && lcmsProf)
			cmsCloseProfile(lcmsProf);
		profile = ScColorProfile();
	}
	cmsSetErrorHandler(NULL);
	return profile;
}
예제 #3
0
/* Do any initialization if needed to the CMS */
int
gscms_create(gs_memory_t *memory)
{
    /* Set our own error handling function */
    cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error);
    return 0;
}
ScColorProfile ScLcmsColorMgmtEngineImpl::openProfileFromFile(ScColorMgmtEngine& engine, const QString& filePath)
{
	// Search profile in profile cache first
	ScColorProfile profile = m_profileCache->profile(filePath);
	if (!profile.isNull())
		return profile;
	cmsHPROFILE lcmsProf = NULL;
	cmsSetErrorHandler(&cmsErrorHandler);
	try
	{
		QFile file(filePath);
		if (file.open(QFile::ReadOnly))
		{
			// We do not use lcms cmsOpenProfileFromFile() to avoid limitations
			// of I/O on 8bit filenames on Windows
			QByteArray data = file.readAll();
			if (!data.isEmpty())
			{
				lcmsProf = cmsOpenProfileFromMem(data.data(), data.size());
				if (lcmsProf)
				{
					ScLcmsColorProfileImpl* profData = new ScLcmsColorProfileImpl(engine, lcmsProf);
					profData->m_profileData = data;
					profData->m_profilePath = filePath;
					profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
					m_profileCache->addProfile(profile);
				}
				if (profile.isNull() && lcmsProf)
				{
					cmsCloseProfile(lcmsProf);
					lcmsProf = NULL;
				}
			}
			file.close();
		}
	}
	catch (lcmsException& e)
	{
		std::cerr << e.what() << std::endl;
		if (profile.isNull() && lcmsProf)
			cmsCloseProfile(lcmsProf);
		profile = ScColorProfile();
	}
	cmsSetErrorHandler(NULL);
	return profile;
}
예제 #5
0
int main(int argc, char *argv[])
{
    WORD Input[MAXCHANNELS], Output[MAXCHANNELS], PCSLab[MAXCHANNELS], PCSxyz[MAXCHANNELS];

    
    fprintf(stderr, "little cms ColorSpace conversion calculator - v1.8\n\n");

      if (argc == 1)  
              Help();              

      HandleSwitches(argc, argv);

      cmsSetErrorHandler(MyErrorHandler);

      OpenTransforms();
      
      for(;;) {

          if (xisatty(stdin))
              printf("\nEnter values, 'q' to quit\n");

          if (feof(stdin))
              break;

          TakeValues(Input);
          cmsDoTransform(hTrans, Input, Output, 1);

          if (Verbose) {

            if (hTransXYZ) cmsDoTransform(hTransXYZ, Input, PCSxyz, 1);
            if (hTransLab) cmsDoTransform(hTransLab, Input, PCSLab, 1);
          }
                    
          if (xisatty(stdin))
                printf("\n");
         
          PrintResults(Output, OutputColorSpace); printf("\n");

          if (Verbose && hTransXYZ && hTransLab) {

            PrintResults(PCSxyz, icSigXYZData); printf("\n");
            PrintResults(PCSLab, icSigLabData); printf("\n");
          }

      }

          
      return 0;     
}
예제 #6
0
int main(int argc, char* argv[])
{
      char *Intents[] = {"perceptual",
                         "relative colorimetric",
                         "saturation",
                         "absolute colorimetric" };

      HandleSwitches(argc, argv);

      cmsSetErrorHandler(MyErrorHandler);

      if ((argc - xoptind) != 2) {

              Help(0);              
              }

     

      if (Verbose) {

          if (lIsDeviceLink)
            fprintf(stdout, "%s(device link) -> %s [%s]", 
                                                argv[xoptind], 
                                                argv[xoptind+1], 
                                                Intents[Intent]);

        else
            fprintf(stdout, "%s(%s) -> %s(%s) [%s]", argv[xoptind],
                                                (cInpProf == NULL ? "sRGB": cInpProf), 
                                                argv[xoptind+1],
                                                (cOutProf == NULL ? "sRGB" : cOutProf), 
                                                Intents[Intent]);
      }

      OpenInput(argv[xoptind]);
      OpenOutput(argv[xoptind+1]);
      TransformImage(cInpProf, cOutProf);


      if (Verbose) fprintf(stdout, "\n");

      Done();

      return 0;
}
예제 #7
0
int main(int argc, char *argv[])
{
	int nargs;

     fprintf(stderr, "little cms PostScript converter - v1.5\n\n");

	 HandleSwitches(argc, argv);

     cmsSetErrorHandler(MyErrorHandler);

     nargs = (argc - xoptind);
	 if (nargs != 0 && nargs != 1)
				Help();            
	
	 if (nargs == 0) 
			OutFile = stdout;
	 else
			OutFile = fopen(argv[xoptind], "wt");
	   		

	 if (cInProf == NULL && cOutProf == NULL)
				Help();

    
	  if (cInProf != NULL)
			GenerateCSA();
		  
	  if (cOutProf != NULL)
			GenerateCRD();
		
	  if (nargs == 1) {
		  fclose(OutFile);
	  }

      return 0;     
}
예제 #8
0
/* Do any initialization if needed to the CMS */
void
gscms_create(void **contextptr)
{
    /* Set our own error handling function */
    cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error);
}
예제 #9
0
/* Get ICC Profile handle from buffer */
gcmmhprofile_t
gscms_get_profile_handle_mem(unsigned char *buffer, unsigned int input_size)
{
    cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error);
    return(cmsOpenProfileFromMem(buffer,input_size));
}
예제 #10
0
int main(int argc, char* argv[])
{
      TIFF *in, *out;
      char *Intents[] = {"perceptual",
                         "relative colorimetric",
                         "saturation",
                         "absolute colorimetric" };

      HandleSwitches(argc, argv);
  
	  cmsSetErrorHandler(MyErrorHandler);

      if ((argc - xoptind) != 2) {

              Help(0);              
              }

     
      if (Verbose) {

        if (lIsDeviceLink)
            fprintf(stdout, "%s(device link) -> %s [%s]", 
                                                argv[xoptind], 
                                                argv[xoptind+1], 
                                                Intents[Intent]);

        else
           fprintf(stdout, "%s(%s) -> %s(%s) [%s]", argv[xoptind],
                                                (cInpProf == NULL ? "sRGB": cInpProf), 
                                                argv[xoptind+1],
                                                (cOutProf == NULL ? "sRGB" : cOutProf), 
                                                Intents[Intent]);
        fflush(stdout);
      }

      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, cOutProf);


      } while (TIFFReadDirectory(in));


      if (Verbose) { fprintf(stdout, "\n"); fflush(stdout); }

      TIFFClose(in);
      TIFFClose(out);

      return 0;
}
예제 #11
0
파일: LCMS.c 프로젝트: frohoff/jdk6
JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    javaVM = jvm;

    cmsSetErrorHandler(errorHandler);
    return JNI_VERSION_1_6;
}
QList<ScColorProfileInfo> ScLcmsColorMgmtEngineImpl::getAvailableProfileInfo(const QString& directory, bool recursive)
{
	QList<ScColorProfileInfo> profileInfos;

	QDir d(directory, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::Dirs | QDir::NoSymLinks);
	if ((!d.exists()) || (d.count() == 0))
		return profileInfos;

	QString nam = "";
	cmsHPROFILE hIn = NULL;

	for (uint dc = 0; dc < d.count(); ++dc)
	{
		QString file = d[dc];
		if (file == "." ||  file == "..")
			continue;
		QFileInfo fi(directory + "/" + file);
		if (fi.isDir() && !recursive)
			continue;
		else if (fi.isDir() && !file.startsWith('.'))
		{
			QList<ScColorProfileInfo> profileInfos2 = getAvailableProfileInfo(fi.filePath()+"/", true);
			profileInfos.append(profileInfos2);
			continue;
		}

		ScColorProfileInfo profileInfo;
		profileInfo.file = fi.filePath();

		QFile f(fi.filePath());
		QByteArray bb(40, ' ');
		if (!f.open(QIODevice::ReadOnly)) {
			profileInfo.debug = QString("couldn't open %1 as color profile").arg(fi.filePath());
			profileInfos.append(profileInfo);
			continue;
		}
		int len = f.read(bb.data(), 40);
		f.close();
		if (len == 40 && bb[36] == 'a' && bb[37] == 'c' && bb[38] == 's' && bb[39] == 'p')
		{
			const QByteArray profilePath( QString(directory + "/" + file).toLocal8Bit() );
			cmsSetErrorHandler(&cmsErrorHandler);
			try
			{
				hIn = cmsOpenProfileFromFile(profilePath.data(), "r");
				if (hIn == NULL)
					continue;
				const char* profileDescriptor = cmsTakeProductDesc(hIn);
				profileInfo.description = QString(profileDescriptor);
				if (profileInfo.description.isEmpty())
				{
					cmsCloseProfile(hIn);
					profileInfo.debug = QString("Color profile %1 is broken : no valid description").arg(fi.filePath());
					profileInfos.append(profileInfo);
					continue;
				}
				profileInfo.colorSpace  = translateLcmsColorSpaceType( cmsGetColorSpace(hIn) );
				profileInfo.deviceClass = translateLcmsProfileClass( cmsGetDeviceClass(hIn) );
				profileInfos.append(profileInfo);
				cmsCloseProfile(hIn);
				hIn = NULL;
			}
			catch (lcmsException&)
			{
				// Profile is broken
				if (hIn)
				{
					cmsCloseProfile(hIn);
					hIn = NULL;
				}
				profileInfo.debug = QString("Color profile %1 is broken").arg(fi.filePath());
				profileInfos.append(profileInfo);
			}
			cmsSetErrorHandler(NULL);
		}
	}
	cmsSetErrorHandler(NULL);

	return profileInfos;
}
ScColorTransform ScLcmsColorMgmtEngineImpl::createProofingTransform(ScColorMgmtEngine& engine,
                                             const ScColorProfile& inputProfile , eColorFormat inputFormat,
	                                         const ScColorProfile& outputProfile, eColorFormat outputFormat,
                                             const ScColorProfile& proofProfile , eRenderIntent renderIntent, 
                                             eRenderIntent proofingIntent, long transformFlags)
{
	ScColorTransform transform(NULL);
	if (inputProfile.isNull() || outputProfile.isNull())
		return transform;
	int inputProfEngineID  = inputProfile.engine().engineID();
	int outputProfEngineID = outputProfile.engine().engineID();
	int proofProfEngineID  = proofProfile.engine().engineID();
	if ((engine.engineID()  != m_engineID) || (inputProfEngineID != m_engineID) || 
		(outputProfEngineID != m_engineID) || (proofProfEngineID != m_engineID))
		return transform;
	const ScLcmsColorProfileImpl* lcmsInputProf    = dynamic_cast<const ScLcmsColorProfileImpl*>(inputProfile.data());
	const ScLcmsColorProfileImpl* lcmsOutputProf   = dynamic_cast<const ScLcmsColorProfileImpl*>(outputProfile.data());
	const ScLcmsColorProfileImpl* lcmsProofingProf = dynamic_cast<const ScLcmsColorProfileImpl*>(proofProfile.data());
	if (!lcmsInputProf || !lcmsOutputProf || !lcmsProofingProf)
		return transform;

	long strategyFlags = 0;
	if (m_strategy.useBlackPointCompensation)
		strategyFlags |= Ctf_BlackPointCompensation;
	if (m_strategy.useBlackPreservation)
		strategyFlags |= Ctf_BlackPreservation;

	ScColorTransformInfo transInfo;
	transInfo.inputProfile    = inputProfile.productDescription();
	transInfo.outputProfile   = outputProfile.productDescription();
	transInfo.proofingProfile = proofProfile.productDescription();
	transInfo.inputFormat     = inputFormat;
	transInfo.outputFormat    = outputFormat;
	transInfo.renderIntent    = renderIntent;
	transInfo.proofingIntent  = proofingIntent;
	transInfo.flags = transformFlags | strategyFlags;

	DWORD lcmsFlags     = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
	DWORD lcmsInputFmt  = translateFormatToLcmsFormat(inputFormat);
	DWORD lcmsOutputFmt = translateFormatToLcmsFormat(outputFormat);
	int   lcmsIntent    = translateIntentToLcmsIntent(renderIntent);
	int   lcmsPrfIntent = translateIntentToLcmsIntent(proofingIntent);

	if (transInfo.inputProfile != transInfo.proofingProfile)
	{
		if (transInfo.proofingProfile == transInfo.outputProfile)
		{
			transInfo.proofingIntent = Intent_Relative_Colorimetric;
			lcmsPrfIntent = translateIntentToLcmsIntent(Intent_Relative_Colorimetric);
		}
		transform = m_transformPool->findTransform(transInfo);
		if (transform.isNull())
		{
			cmsSetErrorHandler(&cmsErrorHandler);
			cmsHTRANSFORM hTransform = NULL;
			try
			{
				hTransform = cmsCreateProofingTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt, 
														lcmsOutputProf->m_profileHandle, lcmsOutputFmt,
														lcmsProofingProf->m_profileHandle, lcmsIntent, 
														lcmsPrfIntent, lcmsFlags | cmsFLAGS_SOFTPROOFING);
				if (hTransform)
				{
					ScLcmsColorTransformImpl* newTrans = new ScLcmsColorTransformImpl(engine, hTransform);
					newTrans->setTransformInfo(transInfo);
					transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
					m_transformPool->addTransform(transform, true);
				}
			}
			catch (lcmsException& e)
			{
				std::cerr << e.what() << std::endl;
				// #9922 : no idea why that crash in release mode
				/*if (transform.isNull() && hTransform)
					cmsDeleteTransform(hTransform);*/
				transform = ScColorTransform();
			}
			cmsSetErrorHandler(NULL);
		}
	}
	else
	{
		transformFlags  &= (~Ctf_Softproofing);
		transformFlags  &= (~Ctf_GamutCheck);
		lcmsFlags        = translateFlagsToLcmsFlags(transformFlags | strategyFlags);
		transInfo.flags  = transformFlags | strategyFlags;
		transInfo.renderIntent   = proofingIntent;
		transInfo.proofingIntent = (eRenderIntent) 0;
		if (transInfo.inputProfile == transInfo.outputProfile)
		{
			lcmsFlags |= cmsFLAGS_NULLTRANSFORM;
			transInfo.inputProfile    = QString();
			transInfo.outputProfile   = QString();
			transInfo.proofingProfile = QString();
			transInfo.renderIntent    = (eRenderIntent) 0;
			transInfo.proofingIntent  = (eRenderIntent) 0;
			transInfo.flags = 0;
		}
		transform = m_transformPool->findTransform(transInfo);
		if (transform.isNull())
		{
			cmsSetErrorHandler(&cmsErrorHandler);
			cmsHTRANSFORM hTransform = NULL;
			try
			{
				hTransform  = cmsCreateTransform(lcmsInputProf->m_profileHandle , lcmsInputFmt, 
											     lcmsOutputProf->m_profileHandle, lcmsOutputFmt, 
												 lcmsPrfIntent, lcmsFlags | cmsFLAGS_LOWRESPRECALC);
				if (hTransform)
				{
					ScLcmsColorTransformImpl* newTrans = new ScLcmsColorTransformImpl(engine, hTransform);
					newTrans->setTransformInfo(transInfo);
					transform = ScColorTransform(dynamic_cast<ScColorTransformData*>(newTrans));
					m_transformPool->addTransform(transform, true);
				}
			}
			catch (lcmsException& e)
			{
				std::cerr << e.what() << std::endl;
				// #9922 : no idea why that crash in release mode
				/*if (transform.isNull() && hTransform)
					cmsDeleteTransform(hTransform);*/
				transform = ScColorTransform();
			}
			cmsSetErrorHandler(NULL);
		}
	}
	return transform;
}
예제 #14
0
int main(int argc, char *argv[])
{
	int i, nargs;
	cmsHPROFILE Profiles[257];
	cmsHPROFILE hProfile;
	DWORD dwFlags = 0;
	cmsHTRANSFORM hTransform;
    

     fprintf(stderr, "little cms device link generator - v1.7\n");

	 HandleSwitches(argc, argv);

     cmsSetErrorHandler(MyErrorHandler);

     nargs = (argc - xoptind);
	 if (nargs < 1)
				Help(0); 
	 
	 if (nargs > 255)
			FatalError("ERROR: Holy profile! what are you trying to do with so many profiles?");


	 for (i=0; i < nargs; i++) {
		 Profiles[i] = OpenProfile(argv[i + xoptind]);
	 }

	

	 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);
	 }

     if (BlackPointCompensation)
            dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

     if (BlackPreservation > 0) {

            dwFlags |= cmsFLAGS_PRESERVEBLACK;
            cmsSetCMYKPreservationStrategy(BlackPreservation-1);
     }

     if (TagResult)
            dwFlags |= cmsFLAGS_GUESSDEVICECLASS;

     if (NoPrelinearization)
         dwFlags |= cmsFLAGS_NOPRELINEARIZATION;
            
     if (InkLimit != 400.0) {

            cmsHPROFILE hInkLimit = cmsCreateInkLimitingDeviceLink(
                                    cmsGetColorSpace(Profiles[nargs-1]), InkLimit);

            Profiles[nargs++] = hInkLimit;
     }

     if (lUse8bits) dwFlags |= cmsFLAGS_NOPRELINEARIZATION;

	 hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags);
	 if (hTransform) {

        size_t size = sizeof(int) + nargs * sizeof(cmsPSEQDESC);
        LPcmsSEQ pseq = (LPcmsSEQ) _cmsMalloc(size);
        
        ZeroMemory(pseq, size);
        pseq ->n = nargs;

        for (i=0; i < nargs; i++) {

            strcpy(pseq ->seq[i].Manufacturer, cmsTakeManufacturer(Profiles[i]));
            strcpy(pseq ->seq[1].Model, cmsTakeModel(Profiles[i]));
        }
	       
		hProfile = 	cmsTransform2DeviceLink(hTransform, dwFlags);

		cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) Description);
		cmsAddTag(hProfile, icSigCopyrightTag, (LPVOID) "Generated by littlecms icclink. No copyright, use freely");
        cmsAddTag(hProfile, icSigProfileSequenceDescTag, (LPVOID) pseq);

        if (lUse8bits) _cmsSetLUTdepth(hProfile, 8);

		if (_cmsSaveProfile(hProfile, cOutProf)) 
				fprintf(stderr, "Ok");
		else 
				fprintf(stderr, "Error saving file!");

		cmsCloseProfile(hProfile);
        _cmsFree(pseq);
	 }

	 cmsDeleteTransform(hTransform);

	 for (i=0; i < nargs; i++) {
		 cmsCloseProfile(Profiles[i]);
	 }

		 	
     return 0;     
}
예제 #15
0
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
    
    cmsSetErrorHandler(MatLabErrorHandler);
    
    // Defaults

    Verbose     = 0;
    cInProf     = NULL;
    cOutProf    = NULL;
    cProofing   = NULL;

	lMultiProfileChain = FALSE;
	nProfiles   = 0;

    Intent      = INTENT_PERCEPTUAL;
    ProofingIntent          = INTENT_ABSOLUTE_COLORIMETRIC;
    PrecalcMode = 0;
    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!
}