blob: 3732ed5f717482ad976fbf6f9f0d9e447113b91c [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{
36 QByteArray dataArray = QByteArray::fromBase64(base64);
José Fonseca52398312013-09-11 18:42:07 +010037
José Fonseca994535d2013-09-12 17:26:34 +010038 image::Image *image;
39
José Fonseca52398312013-09-11 18:42:07 +010040 /*
José Fonseca994535d2013-09-12 17:26:34 +010041 * Detect the PNG vs PFM images.
José Fonseca52398312013-09-11 18:42:07 +010042 */
José Fonseca994535d2013-09-12 17:26:34 +010043 const char pngSignature[] = {(char)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0};
44 if (dataArray.startsWith(pngSignature)) {
45 ByteArrayBuf buf(dataArray);
46 std::istream istr(&buf);
47 image = image::readPNG(istr);
48 } else {
49 image = image::readPNM(dataArray.data(), dataArray.size());
50 }
José Fonseca52398312013-09-11 18:42:07 +010051
52 /*
53 * FIXME: Instead of converting to QImage here, we should be deferring the conversion
54 * to imageviewer.cpp.
55 *
56 * XXX: We still need the thumbnail though.
57 */
58
59 Q_ASSERT(image);
60
61 int width = image->width;
62 int height = image->height;
63
64 m_image = QImage(width, height, QImage::Format_ARGB32);
65
66 const unsigned char *srcRow = image->start();
67 for (int y = 0; y < height; ++y) {
68 QRgb *dst = (QRgb *)m_image.scanLine(y);
69
70 if (image->channelType == image::TYPE_UNORM8) {
71 const unsigned char *src = srcRow;
72 for (int x = 0; x < width; ++x) {
73 unsigned char rgba[4];
74 for (int c = 0; c < image->channels; ++c) {
75 rgba[c] = *src++;
76 }
77 if (image->channels == 1) {
78 // Use gray-scale instead of red
79 rgba[1] = rgba[0];
80 rgba[2] = rgba[0];
81 }
82 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
83 }
84 } else {
85 const float *src = (const float *)srcRow;
86 for (int x = 0; x < width; ++x) {
87 unsigned char rgba[4] = {0, 0, 0, 0xff};
88 for (int c = 0; c < image->channels; ++c) {
89 float f = *src++;
90 unsigned char u;
José Fonseca994535d2013-09-12 17:26:34 +010091 if (f >= 1.0f) {
José Fonseca52398312013-09-11 18:42:07 +010092 u = 255;
93 } else if (f <= 0.0f) {
94 u = 0;
95 } else {
96 u = f * 255 + 0.5;
97 }
98 rgba[c] = u;
99 }
100 if (image->channels == 1) {
101 // Use gray-scale instead of red
102 rgba[1] = rgba[0];
103 rgba[2] = rgba[0];
104 }
105 dst[x] = qRgba(rgba[0], rgba[1], rgba[2], rgba[3]);
106 }
107 }
108
109 srcRow += image->stride();
110 }
111
112 delete image;
113
José Fonseca3f456402012-03-25 20:59:24 +0100114 m_thumb = thumbnail(m_image);
Zack Rusin952e9d42011-04-09 23:37:21 -0400115}
116
117QImage ApiSurface::image() const
118{
119 return m_image;
120}
121
122QImage ApiSurface::thumb() const
123{
124 return m_thumb;
125}
126
Zack Rusinb25c4b92011-11-16 22:43:34 -0500127int ApiSurface::depth() const
128{
129 return m_depth;
130}
131
132void ApiSurface::setDepth(int depth)
133{
134 m_depth = depth;
135}
136
Zack Rusine181b992011-11-17 16:00:41 -0500137QString ApiSurface::formatName() const
138{
139 return m_formatName;
140}
141
142void ApiSurface::setFormatName(const QString &str)
143{
144 m_formatName = str;
145}
146
147
Zack Rusin952e9d42011-04-09 23:37:21 -0400148ApiTexture::ApiTexture()
José Fonseca18081d52011-05-07 00:10:25 +0100149 : ApiSurface()
Zack Rusin952e9d42011-04-09 23:37:21 -0400150{
151}
152
José Fonseca18081d52011-05-07 00:10:25 +0100153QString ApiTexture::label() const
Zack Rusin952e9d42011-04-09 23:37:21 -0400154{
José Fonseca18081d52011-05-07 00:10:25 +0100155 return m_label;
Zack Rusin952e9d42011-04-09 23:37:21 -0400156}
157
José Fonseca18081d52011-05-07 00:10:25 +0100158void ApiTexture::setLabel(const QString &str)
Zack Rusin952e9d42011-04-09 23:37:21 -0400159{
José Fonseca18081d52011-05-07 00:10:25 +0100160 m_label = str;
Zack Rusin952e9d42011-04-09 23:37:21 -0400161}
Zack Rusina6846412011-04-10 19:51:44 -0400162
163ApiFramebuffer::ApiFramebuffer()
164 : ApiSurface()
165{
166}
167
168QString ApiFramebuffer::type() const
169{
170 return m_type;
171}
172
173void ApiFramebuffer::setType(const QString &str)
174{
175 m_type = str;
176}
Zack Rusinb25c4b92011-11-16 22:43:34 -0500177