]> git.cworth.org Git - apitrace/blob - gui/apisurface.cpp
ui: Handle float images in dumps.
[apitrace] / gui / apisurface.cpp
1 #include "apisurface.h"
2 #include "thumbnail.h"
3
4 #include <sstream>
5
6 #include <QDebug>
7 #include <QSysInfo>
8
9 #include "image/image.hpp"
10
11
12 ApiSurface::ApiSurface()
13 {
14 }
15
16 QSize ApiSurface::size() const
17 {
18     return m_size;
19 }
20
21 void ApiSurface::setSize(const QSize &size)
22 {
23     m_size = size;
24 }
25
26 struct ByteArrayBuf : public std::streambuf
27 {
28     ByteArrayBuf(QByteArray & a)
29     {
30         setg(a.data(), a.data(), a.data() + a.size());
31     }
32 };
33
34 void ApiSurface::contentsFromBase64(const QByteArray &base64)
35 {
36     QByteArray dataArray = QByteArray::fromBase64(base64);
37
38     image::Image *image;
39
40     /*
41      * Detect the PNG vs PFM images.
42      */
43     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     }
51
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;
91                     if (f >= 1.0f) {
92                         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
114     m_thumb = thumbnail(m_image);
115 }
116
117 QImage ApiSurface::image() const
118 {
119     return m_image;
120 }
121
122 QImage ApiSurface::thumb() const
123 {
124     return m_thumb;
125 }
126
127 int ApiSurface::depth() const
128 {
129     return m_depth;
130 }
131
132 void ApiSurface::setDepth(int depth)
133 {
134     m_depth = depth;
135 }
136
137 QString ApiSurface::formatName() const
138 {
139     return m_formatName;
140 }
141
142 void ApiSurface::setFormatName(const QString &str)
143 {
144     m_formatName = str;
145 }
146
147
148 ApiTexture::ApiTexture()
149     : ApiSurface()
150 {
151 }
152
153 QString ApiTexture::label() const
154 {
155     return m_label;
156 }
157
158 void ApiTexture::setLabel(const QString &str)
159 {
160     m_label = str;
161 }
162
163 ApiFramebuffer::ApiFramebuffer()
164     : ApiSurface()
165 {
166 }
167
168 QString ApiFramebuffer::type() const
169 {
170     return m_type;
171 }
172
173 void ApiFramebuffer::setType(const QString &str)
174 {
175     m_type = str;
176 }
177