From: Zack Rusin Date: Thu, 12 Sep 2013 21:21:51 +0000 (-0400) Subject: gui: show the original pixel values in the surface viewer X-Git-Url: https://git.cworth.org/git?p=apitrace;a=commitdiff_plain;h=a69f0de6b922160bec029cfd18b5002b904afccf gui: show the original pixel values in the surface viewer Image viewer now holds the original image surface which means that even though it has to display the flattened version it can correctly report the exact pixel value on every surface. --- diff --git a/gui/apisurface.cpp b/gui/apisurface.cpp index 3732ed5..199cd7d 100644 --- a/gui/apisurface.cpp +++ b/gui/apisurface.cpp @@ -33,8 +33,83 @@ struct ByteArrayBuf : public std::streambuf void ApiSurface::contentsFromBase64(const QByteArray &base64) { - QByteArray dataArray = QByteArray::fromBase64(base64); + m_base64Data = base64; + + /* + * We need to do the conversion to create the thumbnail + */ + image::Image *image = imageFromBase64(base64); + Q_ASSERT(image); + QImage img = qimageFromRawImage(image); + m_thumb = thumbnail(img); + delete image; +} + +QByteArray ApiSurface::base64Data() const +{ + return m_base64Data; +} + +QImage ApiSurface::thumb() const +{ + return m_thumb; +} + +int ApiSurface::depth() const +{ + return m_depth; +} + +void ApiSurface::setDepth(int depth) +{ + m_depth = depth; +} + +QString ApiSurface::formatName() const +{ + return m_formatName; +} + +void ApiSurface::setFormatName(const QString &str) +{ + m_formatName = str; +} + + +ApiTexture::ApiTexture() + : ApiSurface() +{ +} + +QString ApiTexture::label() const +{ + return m_label; +} + +void ApiTexture::setLabel(const QString &str) +{ + m_label = str; +} +ApiFramebuffer::ApiFramebuffer() + : ApiSurface() +{ +} + +QString ApiFramebuffer::type() const +{ + return m_type; +} + +void ApiFramebuffer::setType(const QString &str) +{ + m_type = str; +} + +image::Image * +ApiSurface::imageFromBase64(const QByteArray &base64) +{ + QByteArray dataArray = QByteArray::fromBase64(base64); image::Image *image; /* @@ -49,23 +124,22 @@ void ApiSurface::contentsFromBase64(const QByteArray &base64) image = image::readPNM(dataArray.data(), dataArray.size()); } - /* - * FIXME: Instead of converting to QImage here, we should be deferring the conversion - * to imageviewer.cpp. - * - * XXX: We still need the thumbnail though. - */ + return image; +} - Q_ASSERT(image); +QImage +ApiSurface::qimageFromRawImage(const image::Image *image) +{ + QImage img; int width = image->width; int height = image->height; - m_image = QImage(width, height, QImage::Format_ARGB32); + img = QImage(width, height, QImage::Format_ARGB32); const unsigned char *srcRow = image->start(); for (int y = 0; y < height; ++y) { - QRgb *dst = (QRgb *)m_image.scanLine(y); + QRgb *dst = (QRgb *)img.scanLine(y); if (image->channelType == image::TYPE_UNORM8) { const unsigned char *src = srcRow; @@ -109,69 +183,5 @@ void ApiSurface::contentsFromBase64(const QByteArray &base64) srcRow += image->stride(); } - delete image; - - m_thumb = thumbnail(m_image); -} - -QImage ApiSurface::image() const -{ - return m_image; -} - -QImage ApiSurface::thumb() const -{ - return m_thumb; -} - -int ApiSurface::depth() const -{ - return m_depth; + return img; } - -void ApiSurface::setDepth(int depth) -{ - m_depth = depth; -} - -QString ApiSurface::formatName() const -{ - return m_formatName; -} - -void ApiSurface::setFormatName(const QString &str) -{ - m_formatName = str; -} - - -ApiTexture::ApiTexture() - : ApiSurface() -{ -} - -QString ApiTexture::label() const -{ - return m_label; -} - -void ApiTexture::setLabel(const QString &str) -{ - m_label = str; -} - -ApiFramebuffer::ApiFramebuffer() - : ApiSurface() -{ -} - -QString ApiFramebuffer::type() const -{ - return m_type; -} - -void ApiFramebuffer::setType(const QString &str) -{ - m_type = str; -} - diff --git a/gui/apisurface.h b/gui/apisurface.h index 9f00001..79afaf9 100644 --- a/gui/apisurface.h +++ b/gui/apisurface.h @@ -5,6 +5,10 @@ #include #include +namespace image { + class Image; +} + class ApiSurface { public: @@ -21,13 +25,16 @@ public: void contentsFromBase64(const QByteArray &base64); - QImage image() const; + QByteArray base64Data() const; QImage thumb() const; + static image::Image *imageFromBase64(const QByteArray &data); + static QImage qimageFromRawImage(const image::Image *img); + private: QSize m_size; int m_numChannels; - QImage m_image; + QByteArray m_base64Data; QImage m_thumb; int m_depth; QString m_formatName; diff --git a/gui/imageviewer.cpp b/gui/imageviewer.cpp index cd03413..a795993 100644 --- a/gui/imageviewer.cpp +++ b/gui/imageviewer.cpp @@ -1,5 +1,8 @@ #include "imageviewer.h" #include "pixelwidget.h" +#include "apisurface.h" + +#include "image/image.hpp" #include #include @@ -8,7 +11,8 @@ #include ImageViewer::ImageViewer(QWidget *parent) - : QDialog(parent) + : QDialog(parent), + m_image(0) { setupUi(this); @@ -52,11 +56,17 @@ ImageViewer::ImageViewer(QWidget *parent) this, SLOT(showGrid(const QRect &))); } -void ImageViewer::setImage(const QImage &image) +ImageViewer::~ImageViewer() { - m_image = image; - m_temp = m_image; - m_pixelWidget->setSurface(m_image); + delete m_image; +} + +void ImageViewer::setBase64Data(const QByteArray &base64) +{ + delete m_image; + m_image = ApiSurface::imageFromBase64(base64); + m_convertedImage = ApiSurface::qimageFromRawImage(m_image); + m_pixelWidget->setSurface(m_convertedImage); updateGeometry(); } @@ -73,7 +83,8 @@ static inline int clamp(int x) void ImageViewer::slotUpdate() { - m_temp = m_image.mirrored(false, flipCheckBox->isChecked()); + m_convertedImage = + m_convertedImage.mirrored(false, flipCheckBox->isChecked()); double lowerValue = lowerSpinBox->value(); double upperValue = upperSpinBox->value(); @@ -92,7 +103,8 @@ void ImageViewer::slotUpdate() int offset = - lowerValue * 255; int scale = 256 / (upperValue - lowerValue); - m_temp = m_temp.convertToFormat(QImage::Format_ARGB32); + m_convertedImage = + m_convertedImage.convertToFormat(QImage::Format_ARGB32); if (0) { qDebug() @@ -100,13 +112,13 @@ void ImageViewer::slotUpdate() << "scale = " << scale << "\n"; } - int width = m_temp.width(); - int height = m_temp.height(); + int width = m_convertedImage.width(); + int height = m_convertedImage.height(); int aMask = opaque ? 0xff : 0; for (int y = 0; y < height; ++y) { - QRgb *scanline = (QRgb *)m_temp.scanLine(y); + QRgb *scanline = (QRgb *)m_convertedImage.scanLine(y); for (int x = 0; x < width; ++x) { QRgb pixel = scanline[x]; int r = qRed(pixel); @@ -127,7 +139,7 @@ void ImageViewer::slotUpdate() } } - m_pixelWidget->setSurface(m_temp); + m_pixelWidget->setSurface(m_convertedImage); updateGeometry(); } @@ -140,8 +152,8 @@ QSize ImageViewer::sizeHint() const scrollArea->verticalScrollBar()->width() : 0; int hScrollHeight = scrollArea->horizontalScrollBar() ? scrollArea->horizontalScrollBar()->height() : 0; - QSize optimalWindowSize(m_image.width() + vScrollWidth, - m_image.height() + hScrollHeight); + QSize optimalWindowSize(m_convertedImage.width() + vScrollWidth, + m_convertedImage.height() + hScrollHeight); QRect screenRect = QApplication::desktop()->availableGeometry(); const float maxPercentOfDesktopSpace = 0.8f; @@ -157,16 +169,45 @@ void ImageViewer::resizeEvent(QResizeEvent *e) QWidget::resizeEvent(e); } +template +QString createPixelLabel(image::Image *img, int x, int y) +{ + QString pixelLabel; + unsigned char *pixelLocation = 0; + T *pixel; + + pixelLocation = img->pixels + img->stride() * y; + pixelLocation += x * img->bytesPerPixel; + pixel = ((T*)pixelLocation); + + pixelLabel += QLatin1String("["); + pixelLabel += QString::fromLatin1("%1").arg(pixel[0]); + + for (int channel = 1; channel < img->channels; ++channel) { + pixelLabel += QString::fromLatin1(", %1").arg(pixel[channel]); + } + pixelLabel += QLatin1String("]"); + + return pixelLabel; +} + void ImageViewer::showPixel(int x, int y) { xSpinBox->setValue(x); ySpinBox->setValue(y); - QColor clr = m_pixelWidget->colorAtCurrentPosition(); - pixelLabel->setText(tr("RGBA: (%1, %2, %3, %4)") - .arg(clr.red()) - .arg(clr.green()) - .arg(clr.blue()) - .arg(clr.alpha())); + + if (!m_image) + return; + + QString label = tr("Pixel: "); + + if (m_image->channelType == image::TYPE_UNORM8) { + label += createPixelLabel(m_image, x, y); + } else { + label += createPixelLabel(m_image, x, y); + } + + pixelLabel->setText(label); pixelLabel->show(); } diff --git a/gui/imageviewer.h b/gui/imageviewer.h index 141ca17..2e2984e 100644 --- a/gui/imageviewer.h +++ b/gui/imageviewer.h @@ -7,13 +7,18 @@ class PixelWidget; class QLabel; +namespace image { + class Image; +} + class ImageViewer : public QDialog, public Ui_ImageViewer { Q_OBJECT public: ImageViewer(QWidget *parent = 0); + ~ImageViewer(); - void setImage(const QImage &image); + void setBase64Data(const QByteArray &base64); QSize sizeHint() const; @@ -26,8 +31,8 @@ private slots: void showGrid(const QRect &rect); private: - QImage m_image; - QImage m_temp; + image::Image *m_image; + QImage m_convertedImage; PixelWidget *m_pixelWidget; QLabel *m_pixelLabel; }; diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 00469bc..3278330 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -575,7 +575,7 @@ static void addSurfaceItem(const ApiSurface &surface, l->setWordWrap(true); tree->setItemWidget(item, 1, l); - item->setData(0, Qt::UserRole, surface.image()); + item->setData(0, Qt::UserRole, surface.base64Data()); } void MainWindow::fillStateForFrame() @@ -722,8 +722,8 @@ void MainWindow::showSelectedSurface() viewer->setAttribute(Qt::WA_DeleteOnClose, true); QVariant var = item->data(0, Qt::UserRole); - QImage img = var.value(); - viewer->setImage(img); + QByteArray base64Data = var.value(); + viewer->setBase64Data(base64Data); viewer->show(); viewer->raise();