Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/lcms2/utils/common/vprf.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 //--------------------------------------------------------------------------------- | |
| 2 // | |
| 3 // Little Color Management System | |
| 4 // Copyright (c) 1998-2023 Marti Maria Saguer | |
| 5 // | |
| 6 // Permission is hereby granted, free of charge, to any person obtaining | |
| 7 // a copy of this software and associated documentation files (the "Software"), | |
| 8 // to deal in the Software without restriction, including without limitation | |
| 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 10 // and/or sell copies of the Software, and to permit persons to whom the Software | |
| 11 // is furnished to do so, subject to the following conditions: | |
| 12 // | |
| 13 // The above copyright notice and this permission notice shall be included in | |
| 14 // all copies or substantial portions of the Software. | |
| 15 // | |
| 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO | |
| 18 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| 20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| 21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| 22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 23 // | |
| 24 //--------------------------------------------------------------------------------- | |
| 25 // | |
| 26 | |
| 27 #include "utils.h" | |
| 28 | |
| 29 | |
| 30 int Verbose = 0; | |
| 31 | |
| 32 static char ProgramName[256] = ""; | |
| 33 | |
| 34 void FatalError(const char *frm, ...) | |
| 35 { | |
| 36 va_list args; | |
| 37 | |
| 38 va_start(args, frm); | |
| 39 fprintf(stderr, "[%s fatal error]: ", ProgramName); | |
| 40 vfprintf(stderr, frm, args); | |
| 41 fprintf(stderr, "\n"); | |
| 42 va_end(args); | |
| 43 | |
| 44 exit(1); | |
| 45 } | |
| 46 | |
| 47 // Show errors to the end user (unless quiet option) | |
| 48 static | |
| 49 void MyErrorLogHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text) | |
| 50 { | |
| 51 if (Verbose >= 0) | |
| 52 fprintf(stderr, "[%s]: %s\n", ProgramName, Text); | |
| 53 | |
| 54 UTILS_UNUSED_PARAMETER(ErrorCode); | |
| 55 UTILS_UNUSED_PARAMETER(ContextID); | |
| 56 } | |
| 57 | |
| 58 | |
| 59 void InitUtils(cmsContext ContextID, const char* PName) | |
| 60 { | |
| 61 strncpy(ProgramName, PName, sizeof(ProgramName)); | |
| 62 ProgramName[sizeof(ProgramName)-1] = 0; | |
| 63 | |
| 64 cmsSetLogErrorHandler(ContextID, MyErrorLogHandler); | |
| 65 } | |
| 66 | |
| 67 | |
| 68 // Virtual profiles are handled here. | |
| 69 cmsHPROFILE OpenStockProfile(cmsContext ContextID, const char* File) | |
| 70 { | |
| 71 if (!File) | |
| 72 return cmsCreate_sRGBProfile(ContextID); | |
| 73 | |
| 74 if (cmsstrcasecmp(File, "*Lab2") == 0) | |
| 75 return cmsCreateLab2Profile(ContextID, NULL); | |
| 76 | |
| 77 if (cmsstrcasecmp(File, "*Lab4") == 0) | |
| 78 return cmsCreateLab4Profile(ContextID, NULL); | |
| 79 | |
| 80 if (cmsstrcasecmp(File, "*Lab") == 0) | |
| 81 return cmsCreateLab4Profile(ContextID, NULL); | |
| 82 | |
| 83 if (cmsstrcasecmp(File, "*LabD65") == 0) { | |
| 84 | |
| 85 cmsCIExyY D65xyY; | |
| 86 | |
| 87 cmsWhitePointFromTemp(ContextID, &D65xyY, 6504); | |
| 88 return cmsCreateLab4Profile(ContextID, &D65xyY); | |
| 89 } | |
| 90 | |
| 91 if (cmsstrcasecmp(File, "*XYZ") == 0) | |
| 92 return cmsCreateXYZProfile(ContextID); | |
| 93 | |
| 94 if (cmsstrcasecmp(File, "*Gray22") == 0) { | |
| 95 | |
| 96 cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2); | |
| 97 cmsHPROFILE hProfile = cmsCreateGrayProfile(ContextID, cmsD50_xyY(ContextID), Curve); | |
| 98 cmsFreeToneCurve(ContextID, Curve); | |
| 99 return hProfile; | |
| 100 } | |
| 101 | |
| 102 if (cmsstrcasecmp(File, "*Gray30") == 0) { | |
| 103 | |
| 104 cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0); | |
| 105 cmsHPROFILE hProfile = cmsCreateGrayProfile(ContextID, cmsD50_xyY(ContextID), Curve); | |
| 106 cmsFreeToneCurve(ContextID, Curve); | |
| 107 return hProfile; | |
| 108 } | |
| 109 | |
| 110 if (cmsstrcasecmp(File, "*srgb") == 0) | |
| 111 return cmsCreate_sRGBProfile(ContextID); | |
| 112 | |
| 113 if (cmsstrcasecmp(File, "*null") == 0) | |
| 114 return cmsCreateNULLProfile(ContextID); | |
| 115 | |
| 116 | |
| 117 if (cmsstrcasecmp(File, "*Lin2222") == 0) { | |
| 118 | |
| 119 cmsToneCurve* Gamma = cmsBuildGamma(0, 2.2); | |
| 120 cmsToneCurve* Gamma4[4]; | |
| 121 cmsHPROFILE hProfile; | |
| 122 | |
| 123 Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma; | |
| 124 hProfile = cmsCreateLinearizationDeviceLink(ContextID, cmsSigCmykData, Gamma4); | |
| 125 cmsFreeToneCurve(ContextID, Gamma); | |
| 126 return hProfile; | |
| 127 } | |
| 128 | |
| 129 | |
| 130 return cmsOpenProfileFromFile(ContextID, File, "r"); | |
| 131 } | |
| 132 | |
| 133 // Help on available built-ins | |
| 134 void PrintBuiltins(void) | |
| 135 { | |
| 136 fprintf(stderr, "\nBuilt-in profiles:\n\n"); | |
| 137 fprintf(stderr, "\t*Lab2 -- D50-based v2 CIEL*a*b\n" | |
| 138 "\t*Lab4 -- D50-based v4 CIEL*a*b\n" | |
| 139 "\t*Lab -- D50-based v4 CIEL*a*b\n" | |
| 140 "\t*XYZ -- CIE XYZ (PCS)\n" | |
| 141 "\t*sRGB -- sRGB color space\n" | |
| 142 "\t*Gray22 - Monochrome of Gamma 2.2\n" | |
| 143 "\t*Gray30 - Monochrome of Gamma 3.0\n" | |
| 144 "\t*null - Monochrome black for all input\n" | |
| 145 "\t*Lin2222- CMYK linearization of gamma 2.2 on each channel\n\n"); | |
| 146 } | |
| 147 | |
| 148 | |
| 149 // Auxiliary for printing information on profile | |
| 150 static | |
| 151 void PrintInfo(cmsContext ContextID, cmsHPROFILE h, cmsInfoType Info) | |
| 152 { | |
| 153 char* text; | |
| 154 int len; | |
| 155 | |
| 156 len = cmsGetProfileInfoASCII(ContextID, h, Info, "en", "US", NULL, 0); | |
| 157 if (len == 0) return; | |
| 158 | |
| 159 text = (char*) malloc(len * sizeof(char)); | |
| 160 if (text == NULL) return; | |
| 161 | |
| 162 cmsGetProfileInfoASCII(ContextID, h, Info, "en", "US", text, len); | |
| 163 | |
| 164 if (strlen(text) > 0) | |
| 165 printf("%s\n", text); | |
| 166 | |
| 167 free(text); | |
| 168 } | |
| 169 | |
| 170 | |
| 171 | |
| 172 // Displays the colorant table | |
| 173 static | |
| 174 void PrintColorantTable(cmsContext ContextID, cmsHPROFILE hInput, cmsTagSignature Sig, const char* Title) | |
| 175 { | |
| 176 cmsNAMEDCOLORLIST* list; | |
| 177 int i, n; | |
| 178 | |
| 179 if (cmsIsTag(ContextID, hInput, Sig)) { | |
| 180 | |
| 181 printf("%s:\n", Title); | |
| 182 | |
| 183 list = (cmsNAMEDCOLORLIST*) cmsReadTag(ContextID, hInput, Sig); | |
| 184 if (list == NULL) { | |
| 185 printf("(Unavailable)\n"); | |
| 186 return; | |
| 187 } | |
| 188 | |
| 189 n = cmsNamedColorCount(ContextID, list); | |
| 190 for (i=0; i < n; i++) { | |
| 191 | |
| 192 char Name[cmsMAX_PATH]; | |
| 193 | |
| 194 cmsNamedColorInfo(ContextID, list, i, Name, NULL, NULL, NULL, NULL); | |
| 195 printf("\t%s\n", Name); | |
| 196 } | |
| 197 | |
| 198 printf("\n"); | |
| 199 } | |
| 200 | |
| 201 } | |
| 202 | |
| 203 | |
| 204 void PrintProfileInformation(cmsContext ContextID, cmsHPROFILE hInput) | |
| 205 { | |
| 206 if (hInput == NULL) { | |
| 207 fprintf(stderr, "*Wrong or corrupted profile*\n"); | |
| 208 return; | |
| 209 } | |
| 210 | |
| 211 PrintInfo(ContextID, hInput, cmsInfoDescription); | |
| 212 PrintInfo(ContextID, hInput, cmsInfoManufacturer); | |
| 213 PrintInfo(ContextID, hInput, cmsInfoModel); | |
| 214 PrintInfo(ContextID, hInput, cmsInfoCopyright); | |
| 215 | |
| 216 if (Verbose > 2) { | |
| 217 | |
| 218 PrintColorantTable(ContextID, hInput, cmsSigColorantTableTag, "Input colorant table"); | |
| 219 PrintColorantTable(ContextID, hInput, cmsSigColorantTableOutTag, "Input colorant out table"); | |
| 220 } | |
| 221 | |
| 222 printf("\n"); | |
| 223 } | |
| 224 | |
| 225 // ----------------------------------------------------------------------------- | |
| 226 | |
| 227 | |
| 228 void PrintRenderingIntents(cmsContext ContextID) | |
| 229 { | |
| 230 cmsUInt32Number Codes[200]; | |
| 231 char* Descriptions[200]; | |
| 232 cmsUInt32Number n, i; | |
| 233 | |
| 234 fprintf(stderr, "-t<n> rendering intent:\n\n"); | |
| 235 | |
| 236 n = cmsGetSupportedIntents(ContextID, 200, Codes, Descriptions); | |
| 237 | |
| 238 for (i=0; i < n; i++) { | |
| 239 fprintf(stderr, "\t%u - %s\n", Codes[i], Descriptions[i]); | |
| 240 } | |
| 241 fprintf(stderr, "\n"); | |
| 242 } | |
| 243 | |
| 244 | |
| 245 | |
| 246 // ------------------------------------------------------------------------------ | |
| 247 | |
| 248 cmsBool SaveMemoryBlock(const cmsUInt8Number* Buffer, cmsUInt32Number dwLen, const char* Filename) | |
| 249 { | |
| 250 FILE* out = fopen(Filename, "wb"); | |
| 251 if (out == NULL) { | |
| 252 FatalError("Cannot create '%s'", Filename); | |
| 253 return FALSE; | |
| 254 } | |
| 255 | |
| 256 if (fwrite(Buffer, 1, dwLen, out) != dwLen) { | |
| 257 FatalError("Cannot write %ld bytes to %s", (long) dwLen, Filename); | |
| 258 return FALSE; | |
| 259 } | |
| 260 | |
| 261 if (fclose(out) != 0) { | |
| 262 FatalError("Error flushing file '%s'", Filename); | |
| 263 return FALSE; | |
| 264 } | |
| 265 | |
| 266 return TRUE; | |
| 267 } | |
| 268 | |
| 269 // ------------------------------------------------------------------------------ | |
| 270 | |
| 271 // Return a pixel type on depending on the number of channels | |
| 272 int PixelTypeFromChanCount(int ColorChannels) | |
| 273 { | |
| 274 switch (ColorChannels) { | |
| 275 | |
| 276 case 1: return PT_GRAY; | |
| 277 case 2: return PT_MCH2; | |
| 278 case 3: return PT_MCH3; | |
| 279 case 4: return PT_CMYK; | |
| 280 case 5: return PT_MCH5; | |
| 281 case 6: return PT_MCH6; | |
| 282 case 7: return PT_MCH7; | |
| 283 case 8: return PT_MCH8; | |
| 284 case 9: return PT_MCH9; | |
| 285 case 10: return PT_MCH10; | |
| 286 case 11: return PT_MCH11; | |
| 287 case 12: return PT_MCH12; | |
| 288 case 13: return PT_MCH13; | |
| 289 case 14: return PT_MCH14; | |
| 290 case 15: return PT_MCH15; | |
| 291 | |
| 292 default: | |
| 293 | |
| 294 FatalError("What a weird separation of %d channels?!?!", ColorChannels); | |
| 295 return -1; | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 | |
| 300 // ------------------------------------------------------------------------------ | |
| 301 | |
| 302 // Return number of channels of pixel type | |
| 303 int ChanCountFromPixelType(int ColorChannels) | |
| 304 { | |
| 305 switch (ColorChannels) { | |
| 306 | |
| 307 case PT_GRAY: return 1; | |
| 308 | |
| 309 case PT_RGB: | |
| 310 case PT_CMY: | |
| 311 case PT_Lab: | |
| 312 case PT_YUV: | |
| 313 case PT_YCbCr: return 3; | |
| 314 | |
| 315 case PT_CMYK: return 4 ; | |
| 316 case PT_MCH2: return 2 ; | |
| 317 case PT_MCH3: return 3 ; | |
| 318 case PT_MCH4: return 4 ; | |
| 319 case PT_MCH5: return 5 ; | |
| 320 case PT_MCH6: return 6 ; | |
| 321 case PT_MCH7: return 7 ; | |
| 322 case PT_MCH8: return 8 ; | |
| 323 case PT_MCH9: return 9 ; | |
| 324 case PT_MCH10: return 10; | |
| 325 case PT_MCH11: return 11; | |
| 326 case PT_MCH12: return 12; | |
| 327 case PT_MCH13: return 12; | |
| 328 case PT_MCH14: return 14; | |
| 329 case PT_MCH15: return 15; | |
| 330 | |
| 331 default: | |
| 332 | |
| 333 FatalError("Unsupported color space of %d channels", ColorChannels); | |
| 334 return -1; | |
| 335 } | |
| 336 } |
