root/pngdiff/py/pngcompare.py @ 436

Revision 436, 2.9 KB (checked in by ben, 14 months ago)

[pngdiff] Add initial pngdiff (cpp and py).

Line 
1#!/usr/bin/env python
2
3import sys
4import png
5import array
6
7def usage():
8        return """%s <file1.png> <file2.png>""" % sys.argv[0]
9
10def rgb2rgba(px, w, h):
11        npx = array.array('B')
12        nbytes = w * h * 3
13        i = 0
14        while i < nbytes:
15                npx.append(px[i])
16                npx.append(px[i+1])
17                npx.append(px[i+2])
18                npx.append(255)
19                i = i + 3
20        return npx
21
22class Buffer:
23        def __init__(self, w, h, px, format):
24                self.width = w
25                self.height = h
26                if format == "rgb":
27                        self.pixels = rgb2rgba(px, w, h)
28                else:
29                        self.pixels = px
30                self.bpp = 4 # bytes per pixel
31
32        def npixels(self):
33                return self.width * self.height
34
35        def nbytes(self):
36                return self.npixels() * self.bpp
37
38        def compute_histogram(self):
39                hists = [[0 for x in xrange(256)] for y in range(self.bpp)]
40                nbytes = self.nbytes()
41                px = self.pixels
42                stride = self.bpp
43                imsize = self.nbytes()
44                for channel in range(self.bpp):
45                        hist = hists[channel]
46                        i = channel
47                        while i < imsize:
48                                value = px[i]
49                                hist[value] += 1
50                                i = i + stride
51                return hists
52
53def rgba_mse(b1, b2, offset):
54        imsize = b1.nbytes()
55        mse = 0.0
56        p1 = b1.pixels
57        p2 = b2.pixels
58        stride = b1.bpp
59        while offset < imsize:
60                diff = p1[offset] - p2[offset]
61                mse += diff * diff
62                offset += stride
63        return mse / b1.npixels()
64
65def msecompare(b1, b2):
66        return [rgba_mse(b1, b2, c) for c in xrange(4)]
67
68def histcompare(b1, b2):
69        h1 = b1.compute_histogram()
70        h2 = b2.compute_histogram()
71        diffs = [0, 0, 0, 0]
72        for c in xrange(len(h1)):
73                c1 = h1[c]
74                c2 = h2[c]
75                d = diffs[c]
76                for v in xrange(len(c1)):
77                        d = d + abs(c1[v] - c2[v])
78                diffs[c] = d
79        return diffs
80
81def format_from_pngmetadata(m):
82        if m['has_alpha']:
83                return "rgba"
84        else:
85                return "rgb"
86
87if __name__ == "__main__":
88        if len(sys.argv) < 3:
89                print usage()
90                sys.exit(1)
91
92        file1 = sys.argv[1]
93        file2 = sys.argv[2]
94        w1, h1, p1, m1 = png.Reader(file1).read()
95        w2, h2, p2, m2 = png.Reader(file2).read()
96        b1 = Buffer(w1, h1, p1, format_from_pngmetadata(m1))
97        b2 = Buffer(w2, h2, p2, format_from_pngmetadata(m2))
98        print msecompare(b1, b2)
99        print histcompare(b1, b2)
Note: See TracBrowser for help on using the browser.