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

📄 imgcmp.c

📁 这是关于图象压缩的程序
💻 C
字号:
/* * Copyright (c) 2001-2003 Michael David Adams. * All rights reserved. *//* __START_OF_JASPER_LICENSE__ *  * JasPer License Version 2.0 *  * Copyright (c) 1999-2000 Image Power, Inc. * Copyright (c) 1999-2000 The University of British Columbia * Copyright (c) 2001-2003 Michael David Adams *  * All rights reserved. *  * Permission is hereby granted, free of charge, to any person (the * "User") obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, subject to the * following conditions: *  * 1.  The above copyright notices and this permission notice (which * includes the disclaimer below) shall be included in all copies or * substantial portions of the Software. *  * 2.  The name of a copyright holder shall not be used to endorse or * promote products derived from the Software without specific prior * written permission. *  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. *  * __END_OF_JASPER_LICENSE__ *//* * Image Comparison Program * * $Id$ *//******************************************************************************\* Includes.\******************************************************************************/#include <stdlib.h>#include <stdio.h>#include <math.h>#include <float.h>#include <assert.h>#include <jasper/jasper.h>/******************************************************************************\*\******************************************************************************/typedef enum {	OPT_HELP,	OPT_VERSION,	OPT_VERBOSE,	OPT_ORIG,	OPT_RECON,	OPT_METRIC,	OPT_MAXONLY,	OPT_MINONLY,	OPT_DIFFIMAGE} optid_t;typedef enum {	metricid_none = 0,	metricid_equal,	metricid_psnr,	metricid_mse,	metricid_rmse,	metricid_pae,	metricid_mae} metricid_t;/******************************************************************************\*\******************************************************************************/double getdistortion(jas_matrix_t *orig, jas_matrix_t *recon, int depth, int metric);double pae(jas_matrix_t *x, jas_matrix_t *y);double msen(jas_matrix_t *x, jas_matrix_t *y, int n);double psnr(jas_matrix_t *x, jas_matrix_t *y, int depth);jas_image_t *makediffimage(jas_matrix_t *origdata, jas_matrix_t *recondata);void usage(void);void cmdinfo(void);/******************************************************************************\*\******************************************************************************/static jas_taginfo_t metrictab[] = {	{metricid_mse, "mse"},	{metricid_pae, "pae"},	{metricid_rmse, "rmse"},	{metricid_psnr, "psnr"},	{metricid_mae, "mae"},	{metricid_equal, "equal"},	{-1, 0}};static jas_opt_t opts[] = {	{OPT_HELP, "help", 0},	{OPT_VERSION, "version", 0},	{OPT_VERBOSE, "verbose", 0},	{OPT_ORIG, "f", JAS_OPT_HASARG},	{OPT_RECON, "F", JAS_OPT_HASARG},	{OPT_METRIC, "m", JAS_OPT_HASARG},	{OPT_MAXONLY, "max", 0},	{OPT_MINONLY, "min", 0},	{OPT_DIFFIMAGE, "d", JAS_OPT_HASARG},	{-1, 0, 0}};static char *cmdname = 0;/******************************************************************************\* Main program.\******************************************************************************/int main(int argc, char **argv){	char *origpath;	char *reconpath;	int verbose;	char *metricname;	int metric;	int id;	jas_image_t *origimage;	jas_image_t *reconimage;	jas_matrix_t *origdata;	jas_matrix_t *recondata;	jas_image_t *diffimage;	jas_stream_t *diffstream;	int width;	int height;	int depth;	int numcomps;	double d;	double maxdist;	double mindist;	int compno;	jas_stream_t *origstream;	jas_stream_t *reconstream;	char *diffpath;	int maxonly;	int minonly;	int fmtid;	verbose = 0;	origpath = 0;	reconpath = 0;	metricname = 0;	metric = metricid_none;	diffpath = 0;	maxonly = 0;	minonly = 0;	if (jas_init()) {		abort();	}	cmdname = argv[0];	/* Parse the command line options. */	while ((id = jas_getopt(argc, argv, opts)) >= 0) {		switch (id) {		case OPT_MAXONLY:			maxonly = 1;			break;		case OPT_MINONLY:			minonly = 1;			break;		case OPT_METRIC:			metricname = jas_optarg;			break;		case OPT_ORIG:			origpath = jas_optarg;			break;		case OPT_RECON:			reconpath = jas_optarg;			break;		case OPT_VERBOSE:			verbose = 1;			break;		case OPT_DIFFIMAGE:			diffpath = jas_optarg;			break;		case OPT_VERSION:			printf("%s\n", JAS_VERSION);			exit(EXIT_SUCCESS);			break;		case OPT_HELP:		default:			usage();			break;		}	}	if (verbose) {		cmdinfo();	}	/* Ensure that files are given for both the original and reconstructed	  images. */	if (!origpath || !reconpath) {		usage();	}	/* If a metric was specified, process it. */	if (metricname) {		if ((metric = (jas_taginfo_nonull(jas_taginfos_lookup(metrictab,		  metricname))->id)) < 0) {			usage();		}	}	/* Open the original image file. */	if (!(origstream = jas_stream_fopen(origpath, "rb"))) {		fprintf(stderr, "cannot open %s\n", origpath);		return EXIT_FAILURE;	}	/* Open the reconstructed image file. */	if (!(reconstream = jas_stream_fopen(reconpath, "rb"))) {		fprintf(stderr, "cannot open %s\n", reconpath);		return EXIT_FAILURE;	}	/* Decode the original image. */	if (!(origimage = jas_image_decode(origstream, -1, 0))) {		fprintf(stderr, "cannot load original image\n");		return EXIT_FAILURE;	}	/* Decoder the reconstructed image. */	if (!(reconimage = jas_image_decode(reconstream, -1, 0))) {		fprintf(stderr, "cannot load reconstructed image\n");		return EXIT_FAILURE;	}	/* Close the original image file. */	jas_stream_close(origstream);	/* Close the reconstructed image file. */	jas_stream_close(reconstream);	/* Ensure that both images have the same number of components. */	numcomps = jas_image_numcmpts(origimage);	if (jas_image_numcmpts(reconimage) != numcomps) {		fprintf(stderr, "number of components differ\n");		return EXIT_FAILURE;	}	/* Compute the difference for each component. */	maxdist = 0;	mindist = FLT_MAX;	for (compno = 0; compno < numcomps; ++compno) {		width = jas_image_cmptwidth(origimage, compno);		height = jas_image_cmptheight(origimage, compno);		depth = jas_image_cmptprec(origimage, compno);		if (jas_image_cmptwidth(reconimage, compno) != width ||		 jas_image_cmptheight(reconimage, compno) != height) {			fprintf(stderr, "image dimensions differ\n");			return EXIT_FAILURE;		}		if (jas_image_cmptprec(reconimage, compno) != depth) {			fprintf(stderr, "precisions differ\n");			return EXIT_FAILURE;		}		if (!(origdata = jas_matrix_create(height, width))) {			fprintf(stderr, "internal error\n");			return EXIT_FAILURE;		}		if (!(recondata = jas_matrix_create(height, width))) {			fprintf(stderr, "internal error\n");			return EXIT_FAILURE;		}		if (jas_image_readcmpt(origimage, compno, 0, 0, width, height,		  origdata)) {			fprintf(stderr, "cannot read component data\n");			return EXIT_FAILURE;		}		if (jas_image_readcmpt(reconimage, compno, 0, 0, width, height,		  recondata)) {			fprintf(stderr, "cannot read component data\n");			return EXIT_FAILURE;		}		if (diffpath) {			if (!(diffstream = jas_stream_fopen(diffpath, "rwb"))) {				fprintf(stderr, "cannot open diff stream\n");				return EXIT_FAILURE;			}			if (!(diffimage = makediffimage(origdata, recondata))) {				fprintf(stderr, "cannot make diff image\n");				return EXIT_FAILURE;			}			fmtid = jas_image_strtofmt("pnm");			if (jas_image_encode(diffimage, diffstream, fmtid, 0)) {				fprintf(stderr, "cannot save\n");				return EXIT_FAILURE;			}			jas_stream_close(diffstream);			jas_image_destroy(diffimage);		}		if (metric != metricid_none) {			d = getdistortion(origdata, recondata, depth, metric);			if (d > maxdist) {				maxdist = d;			}			if (d < mindist) {				mindist = d;			}			if (!maxonly && !minonly) {				if (metric == metricid_pae || metric == metricid_equal) {					printf("%ld\n", (long) ceil(d));				} else {					printf("%f\n", d);				}			}		}		jas_matrix_destroy(origdata);		jas_matrix_destroy(recondata);	}	if (metric != metricid_none && (maxonly || minonly)) {		if (maxonly) {			d = maxdist;		} else if (minonly) {			d = mindist;		} else {			abort();		}				if (metric == metricid_pae || metric == metricid_equal) {			printf("%ld\n", (long) ceil(d));		} else {			printf("%f\n", d);		}	}	jas_image_destroy(origimage);	jas_image_destroy(reconimage);	jas_image_clearfmts();	return EXIT_SUCCESS;}/******************************************************************************\* Distortion metric computation functions.\******************************************************************************/double getdistortion(jas_matrix_t *orig, jas_matrix_t *recon, int depth, int metric){	double d;	switch (metric) {	case metricid_psnr:	default:		d = psnr(orig, recon, depth);		break;	case metricid_mae:		d = msen(orig, recon, 1);		break;	case metricid_mse:		d = msen(orig, recon, 2);		break;	case metricid_rmse:		d = sqrt(msen(orig, recon, 2));		break;	case metricid_pae:		d = pae(orig, recon);		break;	case metricid_equal:		d = (pae(orig, recon) == 0) ? 0 : 1;		break;	}	return d;}/* Compute peak absolute error. */double pae(jas_matrix_t *x, jas_matrix_t *y){	double s;	double d;	int i;	int j;	s = 0.0;	for (i = 0; i < jas_matrix_numrows(x); i++) {		for (j = 0; j < jas_matrix_numcols(x); j++) {			d = abs(jas_matrix_get(y, i, j) - jas_matrix_get(x, i, j));			if (d > s) {				s = d;			}		}	}	return s;}/* Compute either mean-squared error or mean-absolute error. */double msen(jas_matrix_t *x, jas_matrix_t *y, int n){	double s;	double d;	int i;	int j;	s = 0.0;	for (i = 0; i < jas_matrix_numrows(x); i++) {		for (j = 0; j < jas_matrix_numcols(x); j++) {			d = jas_matrix_get(y, i, j) - jas_matrix_get(x, i, j);			if (n == 1) {				s += fabs(d);			} else if (n == 2) {				s += d * d;			} else {				abort();			}		}	}	return s / ((double) jas_matrix_numrows(x) * jas_matrix_numcols(x));}/* Compute peak signal-to-noise ratio. */double psnr(jas_matrix_t *x, jas_matrix_t *y, int depth){	double m;	double p;	m = msen(x, y, 2);	p = ((1 << depth) - 1);	return 20.0 * log10(p / sqrt(m));}/******************************************************************************\*\******************************************************************************/jas_image_t *makediffimage(jas_matrix_t *origdata, jas_matrix_t *recondata){	jas_image_t *diffimage;	jas_matrix_t *diffdata[3];	int width;	int height;	int i;	int j;	int k;	jas_image_cmptparm_t compparms[3];	jas_seqent_t a;	jas_seqent_t b;	width = jas_matrix_numcols(origdata);	height = jas_matrix_numrows(origdata);	for (i = 0; i < 3; ++i) {		compparms[i].tlx = 0;		compparms[i].tly = 0;		compparms[i].hstep = 1;		compparms[i].vstep = 1;		compparms[i].width = width;		compparms[i].height = height;		compparms[i].prec = 8;		compparms[i].sgnd = false;	}	if (!(diffimage = jas_image_create(3, compparms, JAS_CLRSPC_SRGB))) {		abort();	}	for (i = 0; i < 3; ++i) {		if (!(diffdata[i] = jas_matrix_create(height, width))) {			fprintf(stderr, "internal error\n");			return 0;		}	}	for (j = 0; j < height; ++j) {		for (k = 0; k < width; ++k) {			a = jas_matrix_get(origdata, j, k);			b = jas_matrix_get(recondata, j, k);			if (a > b) {				jas_matrix_set(diffdata[0], j, k, 255);				jas_matrix_set(diffdata[1], j, k, 0);				jas_matrix_set(diffdata[2], j, k, 0);			} else if (a < b) {				jas_matrix_set(diffdata[0], j, k, 0);				jas_matrix_set(diffdata[1], j, k, 255);				jas_matrix_set(diffdata[2], j, k, 0);			} else {				jas_matrix_set(diffdata[0], j, k, a);				jas_matrix_set(diffdata[1], j, k, a);				jas_matrix_set(diffdata[2], j, k, a);			}		}	}	for (i = 0; i < 3; ++i) {		if (jas_image_writecmpt(diffimage, i, 0, 0, width, height, diffdata[i])) {			return 0;		}	}	return diffimage;}/******************************************************************************\*\******************************************************************************/void cmdinfo(){	fprintf(stderr, "Image Comparison Utility (Version %s).\n",	  JAS_VERSION);	fprintf(stderr,	  "Copyright (c) 2001 Michael David Adams.\n"	  "All rights reserved.\n"	  );}void usage(){	cmdinfo();	fprintf(stderr, "usage:\n");	fprintf(stderr,"%s ", cmdname);	fprintf(stderr,	  "-f reference_image_file -F other_image_file [-m metric]\n"	  );	fprintf(stderr,	  "The metric argument may assume one of the following values:\n"	  "    psnr .... peak signal to noise ratio\n"	  "    mse ..... mean squared error\n"	  "    rmse .... root mean squared error\n"	  "    pae ..... peak absolute error\n"	  "    mae ..... mean absolute error\n"	  "    equal ... equality (boolean)\n"	  );	exit(EXIT_FAILURE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -