]> git.cworth.org Git - apitrace/blob - gui/imageviewer.cpp
glretrace: Dump depth buffers as floating point images.
[apitrace] / gui / imageviewer.cpp
1 #include "imageviewer.h"
2 #include "pixelwidget.h"
3
4 #include <QDebug>
5 #include <QDesktopWidget>
6 #include <QPainter>
7 #include <QPixmap>
8 #include <QScrollBar>
9
10 ImageViewer::ImageViewer(QWidget *parent)
11     : QDialog(parent)
12 {
13     setupUi(this);
14
15     connect(lowerSpinBox, SIGNAL(valueChanged(double)),
16             SLOT(slotUpdate()));
17     connect(upperSpinBox, SIGNAL(valueChanged(double)),
18             SLOT(slotUpdate()));
19     connect(flipCheckBox, SIGNAL(stateChanged(int)),
20             SLOT(slotUpdate()));
21     connect(opaqueCheckBox, SIGNAL(stateChanged(int)),
22             SLOT(slotUpdate()));
23     connect(alphaCheckBox, SIGNAL(stateChanged(int)),
24             SLOT(slotUpdate()));
25
26     QPixmap px(32, 32);
27     QPainter p(&px);
28     p.fillRect(0, 0, 32, 32, Qt::white);
29     p.fillRect(0, 0, 16, 16, QColor(193, 193, 193));
30     p.fillRect(16, 16, 16, 16, QColor(193, 193, 193));
31     p.end();
32     QPalette pal = scrollAreaWidgetContents->palette();
33     pal.setBrush(QPalette::Background,
34                  QBrush(px));
35     pal.setBrush(QPalette::Base,
36                  QBrush(px));
37     scrollAreaWidgetContents->setPalette(pal);
38
39     m_pixelWidget = new PixelWidget(scrollAreaWidgetContents);
40     verticalLayout_2->addWidget(m_pixelWidget);
41
42     rectLabel->hide();
43     pixelLabel->hide();
44
45     connect(m_pixelWidget, SIGNAL(zoomChanged(int)),
46             zoomSpinBox, SLOT(setValue(int)));
47     connect(zoomSpinBox, SIGNAL(valueChanged(int)),
48             m_pixelWidget, SLOT(setZoom(int)));
49     connect(m_pixelWidget, SIGNAL(mousePosition(int, int)),
50             this, SLOT(showPixel(int, int)));
51     connect(m_pixelWidget, SIGNAL(gridGeometry(const QRect &)),
52             this, SLOT(showGrid(const QRect &)));
53 }
54
55 void ImageViewer::setImage(const QImage &image)
56 {
57     m_image = image;
58     m_temp = m_image;
59     m_pixelWidget->setSurface(m_image);
60     updateGeometry();
61 }
62
63 static inline int clamp(int x)
64 {
65     if (x <= 0) {
66         return 0;
67     }
68     if (x > 255) {
69         return 255;
70     }
71     return x;
72 }
73
74 void ImageViewer::slotUpdate()
75 {
76     m_temp = m_image.mirrored(false, flipCheckBox->isChecked());
77
78     double lowerValue = lowerSpinBox->value();
79     double upperValue = upperSpinBox->value();
80
81     bool opaque = opaqueCheckBox->isChecked();
82     bool alpha  = alphaCheckBox->isChecked();
83
84     if (lowerValue != 0.0 || upperValue != 1.0 || opaque || alpha) {
85         /*
86          * Rescale the image.
87          *
88          * XXX: This would be much more useful if done with the full precision
89          * of the original image
90          */
91
92         int offset = - lowerValue * 255;
93         int scale = 256 / (upperValue - lowerValue);
94
95         m_temp = m_temp.convertToFormat(QImage::Format_ARGB32);
96
97         if (0) {
98             qDebug()
99                 << "offset = " << offset << "\n"
100                 << "scale = " << scale << "\n";
101         }
102
103         int width = m_temp.width();
104         int height = m_temp.height();
105
106         int aMask = opaque ? 0xff : 0;
107
108         for (int y = 0; y < height; ++y) {
109             QRgb *scanline = (QRgb *)m_temp.scanLine(y);
110             for (int x = 0; x < width; ++x) {
111                 QRgb pixel = scanline[x];
112                 int r = qRed(pixel);
113                 int g = qGreen(pixel);
114                 int b = qBlue(pixel);
115                 int a = qAlpha(pixel);
116                 if (alpha) {
117                     a = clamp(((a + offset) * scale) >> 8);
118                     scanline[x] = qRgba(a, a, a, 0xff);
119                 } else {
120                     r = clamp(((r + offset) * scale) >> 8);
121                     g = clamp(((g + offset) * scale) >> 8);
122                     b = clamp(((b + offset) * scale) >> 8);
123                     a |= aMask;
124                     scanline[x] = qRgba(r, g, b, a);
125                 }
126             }
127         }
128     }
129
130     m_pixelWidget->setSurface(m_temp);
131
132     updateGeometry();
133 }
134
135 QSize ImageViewer::sizeHint() const
136 {
137     QSize size;
138
139     int vScrollWidth = scrollArea->verticalScrollBar() ?
140                 scrollArea->verticalScrollBar()->width() : 0;
141     int hScrollHeight = scrollArea->horizontalScrollBar() ?
142                 scrollArea->horizontalScrollBar()->height() : 0;
143     QSize optimalWindowSize(m_image.width() + vScrollWidth,
144                             m_image.height() + hScrollHeight);
145
146     QRect screenRect = QApplication::desktop()->availableGeometry();
147     const float maxPercentOfDesktopSpace = 0.8f;
148     QSize maxAvailableSize(maxPercentOfDesktopSpace * screenRect.width(),
149                            maxPercentOfDesktopSpace * screenRect.height());
150
151     return QSize(qMin(optimalWindowSize.width(), maxAvailableSize.width()),
152                  qMin(optimalWindowSize.height(), maxAvailableSize.height()));
153 }
154
155 void ImageViewer::resizeEvent(QResizeEvent *e)
156 {
157     QWidget::resizeEvent(e);
158 }
159
160 void ImageViewer::showPixel(int x, int y)
161 {
162     xSpinBox->setValue(x);
163     ySpinBox->setValue(y);
164     QColor clr = m_pixelWidget->colorAtCurrentPosition();
165     pixelLabel->setText(tr("RGBA: (%1, %2, %3, %4)")
166                         .arg(clr.red())
167                         .arg(clr.green())
168                         .arg(clr.blue())
169                         .arg(clr.alpha()));
170     pixelLabel->show();
171 }
172
173 void ImageViewer::showGrid(const QRect &rect)
174 {
175     if (rect.isEmpty()) {
176         rectLabel->hide();
177         return;
178     }
179     rectLabel->setText(tr("Grid: [%1, %2, %3, %4]")
180                        .arg(rect.x())
181                        .arg(rect.y())
182                        .arg(rect.width())
183                        .arg(rect.height()));
184     rectLabel->show();
185 }
186
187 #include "imageviewer.moc"