322 else if( PCS == cmsSigXYZData)
323 {
324 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
325 goto Error;
326 }
327
328 return Lut;
329
330 Error:
331 cmsPipelineFree(Lut);
332 return NULL;
333 }
334
335
336 // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
337 // is adjusted here in order to create a LUT that takes care of all those details.
338 // We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
339 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
340 {
341 cmsTagTypeSignature OriginalType;
342 cmsTagSignature tag16 = Device2PCS16[Intent];
343 cmsTagSignature tagFloat = Device2PCSFloat[Intent];
344 cmsContext ContextID = cmsGetProfileContextID(hProfile);
345
346 // On named color, take the appropiate tag
347 if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
348
349 cmsPipeline* Lut;
350 cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
351
352 if (nc == NULL) return NULL;
353
354 Lut = cmsPipelineAlloc(ContextID, 0, 0);
355 if (Lut == NULL) {
356 cmsFreeNamedColorList(nc);
357 return NULL;
358 }
359
360 if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) ||
361 !cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) {
362 cmsPipelineFree(Lut);
363 return NULL;
364 }
365 return Lut;
366 }
367
368 // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
369 // matter other LUT are present and have precedence. Intent = -1 means just this.
370 if (Intent != -1) {
371
372 if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
373
374 // Floating point LUT are always V4, but the encoding range is no
375 // longer 0..1.0, so we need to add an stage depending on the color space
376 return _cmsReadFloatInputTag(hProfile, tagFloat);
377 }
378
379 // Revert to perceptual if no tag is found
380 if (!cmsIsTag(hProfile, tag16)) {
381 tag16 = Device2PCS16[0];
382 }
383
384 if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
385
386 // Check profile version and LUT type. Do the necessary adjustments if needed
387
388 // First read the tag
389 cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
390 if (Lut == NULL) return NULL;
391
594 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
595 goto Error;
596 }
597 else if (dataSpace == cmsSigXYZData)
598 {
599 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
600 goto Error;
601 }
602
603 return Lut;
604
605 Error:
606 cmsPipelineFree(Lut);
607 return NULL;
608 }
609
610 // Create an output MPE LUT from agiven profile. Version mismatches are handled here
611 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
612 {
613 cmsTagTypeSignature OriginalType;
614 cmsTagSignature tag16 = PCS2Device16[Intent];
615 cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
616 cmsContext ContextID = cmsGetProfileContextID(hProfile);
617
618
619 if (Intent != -1) {
620
621 if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
622
623 // Floating point LUT are always V4
624 return _cmsReadFloatOutputTag(hProfile, tagFloat);
625 }
626
627 // Revert to perceptual if no tag is found
628 if (!cmsIsTag(hProfile, tag16)) {
629 tag16 = PCS2Device16[0];
630 }
631
632 if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
633
634 // Check profile version and LUT type. Do the necessary adjustments if needed
635
636 // First read the tag
637 cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
638 if (Lut == NULL) return NULL;
639
640 // After reading it, we have info about the original type
918 if (ProfileSeq ->n != ProfileId ->n) return cmsDupProfileSequenceDescription(ProfileSeq);
919
920 NewSeq = cmsDupProfileSequenceDescription(ProfileSeq);
921
922 // Ok, proceed to the mixing
923 if (NewSeq != NULL) {
924 for (i=0; i < ProfileSeq ->n; i++) {
925
926 memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID));
927 NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description);
928 }
929 }
930 return NewSeq;
931 }
932
933 // Dump the contents of profile sequence in both tags (if v4 available)
934 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
935 {
936 if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE;
937
938 if (cmsGetProfileVersion(hProfile) >= 4.0) {
939
940 if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE;
941 }
942
943 return TRUE;
944 }
945
946
947 // Auxiliar, read and duplicate a MLU if found.
948 static
949 cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
950 {
951 cmsMLU* mlu = (cmsMLU*) cmsReadTag(h, sig);
952 if (mlu == NULL) return NULL;
953
954 return cmsMLUdup(mlu);
955 }
956
957 // Create a sequence description out of an array of profiles
958 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[])
|
322 else if( PCS == cmsSigXYZData)
323 {
324 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
325 goto Error;
326 }
327
328 return Lut;
329
330 Error:
331 cmsPipelineFree(Lut);
332 return NULL;
333 }
334
335
336 // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
337 // is adjusted here in order to create a LUT that takes care of all those details.
338 // We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
339 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
340 {
341 cmsTagTypeSignature OriginalType;
342 cmsTagSignature tag16;
343 cmsTagSignature tagFloat;
344 cmsContext ContextID = cmsGetProfileContextID(hProfile);
345
346 // On named color, take the appropiate tag
347 if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
348
349 cmsPipeline* Lut;
350 cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
351
352 if (nc == NULL) return NULL;
353
354 Lut = cmsPipelineAlloc(ContextID, 0, 0);
355 if (Lut == NULL) {
356 cmsFreeNamedColorList(nc);
357 return NULL;
358 }
359
360 if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE)) ||
361 !cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID))) {
362 cmsPipelineFree(Lut);
363 return NULL;
364 }
365 return Lut;
366 }
367
368 // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
369 // matter other LUT are present and have precedence. Intent = -1 means just this.
370 if (Intent != -1) {
371
372 tag16 = Device2PCS16[Intent];
373 tagFloat = Device2PCSFloat[Intent];
374
375 if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
376
377 // Floating point LUT are always V4, but the encoding range is no
378 // longer 0..1.0, so we need to add an stage depending on the color space
379 return _cmsReadFloatInputTag(hProfile, tagFloat);
380 }
381
382 // Revert to perceptual if no tag is found
383 if (!cmsIsTag(hProfile, tag16)) {
384 tag16 = Device2PCS16[0];
385 }
386
387 if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
388
389 // Check profile version and LUT type. Do the necessary adjustments if needed
390
391 // First read the tag
392 cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
393 if (Lut == NULL) return NULL;
394
597 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID)))
598 goto Error;
599 }
600 else if (dataSpace == cmsSigXYZData)
601 {
602 if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID)))
603 goto Error;
604 }
605
606 return Lut;
607
608 Error:
609 cmsPipelineFree(Lut);
610 return NULL;
611 }
612
613 // Create an output MPE LUT from agiven profile. Version mismatches are handled here
614 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
615 {
616 cmsTagTypeSignature OriginalType;
617 cmsTagSignature tag16;
618 cmsTagSignature tagFloat;
619 cmsContext ContextID = cmsGetProfileContextID(hProfile);
620
621
622 if (Intent != -1) {
623
624 tag16 = PCS2Device16[Intent];
625 tagFloat = PCS2DeviceFloat[Intent];
626
627 if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
628
629 // Floating point LUT are always V4
630 return _cmsReadFloatOutputTag(hProfile, tagFloat);
631 }
632
633 // Revert to perceptual if no tag is found
634 if (!cmsIsTag(hProfile, tag16)) {
635 tag16 = PCS2Device16[0];
636 }
637
638 if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
639
640 // Check profile version and LUT type. Do the necessary adjustments if needed
641
642 // First read the tag
643 cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
644 if (Lut == NULL) return NULL;
645
646 // After reading it, we have info about the original type
924 if (ProfileSeq ->n != ProfileId ->n) return cmsDupProfileSequenceDescription(ProfileSeq);
925
926 NewSeq = cmsDupProfileSequenceDescription(ProfileSeq);
927
928 // Ok, proceed to the mixing
929 if (NewSeq != NULL) {
930 for (i=0; i < ProfileSeq ->n; i++) {
931
932 memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID));
933 NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description);
934 }
935 }
936 return NewSeq;
937 }
938
939 // Dump the contents of profile sequence in both tags (if v4 available)
940 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
941 {
942 if (!cmsWriteTag(hProfile, cmsSigProfileSequenceDescTag, seq)) return FALSE;
943
944 if (cmsGetEncodedICCversion(hProfile) >= 0x4000000) {
945
946 if (!cmsWriteTag(hProfile, cmsSigProfileSequenceIdTag, seq)) return FALSE;
947 }
948
949 return TRUE;
950 }
951
952
953 // Auxiliar, read and duplicate a MLU if found.
954 static
955 cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
956 {
957 cmsMLU* mlu = (cmsMLU*) cmsReadTag(h, sig);
958 if (mlu == NULL) return NULL;
959
960 return cmsMLUdup(mlu);
961 }
962
963 // Create a sequence description out of an array of profiles
964 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[])
|