📄 cctiff.c
字号:
case 2: clutres = 256; break; case 3: clutres = 33; break; case 4: clutres = 18; break; case 5: clutres = 16; break; case 6: clutres = 9; break; case 7: clutres = 7; break; case 8: clutres = 6; break; deault: /* > 8 chan */ clutres = 3; break; } } else { icmLut *lut; /* ICC LUT table */ icmLuLut *luluo; /* LUT lookup object */ /* Open up the device link profile for reading */ if ((su.dev.fp = new_icmFileStd_name(su.dev.name,"r")) == NULL) error ("Can't open file '%s'",su.dev.name); if ((su.dev.c = new_icc()) == NULL) error ("Creation of ICC object failed"); if ((rv = su.dev.c->read(su.dev.c, su.dev.fp, 0)) != 0) error ("%d, %s",rv,su.dev.c->err); su.dev.h = su.dev.c->header; if (su.verb) { icmFile *op; if ((op = new_icmFileStd_fp(stdout)) == NULL) error ("Can't open stdout"); su.dev.h->dump(su.dev.h, op, 1); op->del(op); } /* Check that the profile is appropriate */ if (su.dev.h->deviceClass != icSigLinkClass) error("Profile isn't a device link profile"); /* Get a conversion object */ if ((su.dev.luo = su.dev.c->get_luobj(su.dev.c, icmFwd, icmDefaultIntent, icmSigDefaultData, icmLuOrdNorm)) == NULL) error ("%d, %s",su.dev.c->errc, su.dev.c->err); /* Get details of conversion (Arguments may be NULL if info not needed) */ su.dev.luo->spaces(su.dev.luo, &su.ins, &su.id, &su.outs, &su.od, &su.dev.alg, NULL, NULL, NULL); if (su.dev.alg != icmLutType) error ("DeviceLink profile doesn't have Lut !"); luluo = (icmLuLut *)su.dev.luo; /* Safe to coerce */ luluo->get_info(luluo, &lut, NULL, NULL, NULL); /* Get some details */ clutres = lut->clutPoints; /* Desired table resolution */ } /* - - - - - - - - - - - - - - - */ /* Open up input tiff file ready for reading */ /* Got arguments, so setup to process the file */ if ((rh = TIFFOpen(in_name, "r")) == NULL) error("error opening read file '%s'",in_name); TIFFGetField(rh, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(rh, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(rh, TIFFTAG_BITSPERSAMPLE, &bitspersample); if (bitspersample != 8 && bitspersample != 16) { error("TIFF Input file must be 8 or 16 bit/channel"); } TIFFGetField(rh, TIFFTAG_PHOTOMETRIC, &photometric); if ((no_pmtc = ColorSpaceSignature2TiffPhotometric(pmtc, su.ins)) == 0) error("ICC input colorspace '%s' can't be handled by a TIFF file!", icm2str(icmColorSpaceSignature, su.ins)); for (i = 0; i < no_pmtc; i++) { if (pmtc[i] == photometric) break; /* Matches */ } if (i >= no_pmtc) { switch (no_pmtc) { case 1: error("ICC input colorspace '%s' doesn't match TIFF photometric '%s'!", icm2str(icmColorSpaceSignature, su.ins), Photometric2str(pmtc[0])); case 2: error("ICC input colorspace '%s' doesn't match TIFF photometric '%s' or '%s'!", icm2str(icmColorSpaceSignature, su.ins), Photometric2str(pmtc[0]), Photometric2str(pmtc[1])); default: error("ICC input colorspace '%s' doesn't match TIFF photometric '%s', '%s' or '%s'!", icm2str(icmColorSpaceSignature, su.ins), Photometric2str(pmtc[0]), Photometric2str(pmtc[1]), Photometric2str(pmtc[2])); } } TIFFGetField(rh, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); if (su.id != samplesperpixel) error ("TIFF Input file has %d input channels mismatched to colorspace '%s'", samplesperpixel, icm2str(icmColorSpaceSignature, su.ins)); TIFFGetField(rh, TIFFTAG_PLANARCONFIG, &pconfig); if (pconfig != PLANARCONFIG_CONTIG) error ("TIFF Input file must be planar"); TIFFGetField(rh, TIFFTAG_RESOLUTIONUNIT, &resunits); TIFFGetField(rh, TIFFTAG_XRESOLUTION, &resx); TIFFGetField(rh, TIFFTAG_YRESOLUTION, &resy); /* - - - - - - - - - - - - - - - */ if ((wh = TIFFOpen(out_name, "w")) == NULL) error("Can\'t create TIFF file '%s'!",out_name); TIFFSetField(wh, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(wh, TIFFTAG_IMAGELENGTH, height); TIFFSetField(wh, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(wh, TIFFTAG_SAMPLESPERPIXEL, su.od); TIFFSetField(wh, TIFFTAG_BITSPERSAMPLE, bitspersample); TIFFSetField(wh, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); if ((no_pmtc = ColorSpaceSignature2TiffPhotometric(pmtc, su.outs)) == 0) error("TIFF file can't handle output colorspace '%s'!", icm2str(icmColorSpaceSignature, su.outs)); TIFFSetField(wh, TIFFTAG_PHOTOMETRIC, pmtc[0]); /* Use first returned */ if (pmtc[0] == PHOTOMETRIC_SEPARATED) { int iset; int inlen; char *inames; iset = ColorSpaceSignature2TiffInkset(su.outs, &inlen, &inames); if (iset != 0xffff && inlen > 0 && inames != NULL) { TIFFSetField(wh, TIFFTAG_INKSET, iset); if (inames != NULL) { TIFFSetField(wh, TIFFTAG_INKNAMES, inlen, inames); } } } TIFFSetField(wh, TIFFTAG_COMPRESSION, COMPRESSION_NONE); if (resunits) { TIFFSetField(wh, TIFFTAG_RESOLUTIONUNIT, resunits); TIFFSetField(wh, TIFFTAG_XRESOLUTION, resx); TIFFSetField(wh, TIFFTAG_YRESOLUTION, resy); } TIFFSetField(wh, TIFFTAG_IMAGEDESCRIPTION, "Color corrected by Argyll"); /* - - - - - - - - - - - - - - - */ /* Setup the imdi */ if (!slow) { s = new_imdi( su.id, /* Number of input dimensions */ su.od, /* Number of output dimensions */ /* Input pixel representation */ bitspersample == 8 ? pixint8 : pixint16, /* Output pixel representation */ 0x0, /* Treat every channel as unsigned */ bitspersample == 8 ? pixint8 : pixint16, 0x0, /* Treat every channel as unsigned */ clutres, /* Desired table resolution */ input_curve, /* Callback functions */ md_table, output_curve, (void *)&su /* Context to callbacks */ ); if (s == NULL) error("new_imdi failed"); } /* - - - - - - - - - - - - - - - */ /* Process colors to translate */ /* (Should fix this to process a group of lines at a time ?) */ inbuf = _TIFFmalloc(TIFFScanlineSize(rh)); outbuf = _TIFFmalloc(TIFFScanlineSize(wh)); if (check) checkbuf = _TIFFmalloc(TIFFScanlineSize(wh)); inp[0] = (unsigned char *)inbuf; outp[0] = (unsigned char *)outbuf; if (!slow) { /* Fast */ for (y = 0; y < height; y++) { /* Read in the next line */ if (TIFFReadScanline(rh, inbuf, y, 0) < 0) error ("Failed to read TIFF line %d",y); /* Do fast conversion */ s->interp(s, (void **)outp, (void **)inp, width); if (check) { /* Do floating point conversion */ for (x = 0; x < width; x++) { int i; double in[MAX_CHAN], out[MAX_CHAN]; if (bitspersample == 8) for (i = 0; i < su.id; i++) in[i] = ((unsigned char *)inbuf)[x * su.id + i]/255.0; else for (i = 0; i < su.id; i++) in[i] = ((unsigned short *)inbuf)[x * su.id + i]/65535.0; if (su.link) { if ((rv = su.in.luo->lookup(su.in.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); if ((rv = su.out.luo->lookup(su.out.luo, out, out)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } else { if ((rv = su.dev.luo->lookup(su.dev.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } if (bitspersample == 8) for (i = 0; i < su.od; i++) ((unsigned char *)checkbuf)[x * su.od + i] = (int)(out[i] * 255.0 + 0.5); else for (i = 0; i < su.od; i++) ((unsigned short *)checkbuf)[x * su.od + i] = (int)(out[i] * 65535.0 + 0.5); } /* Compute the errors */ for (x = 0; x < (width * su.od); x++) { int err; if (bitspersample == 8) err = ((unsigned char *)outbuf)[x] - ((unsigned char *)checkbuf)[x]; else err = ((unsigned short *)outbuf)[x] - ((unsigned short *)checkbuf)[x]; if (err < 0) err = -err; if (err > mxerr) mxerr = err; avgerr += (double)err; avgcount++; } } if (TIFFWriteScanline(wh, outbuf, y, 0) < 0) error ("Failed to write TIFF line %d",y); } } else { /* Slow but precise */ if (bitspersample == 8) { for (y = 0; y < height; y++) { /* Read in the next line */ if (TIFFReadScanline(rh, inbuf, y, 0) < 0) error ("Failed to read TIFF line %d",y); /* Do floating point conversion */ for (x = 0; x < width; x++) { int i; double in[MAX_CHAN], out[MAX_CHAN]; for (i = 0; i < su.id; i++) { in[i] = ((unsigned char *)inbuf)[x * su.id + i]/255.0; } if (su.link) { if ((rv = su.in.luo->lookup(su.in.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); if ((rv = su.out.luo->lookup(su.out.luo, out, out)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } else { if ((rv = su.dev.luo->lookup(su.dev.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } for (i = 0; i < su.od; i++) { double outi = out[i]; if (outi < 0.0) /* Protect against sillies */ outi = 0.0; else if (outi > 1.0) outi = 1.0; ((unsigned char *)outbuf)[x * su.od + i] = (int)(outi * 255.0 + 0.5); } } if (TIFFWriteScanline(wh, outbuf, y, 0) < 0) error ("Failed to write TIFF line %d",y); } } else if (bitspersample == 16) { for (y = 0; y < height; y++) { /* Read in the next line */ if (TIFFReadScanline(rh, inbuf, y, 0) < 0) error ("Failed to read TIFF line %d",y); /* Do floating point conversion */ for (x = 0; x < width; x++) { int i; double in[MAX_CHAN], out[MAX_CHAN]; for (i = 0; i < su.id; i++) { in[i] = ((unsigned short *)inbuf)[x * su.id + i]/65535.0; } if (su.link) { if ((rv = su.in.luo->lookup(su.in.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); if ((rv = su.out.luo->lookup(su.out.luo, out, out)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } else { if ((rv = su.dev.luo->lookup(su.dev.luo, out, in)) > 1) error ("%d, %s",su.dev.c->errc,su.dev.c->err); } for (i = 0; i < su.od; i++) { double outi = out[i]; if (outi < 0.0) /* Protect against sillies */ outi = 0.0; else if (outi > 1.0) outi = 1.0; ((unsigned short *)outbuf)[x * su.od + i] = (int)(outi * 65535.0 + 0.5); } } if (TIFFWriteScanline(wh, outbuf, y, 0) < 0) error ("Failed to write TIFF line %d",y); } } } if (check) { printf("Worst error = %d bits, average error = %f bits\n", mxerr, avgerr/avgcount); if (bitspersample == 8) printf("Worst error = %f%%, average error = %f%%\n", mxerr/2.55, avgerr/(2.55 * avgcount)); else printf("Worst error = %f%%, average error = %f%%\n", mxerr/655.35, avgerr/(655.35 * avgcount)); } /* Done with lookup object */ if (s != NULL) s->done(s); if (su.link) { su.in.luo->del(su.in.luo); su.in.c->del(su.in.c); su.in.fp->del(su.in.fp); su.out.luo->del(su.out.luo); su.out.c->del(su.out.c); su.out.fp->del(su.out.fp); } else { su.dev.luo->del(su.dev.luo); su.dev.c->del(su.dev.c); su.dev.fp->del(su.dev.fp); } _TIFFfree(inbuf); _TIFFfree(outbuf); if (check) _TIFFfree(checkbuf); TIFFClose(rh); /* Close Input file */ TIFFClose(wh); /* Close Output file */ return 0;}/* Basic printf type error() and warning() routines */voiderror(char *fmt, ...){ va_list args; fprintf(stderr,"cctiff: Error - "); va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n"); exit (-1);}voidwarning(char *fmt, ...){ va_list args; fprintf(stderr,"cctiff: Warning - "); va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); fprintf(stderr, "\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -