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