CDB: Support for displaying QImage.

Change-Id: Ic1a4a0e6767a0cecb1fd869bbcfd9673854631aa
Reviewed-by: hjk <qthjk@ovi.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Friedemann Kleint
2012-12-28 19:01:39 +01:00
parent 99f542354a
commit 2344456b3f
3 changed files with 79 additions and 2 deletions

View File

@@ -2066,6 +2066,70 @@ static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str)
return true;
}
static bool dumpQImage(const SymbolGroupValue &v, std::wostream &str, MemoryHandle **memoryHandle)
{
struct CreatorImageHeader { // Header for image display as edit format, followed by data.
int width;
int height;
int format;
};
const QtInfo &qtInfo(QtInfo::get(v.context()));
// Fetch data of unexported private class
const ULONG64 address = v["d"].pointerValue();
if (!address) {
str << L"<null>";
return true;
}
const std::string qImageDataType = qtInfo.prependQtGuiModule("QImageData");
const unsigned long size = SymbolGroupValue::sizeOf(qImageDataType.c_str());
if (!size)
return false;
unsigned char *qImageData = SymbolGroupValue::readMemory(v.context().dataspaces, address, size);
if (!qImageData)
return false;
// read size data
unsigned char *ptr = qImageData + qAtomicIntSize(v.context());
CreatorImageHeader header;
header.width = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
header.height = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
const int depth = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
const int nbytes = *(reinterpret_cast<int *>(ptr));
const unsigned dataOffset = SymbolGroupValue::fieldOffset(qImageDataType.c_str(), "data");
// Qt 4 has a Qt 3 support pointer member between 'data' and 'format'.
const unsigned formatOffset = SymbolGroupValue::fieldOffset(qImageDataType.c_str(), "format");
if (!dataOffset || !formatOffset)
return false;
ptr = qImageData + dataOffset;
// read data pointer
ULONG64 data = 0;
memcpy(&data, ptr, SymbolGroupValue::pointerSize());
// read format
ptr = qImageData + formatOffset;
header.format = *(reinterpret_cast<int *>(ptr));
if (header.width < 0 || header.height < 0 || header.format < 0 || header.format > 255
|| nbytes < 0 || depth < 0) {
return false;
}
str << header.width << L'x' << header.height << L", depth: " << depth
<< L", format: " << header.format << L", "
<< nbytes << L" bytes @0x" << std::hex << data << std::dec;
delete [] qImageData;
// Create Creator Image data for display if reasonable size
if (memoryHandle && data && nbytes > 0 && nbytes < 205824) {
if (unsigned char *imageData = SymbolGroupValue::readMemory(v.context().dataspaces, data, nbytes)) {
unsigned char *creatorImageData = new unsigned char[sizeof(CreatorImageHeader) + nbytes];
memcpy(creatorImageData, &header, sizeof(CreatorImageHeader));
memcpy(creatorImageData + sizeof(CreatorImageHeader), imageData, nbytes);
delete [] imageData;
*memoryHandle = new MemoryHandle(creatorImageData, sizeof(CreatorImageHeader) + nbytes);
}
}
return true;
}
// Dump a rectangle in X11 syntax
template <class T>
inline void dumpRect(std::wostream &str, T x, T y, T width, T height)
@@ -2564,6 +2628,9 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
case KT_QLineF:
rc = dumpQLine_F(v, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
case KT_QImage:
rc = dumpQImage(v, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
case KT_QRect:
rc = dumpQRect(v, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
@@ -2654,6 +2721,11 @@ bool dumpEditValue(const SymbolGroupNode *n, const SymbolGroupValueContext &,
if (const MemoryHandle *mh = n->memory())
formatEditValue(DisplayLatin1String, mh, str);
break;
case KT_QImage:
if (desiredFormat == 1) // Image.
if (const MemoryHandle *mh = n->memory())
formatEditValue(DisplayImageData, mh, str);
break;
}
return true;
}