1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot# Copyright 2017 Google Inc.
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot# Use of this source code is governed by a BSD-style license that can be
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot# found in the LICENSE file.
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot"""
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotVisualize bitmaps in gdb.
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot(gdb) source <path to this file>
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot(gdb) sk_bitmap <symbol>
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotThis should pop up a window with the bitmap displayed.
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotRight clicking should bring up a menu, allowing the
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbitmap to be saved to a file.
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot"""
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotimport gdb
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotfrom enum import Enum
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottry:
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  from PIL import Image
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotexcept ImportError:
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  import Image
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ColorType(Enum):
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unknown = 0
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    alpha_8 = 1
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rgb_565 = 2
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    argb_4444 = 3
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rgba_8888 = 4
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bgra_8888 = 5
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    gray_8 = 6
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    rgba_F16 = 7
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass AlphaType(Enum):
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unknown = 0
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    opaque = 1
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    premul = 2
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unpremul = 3
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass sk_bitmap(gdb.Command):
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  """Displays the content of an SkBitmap image."""
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  def __init__(self):
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      super(sk_bitmap, self).__init__('sk_bitmap',
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      gdb.COMMAND_SUPPORT,
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      gdb.COMPLETE_FILENAME)
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot  def invoke(self, arg, from_tty):
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    frame = gdb.selected_frame()
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    val = frame.read_var(arg)
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if str(val.type.strip_typedefs()) == 'SkBitmap':
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      pixels = val['fPixels']
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      row_bytes = val['fRowBytes']
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      info = val['fInfo']
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      width = info['fWidth']
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      height = info['fHeight']
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      color_type = info['fColorType']
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      alpha_type = info['fAlphaType']
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      process = gdb.selected_inferior()
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      memory_data = process.read_memory(pixels, row_bytes * height)
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      size = (width, height)
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      image = None
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      # See Unpack.c for the values understood after the "raw" parameter.
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      if color_type == ColorType.bgra_8888.value:
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if alpha_type == AlphaType.unpremul.value:
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          image = Image.frombytes("RGBA", size, memory_data.tobytes(),
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  "raw", "BGRA", row_bytes, 1)
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        elif alpha_type == AlphaType.premul.value:
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          # RGBA instead of RGBa, because Image.show() doesn't work with RGBa.
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot          image = Image.frombytes("RGBA", size, memory_data.tobytes(),
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  "raw", "BGRa", row_bytes, 1)
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      if image:
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        # Fails on premultiplied alpha, it cannot convert to RGB.
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        image.show()
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot      else:
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        print ("Need to add support for %s %s." % (
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               str(ColorType(int(color_type))),
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               str(AlphaType(int(alpha_type)))
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ))
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_bitmap()
84