📄 cmsio1.c
字号:
NewLUT -> OutputChan = LUT8.outputChan; NewLUT -> InputEntries = 256; NewLUT -> OutputEntries = 256; AdjustEndianess32((LPBYTE) &LUT8.e00); AdjustEndianess32((LPBYTE) &LUT8.e01); AdjustEndianess32((LPBYTE) &LUT8.e02); AdjustEndianess32((LPBYTE) &LUT8.e10); AdjustEndianess32((LPBYTE) &LUT8.e11); AdjustEndianess32((LPBYTE) &LUT8.e12); AdjustEndianess32((LPBYTE) &LUT8.e20); AdjustEndianess32((LPBYTE) &LUT8.e21); AdjustEndianess32((LPBYTE) &LUT8.e22); // Matrix handling NewLUT -> Matrix.v[0].n[0] = (Fixed32) LUT8.e00; NewLUT -> Matrix.v[0].n[1] = (Fixed32) LUT8.e01; NewLUT -> Matrix.v[0].n[2] = (Fixed32) LUT8.e02; NewLUT -> Matrix.v[1].n[0] = (Fixed32) LUT8.e10; NewLUT -> Matrix.v[1].n[1] = (Fixed32) LUT8.e11; NewLUT -> Matrix.v[1].n[2] = (Fixed32) LUT8.e12; NewLUT -> Matrix.v[2].n[0] = (Fixed32) LUT8.e20; NewLUT -> Matrix.v[2].n[1] = (Fixed32) LUT8.e21; NewLUT -> Matrix.v[2].n[2] = (Fixed32) LUT8.e22; // Only operates if not identity... if (!MAT3isIdentity(&NewLUT -> Matrix, 0.0001)) { NewLUT -> wFlags |= LUT_HASMATRIX; } // Copy input tables Temp = (LPBYTE) malloc(256); AllLinear = 0; for (i=0; i < NewLUT -> InputChan; i++) { PtrW = (LPWORD) malloc(sizeof(WORD) * 256); NewLUT -> L1[i] = PtrW; Icc ->Read(Temp, 1, 256, Icc); for (j=0; j < 256; j++) PtrW[j] = TO16_TAB(Temp[j]); AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries); } // Linear input, so ignore full step if (AllLinear == NewLUT -> InputChan) { NewLUT -> wFlags &= ~LUT_HASTL1; } free(Temp); // Copy 3D CLUT nTabSize = (NewLUT -> OutputChan * uipow(NewLUT->cLutPoints, NewLUT->InputChan)); if (nTabSize > 0) { PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize); Temp = (LPBYTE) malloc(nTabSize); Icc ->Read(Temp, 1, nTabSize, Icc); NewLUT -> T = PtrW; NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD)); for (i = 0; i < nTabSize; i++) { *PtrW++ = TO16_TAB(Temp[i]); } free(Temp); } else { NewLUT ->T = NULL; NewLUT ->Tsize = 0; NewLUT -> wFlags &= ~LUT_HAS3DGRID; } // Copy output tables Temp = (LPBYTE) malloc(256); AllLinear = 0; for (i=0; i < NewLUT -> OutputChan; i++) { PtrW = (LPWORD) malloc(sizeof(WORD) * 256); NewLUT -> L2[i] = PtrW; Icc ->Read(Temp, 1, 256, Icc); for (j=0; j < 256; j++) PtrW[j] = TO16_TAB(Temp[j]); AllLinear += cmsIsLinear(NewLUT -> L2[i], 256); } // Linear input, so ignore full step if (AllLinear == NewLUT -> OutputChan) { NewLUT -> wFlags &= ~LUT_HASTL2; } free(Temp); cmsCalcL16Params(NewLUT -> InputEntries, &NewLUT -> In16params); cmsCalcL16Params(NewLUT -> OutputEntries, &NewLUT -> Out16params); cmsCalcCLUT16Params(NewLUT -> cLutPoints, NewLUT -> InputChan, NewLUT -> OutputChan, &NewLUT -> CLut16params); // Fixup if (Icc ->PCS == icSigLabData) { // Abstract or Lab identity if (Icc -> ColorSpace == icSigLabData) FixLUT8bothSides(NewLUT, nTabSize); else FixLUT8(NewLUT, sig, nTabSize); // Now some additional fixup. Lab encoding on 8 bit makes // impossible to place gray axis on a exact node. However, // some profiles does claim to do that. Poor lcms will try // to detect such condition and fix up "on the fly". { LPWORD WhiteLab, ExpectedWhite; WORD WhiteFixed[MAXCHANNELS], WhiteUnfixed[MAXCHANNELS]; int j, nChannels; double Dist, DistFixed, DistUnfixed; _cmsEndPointsBySpace(icSigLabData, &WhiteLab, NULL, NULL); if (_cmsEndPointsBySpace(Icc -> ColorSpace, &ExpectedWhite, NULL, &nChannels)) { // 1.- Find white obtained by both combinations NewLUT -> FixGrayAxes = FALSE; cmsEvalLUT(NewLUT, WhiteLab, WhiteUnfixed); NewLUT -> FixGrayAxes = TRUE; cmsEvalLUT(NewLUT, WhiteLab, WhiteFixed); // 2.- Which method gives closer white? DistFixed = DistUnfixed = 0; for (j=0; j < nChannels; j++) { Dist = ExpectedWhite[j] - WhiteFixed[j]; DistFixed += Dist*Dist; Dist = ExpectedWhite[j] - WhiteUnfixed[j]; DistUnfixed += Dist*Dist; } // 3.- Decide method if (sqrt(DistFixed) < sqrt(DistUnfixed)) NewLUT -> FixGrayAxes = TRUE; else NewLUT -> FixGrayAxes = FALSE; } } }}// Case LUT 16staticvoid ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT){ icLut16 LUT16; size_t nTabSize; unsigned int i; unsigned int AllLinear; LPWORD PtrW; Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc); NewLUT -> wFlags = LUT_HASTL1 | LUT_HASTL2 | LUT_HAS3DGRID; NewLUT -> cLutPoints = LUT16.clutPoints; NewLUT -> InputChan = LUT16.inputChan; NewLUT -> OutputChan = LUT16.outputChan; AdjustEndianess16((LPBYTE) &LUT16.inputEnt); AdjustEndianess16((LPBYTE) &LUT16.outputEnt); NewLUT -> InputEntries = LUT16.inputEnt; NewLUT -> OutputEntries = LUT16.outputEnt; // Matrix handling AdjustEndianess32((LPBYTE) &LUT16.e00); AdjustEndianess32((LPBYTE) &LUT16.e01); AdjustEndianess32((LPBYTE) &LUT16.e02); AdjustEndianess32((LPBYTE) &LUT16.e10); AdjustEndianess32((LPBYTE) &LUT16.e11); AdjustEndianess32((LPBYTE) &LUT16.e12); AdjustEndianess32((LPBYTE) &LUT16.e20); AdjustEndianess32((LPBYTE) &LUT16.e21); AdjustEndianess32((LPBYTE) &LUT16.e22); NewLUT -> Matrix.v[0].n[0] = (Fixed32) LUT16.e00; NewLUT -> Matrix.v[0].n[1] = (Fixed32) LUT16.e01; NewLUT -> Matrix.v[0].n[2] = (Fixed32) LUT16.e02; NewLUT -> Matrix.v[1].n[0] = (Fixed32) LUT16.e10; NewLUT -> Matrix.v[1].n[1] = (Fixed32) LUT16.e11; NewLUT -> Matrix.v[1].n[2] = (Fixed32) LUT16.e12; NewLUT -> Matrix.v[2].n[0] = (Fixed32) LUT16.e20; NewLUT -> Matrix.v[2].n[1] = (Fixed32) LUT16.e21; NewLUT -> Matrix.v[2].n[2] = (Fixed32) LUT16.e22; // Only operates if not identity... if (!MAT3isIdentity(&NewLUT -> Matrix, 0.0001)) { NewLUT -> wFlags |= LUT_HASMATRIX; } // Copy input tables AllLinear = 0; for (i=0; i < NewLUT -> InputChan; i++) { PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries); NewLUT -> L1[i] = PtrW; Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc); AdjustEndianessArray16(PtrW, NewLUT -> InputEntries); AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries); } // Linear input, so ignore full step if (AllLinear == NewLUT -> InputChan) { NewLUT -> wFlags &= ~LUT_HASTL1; } // Copy 3D CLUT nTabSize = (NewLUT -> OutputChan * uipow(NewLUT->cLutPoints, NewLUT->InputChan)); if (nTabSize > 0) { PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize); NewLUT -> T = PtrW; NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD)); Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc); AdjustEndianessArray16(NewLUT -> T, nTabSize); } else { NewLUT ->T = NULL; NewLUT ->Tsize = 0; NewLUT -> wFlags &= ~LUT_HAS3DGRID; } // Copy output tables AllLinear = 0; for (i=0; i < NewLUT -> OutputChan; i++) { PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries); NewLUT -> L2[i] = PtrW; Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc); AdjustEndianessArray16(PtrW, NewLUT -> OutputEntries); AllLinear += cmsIsLinear(NewLUT -> L2[i], NewLUT -> OutputEntries); } // Linear output, ignore step if (AllLinear == NewLUT -> OutputChan) { NewLUT -> wFlags &= ~LUT_HASTL2; } cmsCalcL16Params(NewLUT -> InputEntries, &NewLUT -> In16params); cmsCalcL16Params(NewLUT -> OutputEntries, &NewLUT -> Out16params); cmsCalcCLUT16Params(NewLUT -> cLutPoints, NewLUT -> InputChan, NewLUT -> OutputChan, &NewLUT -> CLut16params);}// This is a shared routine for reading curves. It can handle v2 curves// as linear, single gamma and table-based as well as v4 parametric curves.staticLPGAMMATABLE ReadCurve(LPLCMSICCPROFILE Icc){ icUInt32Number Count; LPGAMMATABLE NewGamma; icTagTypeSignature BaseType; int n; BaseType = ReadBase(Icc); switch (BaseType) { case 0x9478ee00L: // Monaco 2 profiler is BROKEN! case icSigCurveType: Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &Count); switch (Count) { case 0: // Linear. NewGamma = cmsAllocGamma(2); if (!NewGamma) return NULL; NewGamma -> GammaTable[0] = 0; NewGamma -> GammaTable[1] = 0xFFFF; return NewGamma; case 1: // Specified as the exponent of gamma function { WORD SingleGammaFixed; Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc); AdjustEndianess16((LPBYTE) &SingleGammaFixed); return cmsBuildGamma(4096, Convert8Fixed8(SingleGammaFixed)); } default: { // Curve NewGamma = cmsAllocGamma(Count); if (!NewGamma) return NULL; Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc); AdjustEndianessArray16(NewGamma -> GammaTable, Count); return NewGamma; } } break; // Parametric curves case icSigParametricCurveType: { int ParamsByType[] = { 1, 3, 4, 5, 7 }; double Params[10]; icS15Fixed16Number Num; icUInt32Number Reserved; icUInt16Number Type; int i; Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc); Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc); AdjustEndianess16((LPBYTE) &Type); if (Type > 5) { cmsSignalError(LCMS_ERRC_ABORTED, "Unknown parametric curve type '%d' found.", Type); return NULL; } ZeroMemory(Params, 10* sizeof(double)); n = ParamsByType[Type]; for (i=0; i < n; i++) { Num = 0; Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); Params[i] = Convert15Fixed16(Num); } NewGamma = cmsBuildParametricGamma(4096, Type+1, Params); return NewGamma; } default: cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature '%lx' found.", BaseType); return NULL; } }// Similar to anterior, but curve is reversedstaticLPGAMMATABLE ReadCurveReversed(LPLCMSICCPROFILE Icc){ icTagTypeSignature BaseType; LPGAMMATABLE NewGamma, ReturnGamma; icUInt32Number Count; int n; BaseType = ReadBase(Icc); switch (BaseType) { case 0x9478ee00L: // Monaco 2 profiler is BROKEN! case icSigCurveType: Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &Count); switch (Count) { case 0: // Linear, reverse is same. NewGamma = cmsAllocGamma(2); if (!NewGamma) return NULL; NewGamma -> GammaTable[0] = 0; NewGamma -> GammaTable[1] = 0xFFFF; return NewGamma; case 1: { WORD SingleGammaFixed; Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc); AdjustEndianess16((LPBYTE) &SingleGammaFixed); return cmsBuildGamma(4096, 1./Convert8Fixed8(SingleGammaFixed)); } default: { // Curve. Do our best to trying to reverse the curve NewGamma = cmsAllocGamma(Count); if (!NewGamma) return NULL; Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc); AdjustEndianessArray16(NewGamma -> GammaTable, Count); if (Count < 256) Count = 256; // Reverse of simple curve has not necesarely to be simple ReturnGamma = cmsReverseGamma(Count, NewGamma); cmsFreeGamma(NewGamma); return ReturnGamma; } } break; // Parametric curves case icSigParametricCurveType: { int ParamsByType[] = { 1, 3, 4, 5, 7 }; double Params[10]; icS15Fixed16Number Num; icUInt32Number Reserved; icUInt16Number Type; int i; Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc); Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -