imgcmp.c
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· C语言 代码 · 共 578 行 · 第 1/2 页
C
578 行
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) {
jas_eprintf("image dimensions differ\n");
return EXIT_FAILURE;
}
if (jas_image_cmptprec(reconimage, compno) != depth) {
jas_eprintf("precisions differ\n");
return EXIT_FAILURE;
}
if (!(origdata = jas_matrix_create(height, width))) {
jas_eprintf("internal error\n");
return EXIT_FAILURE;
}
if (!(recondata = jas_matrix_create(height, width))) {
jas_eprintf("internal error\n");
return EXIT_FAILURE;
}
if (jas_image_readcmpt(origimage, compno, 0, 0, width, height,
origdata)) {
jas_eprintf("cannot read component data\n");
return EXIT_FAILURE;
}
if (jas_image_readcmpt(reconimage, compno, 0, 0, width, height,
recondata)) {
jas_eprintf("cannot read component data\n");
return EXIT_FAILURE;
}
if (diffpath) {
if (!(diffstream = jas_stream_fopen(diffpath, "rwb"))) {
jas_eprintf("cannot open diff stream\n");
return EXIT_FAILURE;
}
if (!(diffimage = makediffimage(origdata, recondata))) {
jas_eprintf("cannot make diff image\n");
return EXIT_FAILURE;
}
fmtid = jas_image_strtofmt("pnm");
if (jas_image_encode(diffimage, diffstream, fmtid, 0)) {
jas_eprintf("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) {
jas_eprintf("%ld\n", (long) ceil(d));
} else {
jas_eprintf("%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 = jas_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))) {
jas_eprintf("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()
{
jas_eprintf("Image Comparison Utility (Version %s).\n",
JAS_VERSION);
jas_eprintf(
"Copyright (c) 2001 Michael David Adams.\n"
"All rights reserved.\n"
);
}
void usage()
{
cmdinfo();
jas_eprintf("usage:\n");
jas_eprintf("%s ", cmdname);
jas_eprintf(
"-f reference_image_file -F other_image_file [-m metric]\n"
);
jas_eprintf(
"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 + =
减小字号Ctrl + -
显示快捷键?