⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmslut.c

📁 Linux下的无线网卡通用驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
              MAT3evalW(&OutVect, &Lut -> Matrix, &InVect);              // PCS in 1Fixed15 format, adjusting              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));       }              // First linearization       if (Lut -> wFlags & LUT_HASTL1)       {              for (i=0; i < Lut -> InputChan; i++)                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],                                                   Lut -> L1[i],                                                   &Lut -> In16params);       }       //  Mat3, Ofs3, L3 processing                    if (Lut ->wFlags & LUT_HASMATRIX3) {              WVEC3 InVect, OutVect;              InVect.n[VX] = ToFixedDomain(StageABC[0]);              InVect.n[VY] = ToFixedDomain(StageABC[1]);              InVect.n[VZ] = ToFixedDomain(StageABC[2]);              MAT3evalW(&OutVect, &Lut -> Mat3, &InVect);                            OutVect.n[VX] += Lut ->Ofs3.n[VX];              OutVect.n[VY] += Lut ->Ofs3.n[VY];              OutVect.n[VZ] += Lut ->Ofs3.n[VZ];              StageABC[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));              StageABC[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));              StageABC[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));       }              if (Lut ->wFlags & LUT_HASTL3) {             for (i=0; i < Lut -> InputChan; i++)                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],                                                   Lut -> L3[i],                                                   &Lut -> L3params);       }       if (Lut -> wFlags & LUT_HAS3DGRID) {            Lut ->CLut16params.Interp3D(StageABC, StageLMN, Lut -> T, &Lut -> CLut16params);       }       else       {                            for (i=0; i < Lut -> InputChan; i++)                            StageLMN[i] = StageABC[i];       }       // Mat4, Ofs4, L4 processing            if (Lut ->wFlags & LUT_HASTL4) {            for (i=0; i < Lut -> OutputChan; i++)                     StageLMN[i] = cmsLinearInterpLUT16(StageLMN[i],                                                   Lut -> L4[i],                                                   &Lut -> L4params);       }               if (Lut ->wFlags & LUT_HASMATRIX4) {              WVEC3 InVect, OutVect;              InVect.n[VX] = ToFixedDomain(StageLMN[0]);              InVect.n[VY] = ToFixedDomain(StageLMN[1]);              InVect.n[VZ] = ToFixedDomain(StageLMN[2]);              MAT3evalW(&OutVect, &Lut -> Mat4, &InVect);                            OutVect.n[VX] += Lut ->Ofs4.n[VX];              OutVect.n[VY] += Lut ->Ofs4.n[VY];              OutVect.n[VZ] += Lut ->Ofs4.n[VZ];              StageLMN[0] = _cmsClampWord(FromFixedDomain(OutVect.n[VX]));              StageLMN[1] = _cmsClampWord(FromFixedDomain(OutVect.n[VY]));              StageLMN[2] = _cmsClampWord(FromFixedDomain(OutVect.n[VZ]));       }       // Last linearitzation       if (Lut -> wFlags & LUT_HASTL2)       {              for (i=0; i < Lut -> OutputChan; i++)                     Out[i] = cmsLinearInterpLUT16(StageLMN[i],                                                   Lut -> L2[i],                                                   &Lut -> Out16params);       }       else       {       for (i=0; i < Lut -> OutputChan; i++)              Out[i] = StageLMN[i];       }              if (Lut ->wFlags & LUT_V4_INPUT_EMULATE_V2) {                      Out[0] = (WORD) FROM_V4_TO_V2(Out[0]);           Out[1] = (WORD) FROM_V4_TO_V2(Out[1]);           Out[2] = (WORD) FROM_V4_TO_V2(Out[2]);                  }       if (Lut ->wFlags & LUT_V2_INPUT_EMULATE_V4) {                      Out[0] = (WORD) FROM_V2_TO_V4(Out[0]);           Out[1] = (WORD) FROM_V2_TO_V4(Out[1]);           Out[2] = (WORD) FROM_V2_TO_V4(Out[2]);                  }}// Precomputes tables for 8-bit on input devicelink. // LPLUT _cmsBlessLUT8(LPLUT Lut){   int i, j;   WORD StageABC[3];   Fixed32 v1, v2, v3;   LPL8PARAMS p8;    LPL16PARAMS p = &Lut ->CLut16params;     p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS));   if (p8 == NULL) return NULL;  // values comes * 257, so we can safely take first byte (x << 8 + x)  // if there are prelinearization, is already smelted in tables   for (i=0; i < 256; i++) {           StageABC[0] = StageABC[1] = StageABC[2] = RGB_8_TO_16(i);           if (Lut ->wFlags & LUT_HASTL1) {              for (j=0; j < 3; j++)                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],                                                        Lut -> L1[i],                                                       &Lut -> In16params);              Lut ->wFlags &= ~LUT_HASTL1;           }                              v1 = ToFixedDomain(StageABC[0] * p -> Domain);           v2 = ToFixedDomain(StageABC[1] * p -> Domain);           v3 = ToFixedDomain(StageABC[2] * p -> Domain);           p8 ->X0[i] = p->opta3 * FIXED_TO_INT(v1);           p8 ->Y0[i] = p->opta2 * FIXED_TO_INT(v2);           p8 ->Z0[i] = p->opta1 * FIXED_TO_INT(v3);           p8 ->rx[i] = (WORD) FIXED_REST_TO_INT(v1);           p8 ->ry[i] = (WORD) FIXED_REST_TO_INT(v2);           p8 ->rz[i] = (WORD) FIXED_REST_TO_INT(v3);    }   Lut -> CLut16params.p8 = p8;   Lut -> CLut16params.Interp3D = cmsTetrahedralInterp8;   return Lut;}// ----------------------------------------------------------- Reverse interpolation// Here's how it goes. The derivative Df(x) of the function f is the linear // transformation that best approximates f near the point x. It can be represented // by a matrix A whose entries are the partial derivatives of the components of f // with respect to all the coordinates. This is know as the Jacobian//// The best linear approximation to f is given by the matrix equation: // // y-y0 = A (x-x0) // // So, if x0 is a good "guess" for the zero of f, then solving for the zero of this // linear approximation will give a "better guess" for the zero of f. Thus let y=0, // and since y0=f(x0) one can solve the above equation for x. This leads to the // Newton's method formula: //// xn+1 = xn - A-1 f(xn) // // where xn+1 denotes the (n+1)-st guess, obtained from the n-th guess xn in the // fashion described above. Iterating this will give better and better approximations // if you have a "good enough" initial guess. #define JACOBIAN_EPSILON            0.001#define INVERSION_MAX_ITERATIONS    30// Evaluates the CLUT part of a LUT (3x3 only)staticvoid EvalLUTdoubleK(LPLUT Lut, const VEC3* In, WORD FixedK, LPVEC3 Out){    WORD wIn[4], wOut[3];    wIn[0] = (WORD) floor(In ->n[0] * 65535.0 + 0.5);    wIn[1] = (WORD) floor(In ->n[1] * 65535.0 + 0.5);    wIn[2] = (WORD) floor(In ->n[2] * 65535.0 + 0.5);    wIn[3] = FixedK;    cmsEvalLUT(Lut, wIn, wOut);         Out ->n[0] = (double) wOut[0] / 65535.0;    Out ->n[1] = (double) wOut[1] / 65535.0;    Out ->n[2] = (double) wOut[2] / 65535.0;    }// Increment with reflexion on boundarystatic void IncDelta(double *Val){    if (*Val < (1.0 - JACOBIAN_EPSILON))         *Val += JACOBIAN_EPSILON;        else         *Val -= JACOBIAN_EPSILON;    }// Builds a Jacobian CMY->Labstaticvoid ComputeJacobian(LPLUT Lut, LPMAT3 Jacobian, const VEC3* Colorant, WORD K){    VEC3 ColorantD;    double DeltaColorant;    VEC3 Lab, LabD;    int  i, j;                EvalLUTdoubleK(Lut, Colorant, K, &Lab);        for (j = 0; j < 3; j++) {        ColorantD.n[0] = Colorant ->n[0];        ColorantD.n[1] = Colorant ->n[1];        ColorantD.n[2] = Colorant ->n[2];                IncDelta(&ColorantD.n[j]);        EvalLUTdoubleK(Lut, &ColorantD, K, &LabD);        DeltaColorant = (Colorant->n[j] - ColorantD.n[j]);        for (i = 0; i < 3; i++) {            double DeltaTristim  = (Lab.n[i] - LabD.n[i]);                        Jacobian->v[i].n[j] = (DeltaTristim / DeltaColorant);        }    }}staticvoid ToEncoded(WORD Encoded[3], LPVEC3 Float){    Encoded[0] = (WORD) floor(Float->n[0] * 65535.0 + 0.5);    Encoded[1] = (WORD) floor(Float->n[1] * 65535.0 + 0.5);    Encoded[2] = (WORD) floor(Float->n[2] * 65535.0 + 0.5);}staticvoid FromEncoded(LPVEC3 Float, WORD Encoded[3]){    Float->n[0] = Encoded[0] / 65535.0;    Float->n[1] = Encoded[1] / 65535.0;    Float->n[2] = Encoded[2] / 65535.0;}// Evaluate a LUT in reverse direction. It only searches on 3->3 LUT, but It // can be used on CMYK -> Lab LUT to obtain black preservation. // Target holds LabK in this caseLCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Result[], LPWORD Hint){    int      i;    double   error, LastError;    VEC3     Guess;    VEC3     Goal, TestPoint, Colorant;    MAT3     Jacobian, JacobianInverse;    WORD     FixedK;    WORD     LastResult[4];                // This is our Lab goal    FromEncoded(&Goal, Target);        // Special case for CMYK->Lab     if (Lut ->InputChan == 4)            FixedK = Target[3];    else            FixedK = 0;                // Take the hint as starting point if specified    if (Hint == NULL) {        // Begin at any point, we choose 1/3 of neutral CMY gray        Colorant.n[0] =         Colorant.n[1] =         Colorant.n[2] = 0.3;    }    else {        FromEncoded(&Colorant, Hint);    }                    LastError = 1E20;    // Iterate        for (i = 0; i < INVERSION_MAX_ITERATIONS; i++) {        // Get beginning guess        EvalLUTdoubleK(Lut, &Colorant, FixedK, &Guess);            // Compute error        error = VEC3distance(&Guess, &Goal);                                // If not convergent, return last safe value        if (error >= LastError)             break;        // Keep latest values        LastError = error;        ToEncoded(LastResult, &Colorant);        LastResult[3] = FixedK;                        // Obtain slope        ComputeJacobian(Lut, &Jacobian, &Colorant, FixedK);        // Evaluate jacobian        MAT3eval(&TestPoint, &Jacobian, &Colorant);                // Move testpoint        TestPoint.n[0] += (Goal.n[0] - Guess.n[0]);        TestPoint.n[1] += (Goal.n[1] - Guess.n[1]);        TestPoint.n[2] += (Goal.n[2] - Guess.n[2]);        VEC3saturate(&TestPoint);                       // Jacobian ^ -1        if (MAT3inverse(&Jacobian, &JacobianInverse) < 0) {            // Singular matrix,             break;        }        // Obtain colorant from current point        MAT3eval(&Colorant, &JacobianInverse, &TestPoint);        // Some clipping....        VEC3saturate(&Colorant);                    }    Result[0] = LastResult[0];    Result[1] = LastResult[1];    Result[2] = LastResult[2];    Result[3] = LastResult[3];    return LastError;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -