~vcs-imports/lcms/main

« back to all changes in this revision

Viewing changes to src/cmslut.c

  • Committer: mm2
  • Date: 2006-08-11 15:48:30 UTC
  • Revision ID: vcs-imports@canonical.com-20060811154830-7ddd1a05a699e8cb
no message

Show diffs side-by-side

added added

removed removed

Lines of Context:
622
622
#define JACOBIAN_EPSILON            0.001
623
623
#define INVERSION_MAX_ITERATIONS    30
624
624
 
625
 
/*
626
 
// Evaluates the CLUT part of a LUT (3x3 only)
627
 
 
628
 
static
629
 
void EvalLUTdoubleK(LPLUT Lut, const VEC3* In, WORD FixedK, LPVEC3 Out)
630
 
{
631
 
    WORD wIn[4], wOut[3];
632
 
 
633
 
    wIn[0] = (WORD) floor(In ->n[0] * 65535.0 + 0.5);
634
 
    wIn[1] = (WORD) floor(In ->n[1] * 65535.0 + 0.5);
635
 
    wIn[2] = (WORD) floor(In ->n[2] * 65535.0 + 0.5);
636
 
    wIn[3] = FixedK;
637
 
 
638
 
    cmsEvalLUT(Lut, wIn, wOut);     
639
 
 
640
 
    Out ->n[0] = (double) wOut[0] / 65535.0;
641
 
    Out ->n[1] = (double) wOut[1] / 65535.0;
642
 
    Out ->n[2] = (double) wOut[2] / 65535.0;    
643
 
}
644
 
*/
 
625
 
645
626
 
646
627
// Increment with reflexion on boundary
647
628
 
658
639
}
659
640
 
660
641
 
661
 
/*
662
 
// Builds a Jacobian CMY->Lab
663
 
 
664
 
static
665
 
void ComputeJacobian(LPLUT Lut, LPMAT3 Jacobian, const VEC3* Colorant, WORD K)
666
 
{
667
 
    VEC3 ColorantD;
668
 
    double DeltaColorant;
669
 
    VEC3 Lab, LabD;
670
 
    int  i, j;
671
 
            
672
 
    EvalLUTdoubleK(Lut, Colorant, K, &Lab);
673
 
    
674
 
 
675
 
    for (j = 0; j < 3; j++) {
676
 
 
677
 
        ColorantD.n[0] = Colorant ->n[0];
678
 
        ColorantD.n[1] = Colorant ->n[1];
679
 
        ColorantD.n[2] = Colorant ->n[2];
680
 
        
681
 
        IncDelta(&ColorantD.n[j]);
682
 
 
683
 
        EvalLUTdoubleK(Lut, &ColorantD, K, &LabD);
684
 
 
685
 
        DeltaColorant = (Colorant->n[j] - ColorantD.n[j]);
686
 
 
687
 
        for (i = 0; i < 3; i++) {
688
 
 
689
 
            double DeltaTristim  = (Lab.n[i] - LabD.n[i]);
690
 
            
691
 
            Jacobian->v[i].n[j] = (DeltaTristim / DeltaColorant);
692
 
        }
693
 
    }
694
 
}
695
 
*/
696
642
 
697
643
static
698
644
void ToEncoded(WORD Encoded[3], LPVEC3 Float)
849
795
}
850
796
 
851
797
 
852
 
/*
853
 
 
854
 
LCMSAPI double LCMSEXPORT cmsEvalLUTreverse2(LPLUT Lut, WORD Target[], WORD Result[], LPWORD Hint)
855
 
{
856
 
    int      i;
857
 
    double   error, LastError;
858
 
    VEC3     fx;
859
 
    VEC3     Goal, TestPoint, x;
860
 
    MAT3     Jacobian, JacobianInverse;
861
 
    WORD     FixedK;
862
 
    WORD     LastResult[4];
863
 
    
864
 
 
865
 
 
866
 
        
867
 
    // This is our Lab goal
868
 
    FromEncoded(&Goal, Target);
869
 
    
870
 
    // Special case for CMYK->Lab 
871
 
 
872
 
    if (Lut ->InputChan == 4)
873
 
            FixedK = Target[3];
874
 
    else
875
 
            FixedK = 0;
876
 
        
877
 
    
878
 
    // Take the hint as starting point if specified
879
 
 
880
 
    if (Hint == NULL) {
881
 
 
882
 
        // Begin at any point, we choose 1/3 of neutral CMY gray
883
 
 
884
 
        x.n[0] = x.n[1] = x.n[2] = 0.3;
885
 
 
886
 
    }
887
 
    else {
888
 
        FromEncoded(&x, Hint);
889
 
    }
890
 
    
891
 
            
892
 
    LastError = 1E20;
893
 
 
894
 
    // Iterate
895
 
    
896
 
    for (i = 0; i < INVERSION_MAX_ITERATIONS; i++) {
897
 
 
898
 
        // Get beginning fx
899
 
        EvalLUTdoubleK(Lut, &x, FixedK, &fx);
900
 
    
901
 
        // Compute error
902
 
        error = VEC3distance(&fx, &Goal);
903
 
                        
904
 
        // If not convergent, return last safe value
905
 
        if (error >= LastError) 
906
 
            break;
907
 
 
908
 
        // Keep latest values
909
 
        LastError = error;
910
 
 
911
 
        ToEncoded(LastResult, &x);
912
 
        LastResult[3] = FixedK;
913
 
 
914
 
                
915
 
        // Obtain slope
916
 
        ComputeJacobian(Lut, &Jacobian, &x, FixedK);
917
 
 
918
 
        // Evaluate jacobian
919
 
        MAT3eval(&TestPoint, &Jacobian, &x);
920
 
        
921
 
        // Move testpoint
922
 
        TestPoint.n[0] += (Goal.n[0] - fx.n[0]);
923
 
        TestPoint.n[1] += (Goal.n[1] - fx.n[1]);
924
 
        TestPoint.n[2] += (Goal.n[2] - fx.n[2]);
925
 
 
926
 
        VEC3saturate(&TestPoint);       
927
 
        
928
 
        // Jacobian ^ -1
929
 
        if (MAT3inverse(&Jacobian, &JacobianInverse) < 0) {
930
 
 
931
 
            // Singular matrix, 
932
 
            break;
933
 
        }
934
 
 
935
 
 
936
 
        // Obtain x from current point
937
 
        MAT3eval(&x, &JacobianInverse, &TestPoint);
938
 
 
939
 
        // Some clipping....
940
 
        VEC3saturate(&x);                
941
 
    }
942
 
 
943
 
    Result[0] = LastResult[0];
944
 
    Result[1] = LastResult[1];
945
 
    Result[2] = LastResult[2];
946
 
    Result[3] = LastResult[3];
947
 
 
948
 
    return LastError;    
949
 
    
950
 
}
951
 
 
952
 
*/
953
 
 
954
798