forked from qt-creator/qt-creator
Debugger: Make QImage dumper work with release versions
This accidentally also allows non-debug Qt users to reproduce the http://blog.qt.digia.com/blog/2010/04/22/peek-and-poke-vol-3/ smiley drawing. Change-Id: Ica436f55494d012d5516ef9d00d6310f2ac2d4ee Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -748,50 +748,57 @@ def qform__QImage():
|
|||||||
return "Normal,Displayed"
|
return "Normal,Displayed"
|
||||||
|
|
||||||
def qdump__QImage(d, value):
|
def qdump__QImage(d, value):
|
||||||
# This relies on current QImage layout
|
# This relies on current QImage layout:
|
||||||
intPtrType = d.lookupType("int").pointer()
|
# QImageData:
|
||||||
offset = (3 if d.qtVersion() >= 0x050000 else 2) * intPtrType.sizeof
|
# - QAtomicInt ref
|
||||||
base = d.createValue(d.addressOf(value) + offset, intPtrType)
|
# - int width, height, depth, nbytes
|
||||||
width = int(base[1])
|
# - qreal devicePixelRatio (+20) # Assume qreal == double, Qt 5 only
|
||||||
height = int(base[2])
|
# - QVector<QRgb> colortable (+20 + gap)
|
||||||
|
# - uchar *data (+20 + gap + ptr)
|
||||||
|
# [- uchar **jumptable jumptable with Qt 3 suppor]
|
||||||
|
# - enum format (+20 + gap + 2 * ptr)
|
||||||
|
|
||||||
|
ptrSize = d.ptrSize()
|
||||||
|
isQt5 = d.qtVersion() >= 0x050000
|
||||||
|
offset = (3 if isQt5 else 2) * ptrSize
|
||||||
|
base = d.dereference(d.addressOf(value) + offset)
|
||||||
|
width = d.extractInt(base + 4)
|
||||||
|
height = d.extractInt(base + 8)
|
||||||
|
nbytes = d.extractInt(base + 16)
|
||||||
|
pixelRatioSize = 8 if isQt5 else 0
|
||||||
|
jumpTableSize = ptrSize if not isQt5 else 0 # FIXME: Assumes Qt3 Support
|
||||||
|
bits = d.dereference(base + 20 + pixelRatioSize + ptrSize)
|
||||||
|
iformat = d.extractInt(base + 20 + pixelRatioSize + jumpTableSize + 2 * ptrSize)
|
||||||
d.putValue("(%dx%d)" % (width, height))
|
d.putValue("(%dx%d)" % (width, height))
|
||||||
d.putNumChild(0)
|
d.putNumChild(1)
|
||||||
#d.putNumChild(1)
|
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
with Children(d):
|
with Children(d):
|
||||||
|
d.putIntItem("width", width)
|
||||||
|
d.putIntItem("height", height)
|
||||||
|
d.putIntItem("nbytes", nbytes)
|
||||||
|
d.putIntItem("format", iformat)
|
||||||
with SubItem(d, "data"):
|
with SubItem(d, "data"):
|
||||||
d.putNoType()
|
d.putValue("0x%x" % bits)
|
||||||
d.putNumChild(0)
|
d.putNumChild(0)
|
||||||
d.putValue("size: %s bytes" % nbytes);
|
d.putType("void *")
|
||||||
|
|
||||||
format = d.currentItemFormat()
|
format = d.currentItemFormat()
|
||||||
if format == 1:
|
if format == 1:
|
||||||
d.putDisplay(StopDisplay)
|
d.putDisplay(StopDisplay)
|
||||||
elif format == 2:
|
elif format == 2:
|
||||||
d_ptr = value["d"]
|
# This is critical for performance. Writing to an external
|
||||||
bits = d_ptr["data"]
|
# file using the following is faster when using GDB.
|
||||||
nbytes = d_ptr["nbytes"]
|
# file = tempfile.mkstemp(prefix="gdbpy_")
|
||||||
if False:
|
# filename = file[1].replace("\\", "\\\\")
|
||||||
# Take four bytes at a time, this is critical for performance.
|
# gdb.execute("dump binary memory %s %s %s" %
|
||||||
# In fact, even four at a time is too slow beyond 100x100 or so.
|
# (filename, bits, bits + nbytes))
|
||||||
d.putField("editformat", DisplayImageData)
|
# d.putDisplay(DisplayImageFile, " %d %d %d %d %s"
|
||||||
d.put('%s="' % name)
|
# % (width, height, nbytes, iformat, filename))
|
||||||
d.put("%08x" % width)
|
d.putField("editformat", DisplayImageData)
|
||||||
d.put("%08x" % height)
|
d.put('editvalue="')
|
||||||
d.put("%08x" % int(d_ptr["format"]))
|
d.put('%08x%08x%08x%08x' % (width, height, nbytes, iformat))
|
||||||
p = bits.cast(d.intType().pointer())
|
d.put(d.readRawMemory(bits, nbytes))
|
||||||
for i in xrange(nbytes / 4):
|
d.put('",')
|
||||||
d.put("%08x" % int(p.dereference()))
|
|
||||||
p += 1
|
|
||||||
d.put('",')
|
|
||||||
else:
|
|
||||||
# Write to an external file. Much faster ;-(
|
|
||||||
file = tempfile.mkstemp(prefix="gdbpy_")
|
|
||||||
filename = file[1].replace("\\", "\\\\")
|
|
||||||
p = bits.cast(d.charType().pointer())
|
|
||||||
gdb.execute("dump binary memory %s %s %s" %
|
|
||||||
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
|
|
||||||
d.putDisplay(DisplayImageFile, " %d %d %d %s"
|
|
||||||
% (width, height, d_ptr["format"], filename))
|
|
||||||
|
|
||||||
|
|
||||||
def qdump__QLinkedList(d, value):
|
def qdump__QLinkedList(d, value):
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ void ImageWidget::setImage(const QImage &image)
|
|||||||
{
|
{
|
||||||
setFixedSize(image.size() + QSize(2, 2));
|
setFixedSize(image.size() + QSize(2, 2));
|
||||||
m_image = image;
|
m_image = image;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageWidget::mousePressEvent(QMouseEvent *ev)
|
void ImageWidget::mousePressEvent(QMouseEvent *ev)
|
||||||
|
|||||||
@@ -1679,28 +1679,37 @@ void WatchHandler::showEditValue(const WatchData &data)
|
|||||||
showSeparateWidget(l);
|
showSeparateWidget(l);
|
||||||
m_model->m_editHandlers[key] = l;
|
m_model->m_editHandlers[key] = l;
|
||||||
}
|
}
|
||||||
int width = 0, height = 0, format = 0;
|
int width = 0, height = 0, nbytes = 0, format = 0;
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
uchar *bits = 0;
|
uchar *bits = 0;
|
||||||
if (data.editformat == DisplayImageData) {
|
if (data.editformat == DisplayImageData) {
|
||||||
ba = QByteArray::fromHex(data.editvalue);
|
ba = QByteArray::fromHex(data.editvalue);
|
||||||
|
QTC_ASSERT(ba.size() > 16, return);
|
||||||
const int *header = (int *)(ba.data());
|
const int *header = (int *)(ba.data());
|
||||||
if (!ba.at(0) && !ba.at(1)) // Check on 'width' for Python dumpers returning 4-byte swapped-data.
|
if (!ba.at(0) && !ba.at(1)) // Check on 'width' for Python dumpers returning 4-byte swapped-data.
|
||||||
swapEndian(ba.data(), ba.size());
|
swapEndian(ba.data(), 16);
|
||||||
bits = 12 + (uchar *)(ba.data());
|
bits = 16 + (uchar *)(ba.data());
|
||||||
width = header[0];
|
width = header[0];
|
||||||
height = header[1];
|
height = header[1];
|
||||||
format = header[2];
|
nbytes = header[2];
|
||||||
|
format = header[3];
|
||||||
} else if (data.editformat == DisplayImageFile) {
|
} else if (data.editformat == DisplayImageFile) {
|
||||||
QTextStream ts(data.editvalue);
|
QTextStream ts(data.editvalue);
|
||||||
QString fileName;
|
QString fileName;
|
||||||
ts >> width >> height >> format >> fileName;
|
ts >> width >> height >> nbytes >> format >> fileName;
|
||||||
QFile f(fileName);
|
QFile f(fileName);
|
||||||
f.open(QIODevice::ReadOnly);
|
f.open(QIODevice::ReadOnly);
|
||||||
ba = f.readAll();
|
ba = f.readAll();
|
||||||
bits = (uchar*)ba.data();
|
bits = (uchar*)ba.data();
|
||||||
|
nbytes = width * height;
|
||||||
}
|
}
|
||||||
l->setImage(QImage(bits, width, height, QImage::Format(format)));
|
QTC_ASSERT(0 < width && width < 10000, return);
|
||||||
|
QTC_ASSERT(0 < height && height < 10000, return);
|
||||||
|
QTC_ASSERT(0 < nbytes && nbytes < 10000 * 10000, return);
|
||||||
|
QTC_ASSERT(0 < format && format < 32, return);
|
||||||
|
QImage im(width, height, QImage::Format(format));
|
||||||
|
qMemCopy(im.bits(), bits, nbytes);
|
||||||
|
l->setImage(im);
|
||||||
showSeparateWidget(l);
|
showSeparateWidget(l);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user