1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import os
6import tempfile
7import unittest
8
9from telemetry import benchmark
10from telemetry.core import bitmap
11from telemetry.core import util
12
13# This is a simple base64 encoded 2x2 PNG which contains, in order, a single
14# Red, Yellow, Blue, and Green pixel.
15test_png = """
16iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91
17JpzAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACx
18MBAJqcGAAAABZJREFUCNdj/M/AwPCfgYGB4T/DfwY
19AHAAD/iOWZXsAAAAASUVORK5CYII=
20"""
21test_png_path = os.path.join(util.GetUnittestDataDir(), 'test_png.png')
22test_png_2_path = os.path.join(util.GetUnittestDataDir(), 'test_png_2.png')
23
24
25class HistogramDistanceTest(unittest.TestCase):
26  def testNoData(self):
27    hist1 = []
28    hist2 = []
29    self.assertRaises(
30        ValueError, lambda: bitmap.HistogramDistance(hist1, hist2))
31
32    hist1 = [0, 0, 0]
33    hist2 = [0, 0, 0]
34    self.assertRaises(
35        ValueError, lambda: bitmap.HistogramDistance(hist1, hist2))
36
37  def testWrongSizes(self):
38    hist1 = [1]
39    hist2 = [1, 0]
40    self.assertRaises(
41        ValueError, lambda: bitmap.HistogramDistance(hist1, hist2))
42
43  def testNoDistance(self):
44    hist1 = [2, 4, 1, 8, 0, -1]
45    hist2 = [2, 4, 1, 8, 0, -1]
46    self.assertEqual(bitmap.HistogramDistance(hist1, hist2), 0)
47
48  def testNormalizeCounts(self):
49    hist1 = [0, 0, 1, 0, 0]
50    hist2 = [0, 0, 0, 0, 7]
51    self.assertEqual(bitmap.HistogramDistance(hist1, hist2), 2)
52    self.assertEqual(bitmap.HistogramDistance(hist2, hist1), 2)
53
54  def testDistance(self):
55    hist1 = [2, 0, 1, 3, 4]
56    hist2 = [3, 1, 2, 4, 0]
57    self.assertEqual(bitmap.HistogramDistance(hist1, hist2), 1)
58    self.assertEqual(bitmap.HistogramDistance(hist2, hist1), 1)
59
60    hist1 = [0, 1, 3, 1]
61    hist2 = [2, 2, 1, 0]
62    self.assertEqual(bitmap.HistogramDistance(hist1, hist2), 1.2)
63    self.assertEqual(bitmap.HistogramDistance(hist2, hist1), 1.2)
64
65
66class BitmapTest(unittest.TestCase):
67
68  # pylint: disable=C0324
69
70  def testReadFromBase64Png(self):
71    bmp = bitmap.Bitmap.FromBase64Png(test_png)
72
73    self.assertEquals(2, bmp.width)
74    self.assertEquals(2, bmp.height)
75
76    bmp.GetPixelColor(0, 0).AssertIsRGB(255, 0, 0)
77    bmp.GetPixelColor(1, 1).AssertIsRGB(0, 255, 0)
78    bmp.GetPixelColor(0, 1).AssertIsRGB(0, 0, 255)
79    bmp.GetPixelColor(1, 0).AssertIsRGB(255, 255, 0)
80
81  def testReadFromPngFile(self):
82    file_bmp = bitmap.Bitmap.FromPngFile(test_png_path)
83
84    self.assertEquals(2, file_bmp.width)
85    self.assertEquals(2, file_bmp.height)
86
87    file_bmp.GetPixelColor(0, 0).AssertIsRGB(255, 0, 0)
88    file_bmp.GetPixelColor(1, 1).AssertIsRGB(0, 255, 0)
89    file_bmp.GetPixelColor(0, 1).AssertIsRGB(0, 0, 255)
90    file_bmp.GetPixelColor(1, 0).AssertIsRGB(255, 255, 0)
91
92  def testWritePngToPngFile(self):
93    orig = bitmap.Bitmap.FromPngFile(test_png_path)
94    temp_file = tempfile.NamedTemporaryFile().name
95    orig.WritePngFile(temp_file)
96    new_file = bitmap.Bitmap.FromPngFile(temp_file)
97    self.assertTrue(orig.IsEqual(new_file))
98
99  @benchmark.Disabled
100  def testWriteCroppedBmpToPngFile(self):
101    pixels = [255,0,0, 255,255,0, 0,0,0,
102              255,255,0, 0,255,0, 0,0,0]
103    orig = bitmap.Bitmap(3, 3, 2, pixels)
104    orig.Crop(0, 0, 2, 2)
105    temp_file = tempfile.NamedTemporaryFile().name
106    orig.WritePngFile(temp_file)
107    new_file = bitmap.Bitmap.FromPngFile(temp_file)
108    self.assertTrue(orig.IsEqual(new_file))
109
110  def testIsEqual(self):
111    bmp = bitmap.Bitmap.FromBase64Png(test_png)
112    file_bmp = bitmap.Bitmap.FromPngFile(test_png_path)
113    self.assertTrue(bmp.IsEqual(file_bmp))
114
115  def testDiff(self):
116    file_bmp = bitmap.Bitmap.FromPngFile(test_png_path)
117    file_bmp_2 = bitmap.Bitmap.FromPngFile(test_png_2_path)
118
119    diff_bmp = file_bmp.Diff(file_bmp)
120
121    self.assertEquals(2, diff_bmp.width)
122    self.assertEquals(2, diff_bmp.height)
123
124    diff_bmp.GetPixelColor(0, 0).AssertIsRGB(0, 0, 0)
125    diff_bmp.GetPixelColor(1, 1).AssertIsRGB(0, 0, 0)
126    diff_bmp.GetPixelColor(0, 1).AssertIsRGB(0, 0, 0)
127    diff_bmp.GetPixelColor(1, 0).AssertIsRGB(0, 0, 0)
128
129    diff_bmp = file_bmp.Diff(file_bmp_2)
130
131    self.assertEquals(3, diff_bmp.width)
132    self.assertEquals(3, diff_bmp.height)
133
134    diff_bmp.GetPixelColor(0, 0).AssertIsRGB(0, 255, 255)
135    diff_bmp.GetPixelColor(1, 1).AssertIsRGB(255, 0, 255)
136    diff_bmp.GetPixelColor(0, 1).AssertIsRGB(255, 255, 0)
137    diff_bmp.GetPixelColor(1, 0).AssertIsRGB(0, 0, 255)
138
139    diff_bmp.GetPixelColor(0, 2).AssertIsRGB(255, 255, 255)
140    diff_bmp.GetPixelColor(1, 2).AssertIsRGB(255, 255, 255)
141    diff_bmp.GetPixelColor(2, 0).AssertIsRGB(255, 255, 255)
142    diff_bmp.GetPixelColor(2, 1).AssertIsRGB(255, 255, 255)
143    diff_bmp.GetPixelColor(2, 2).AssertIsRGB(255, 255, 255)
144
145  @benchmark.Disabled
146  def testGetBoundingBox(self):
147    pixels = [0,0,0, 0,0,0, 0,0,0, 0,0,0,
148              0,0,0, 1,0,0, 1,0,0, 0,0,0,
149              0,0,0, 0,0,0, 0,0,0, 0,0,0]
150    bmp = bitmap.Bitmap(3, 4, 3, pixels)
151    box, count = bmp.GetBoundingBox(bitmap.RgbaColor(1, 0, 0))
152    self.assertEquals(box, (1, 1, 2, 1))
153    self.assertEquals(count, 2)
154
155    box, count = bmp.GetBoundingBox(bitmap.RgbaColor(0, 1, 0))
156    self.assertEquals(box, None)
157    self.assertEquals(count, 0)
158
159  @benchmark.Disabled
160  def testCrop(self):
161    pixels = [0,0,0, 1,0,0, 2,0,0, 3,0,0,
162              0,1,0, 1,1,0, 2,1,0, 3,1,0,
163              0,2,0, 1,2,0, 2,2,0, 3,2,0]
164    bmp = bitmap.Bitmap(3, 4, 3, pixels)
165    bmp.Crop(1, 2, 2, 1)
166
167    self.assertEquals(bmp.width, 2)
168    self.assertEquals(bmp.height, 1)
169    bmp.GetPixelColor(0, 0).AssertIsRGB(1, 2, 0)
170    bmp.GetPixelColor(1, 0).AssertIsRGB(2, 2, 0)
171    self.assertEquals(bmp.pixels, bytearray([1,2,0, 2,2,0]))
172
173  @benchmark.Disabled
174  def testHistogram(self):
175    pixels = [1,2,3, 1,2,3, 1,2,3, 1,2,3,
176              1,2,3, 8,7,6, 5,4,6, 1,2,3,
177              1,2,3, 8,7,6, 5,4,6, 1,2,3]
178    bmp = bitmap.Bitmap(3, 4, 3, pixels)
179    bmp.Crop(1, 1, 2, 2)
180
181    histogram = bmp.ColorHistogram()
182    for i in xrange(3):
183      self.assertEquals(sum(histogram[i]), bmp.width * bmp.height)
184    self.assertEquals(histogram.r[1], 0)
185    self.assertEquals(histogram.r[5], 2)
186    self.assertEquals(histogram.r[8], 2)
187    self.assertEquals(histogram.g[2], 0)
188    self.assertEquals(histogram.g[4], 2)
189    self.assertEquals(histogram.g[7], 2)
190    self.assertEquals(histogram.b[3], 0)
191    self.assertEquals(histogram.b[6], 4)
192
193  @benchmark.Disabled
194  def testHistogramIgnoreColor(self):
195    pixels = [1,2,3, 1,2,3, 1,2,3, 1,2,3,
196              1,2,3, 8,7,6, 5,4,6, 1,2,3,
197              1,2,3, 8,7,6, 5,4,6, 1,2,3]
198    bmp = bitmap.Bitmap(3, 4, 3, pixels)
199
200    histogram = bmp.ColorHistogram(ignore_color=bitmap.RgbaColor(1, 2, 3))
201    self.assertEquals(histogram.r[1], 0)
202    self.assertEquals(histogram.r[5], 2)
203    self.assertEquals(histogram.r[8], 2)
204    self.assertEquals(histogram.g[2], 0)
205    self.assertEquals(histogram.g[4], 2)
206    self.assertEquals(histogram.g[7], 2)
207    self.assertEquals(histogram.b[3], 0)
208    self.assertEquals(histogram.b[6], 4)
209
210  @benchmark.Disabled
211  def testHistogramIgnoreColorTolerance(self):
212    pixels = [1,2,3, 4,5,6,
213              7,8,9, 8,7,6]
214    bmp = bitmap.Bitmap(3, 2, 2, pixels)
215
216    histogram = bmp.ColorHistogram(ignore_color=bitmap.RgbaColor(0, 1, 2),
217                                   tolerance=1)
218    self.assertEquals(histogram.r[1], 0)
219    self.assertEquals(histogram.r[4], 1)
220    self.assertEquals(histogram.r[7], 1)
221    self.assertEquals(histogram.r[8], 1)
222    self.assertEquals(histogram.g[2], 0)
223    self.assertEquals(histogram.g[5], 1)
224    self.assertEquals(histogram.g[7], 1)
225    self.assertEquals(histogram.g[8], 1)
226    self.assertEquals(histogram.b[3], 0)
227    self.assertEquals(histogram.b[6], 2)
228    self.assertEquals(histogram.b[9], 1)
229
230  @benchmark.Disabled
231  def testHistogramDistanceIgnoreColor(self):
232    pixels = [1,2,3, 1,2,3,
233              1,2,3, 1,2,3]
234    bmp = bitmap.Bitmap(3, 2, 2, pixels)
235
236    hist1 = bmp.ColorHistogram(ignore_color=bitmap.RgbaColor(1, 2, 3))
237    hist2 = bmp.ColorHistogram()
238
239    self.assertEquals(hist1.Distance(hist2), 0)
240