📄 cctiff2.c
字号:
char name[500]; icmFile *fp; icc *c; icmHeader *h; icRenderingIntent intent; /* Rendering intent chosen */ icmLookupFunc func; /* Type of function to use in lookup */ icColorSpaceSignature ins, outs; /* Colorspace of conversion */ icColorSpaceSignature id, od; /* Dimensions of conversion */ icmLuAlgType alg; /* Type of lookup algorithm used */ icColorSpaceSignature natpcs; /* Underlying natural PCS */ icmLuBase *luo; /* Base Lookup type object */}; typedef struct _profinfo profinfo;/* Context for imdi setup callbacks */typedef struct { /* Overall parameters */ int verb; /* Non-zero if verbose */ icColorSpaceSignature ins, outs; /* Input/Output spaces */ int id, od; /* Input/Output dimensions */ int isign_mask; /* Input sign mask */ int osign_mask; /* Output sign mask */ int icombine; /* Non-zero if input curves are to be combined */ int ocombine; /* Non-zero if output curves are to be combined */ void (*icvt)(double *out, double *in); /* If non-NULL, Input format conversion */ void (*ocvt)(double *out, double *in); /* If non-NULL, Output format conversion */ int nprofs; /* Number of profiles in the chain */ profinfo *profs; /* Profile information */} sucntx;/* Input curve function */double input_curve( void *cntx, int ch, double in_val) { sucntx *rx = (sucntx *)cntx; int i; double vals[MAX_CHAN];#ifdef NEVER if (rx->icombine) return in_val; if (rx->link) { for (i = 0; i < rx->id; i++) vals[i] = 0.0; vals[ch] = in_val; switch(rx->in.alg) { case icmMonoFwdType: { icmLuMono *lu = (icmLuMono *)rx->in.luo; /* Safe to coerce */ lu->fwd_curve(lu, vals, vals); break; } case icmMatrixFwdType: { icmLuMatrix *lu = (icmLuMatrix *)rx->in.luo; /* Safe to coerce */ lu->fwd_curve(lu, vals, vals); break; } case icmLutType: { icmLuLut *lu = (icmLuLut *)rx->in.luo; /* Safe to coerce */ /* Since not PCS, in_abs and matrix cannot be valid, */ /* so input curve on own is ok to use. */ lu->input(lu, vals, vals); break; } default: error("Unexpected algorithm type in input curve"); } } else { icmLuLut *lu = (icmLuLut *)rx->dev.luo; /* Safe to coerce */ for (i = 0; i < rx->id; i++) vals[i] = 0.0; vals[ch] = in_val; /* Since input not PCS, in_abs and matrix cannot be valid, */ /* so input curve on own is ok to use. */ lu->input(lu, vals, vals); }#endif // NEVER return vals[ch];}/* Multi-dim table function */void md_table(void *cntx,double *out_vals,double *in_vals) { sucntx *rx = (sucntx *)cntx; double pcsv[3]; int i; #ifdef NEVER if (rx->link) { double vals[MAX_CHAN]; switch(rx->in.alg) { case icmMonoFwdType: { icmLuMono *lu = (icmLuMono *)rx->in.luo; /* Safe to coerce */ if (rx->icombine) { lu->fwd_curve(lu, vals, in_vals); lu->fwd_map(lu, pcsv, vals); } else { lu->fwd_map(lu, pcsv, in_vals); } lu->fwd_abs(lu, pcsv, pcsv); break; } case icmMatrixFwdType: { icmLuMatrix *lu = (icmLuMatrix *)rx->in.luo; /* Safe to coerce */ if (rx->icombine) { lu->fwd_curve(lu, vals, in_vals); lu->fwd_matrix(lu, pcsv, vals); } else { lu->fwd_matrix(lu, pcsv, in_vals); } lu->fwd_abs(lu, pcsv, pcsv); break; } case icmLutType: { icmLuLut *lu = (icmLuLut *)rx->in.luo; /* Safe to coerce */ if (rx->icombine) { /* Since not PCS, in_abs and matrix cannot be valid, */ /* so input curve on own is ok to use. */ lu->input(lu, vals, in_vals); lu->clut(lu, pcsv, vals); } else { lu->clut(lu, pcsv, in_vals); } lu->output(lu, pcsv, pcsv); lu->out_abs(lu, pcsv, pcsv); break; } default: error("Unexpected algorithm type in clut lookup"); } switch(rx->out.alg) { case icmMonoBwdType: { icmLuMono *lu = (icmLuMono *)rx->out.luo; /* Safe to coerce */ lu->bwd_abs(lu, pcsv, pcsv); lu->bwd_map(lu, out_vals, pcsv); if (rx->ocombine) { lu->bwd_curve(lu, out_vals, out_vals); } break; } case icmMatrixBwdType: { icmLuMatrix *lu = (icmLuMatrix *)rx->out.luo; /* Safe to coerce */ lu->bwd_abs(lu, pcsv, pcsv); lu->bwd_matrix(lu, out_vals, pcsv); if (rx->ocombine) { lu->bwd_curve(lu, out_vals, out_vals); } break; } case icmLutType: { icmLuLut *lu = (icmLuLut *)rx->out.luo; /* Safe to coerce */ lu->in_abs(lu, pcsv, pcsv); lu->matrix(lu, pcsv, pcsv); lu->input(lu, pcsv, pcsv); lu->clut(lu, out_vals, pcsv); if (rx->ocombine) { lu->output(lu, out_vals, out_vals); /* Since not PCS, out_abs is never used */ } break; } default: error("Unexpected algorithm type in clut lookup"); } } else { icmLuLut *lu = (icmLuLut *)rx->dev.luo; /* Safe to coerce */ if (rx->icombine && rx->ocombine) { lu->lookup((icmLuBase *)lu, out_vals, in_vals); /* Do everything here */ } else { lu->clut(lu, out_vals, in_vals); } }#endif // NEVER}/* Output curve function */double output_curve(void *cntx,int ch,double in_val) { sucntx *rx = (sucntx *)cntx; int i; double vals[MAX_CHAN]; if (rx->ocombine) return in_val;#ifdef NEVER if (rx->link) { for (i = 0; i < rx->od; i++) vals[i] = 0.0; vals[ch] = in_val; switch(rx->out.alg) { case icmMonoBwdType: { icmLuMono *lu = (icmLuMono *)rx->out.luo; /* Safe to coerce */ lu->bwd_curve(lu, vals, vals); break; } case icmMatrixBwdType: { icmLuMatrix *lu = (icmLuMatrix *)rx->out.luo; /* Safe to coerce */ lu->bwd_curve(lu, vals, vals); break; } case icmLutType: { icmLuLut *lu = (icmLuLut *)rx->out.luo; /* Safe to coerce */ lu->output(lu, vals, vals); /* Since not PCS, out_abs is never used */ break; } default: error("Unexpected algorithm type in devop_devo()"); } } else { icmLuLut *lu = (icmLuLut *)rx->dev.luo; /* Safe to coerce */ for (i = 0; i < rx->od; i++) vals[i] = 0.0; vals[ch] = in_val; /* Since output not PCS, out_abs cannot be valid, */ lu->output(lu, vals, vals); }#endif // NEVER return vals[ch];}/* Check whether two colorspaces appear compatible *//* return NZ if they match, Z if they don't. *//* Compatible means any PCS == any PCS, or exact match */int CSMatch(icColorSpaceSignature s1, icColorSpaceSignature s2) { if (s1 == s2) return 1; if ((s1 == icSigXYZData || s1 == icSigLabData) && (s2 == icSigXYZData || s2 == icSigLabData)) return 1; if ((s1 == icSig5colorData || s1 == icSigMch5Data) && (s2 == icSig5colorData || s2 == icSigMch5Data)) return 1; if ((s1 == icSig6colorData || s1 == icSigMch6Data) && (s2 == icSig6colorData || s2 == icSigMch6Data)) return 1; if ((s1 == icSig7colorData || s1 == icSigMch7Data) && (s2 == icSig7colorData || s2 == icSigMch7Data)) return 1; if ((s1 == icSig8colorData || s1 == icSigMch8Data) && (s2 == icSig8colorData || s2 == icSigMch8Data)) return 1; return 0;}intmain(int argc, char *argv[]) { int fa,nfa; /* argument we're looking at */ char in_name[100]; /* Raster file name */ char out_name[100]; /* Raster file name */ icRenderingIntent next_intent; /* Rendering intent for next profile */ icColorSpaceSignature last_colorspace; /* Next colorspace between conversions */ int slow = 0; int check = 0; int ochoice = 0; /* Output photometric choice */ int i, rv = 0; /* TIFF file info */ TIFF *rh = NULL, *wh = NULL; int x, y, width, height; /* Common size of image */ uint16 bitspersample; /* Bits per sample */ uint16 resunits; float resx, resy; uint16 pconfig; /* Planar configuration */ uint16 rsamplesperpixel, wsamplesperpixel; /* Bits per sample */ uint16 rphotometric, wphotometric; /* Photometrics */ tdata_t *inbuf, *outbuf, *checkbuf; /* IMDI */ imdi *s = NULL; sucntx su; /* Setup context */ unsigned char *inp[MAX_CHAN]; unsigned char *outp[MAX_CHAN]; int clutres = 0; /* Error check */ int mxerr = 0; double avgerr = 0.0; double avgcount = 0.0; if (argc < 2) usage("Too few arguments"); su.verb = 0; su.icombine = 0; su.ocombine = 0; su.nprofs = 0; su.profs = NULL; next_intent = icmDefaultIntent; /* Process the arguments */ for(fa = 1;fa < argc;fa++) { char mes[200]; nfa = fa; /* skip to nfa if next argument is used */ if (argv[fa][0] == '-') { /* Look for any flags */ char *na = NULL; /* next argument after flag, null if none */ if (argv[fa][2] != '\000') na = &argv[fa][2]; /* next is directly after flag */ else { if ((fa+1) < argc) { if (argv[fa+1][0] != '-') { nfa = fa + 1; na = argv[nfa]; /* next is seperate non-flag argument */ } } } if (argv[fa][1] == '?') usage("Usage requested"); /* Slow, Precise */ else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') { slow = 1; } /* Combine per channel curves */ else if (argv[fa][1] == 'c' || argv[fa][1] == 'C') { su.icombine = 1; su.ocombine = 1; } /* Check curves */ else if (argv[fa][1] == 'k' || argv[fa][1] == 'K') { check = 1; } /* Output photometric choice */ else if (argv[fa][1] == 'o' || argv[fa][1] == 'O') { fa = nfa; if (na == NULL) usage("Expect argument to -o flag"); ochoice = atoi(na); } /* Next profile Intent */ else if (argv[fa][1] == 'i' || argv[fa][1] == 'I') { fa = nfa; if (na == NULL) usage("Missing argument to -i flag"); switch (na[0]) { case 'p': case 'P': next_intent = icPerceptual; break; case 'r': case 'R': next_intent = icRelativeColorimetric; break; case 's': case 'S': next_intent = icSaturation; break; case 'a': case 'A': next_intent = icAbsoluteColorimetric; break; default: sprintf(mes,"Unknown argument '%c' to -i flag",na[0]); usage(mes); } } /* Verbosity */ else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') { su.verb = 1; } else { sprintf(mes,"Unknown flag '%c'",argv[fa][1]); usage(mes); } } else if (argv[fa][0] != '\000') { /* Get the next filename */ if (su.nprofs == 0) su.profs = (profinfo *)malloc(sizeof(profinfo)); else su.profs = (profinfo *)realloc(su.profs, (su.nprofs+1) * sizeof(profinfo)); if (su.profs == NULL) error("Malloc failed in allocating space for profile info."); strcpy(su.profs[su.nprofs].name,argv[fa]); su.profs[su.nprofs].intent = next_intent; su.nprofs++; next_intent = icmDefaultIntent; } else { break; } } /* The last two "profiles" are actually the input and output TIFF filenames */ /* Unwind them */ if (su.nprofs < 3) usage("Not enough arguments to specify input and output TIFF files"); strcpy(out_name,su.profs[--su.nprofs].name); strcpy(in_name,su.profs[--su.nprofs].name);#ifdef NEVER /* Dump where we're at */ printf("~1 There are %d profile in the chain\n",su.nprofs); for (i = 0; i < su.nprofs; i++) { printf("~1 Profile %d is '%s' intent 0x%x\n",i+1,su.profs[i].name,su.profs[i].intent); } printf("~1 Input TIFF is '%s'\n",in_name); printf("~1 Output TIFF is '%s'\n",out_name);#endif/* Logic required: Discover input TIFF colorspace and set as (ICC) "next_space" Set any special input space encoding transform (ie. device, Lab flavour) For each profile: case abstract: set dir = fwd, intent = default check next_space == CIE next_space = CIE case dev link: set dir = fwd, intent = default check next_space == profile.in_devspace next_space = profile.out_devspace case colorspace/input/display/output: if colorspace set intent = default
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -