root/pngdiff/cpp/pngdiff.cpp @ 488

Revision 488, 2.9 KB (checked in by ben, 8 months ago)

Add BSD license headers to pngdiff code.

Line 
1// Copyright (c) 2009 Ben Karel. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE.txt file or at http://eschew.org/txt/bsd.txt
4
5#include <png++/png.hpp>
6#include <vector>
7using namespace std;
8typedef png::image<png::rgba_pixel> img;
9
10#include <windows.h>
11#include <boost/typeof/typeof.hpp>
12
13void compute_histogram(img& a, int histout[4][256]) {
14        int hist[4][256];
15        png::rgba_pixel pa;
16        const int nhistbytes = sizeof(int)*256*4;
17        memset(hist, 0, nhistbytes);
18
19        for (int j = 0; j < a.get_height(); ++j) {
20                for (int i = 0; i < a.get_width(); ++i) {
21                        pa = a[j][i];
22                        hist[0][pa.red]++;
23                        hist[1][pa.green]++;
24                        hist[2][pa.blue]++;
25                        hist[3][pa.alpha]++;
26                }
27        }
28        memcpy(histout, hist, nhistbytes);
29}
30
31void compute_hists(img& a, img& b, int histdiffs[4][256]) {
32        int hista[4][256];
33        int histb[4][256];
34        compute_histogram(a, hista);
35        compute_histogram(b, histb);
36}
37
38void compute_mse(img& a, img& b, float* mses) {
39        png::rgba_pixel pa, pb;
40        for (int j = 0; j < a.get_height(); ++j) {
41                int dr, dg, db, da;
42                dr = dg = db = da = 0;
43                std::vector<png::rgba_pixel>& aj = a[j];
44                std::vector<png::rgba_pixel>& bj = b[j];
45                for (int i = 0; i < a.get_width(); ++i) {
46                        pa = aj[i];
47                        pb = bj[i];
48                        int x;
49#define COMP_DIFF(comp, accum) \
50        x = pa.comp - pb.comp; \
51        accum += x*x
52                        COMP_DIFF(red, dr);
53                        COMP_DIFF(green, dg);
54                        COMP_DIFF(blue, db);
55                        COMP_DIFF(alpha, da);
56#undef COMP_DIFF
57                }
58                mses[0] += dr;
59                mses[1] += dg;
60                mses[2] += db;
61                mses[3] += da;
62        }
63        float npixels = a.get_width() * a.get_height();
64        mses[0] /= npixels;
65        mses[1] /= npixels;
66        mses[2] /= npixels;
67        mses[3] /= npixels;
68}
69
70struct CycleCounter {
71        CycleCounter() {
72                LARGE_INTEGER ifreq;
73                QueryPerformanceFrequency(&ifreq);
74                freq = double(ifreq.QuadPart);
75                QueryPerformanceCounter(&start);
76                last.QuadPart = start.QuadPart;
77        }
78        void split(const std::string& str) {
79                LARGE_INTEGER now;     
80                QueryPerformanceCounter(&now);
81                double totalsecs = double(now.QuadPart - start.QuadPart) / freq;
82                double lastsecs = double(now.QuadPart - last.QuadPart) / freq;
83
84                std::cout << str << ": " << (lastsecs*1000)
85                       << ", total: " << (totalsecs*1000) << std::endl;
86                QueryPerformanceCounter(&last);
87                start.QuadPart += (last.QuadPart - now.QuadPart) + 4;
88        }
89        LARGE_INTEGER start;
90        LARGE_INTEGER last;
91        double freq;
92};
93
94int main(int argc, char** argv) {
95        if (argc < 3) {
96                printf("Usage: %s <file1.png> <file2.png>\n", argv[0]);
97                return 1;
98        }
99        CycleCounter cc;
100        png::image<png::rgba_pixel> i1(argv[1]);
101        png::image<png::rgba_pixel> i2(argv[2]);
102        cc.split("image loading");
103
104        float mses[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
105        compute_mse(i1, i2, mses);
106        cc.split("mses");
107
108        bool verbose = true;
109        if (verbose) printf("MSE:   ");
110        printf("%f %f %f %f\n", mses[0], mses[1], mses[2], mses[3]);
111
112
113
114        if (verbose) printf("dHIST: ");
115
116        return 0;
117}
Note: See TracBrowser for help on using the browser.