| Index: tools/telemetry/telemetry/core/bitmap.py
|
| diff --git a/tools/telemetry/telemetry/core/bitmap.py b/tools/telemetry/telemetry/core/bitmap.py
|
| index c2b26084354a68d3c083f43e15d251cfacd4d6b2..623ced93808defd2ec5c474bfd785458c70ffa71 100644
|
| --- a/tools/telemetry/telemetry/core/bitmap.py
|
| +++ b/tools/telemetry/telemetry/core/bitmap.py
|
| @@ -39,14 +39,20 @@ class RgbaColor(object):
|
| class Bitmap(object):
|
| """Utilities for parsing and inspecting a bitmap."""
|
|
|
| - def __init__(self, png_data):
|
| - self._png_data = png_data
|
| - self._png = png.Reader(bytes=self._png_data)
|
| - rgba8_data = self._png.asRGBA8()
|
| - self._width = rgba8_data[0]
|
| - self._height = rgba8_data[1]
|
| - self._pixels = list(rgba8_data[2])
|
| - self._metadata = rgba8_data[3]
|
| + def __init__(self, bpp, width, height, pixels, metadata=None):
|
| + assert bpp in [3, 4], 'Invalid bytes per pixel'
|
| + assert width > 0, 'Invalid width'
|
| + assert height > 0, 'Invalid height'
|
| + assert pixels, 'Must specify pixels'
|
| + assert bpp * width * height == len(pixels), 'Dimensions and pixels mismatch'
|
| +
|
| + self._bpp = bpp
|
| + self._width = width
|
| + self._height = height
|
| + self._pixels = pixels
|
| + self._metadata = metadata
|
| + if not self._metadata:
|
| + self._metadata = {'size': (width, height)}
|
|
|
| @property
|
| def width(self):
|
| @@ -60,37 +66,53 @@ class Bitmap(object):
|
|
|
| def GetPixelColor(self, x, y):
|
| """Returns a RgbaColor for the pixel at (x, y)"""
|
| - row = self._pixels[y]
|
| - offset = x * 4
|
| - return RgbaColor(row[offset], row[offset+1], row[offset+2], row[offset+3])
|
| + base = self._bpp * (y * self._width + x)
|
| + if self._bpp == 4:
|
| + return RgbaColor(self._pixels[base + 0], self._pixels[base + 1],
|
| + self._pixels[base + 2], self._pixels[base + 3])
|
| + return RgbaColor(self._pixels[base + 0], self._pixels[base + 1],
|
| + self._pixels[base + 2])
|
|
|
| def WritePngFile(self, path):
|
| with open(path, "wb") as f:
|
| - f.write(self._png_data)
|
| + png.Writer(**self._metadata).write_array(f, self._pixels)
|
| +
|
| + @staticmethod
|
| + def FromPng(png_data):
|
| + width, height, pixels, meta = png.Reader(bytes=png_data).read_flat()
|
| + return Bitmap(4 if meta['alpha'] else 3, width, height, pixels, meta)
|
|
|
| @staticmethod
|
| def FromPngFile(path):
|
| with open(path, "rb") as f:
|
| - return Bitmap(f.read())
|
| + return Bitmap.FromPng(f.read())
|
|
|
| @staticmethod
|
| def FromBase64Png(base64_png):
|
| - return Bitmap(base64.b64decode(base64_png))
|
| + return Bitmap.FromPng(base64.b64decode(base64_png))
|
|
|
| - def IsEqual(self, expected, tolerance=0):
|
| + # pylint: disable=W0212
|
| + def IsEqual(self, other, tolerance=0):
|
| """Determines whether two Bitmaps are identical within a given tolerance"""
|
|
|
| # Dimensions must be equal
|
| - if self.width != expected.width or self.height != expected.height:
|
| + if self.width != other.width or self.height != other.height:
|
| return False
|
|
|
| # Loop over each pixel and test for equality
|
| - for y in range(self.height):
|
| - for x in range(self.width):
|
| - c0 = self.GetPixelColor(x, y)
|
| - c1 = expected.GetPixelColor(x, y)
|
| - if not c0.IsEqual(c1, tolerance):
|
| - return False
|
| + if tolerance or self._bpp != other._bpp:
|
| + for y in range(self.height):
|
| + for x in range(self.width):
|
| + c0 = self.GetPixelColor(x, y)
|
| + c1 = other.GetPixelColor(x, y)
|
| + if not c0.IsEqual(c1, tolerance):
|
| + return False
|
| + else:
|
| + if type(self._pixels) is not bytearray:
|
| + self._pixels = bytearray(self._pixels)
|
| + if type(other._pixels) is not bytearray:
|
| + other._pixels = bytearray(other._pixels)
|
| + return self._pixels == other._pixels
|
|
|
| return True
|
|
|
| @@ -128,7 +150,7 @@ class Bitmap(object):
|
| output = cStringIO.StringIO()
|
| try:
|
| diff_img.save(output)
|
| - diff = Bitmap(output.getvalue())
|
| + diff = Bitmap.FromPng(output.getvalue())
|
| finally:
|
| output.close()
|
|
|
| @@ -162,7 +184,7 @@ class Bitmap(object):
|
| output = cStringIO.StringIO()
|
| try:
|
| crop_img.save(output)
|
| - crop = Bitmap(output.getvalue())
|
| + crop = Bitmap.FromPng(output.getvalue())
|
| finally:
|
| output.close()
|
|
|
|
|