1 #include "apisurface.h"
9 #include "image/image.hpp"
12 ApiSurface::ApiSurface()
16 QSize ApiSurface::size() const
21 void ApiSurface::setSize(const QSize &size)
26 struct ByteArrayBuf : public std::streambuf
28 ByteArrayBuf(QByteArray & a)
30 setg(a.data(), a.data(), a.data() + a.size());
34 void ApiSurface::contentsFromBase64(const QByteArray &base64)
36 m_base64Data = base64;
39 * We need to do the conversion to create the thumbnail
41 image::Image *image = imageFromBase64(base64);
43 QImage img = qimageFromRawImage(image);
44 m_thumb = thumbnail(img);
48 QByteArray ApiSurface::base64Data() const
53 QImage ApiSurface::thumb() const
58 int ApiSurface::depth() const
63 void ApiSurface::setDepth(int depth)
68 QString ApiSurface::formatName() const
73 void ApiSurface::setFormatName(const QString &str)
79 ApiTexture::ApiTexture()
84 QString ApiTexture::label() const
89 void ApiTexture::setLabel(const QString &str)
94 ApiFramebuffer::ApiFramebuffer()
99 QString ApiFramebuffer::type() const
104 void ApiFramebuffer::setType(const QString &str)
110 ApiSurface::imageFromBase64(const QByteArray &base64)
112 QByteArray dataArray = QByteArray::fromBase64(base64);
116 * Detect the PNG vs PFM images.
118 const char pngSignature[] = {(char)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0};
119 if (dataArray.startsWith(pngSignature)) {
120 ByteArrayBuf buf(dataArray);
121 std::istream istr(&buf);
122 image = image::readPNG(istr);
124 image = image::readPNM(dataArray.data(), dataArray.size());
131 static inline unsigned char clamp(int x)
139 return (unsigned char) x;
142 static inline unsigned char clamp(float x)
150 return (unsigned char) (x + 0.5f);
155 ApiSurface::qimageFromRawImage(const image::Image *image,
162 int width = image->width;
163 int height = image->height;
165 img = QImage(width, height, QImage::Format_ARGB32);
167 int offset = - lowerValue * 255;
168 int scale = 256 / (upperValue - lowerValue);
170 float offset_f = - lowerValue;
171 float scale_f = 255.0f / (upperValue - lowerValue);
173 int aMask = (opaque || alpha) ? 0xff : 0;
175 const unsigned char *srcRow = image->start();
176 for (int y = 0; y < height; ++y) {
177 QRgb *dst = (QRgb *)img.scanLine(y);
179 if (image->channelType == image::TYPE_UNORM8) {
180 const unsigned char *src = srcRow;
181 for (int x = 0; x < width; ++x) {
182 unsigned char rgba[4] = {0, 0, 0, 0xff};
183 for (int c = 0; c < image->channels; ++c) {
184 rgba[c] = clamp(((*src++ + offset) * scale) >> 8);
186 if (image->channels == 1) {
187 // Use gray-scale instead of red
192 rgba[2] = rgba[1] = rgba[0] = rgba[3];
195 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
198 const float *src = (const float *)srcRow;
199 for (int x = 0; x < width; ++x) {
200 unsigned char rgba[4] = {0, 0, 0, 0xff};
201 for (int c = 0; c < image->channels; ++c) {
202 rgba[c] = clamp((*src++ + offset_f)*scale_f);
204 if (image->channels == 1) {
205 // Use gray-scale instead of red
210 rgba[2] = rgba[1] = rgba[0] = rgba[3];
213 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
217 srcRow += image->stride();