// Dispose resources void CMSEXPORT cmsDictFree(cmsHANDLE hDict) { _cmsDICT* dict = (_cmsDICT*) hDict; cmsDICTentry *entry, *next; _cmsAssert(dict != NULL); // Walk the list freeing all nodes entry = dict ->head; while (entry != NULL) { if (entry ->DisplayName != NULL) cmsMLUfree(entry ->DisplayName); if (entry ->DisplayValue != NULL) cmsMLUfree(entry ->DisplayValue); if (entry ->Name != NULL) _cmsFree(dict ->ContextID, entry -> Name); if (entry ->Value != NULL) _cmsFree(dict ->ContextID, entry -> Value); // Don't fall in the habitual trap... next = entry ->Next; _cmsFree(dict ->ContextID, entry); entry = next; } _cmsFree(dict ->ContextID, dict); }
static cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], cmsFloat32Number z[], cmsFloat32Number lambda, int m) { int i, i1, i2; cmsFloat32Number *c, *d, *e; cmsBool st; c = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); d = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); e = (cmsFloat32Number*) _cmsCalloc(ContextID, MAX_NODES_IN_CURVE, sizeof(cmsFloat32Number)); if (c != NULL && d != NULL && e != NULL) { d[1] = w[1] + lambda; c[1] = -2 * lambda / d[1]; e[1] = lambda /d[1]; z[1] = w[1] * y[1]; d[2] = w[2] + 5 * lambda - d[1] * c[1] * c[1]; c[2] = (-4 * lambda - d[1] * c[1] * e[1]) / d[2]; e[2] = lambda / d[2]; z[2] = w[2] * y[2] - c[1] * z[1]; for (i = 3; i < m - 1; i++) { i1 = i - 1; i2 = i - 2; d[i]= w[i] + 6 * lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; c[i] = (-4 * lambda -d[i1] * c[i1] * e[i1])/ d[i]; e[i] = lambda / d[i]; z[i] = w[i] * y[i] - c[i1] * z[i1] - e[i2] * z[i2]; } i1 = m - 2; i2 = m - 3; d[m - 1] = w[m - 1] + 5 * lambda -c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; c[m - 1] = (-2 * lambda - d[i1] * c[i1] * e[i1]) / d[m - 1]; z[m - 1] = w[m - 1] * y[m - 1] - c[i1] * z[i1] - e[i2] * z[i2]; i1 = m - 1; i2 = m - 2; d[m] = w[m] + lambda - c[i1] * c[i1] * d[i1] - e[i2] * e[i2] * d[i2]; z[m] = (w[m] * y[m] - c[i1] * z[i1] - e[i2] * z[i2]) / d[m]; z[m - 1] = z[m - 1] / d[m - 1] - c[m - 1] * z[m]; for (i = m - 2; 1<= i; i--) z[i] = z[i] / d[i] - c[i] * z[i + 1] - e[i] * z[i + 2]; st = TRUE; } else st = FALSE; if (c != NULL) _cmsFree(ContextID, c); if (d != NULL) _cmsFree(ContextID, d); if (e != NULL) _cmsFree(ContextID, e); return st; }
// Free any used memory void CMSEXPORT cmsMLUfree(cmsMLU* mlu) { if (mlu) { if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries); if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool); _cmsFree(mlu ->ContextID, mlu); } }
static LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc) { FILEMEM* ResData = (FILEMEM*) Icc ->stream; if (ResData ->FreeBlockOnClose) { if (ResData ->Block) _cmsFree(ResData ->Block); } _cmsFree(ResData); return 0; }
void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq) { cmsUInt32Number i; for (i=0; i < pseq ->n; i++) { if (pseq ->seq[i].Manufacturer != NULL) cmsMLUfree(pseq ->seq[i].Manufacturer); if (pseq ->seq[i].Model != NULL) cmsMLUfree(pseq ->seq[i].Model); if (pseq ->seq[i].Description != NULL) cmsMLUfree(pseq ->seq[i].Description); } if (pseq ->seq != NULL) _cmsFree(pseq ->ContextID, pseq ->seq); _cmsFree(pseq -> ContextID, pseq); }
// Get rid of whole linked list void _cmsSubAllocDestroy(_cmsSubAllocator* sub) { _cmsSubAllocator_chunk *chunk, *n; for (chunk = sub ->h; chunk != NULL; chunk = n) { n = chunk->next; if (chunk->Block != NULL) _cmsFree(sub ->ContextID, chunk->Block); _cmsFree(sub ->ContextID, chunk); } // Free the header _cmsFree(sub ->ContextID, sub); }
void cmsFreeMatShaper(LPMATSHAPER MatShaper) { int i; if (!MatShaper) return; for (i=0; i < 3; i++) { if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]); if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]); } _cmsFree(MatShaper); }
// Sub allocation takes care of many pointers of small size. The memory allocated in // this way have be freed at once. Next function allocates a single chunk for linked list // I prefer this method over realloc due to the big inpact on xput realloc may have if // memory is being swapped to disk. This approach is safer (although that may not be true on all platforms) static _cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial) { _cmsSubAllocator_chunk* chunk; // 20K by default if (Initial == 0) Initial = 20*1024; // Create the container chunk = (_cmsSubAllocator_chunk*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator_chunk)); if (chunk == NULL) return NULL; // Initialize values chunk ->Block = (cmsUInt8Number*) _cmsMalloc(ContextID, Initial); if (chunk ->Block == NULL) { // Something went wrong _cmsFree(ContextID, chunk); return NULL; } chunk ->BlockSize = Initial; chunk ->Used = 0; chunk ->next = NULL; return chunk; }
cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUInt32Number n) { cmsSEQ* Seq; cmsUInt32Number i; if (n == 0) return NULL; // In a absolutely arbitrary way, I hereby decide to allow a maxim of 255 profiles linked // in a devicelink. It makes not sense anyway and may be used for exploits, so let's close the door! if (n > 255) return NULL; Seq = (cmsSEQ*) _cmsMallocZero(ContextID, sizeof(cmsSEQ)); if (Seq == NULL) return NULL; Seq -> ContextID = ContextID; Seq -> seq = (cmsPSEQDESC*) _cmsCalloc(ContextID, n, sizeof(cmsPSEQDESC)); Seq -> n = n; if (Seq -> seq == NULL) { _cmsFree(ContextID, Seq); return NULL; } for (i=0; i < n; i++) { Seq -> seq[i].Manufacturer = NULL; Seq -> seq[i].Model = NULL; Seq -> seq[i].Description = NULL; } return Seq; }
// Allocates an empty multi localizad unicode object cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems) { cmsMLU* mlu; // nItems should be positive if given if (nItems <= 0) nItems = 2; // Create the container mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU)); if (mlu == NULL) return NULL; mlu ->ContextID = ContextID; // Create entry array mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry)); if (mlu ->Entries == NULL) { _cmsFree(ContextID, mlu); return NULL; } // Ok, keep indexes up to date mlu ->AllocatedEntries = nItems; mlu ->UsedEntries = 0; return mlu; }
// Get rid of transform resources void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform) { _cmsTRANSFORM* p = (_cmsTRANSFORM*) hTransform; _cmsAssert(p != NULL); if (p -> GamutCheck) cmsPipelineFree(p -> GamutCheck); if (p -> Lut) cmsPipelineFree(p -> Lut); if (p ->InputColorant) cmsFreeNamedColorList(p ->InputColorant); if (p -> OutputColorant) cmsFreeNamedColorList(p ->OutputColorant); if (p ->Sequence) cmsFreeProfileSequenceDescription(p ->Sequence); if (p ->UserData) p ->FreeUserData(p ->ContextID, p ->UserData); _cmsFree(p ->ContextID, (void *) p); }
static LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode) { FILEMEM* fm = (FILEMEM*) _cmsMalloc(sizeof(FILEMEM)); if (fm == NULL) return NULL; ZeroMemory(fm, sizeof(FILEMEM)); if (Mode == 'r') { fm ->Block = (LPBYTE) _cmsMalloc(Size); if (fm ->Block == NULL) { _cmsFree(fm); return NULL; } CopyMemory(fm->Block, Block, Size); fm ->FreeBlockOnClose = TRUE; } else { fm ->Block = Block; fm ->FreeBlockOnClose = FALSE; } fm ->Size = Size; fm ->Pointer = 0; return (LPVOID) fm; }
void cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST v) { if (v == NULL) { cmsSignalError(LCMS_ERRC_RECOVERABLE, "Couldn't free a NULL named color list"); return; } _cmsFree(v); }
// The suballocated is nothing but a pointer to the first element in the list. We also keep // the thread ID in this structure. _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial) { _cmsSubAllocator* sub; // Create the container sub = (_cmsSubAllocator*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator)); if (sub == NULL) return NULL; sub ->ContextID = ContextID; sub ->h = _cmsCreateSubAllocChunk(ContextID, Initial); if (sub ->h == NULL) { _cmsFree(ContextID, sub); return NULL; } return sub; }
// Compute K -> L* relationship. Flags may include black point compensation. In this case, // the relationship is assumed from the profile with BPC to a black point zero. static cmsToneCurve* ComputeKToLstar(cmsContext ContextID, cmsUInt32Number nPoints, cmsUInt32Number nProfiles, const cmsUInt32Number Intents[], const cmsHPROFILE hProfiles[], const cmsBool BPC[], const cmsFloat64Number AdaptationStates[], cmsUInt32Number dwFlags) { cmsToneCurve* out = NULL; cmsUInt32Number i; cmsHTRANSFORM xform; cmsCIELab Lab; cmsFloat32Number cmyk[4]; cmsFloat32Number* SampledPoints; xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags); if (xform == NULL) return NULL; SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number)); if (SampledPoints == NULL) goto Error; for (i=0; i < nPoints; i++) { cmyk[0] = 0; cmyk[1] = 0; cmyk[2] = 0; cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1)); cmsDoTransform(xform, cmyk, &Lab, 1); SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation } out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints); Error: cmsDeleteTransform(xform); if (SampledPoints) _cmsFree(ContextID, SampledPoints); return out; }
static void GenerateCSA(void) { cmsHPROFILE hProfile = cmsOpenProfileFromFile(cInProf, "r"); size_t n; char* Buffer; n = cmsGetPostScriptCSA(hProfile, Intent, NULL, 0); if (n == 0) return; Buffer = (char*) _cmsMalloc(n + 1); cmsGetPostScriptCSA(hProfile, Intent, Buffer, n); Buffer[n] = 0; fprintf(OutFile, "%s", Buffer); _cmsFree(Buffer); cmsCloseProfile(hProfile); }
// Add an ASCII entry. cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString) { cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1; wchar_t* WStr; cmsBool rc; cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); if (mlu == NULL) return FALSE; WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len, sizeof(wchar_t)); if (WStr == NULL) return FALSE; for (i=0; i < len; i++) WStr[i] = (wchar_t) ASCIIString[i]; rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry); _cmsFree(mlu ->ContextID, WStr); return rc; }
// Joins two curves for X and Y. Curves should be monotonic. // We want to get // // y = Y^-1(X(t)) // cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, const cmsToneCurve* X, const cmsToneCurve* Y, cmsUInt32Number nResultingPoints) { cmsToneCurve* out = NULL; cmsToneCurve* Yreversed = NULL; cmsFloat32Number t, x; cmsFloat32Number* Res = NULL; cmsUInt32Number i; _cmsAssert(X != NULL); _cmsAssert(Y != NULL); Yreversed = cmsReverseToneCurveEx(nResultingPoints, Y); if (Yreversed == NULL) goto Error; Res = (cmsFloat32Number*) _cmsCalloc(ContextID, nResultingPoints, sizeof(cmsFloat32Number)); if (Res == NULL) goto Error; //Iterate for (i=0; i < nResultingPoints; i++) { t = (cmsFloat32Number) i / (nResultingPoints-1); x = cmsEvalToneCurveFloat(X, t); Res[i] = cmsEvalToneCurveFloat(Yreversed, x); } // Allocate space for output out = cmsBuildTabulatedToneCurveFloat(ContextID, nResultingPoints, Res); Error: if (Res != NULL) _cmsFree(ContextID, Res); if (Yreversed != NULL) cmsFreeToneCurve(Yreversed); return out; }
static LPcmsNAMEDCOLORLIST GrowNamedColorList(LPcmsNAMEDCOLORLIST v, int ByElements) { if (ByElements > v ->Allocated) { LPcmsNAMEDCOLORLIST TheNewList; int NewElements; size_t size; if (v ->Allocated == 0) NewElements = 64; // Initial guess else NewElements = v ->Allocated; while (ByElements > NewElements) NewElements *= 2; size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements); TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size); if (TheNewList == NULL) { cmsSignalError(LCMS_ERRC_ABORTED, "Out of memory reallocating named color list"); return NULL; } else { ZeroMemory(TheNewList, size); CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR)); TheNewList -> Allocated = NewElements; _cmsFree(v); return TheNewList; } } return v; }
static void GenerateCRD(void) { cmsHPROFILE hProfile = cmsOpenProfileFromFile(cOutProf, "r"); size_t n; char* Buffer; DWORD dwFlags = 0; if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (Undecorated) dwFlags |= cmsFLAGS_NODEFAULTRESOURCEDEF; switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 1: if (NumOfGridPoints > 0) dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints); break; default: FatalError("ERROR: Unknown precalculation mode '%d'", PrecalcMode); } n = cmsGetPostScriptCRDEx(hProfile, Intent, dwFlags, NULL, 0); if (n == 0) return; Buffer = (char*) _cmsMalloc(n + 1); cmsGetPostScriptCRDEx(hProfile, Intent, dwFlags, Buffer, n); Buffer[n] = 0; fprintf(OutFile, "%s", Buffer); _cmsFree(Buffer); cmsCloseProfile(hProfile); }
LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init) { LPVOID Ptr; icInt32Number i; i = _cmsSearchTag(Icc, sig, FALSE); if (i >=0) { if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]); } else { i = Icc -> TagCount; Icc -> TagCount++; if (Icc ->TagCount >= MAX_TABLE_TAG) { cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG); Icc ->TagCount = MAX_TABLE_TAG-1; return NULL; } } Ptr = _cmsMalloc(size); if (Ptr == NULL) return NULL; CopyMemory(Ptr, Init, size); Icc ->TagNames[i] = sig; Icc ->TagSizes[i] = size; Icc ->TagPtrs[i] = Ptr; return Ptr; }
// Free all memory taken by the gamma curve void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve) { cmsContext ContextID; if (Curve == NULL) return; ContextID = Curve ->InterpParams->ContextID; _cmsFreeInterpParams(Curve ->InterpParams); if (Curve -> Table16) _cmsFree(ContextID, Curve ->Table16); if (Curve ->Segments) { cmsUInt32Number i; for (i=0; i < Curve ->nSegments; i++) { if (Curve ->Segments[i].SampledPoints) { _cmsFree(ContextID, Curve ->Segments[i].SampledPoints); } if (Curve ->SegInterp[i] != 0) _cmsFreeInterpParams(Curve->SegInterp[i]); } _cmsFree(ContextID, Curve ->Segments); _cmsFree(ContextID, Curve ->SegInterp); } if (Curve -> Evals) _cmsFree(ContextID, Curve -> Evals); if (Curve) _cmsFree(ContextID, Curve); }
int main(int argc, char *argv[]) { int i, nargs; cmsHPROFILE Profiles[257]; cmsHPROFILE hProfile; DWORD dwFlags = 0; cmsHTRANSFORM hTransform; fprintf(stderr, "little cms device link generator - v1.7\n"); HandleSwitches(argc, argv); cmsSetErrorHandler(MyErrorHandler); nargs = (argc - xoptind); if (nargs < 1) Help(0); if (nargs > 255) FatalError("ERROR: Holy profile! what are you trying to do with so many profiles?"); for (i=0; i < nargs; i++) { Profiles[i] = OpenProfile(argv[i + xoptind]); } switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 1: if (NumOfGridPoints > 0) dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints); break; default: FatalError("ERROR: Unknown precalculation mode '%d'", PrecalcMode); } if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (BlackPreservation > 0) { dwFlags |= cmsFLAGS_PRESERVEBLACK; cmsSetCMYKPreservationStrategy(BlackPreservation-1); } if (TagResult) dwFlags |= cmsFLAGS_GUESSDEVICECLASS; if (NoPrelinearization) dwFlags |= cmsFLAGS_NOPRELINEARIZATION; if (InkLimit != 400.0) { cmsHPROFILE hInkLimit = cmsCreateInkLimitingDeviceLink( cmsGetColorSpace(Profiles[nargs-1]), InkLimit); Profiles[nargs++] = hInkLimit; } if (lUse8bits) dwFlags |= cmsFLAGS_NOPRELINEARIZATION; hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags); if (hTransform) { size_t size = sizeof(int) + nargs * sizeof(cmsPSEQDESC); LPcmsSEQ pseq = (LPcmsSEQ) _cmsMalloc(size); ZeroMemory(pseq, size); pseq ->n = nargs; for (i=0; i < nargs; i++) { strcpy(pseq ->seq[i].Manufacturer, cmsTakeManufacturer(Profiles[i])); strcpy(pseq ->seq[1].Model, cmsTakeModel(Profiles[i])); } hProfile = cmsTransform2DeviceLink(hTransform, dwFlags); cmsAddTag(hProfile, icSigProfileDescriptionTag, (LPVOID) Description); cmsAddTag(hProfile, icSigCopyrightTag, (LPVOID) "Generated by littlecms icclink. No copyright, use freely"); cmsAddTag(hProfile, icSigProfileSequenceDescTag, (LPVOID) pseq); if (lUse8bits) _cmsSetLUTdepth(hProfile, 8); if (_cmsSaveProfile(hProfile, cOutProf)) fprintf(stderr, "Ok"); else fprintf(stderr, "Error saving file!"); cmsCloseProfile(hProfile); _cmsFree(pseq); } cmsDeleteTransform(hTransform); for (i=0; i < nargs; i++) { cmsCloseProfile(Profiles[i]); } return 0; }
static void defMtxDestroy(cmsContext id, void* mtx) { _cmsDestroyMutexPrimitive((_cmsMutex *) mtx); _cmsFree(id, mtx); }
void CMSEXPORT cmsCIECAM02Done(cmsHANDLE hModel) { cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel; if (lpMod) _cmsFree(lpMod ->ContextID, lpMod); }
// Low level allocate, which takes care of memory details. nEntries may be zero, and in this case // no optimation curve is computed. nSegments may also be zero in the inverse case, where only the // optimization curve is given. Both features simultaneously is an error static cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntries, cmsInt32Number nSegments, const cmsCurveSegment* Segments, const cmsUInt16Number* Values) { cmsToneCurve* p; int i; // We allow huge tables, which are then restricted for smoothing operations if (nEntries > 65530 || nEntries < 0) { cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries"); return NULL; } if (nEntries <= 0 && nSegments <= 0) { cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table"); return NULL; } // Allocate all required pointers, etc. p = (cmsToneCurve*) _cmsMallocZero(ContextID, sizeof(cmsToneCurve)); if (!p) return NULL; // In this case, there are no segments if (nSegments <= 0) { p ->Segments = NULL; p ->Evals = NULL; } else { p ->Segments = (cmsCurveSegment*) _cmsCalloc(ContextID, nSegments, sizeof(cmsCurveSegment)); if (p ->Segments == NULL) goto Error; p ->Evals = (cmsParametricCurveEvaluator*) _cmsCalloc(ContextID, nSegments, sizeof(cmsParametricCurveEvaluator)); if (p ->Evals == NULL) goto Error; } p -> nSegments = nSegments; // This 16-bit table contains a limited precision representation of the whole curve and is kept for // increasing xput on certain operations. if (nEntries <= 0) { p ->Table16 = NULL; } else { p ->Table16 = (cmsUInt16Number*) _cmsCalloc(ContextID, nEntries, sizeof(cmsUInt16Number)); if (p ->Table16 == NULL) goto Error; } p -> nEntries = nEntries; // Initialize members if requested if (Values != NULL && (nEntries > 0)) { for (i=0; i < nEntries; i++) p ->Table16[i] = Values[i]; } // Initialize the segments stuff. The evaluator for each segment is located and a pointer to it // is placed in advance to maximize performance. if (Segments != NULL && (nSegments > 0)) { _cmsParametricCurvesCollection *c; p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*)); if (p ->SegInterp == NULL) goto Error; for (i=0; i< nSegments; i++) { // Type 0 is a special marker for table-based curves if (Segments[i].Type == 0) p ->SegInterp[i] = _cmsComputeInterpParams(ContextID, Segments[i].nGridPoints, 1, 1, NULL, CMS_LERP_FLAGS_FLOAT); memmove(&p ->Segments[i], &Segments[i], sizeof(cmsCurveSegment)); if (Segments[i].Type == 0 && Segments[i].SampledPoints != NULL) p ->Segments[i].SampledPoints = (cmsFloat32Number*) _cmsDupMem(ContextID, Segments[i].SampledPoints, sizeof(cmsFloat32Number) * Segments[i].nGridPoints); else p ->Segments[i].SampledPoints = NULL; c = GetParametricCurveByType(Segments[i].Type, NULL); if (c != NULL) p ->Evals[i] = c ->Evaluator; } } p ->InterpParams = _cmsComputeInterpParams(ContextID, p ->nEntries, 1, 1, p->Table16, CMS_LERP_FLAGS_16BITS); return p; Error: if (p -> Segments) _cmsFree(ContextID, p ->Segments); if (p -> Evals) _cmsFree(ContextID, p -> Evals); if (p ->Table16) _cmsFree(ContextID, p ->Table16); _cmsFree(ContextID, p); return NULL; }
// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper // for separated transforms. If this is the case, static _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) { _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin); _cmsTransformCollection* Plugin; // Allocate needed memory _cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM)); if (!p) return NULL; // Store the proposed pipeline p ->Lut = lut; // Let's see if any plug-in want to do the transform by itself for (Plugin = ctx ->TransformCollection; Plugin != NULL; Plugin = Plugin ->Next) { if (Plugin ->Factory(&p->xform, &p->UserData, &p ->FreeUserData, &p ->Lut, InputFormat, OutputFormat, dwFlags)) { // Last plugin in the declaration order takes control. We just keep // the original parameters as a logging. // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default // an optimized transform is not reusable. The plug-in can, however, change // the flags and make it suitable. p ->ContextID = ContextID; p ->InputFormat = *InputFormat; p ->OutputFormat = *OutputFormat; p ->dwOriginalFlags = *dwFlags; // Fill the formatters just in case the optimized routine is interested. // No error is thrown if the formatter doesn't exist. It is up to the optimization // factory to decide what to do in those cases. p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; return p; } } // Not suitable for the transform plug-in, let's check the pipeline plug-in if (p ->Lut != NULL) _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags); // Check whatever this is a true floating point transform if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) { // Get formatter function always return a valid union, but the contents of this union may be NULL. p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); _cmsFree(ContextID, p); return NULL; } if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { p ->xform = NullFloatXFORM; } else { // Float transforms don't use cach? always are non-NULL p ->xform = FloatXFORM; } } else { if (*InputFormat == 0 && *OutputFormat == 0) { p ->FromInput = p ->ToOutput = NULL; *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; } else { int BytesPerPixelInput; p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; if (p ->FromInput == NULL || p ->ToOutput == NULL) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); _cmsFree(ContextID, p); return NULL; } BytesPerPixelInput = T_BYTES(p ->InputFormat); if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2) *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; } if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { p ->xform = NullXFORM; } else { if (*dwFlags & cmsFLAGS_NOCACHE) { if (*dwFlags & cmsFLAGS_GAMUTCHECK) p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cach? else p ->xform = PrecalculatedXFORM; // No cach? no gamut check } else { if (*dwFlags & cmsFLAGS_GAMUTCHECK) p ->xform = CachedXFORMGamutCheck; // Gamut check, cach? else p ->xform = CachedXFORM; // No gamut check, cach? } } } p ->InputFormat = *InputFormat; p ->OutputFormat = *OutputFormat; p ->dwOriginalFlags = *dwFlags; p ->ContextID = ContextID; p ->UserData = NULL; return p; }
void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD) { cmsGDB* gbd = (cmsGDB*) hGBD; if (hGBD != NULL) _cmsFree(gbd->ContextID, (void*) gbd); }
void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel) { LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel; if (lpMod) _cmsFree(lpMod); }
// Free a list void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v) { if (v ->List) _cmsFree(v ->ContextID, v ->List); if (v) _cmsFree(v ->ContextID, v); }