From 52398312caaba3e1bc0613016d5bf3507d1e242a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 11 Sep 2013 18:42:07 +0100 Subject: [PATCH] gui: load image data via the Image class. A bit hackish. A stepping stone to store images with Image class instead of QImage. --- gui/apisurface.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/gui/apisurface.cpp b/gui/apisurface.cpp index d17560f..d6bc72c 100644 --- a/gui/apisurface.cpp +++ b/gui/apisurface.cpp @@ -1,9 +1,14 @@ #include "apisurface.h" #include "thumbnail.h" +#include + #include #include +#include "image/image.hpp" + + ApiSurface::ApiSurface() { } @@ -18,10 +23,87 @@ void ApiSurface::setSize(const QSize &size) m_size = size; } +struct ByteArrayBuf : public std::streambuf +{ + ByteArrayBuf(QByteArray & a) + { + setg(a.data(), a.data(), a.data() + a.size()); + } +}; + void ApiSurface::contentsFromBase64(const QByteArray &base64) { QByteArray dataArray = QByteArray::fromBase64(base64); - m_image.loadFromData(dataArray, "png"); + + /* + * FIXME: Detect the float PFM images here. + */ + ByteArrayBuf buf(dataArray); + std::istream istr(&buf); + image::Image *image = image::readPNG(istr); + + /* + * FIXME: Instead of converting to QImage here, we should be deferring the conversion + * to imageviewer.cpp. + * + * XXX: We still need the thumbnail though. + */ + + Q_ASSERT(image); + + int width = image->width; + int height = image->height; + + m_image = 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); + + if (image->channelType == image::TYPE_UNORM8) { + const unsigned char *src = srcRow; + for (int x = 0; x < width; ++x) { + unsigned char rgba[4]; + for (int c = 0; c < image->channels; ++c) { + rgba[c] = *src++; + } + if (image->channels == 1) { + // Use gray-scale instead of red + rgba[1] = rgba[0]; + rgba[2] = rgba[0]; + } + dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]); + } + } else { + const float *src = (const float *)srcRow; + for (int x = 0; x < width; ++x) { + unsigned char rgba[4] = {0, 0, 0, 0xff}; + for (int c = 0; c < image->channels; ++c) { + float f = *src++; + unsigned char u; + if (f >= 255.0f) { + u = 255; + } else if (f <= 0.0f) { + u = 0; + } else { + u = f * 255 + 0.5; + } + rgba[c] = u; + } + if (image->channels == 1) { + // Use gray-scale instead of red + rgba[1] = rgba[0]; + rgba[2] = rgba[0]; + } + dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]); + } + } + + srcRow += image->stride(); + } + + delete image; + m_thumb = thumbnail(m_image); } -- 2.43.0