⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 greytiff.c

📁   这是一个高速多维插值算法。当我们建模以后
💻 C
字号:
/*  * Convert a TIFF to monochrome in a colorimetrically correct way. * * Author:  Graeme W. Gill * Date:    01/8/29 * Version: 1.00 * * Copyright 2000, Graeme W. Gill * All rights reserved. * * This material is licenced under the GNU GENERAL PUBLIC LICENCE :- * see the Licence.txt file for licencing details. *//* * Thanks to Neil Okamoto for the 16 bit TIFF mods. *//* TTBD: * *//*	This program is a framework that exercises the	IMDI code.  It can also do the conversion using the    floating point code in ICCLIB as a reference. */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <fcntl.h>#include <string.h>#include <math.h>#include "copyright.h"#include "config.h"#include "tiffio.h"#include "icc.h"#include "imdi.h"#undef DO_CHECK		/* Do floating point check */void error(char *fmt, ...), warning(char *fmt, ...);void usage(void) {	fprintf(stderr,"Convert a TIFF file to monochrome using an ICC device profile, V%s\n",ARGYLL_VERSION_STR);	fprintf(stderr,"Author: Graeme W. Gill, licensed under the GPL\n");	fprintf(stderr,"usage: greytiff [-v level] profile.icm infile.tif outfile.tif\n");	fprintf(stderr," -p            Use slow precise correction\n");	fprintf(stderr," -v            Verbose\n");	exit(1);}/* Convert an ICC colorspace to the corresponding TIFF Photometric tag *//* return 0xffff if not possible. */intColorSpaceSignature2TiffPhotometric(icColorSpaceSignature cspace) {	switch(cspace) {		case icSigGrayData:			return PHOTOMETRIC_MINISBLACK;		case icSigRgbData:			return PHOTOMETRIC_RGB;		case icSigCmykData:			return PHOTOMETRIC_SEPARATED;		case icSigYCbCrData:			return PHOTOMETRIC_YCBCR;		case icSigLabData:			return PHOTOMETRIC_CIELAB;		case icSigXYZData:		case icSigLuvData:		case icSigYxyData:		case icSigHsvData:		case icSigHlsData:		case icSigCmyData:		case icSig2colorData:		case icSig3colorData:		case icSig4colorData:		case icSig5colorData:		case icSigMch5Data:		case icSig6colorData:		case icSigMch6Data:		case icSig7colorData:		case icSigMch7Data:		case icSig8colorData:		case icSigMch8Data:		case icSig9colorData:		case icSig10colorData:		case icSig11colorData:		case icSig12colorData:		case icSig13colorData:		case icSig14colorData:		case icSig15colorData:		default:			return 0xffff;	}	return 0xffff;}char *Photometric2str(int pmtc) {	static char buf[80];	switch (pmtc) {		case PHOTOMETRIC_MINISWHITE:			return "Subtractive Gray";		case PHOTOMETRIC_MINISBLACK:			return "Additive Gray";		case PHOTOMETRIC_RGB:			return "RGB";		case PHOTOMETRIC_PALETTE:			return "Indexed";		case PHOTOMETRIC_MASK:			return "Transparency Mask";		case PHOTOMETRIC_SEPARATED:			return "CMYK";		case PHOTOMETRIC_YCBCR:			return "YCbCr";		case PHOTOMETRIC_CIELAB:			return "CIELab";		case PHOTOMETRIC_LOGL:			return "CIELog2L";		case PHOTOMETRIC_LOGLUV:			return "CIELog2Luv";	}	sprintf(buf,"Unknonw Tag %d",pmtc);	return buf;}/* Callbacks used to initialise imdi *//* Context for imdi setup callbacks */typedef struct {	icmLuBase *flu;		/* Device -> Lab */	icmLuBase *blu;		/* Lab -> Device */} sucntx;/* Input curve function */double input_curve(	void *cntx,	int ch,	double in_val) {	return in_val;}/* Multi-dim table function */void md_table(void *cntx,double *out_vals,double *in_vals) {	sucntx *rx = (sucntx *)cntx;	double Lab[3];		rx->flu->lookup(rx->flu, Lab, in_vals);	Lab[1] = Lab[2] = 0.0;	rx->blu->lookup(rx->blu, out_vals, Lab);}/* Output curve function */double output_curve(void *cntx,int ch,double in_val) {	return in_val;}intmain(int argc, char *argv[]) {	int fa,nfa;				/* argument we're looking at */	char prof_name[100];	char in_name[100];	char out_name[100];	icmFile *p_fp;	icc *icco;	int verb = 0;	int slow = 0;	int rv = 0;	TIFF *rh = NULL, *wh = NULL;	int x, y, width, height;					/* Size of image */	uint16 samplesperpixel, bitspersample;	uint16 pconfig, photometric, pmtc;	uint16 resunits;	float resx, resy;	tdata_t *inbuf, *outbuf, *checkbuf;	icColorSpaceSignature ins;		/* Type of input spaces */	int inn;						/* Number of device components */	/* IMDI */	imdi *s = NULL;	sucntx su;		/* Setup context */	unsigned char *inp[MAX_CHAN];	unsigned char *outp[MAX_CHAN];	/* Error check */	int mxerr = 0;	double avgerr = 0.0;	double avgcount = 0.0;	if (argc < 2)		usage();	/* Process the arguments */	for(fa = 1;fa < argc;fa++) {		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();			/* Slow, Precise */			else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') {				slow = 1;			}			/* Verbosity */			else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') {				verb = 1;			}			else 				usage();		} else			break;	}	if (fa >= argc || argv[fa][0] == '-') usage();	strcpy(prof_name,argv[fa++]);	if (fa >= argc || argv[fa][0] == '-') usage();	strcpy(in_name,argv[fa++]);	if (fa >= argc || argv[fa][0] == '-') usage();	strcpy(out_name,argv[fa++]);	/* - - - - - - - - - - - - - - - - */	/* Open up the profile for reading */	if ((p_fp = new_icmFileStd_name(prof_name,"r")) == NULL)		error ("Can't open file '%s'",prof_name);	if ((icco = new_icc()) == NULL)		error ("Creation of ICC object failed");	if ((rv = icco->read(icco,p_fp,0)) != 0)		error ("%d, %s",rv,icco->err);	if (verb) {		icmFile *op;		if ((op = new_icmFileStd_fp(stdout)) == NULL)			error ("Can't open stdout");		icco->header->dump(icco->header, op, 1);		op->del(op);	}	/* Check that the profile is appropriate */	if (icco->header->deviceClass != icSigDisplayClass	 && icco->header->deviceClass != icSigOutputClass)		error("Profile isn't a Display or Output profile");	/* Get a fwd conversion object */	if ((su.flu = icco->get_luobj(icco, icmFwd, icRelativeColorimetric, icSigLabData, icmLuOrdNorm)) == NULL) {		if ((su.flu = icco->get_luobj(icco, icmFwd, icmDefaultIntent, icSigLabData, icmLuOrdNorm)) == NULL)			error ("%d, %s",icco->errc, icco->err);	}	/* Get details of conversion (Arguments may be NULL if info not needed) */	su.flu->spaces(su.flu, &ins, &inn, NULL, NULL, NULL, NULL, NULL, NULL);	/* Get a bwd conversion object */	if ((su.blu = icco->get_luobj(icco, icmBwd, icRelativeColorimetric, icSigLabData, icmLuOrdNorm)) == NULL) {		if ((su.blu = icco->get_luobj(icco, icmBwd, icmDefaultIntent, icSigLabData, icmLuOrdNorm)) == NULL)			error ("%d, %s",icco->errc, icco->err);	}	/* - - - - - - - - - - - - - - - */	/* 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  ((pmtc = ColorSpaceSignature2TiffPhotometric(ins)) == 0xffff)		error("ICC  input colorspace '%s' can't be handled by a TIFF file!",		      icm2str(icmColorSpaceSignature, ins));	if (pmtc != photometric)		error("ICC  input colorspace '%s' doesn't match TIFF photometric '%s'!",		      icm2str(icmColorSpaceSignature, ins), Photometric2str(photometric));	TIFFGetField(rh, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);	if (inn != samplesperpixel)		error ("TIFF Input file has %d input channels mismatched to colorspace '%s'",		       samplesperpixel, icm2str(icmColorSpaceSignature, 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, inn);	TIFFSetField(wh, TIFFTAG_BITSPERSAMPLE, bitspersample);	TIFFSetField(wh, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);	if  ((pmtc = ColorSpaceSignature2TiffPhotometric(ins)) == 0xffff)		error("TIFF file can't handle output colorspace '%s'!",		      icm2str(icmColorSpaceSignature, ins));	TIFFSetField(wh, TIFFTAG_PHOTOMETRIC, pmtc);	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(			inn,			/* Number of input dimensions */			inn,			/* Number of output dimensions */			bitspersample == 8 ? pixint8 : pixint16,							/* Output pixel representation */			0x0,			/* Treat every channel as unsigned */			bitspersample == 8 ? pixint8 : pixint16,			0x0,			/* Treat every channel as unsigned */			17,				/* Desired table resolution. 33 is also a good number */			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));	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);			#ifdef DO_CHECK			/* Do floating point conversion */			for (x = 0; x < width; x++) {				int i;				double in[MAX_CHAN], out[MAX_CHAN];				double Lab[3];								if (bitspersample == 8)					for (i = 0; i < inn; i++)						in[i] = ((unsigned char *)inbuf)[x * inn + i]/255.0;				else					for (i = 0; i < inn; i++)						in[i] = ((unsigned short *)inbuf)[x * inn + i]/65535.0;									if ((rv = su.flu->lookup(su.flu, Lab, in)) > 1)					error ("%d, %s",icco->errc,icco->err);				Lab[1] = Lab[2] = 0.0;				if ((rv = su.blu->lookup(su.blu, out, Lab)) > 1)					error ("%d, %s",icco->errc,icco->err);				if (bitspersample == 8)					for (i = 0; i < inn; i++)						((unsigned char *)checkbuf)[x * inn + i] = (int)(out[i] * 255.0 + 0.5);				else					for (i = 0; i < inn; i++)						((unsigned short *)checkbuf)[x * inn + i] = (int)(out[i] * 65535.0 + 0.5);			}			/* Compute the errors */			for (x = 0; x < (width * inn); 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++;			}#endif /* DO_CHECK */							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];					double Lab[3];										for (i = 0; i < inn; i++) {						in[i] = ((unsigned char *)inbuf)[x * inn + i]/255.0;					}										if ((rv = su.flu->lookup(su.flu, Lab, in)) > 1)						error ("%d, %s",icco->errc,icco->err);						Lab[1] = Lab[2] = 0.0;						if ((rv = su.blu->lookup(su.blu, out, Lab)) > 1)						error ("%d, %s",icco->errc,icco->err);					for (i = 0; i < inn; i++) {						((unsigned char *)outbuf)[x * inn + i] = (int)(out[i] * 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];					double Lab[3];										for (i = 0; i < inn; i++) {						in[i] = ((unsigned short *)inbuf)[x * inn + i]/65535.0;					}										if ((rv = su.flu->lookup(su.flu, Lab, in)) > 1)						error ("%d, %s",icco->errc,icco->err);						Lab[1] = Lab[2] = 0.0;						if ((rv = su.blu->lookup(su.blu, out, Lab)) > 1)						error ("%d, %s",icco->errc,icco->err);					for (i = 0; i < inn; i++) {						((unsigned short *)outbuf)[x * inn + i] = (int)(out[i] * 65535.0 + 0.5);					}				}				if (TIFFWriteScanline(wh, outbuf, y, 0) < 0)					error ("Failed to write TIFF line %d",y);			}		}	}#ifdef DO_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));#endif /* DO_CHECK */	/* Done with lookup object */	if (s != NULL)		s->done(s);	su.flu->del(su.flu);	su.blu->del(su.blu);	icco->del(icco);	p_fp->del(p_fp);	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,"greytiff: 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,"greytiff: 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 + -