151{
152 int minargs = 2;
153 if (argc < minargs) {
155 return -1;
156 }
157
160
161 if (argc > 2 && !
stricmp(argv[1],
"-cfg")) {
162 json cfg;
164 printf("Unable to read configuration from '%s'\n", argv[2]);
165 return -1;
166 }
167
168 if (cfg.find(
"imageFiles") == cfg.end() || !cfgApply.
fromJson(cfg[
"imageFiles"])) {
169 printf("Unable to parse imageFiles configuration from '%s'\n", argv[2]);
170 return -1;
171 }
172
173 if (cfg.find(
"profileSequence") == cfg.end() || !cfgProfiles.
fromJson(cfg[
"profileSequence"])) {
174 printf("Unable to parse profileSequence configuration from '%s'\n", argv[2]);
175 return -1;
176 }
177 }
178 else {
179 argv++;
180 argc--;
181
182 int nArg = cfgApply.
fromArgs(&argv[0], argc);
183 if (!nArg) {
184 printf("Unable to parse configuration arguments\n");
186 return -1;
187 }
188 argv += nArg;
189 argc -= nArg;
190
191 nArg = cfgProfiles.
fromArgs(&argv[0], argc);
192 if (!nArg) {
193 printf("Unable to parse profile sequence arguments\n");
195 return -1;
196 }
197 }
198
199 int i, j, k;
200 unsigned int sn, sphoto, photo, bps, dbps;
202 unsigned char *sptr, *dptr;
203 bool bSuccess = true;
204 bool bConvert = false;
205 const char *last_path = NULL;
206
207
209 printf(
"\nFile [%s] cannot be opened.\n", cfgApply.
m_srcImgFile.c_str());
210 return false;
211 }
215
216
217 icFloatColorEncoding srcEncoding, destEncoding;
218 switch(bps) {
219 case 8:
220 srcEncoding = icEncode8Bit;
221 break;
222 case 16:
223 srcEncoding = icEncode16Bit;
224 break;
225 case 32:
226 srcEncoding = icEncodeFloat;
227 break;
228 default:
229 printf("Source bit depth / color data encoding not supported.\n");
230 return false;
231 }
232
234 destEncoding = srcEncoding;
235 dbps = bps;
236 }
237 else {
239 switch (destEncoding) {
240 case icEncode8Bit:
241 dbps = 8;
242 break;
243 case icEncode16Bit:
244 dbps = 16;
245 break;
246 case icEncodeFloat:
247 dbps = 32;
248 break;
249 default:
250 printf("Source color data encoding not recognized.\n");
251 return false;
252 }
253 }
254 unsigned char* pSrcProfile;
255 unsigned int nSrcProfileLen;
256 bool bHasSrcProfile = SrcImg.
GetIccProfile(pSrcProfile, nSrcProfileLen);
257
258
262
263
264
265
266
268
269
270
272
274
275
276
277 bool bFirst = true;
278 for (
auto pProfIter = cfgProfiles.
m_profiles.begin(); pProfIter != cfgProfiles.
m_profiles.end(); bFirst=
false, pProfIter++) {
280
281 if (!pProfCfg) {
282 printf("Invalid Profile configuration!\n");
283 return -1;
284 }
285
286 CIccProfile* pPccProfile = NULL;
287
288
289 CIccCreateXformHintManager Hint;
292
294 Hint.AddHint(new CIccLuminanceMatchingHint());
295 }
296
299 if (!pPccProfile) {
300 printf(
"Unable to open Profile Connections Conditions from '%s'\n", pProfCfg->
m_pccFile.c_str());
301 return -1;
302 }
303
304 pccList.push_back(pPccProfile);
305 }
306
307
310 }
311
314 }
315
316
317 if (bFirst && !pProfCfg->
m_iccFile.size()) {
318 if (bHasSrcProfile) {
321 pProfCfg->m_interpolation,
322 pPccProfile,
323 pProfCfg->m_transform,
324 pProfCfg->m_useD2BxB2Dx,
325 &Hint,
326 pProfCfg->m_useV5SubProfile)) {
327 printf(
"Invalid embedded profile in [%s]!\n", cfgApply.
m_srcImgFile.c_str());
328 return -1;
329 }
330 }
331 else {
332 printf("Source image doesn't have embedded profile!\n");
333 return -1;
334 }
335
336 }
337 else {
339 if (theCmm.AddXform(pProfCfg->
m_iccFile.c_str(),
341 pProfCfg->m_interpolation,
342 pPccProfile,
343 pProfCfg->m_transform,
344 pProfCfg->m_useD2BxB2Dx,
345 &Hint,
346 pProfCfg->m_useV5SubProfile)) {
347 printf(
"Invalid Profile: %s\n", pProfCfg->
m_iccFile.c_str());
348 return -1;
349 }
350 }
351 }
352
353
354
355 if((stat=theCmm.Begin())) {
356 printf("Error %d - Unable to begin profile application - Possibly invalid or incompatible profiles\n", stat);
357 return -1;
358 }
359
360
361 IccProfilePtrList::iterator pcc;
362 for (pcc=pccList.begin(); pcc!=pccList.end(); pcc++) {
363 CIccProfile *pPccProfile = *pcc;
364 delete pPccProfile;
365 }
366 pccList.clear();
367
368
371
372 if (nSrcSamples != (int)sn) {
373 printf(
"Number of samples %d in image[%s] doesn't match device samples %d in first profile\n", sn, cfgApply.
m_srcImgFile.c_str(), nSrcSamples);
374 return -1;
375 }
376
377
380
381 switch (DestspaceSig) {
384 break;
385
394 break;
395
397 bConvert = true;
398
399
402 break;
403
404 default:
406 break;
407 }
408
409 unsigned long sbpp = (nSrcSamples * bps + 7) / 8;
410 unsigned long dbpp = (nDestSamples * dbps + 7)/ 8;
411
412
414 printf(
"Unable to create Tiff file - '%s'\n", cfgApply.
m_dstImgFile.c_str());
415 return false;
416 }
417
418
419 if (bEmbed && last_path) {
420 unsigned long length = 0;
422
424 if (io.
Open(last_path,
"r")) {
427 if (pDestProfile) {
428 io.
Read8(pDestProfile, length);
430 free(pDestProfile);
431 }
433 }
434 }
435
436
437 unsigned char *pSBuf = (
unsigned char *)malloc(SrcImg.
GetBytesPerLine());
438 if (!pSBuf) {
439 printf("Out of Memory!\n");
440 return false;
441 }
442
443
444 unsigned char *pDBuf = (
unsigned char *)malloc(DstImg.
GetBytesPerLine());
445 if (!pDBuf) {
446 printf("Out of Memory!\n");
447 free(pSBuf);
448 return false;
449 }
450
451
452 CIccPixelBuf SrcPixel(nSrcSamples+16), DestPixel(nDestSamples+16), Pixel(
icIntMax(nSrcSamples, nDestSamples)+16);
453 int lastPer = -1;
454 int curper;
455
456
457 for (i=0; i<(int)SrcImg.
GetHeight(); i++) {
459 bSuccess = false;
460 break;
461 }
462 for (sptr=pSBuf, dptr=pDBuf, j=0; j<(int)SrcImg.
GetWidth(); j++, sptr+=sbpp, dptr+=dbpp) {
463
464
465 switch(bps) {
466 case 8:
468 unsigned char *pSPixel = sptr;
473 }
474 else {
475 unsigned char *pSPixel = sptr;
477 for (k=0; k<nSrcSamples; k++) {
479 }
480 }
481 break;
482
483 case 16:
485 unsigned short *pSPixel = (unsigned short*)sptr;
490 }
491 else {
492 unsigned short *pSPixel = (unsigned short*)sptr;
494 for (k=0; k<nSrcSamples; k++) {
496 }
497 }
498 break;
499
500 case 32:
501 {
503 memcpy(SrcPixel.get(), sptr, sbpp);
504 }
505 else {
508 for (k=0; k<nSrcSamples; k++) {
510 }
511 }
512
515 }
516 }
517 break;
518
519 default:
520 printf("Invalid source bit depth\n");
521 return -1;
522 }
527 }
528
529
530 theCmm.Apply(DestPixel, SrcPixel);
531
532
537 }
538 switch(dbps) {
539 case 8:
541 unsigned char *pDPixel = dptr;
546 }
547 else {
550 for (k=0; k<nDestSamples; k++) {
552 }
553 }
554 break;
555
556 case 16:
558 unsigned short *pDPixel = (unsigned short*)dptr;
563 }
564 else {
567 for (k=0; k<nDestSamples; k++) {
569 }
570 }
571 break;
572
573 case 32:
574 {
577 }
578
580 memcpy(dptr, DestPixel.get(), dbpp);
581 }
582 else {
585 for (k=0; k<nDestSamples; k++) {
587 }
588 }
589 }
590 break;
591
592 default:
593 printf("Invalid source bit depth\n");
594 return -1;
595 }
596 }
597
598
600 bSuccess = false;
601 break;
602 }
603
604
605 curper = (int)((
float)(i+1)*100.0f/(
float)SrcImg.
GetHeight());
606 if (curper !=lastPer) {
607 printf("\r%d%%", curper);
608 lastPer = curper;
609 }
610 }
611 printf("\n");
612
613
615
616 free(pSBuf);
617 free(pDBuf);
618
620
621 return 0;
622}
icStatusCMM
CMM return status values.
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
bool loadJsonFrom(json &j, const char *szFname)
CIccProfile * OpenIccProfile(const icChar *szFilename, bool bUseSubProfile)
Name: OpenIccProfile.
void icXyzToPcs(icFloatNumber *XYZ)
void icXyzFromPcs(icFloatNumber *XYZ)
Floating point encoding of XYZ in PCS is in range 0.0 to 1.0 (Note: X=1.0 is encoded as about 0....
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
void icLabFromPcs(icFloatNumber *Lab)
Floating point encoding of Lab in PCS is in range 0.0 to 1.0.
void icLabToPcs(icFloatNumber *Lab)
void icLabtoXYZ(icFloatNumber *XYZ, const icFloatNumber *Lab, const icFloatNumber *WhiteXYZ)
icUInt32Number icIntMax(icUInt32Number v1, icUInt32Number v2)
void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ, const icFloatNumber *WhiteXYZ)
unsigned int icUInt32Number
icFloatColorEncoding m_dstEncoding
int fromArgs(const char **args, int nArg, bool bReset=false)
bool fromJson(json obj, bool bReset=false)
icDstBool m_dstCompression
icCmmEnvSigMap m_pccEnvVars
icCmmEnvSigMap m_iccEnvVars
bool m_adjustPcsLuminance
CIccCfgProfileArray m_profiles
int fromArgs(const char **args, int nArg, bool bReset=false)
bool fromJson(json obj, bool bReset=false)
virtual icInt32Number Read8(void *pBuf, icInt32Number nNum=1)
virtual icInt32Number GetLength()
bool Open(const icChar *szFilename, const icChar *szAttr)
bool Open(const char *szFname)
unsigned int GetBitsPerSample()
bool Create(const char *szFname, unsigned int nWidth, unsigned int nHeight, unsigned int nBPS, unsigned int nPhoto, unsigned int nSamples, float fXRes, float fYRes, bool bCompress=true, bool bSep=false)
unsigned int GetSamples()
bool WriteLine(unsigned char *pBuf)
unsigned int GetBytesPerLine()
bool ReadLine(unsigned char *pBuf)
bool SetIccProfile(unsigned char *pProfile, unsigned int nLen)
bool GetIccProfile(unsigned char *&pProfile, unsigned int &nLen)
unsigned int GetCompress()
std::list< CIccProfile * > IccProfilePtrList
static icFloatNumber UnitClip(icFloatNumber v)