blob: 199cd7d3cdb115c884571fb58005150b644ed094 [file] [log] [blame]
Zack Rusin952e9d42011-04-09 23:37:21 -04001#include "apisurface.h"
José Fonseca3f456402012-03-25 20:59:24 +01002#include "thumbnail.h"
Zack Rusin952e9d42011-04-09 23:37:21 -04003
José Fonseca52398312013-09-11 18:42:07 +01004#include <sstream>
5
Zack Rusin952e9d42011-04-09 23:37:21 -04006#include <QDebug>
7#include <QSysInfo>
8
José Fonseca52398312013-09-11 18:42:07 +01009#include "image/image.hpp"
10
11
Zack Rusin952e9d42011-04-09 23:37:21 -040012ApiSurface::ApiSurface()
13{
14}
15
16QSize ApiSurface::size() const
17{
18 return m_size;
19}
20
21void ApiSurface::setSize(const QSize &size)
22{
23 m_size = size;
24}
25
José Fonseca52398312013-09-11 18:42:07 +010026struct ByteArrayBuf : public std::streambuf
27{
28 ByteArrayBuf(QByteArray & a)
29 {
30 setg(a.data(), a.data(), a.data() + a.size());
31 }
32};
33
Zack Rusin952e9d42011-04-09 23:37:21 -040034void ApiSurface::contentsFromBase64(const QByteArray &base64)
35{
Zack Rusina69f0de2013-09-12 17:21:51 -040036 m_base64Data = base64;
José Fonseca994535d2013-09-12 17:26:34 +010037
José Fonseca52398312013-09-11 18:42:07 +010038 /*
Zack Rusina69f0de2013-09-12 17:21:51 -040039 * We need to do the conversion to create the thumbnail
José Fonseca52398312013-09-11 18:42:07 +010040 */
Zack Rusina69f0de2013-09-12 17:21:51 -040041 image::Image *image = imageFromBase64(base64);
José Fonseca52398312013-09-11 18:42:07 +010042 Q_ASSERT(image);
Zack Rusina69f0de2013-09-12 17:21:51 -040043 QImage img = qimageFromRawImage(image);
44 m_thumb = thumbnail(img);
José Fonseca52398312013-09-11 18:42:07 +010045 delete image;
Zack Rusin952e9d42011-04-09 23:37:21 -040046}
47
Zack Rusina69f0de2013-09-12 17:21:51 -040048QByteArray ApiSurface::base64Data() const
Zack Rusin952e9d42011-04-09 23:37:21 -040049{
Zack Rusina69f0de2013-09-12 17:21:51 -040050 return m_base64Data;
Zack Rusin952e9d42011-04-09 23:37:21 -040051}
52
53QImage ApiSurface::thumb() const
54{
55 return m_thumb;
56}
57
Zack Rusinb25c4b92011-11-16 22:43:34 -050058int ApiSurface::depth() const
59{
60 return m_depth;
61}
62
63void ApiSurface::setDepth(int depth)
64{
65 m_depth = depth;
66}
67
Zack Rusine181b992011-11-17 16:00:41 -050068QString ApiSurface::formatName() const
69{
70 return m_formatName;
71}
72
73void ApiSurface::setFormatName(const QString &str)
74{
75 m_formatName = str;
76}
77
78
Zack Rusin952e9d42011-04-09 23:37:21 -040079ApiTexture::ApiTexture()
José Fonseca18081d52011-05-07 00:10:25 +010080 : ApiSurface()
Zack Rusin952e9d42011-04-09 23:37:21 -040081{
82}
83
José Fonseca18081d52011-05-07 00:10:25 +010084QString ApiTexture::label() const
Zack Rusin952e9d42011-04-09 23:37:21 -040085{
José Fonseca18081d52011-05-07 00:10:25 +010086 return m_label;
Zack Rusin952e9d42011-04-09 23:37:21 -040087}
88
José Fonseca18081d52011-05-07 00:10:25 +010089void ApiTexture::setLabel(const QString &str)
Zack Rusin952e9d42011-04-09 23:37:21 -040090{
José Fonseca18081d52011-05-07 00:10:25 +010091 m_label = str;
Zack Rusin952e9d42011-04-09 23:37:21 -040092}
Zack Rusina6846412011-04-10 19:51:44 -040093
94ApiFramebuffer::ApiFramebuffer()
95 : ApiSurface()
96{
97}
98
99QString ApiFramebuffer::type() const
100{
101 return m_type;
102}
103
104void ApiFramebuffer::setType(const QString &str)
105{
106 m_type = str;
107}
Zack Rusinb25c4b92011-11-16 22:43:34 -0500108
Zack Rusina69f0de2013-09-12 17:21:51 -0400109image::Image *
110ApiSurface::imageFromBase64(const QByteArray &base64)
111{
112 QByteArray dataArray = QByteArray::fromBase64(base64);
113 image::Image *image;
114
115 /*
116 * Detect the PNG vs PFM images.
117 */
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);
123 } else {
124 image = image::readPNM(dataArray.data(), dataArray.size());
125 }
126
127 return image;
128}
129
130
131QImage
132ApiSurface::qimageFromRawImage(const image::Image *image)
133{
134 QImage img;
135 int width = image->width;
136 int height = image->height;
137
138 img = QImage(width, height, QImage::Format_ARGB32);
139
140 const unsigned char *srcRow = image->start();
141 for (int y = 0; y < height; ++y) {
142 QRgb *dst = (QRgb *)img.scanLine(y);
143
144 if (image->channelType == image::TYPE_UNORM8) {
145 const unsigned char *src = srcRow;
146 for (int x = 0; x < width; ++x) {
147 unsigned char rgba[4];
148 for (int c = 0; c < image->channels; ++c) {
149 rgba[c] = *src++;
150 }
151 if (image->channels == 1) {
152 // Use gray-scale instead of red
153 rgba[1] = rgba[0];
154 rgba[2] = rgba[0];
155 }
156 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
157 }
158 } else {
159 const float *src = (const float *)srcRow;
160 for (int x = 0; x < width; ++x) {
161 unsigned char rgba[4] = {0, 0, 0, 0xff};
162 for (int c = 0; c < image->channels; ++c) {
163 float f = *src++;
164 unsigned char u;
165 if (f >= 1.0f) {
166 u = 255;
167 } else if (f <= 0.0f) {
168 u = 0;
169 } else {
170 u = f * 255 + 0.5;
171 }
172 rgba[c] = u;
173 }
174 if (image->channels == 1) {
175 // Use gray-scale instead of red
176 rgba[1] = rgba[0];
177 rgba[2] = rgba[0];
178 }
179 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
180 }
181 }
182
183 srcRow += image->stride();
184 }
185
186 return img;
187}