Changeset View
Changeset View
Standalone View
Standalone View
src/imageformats/hdr.cpp
Context not available. | |||||
15 | 15 | | |||
---|---|---|---|---|---|
16 | #include <QDebug> | 16 | #include <QDebug> | ||
17 | 17 | | |||
18 | typedef Q_UINT8 uchar; | 18 | typedef unsigned char uchar; | ||
19 | 19 | | |||
20 | namespace // Private. | 20 | namespace // Private. | ||
21 | { | 21 | { | ||
Context not available. | |||||
93 | uchar val, code; | 93 | uchar val, code; | ||
94 | 94 | | |||
95 | // Create dst image. | 95 | // Create dst image. | ||
96 | if (!img.create(width, height, 32)) { | 96 | img = QImage(width, height, QImage::Format_RGB32); | ||
97 | if (img.isNull()) { | ||||
97 | return false; | 98 | return false; | ||
98 | } | 99 | } | ||
99 | 100 | | |||
100 | QMemArray<uchar> image(width * 4); | 101 | QByteArray lineArray; | ||
102 | lineArray.resize(4 * width); | ||||
103 | uchar *image = (uchar *) lineArray.data(); | ||||
101 | 104 | | |||
102 | for (int cline = 0; cline < height; cline++) { | 105 | for (int cline = 0; cline < height; cline++) { | ||
103 | QRgb *scanline = (QRgb *) img.scanLine(cline); | 106 | QRgb *scanline = (QRgb *) img.scanLine(cline); | ||
104 | 107 | | |||
105 | // determine scanline type | 108 | // determine scanline type | ||
106 | if ((width < MINELEN) || (MAXELEN < width)) { | 109 | if ((width < MINELEN) || (MAXELEN < width)) { | ||
107 | Read_Old_Line(image.data(), width, s); | 110 | Read_Old_Line(image, width, s); | ||
108 | RGBE_To_QRgbLine(image.data(), scanline, width); | 111 | RGBE_To_QRgbLine(image, scanline, width); | ||
109 | continue; | 112 | continue; | ||
110 | } | 113 | } | ||
111 | 114 | | |||
Context not available. | |||||
116 | } | 119 | } | ||
117 | 120 | | |||
118 | if (val != 2) { | 121 | if (val != 2) { | ||
119 | s.device()->at(s.device()->at() - 1); | 122 | s.device()->ungetChar(val); | ||
120 | Read_Old_Line(image.data(), width, s); | 123 | Read_Old_Line(image, width, s); | ||
121 | RGBE_To_QRgbLine(image.data(), scanline, width); | 124 | RGBE_To_QRgbLine(image, scanline, width); | ||
122 | continue; | 125 | continue; | ||
123 | } | 126 | } | ||
124 | 127 | | |||
Context not available. | |||||
132 | 135 | | |||
133 | if ((image[1] != 2) || (image[2] & 128)) { | 136 | if ((image[1] != 2) || (image[2] & 128)) { | ||
134 | image[0] = 2; | 137 | image[0] = 2; | ||
135 | Read_Old_Line(image.data() + 4, width - 1, s); | 138 | Read_Old_Line(image + 4, width - 1, s); | ||
136 | RGBE_To_QRgbLine(image.data(), scanline, width); | 139 | RGBE_To_QRgbLine(image, scanline, width); | ||
137 | continue; | 140 | continue; | ||
138 | } | 141 | } | ||
139 | 142 | | |||
Context not available. | |||||
168 | } | 171 | } | ||
169 | } | 172 | } | ||
170 | 173 | | |||
171 | RGBE_To_QRgbLine(image.data(), scanline, width); | 174 | RGBE_To_QRgbLine(image, scanline, width); | ||
172 | } | 175 | } | ||
173 | 176 | | |||
174 | return true; | 177 | return true; | ||
Context not available. | |||||
176 | 179 | | |||
177 | } // namespace | 180 | } // namespace | ||
178 | 181 | | |||
179 | Q_DECL_EXPORT void kimgio_hdr_read(QImageIO *io) | 182 | bool HDRHandler::read(QImage *outImage) | ||
180 | { | 183 | { | ||
181 | int len; | 184 | int len; | ||
182 | char line[MAXLINE]; | 185 | char line[MAXLINE]; | ||
Context not available. | |||||
185 | 188 | | |||
186 | // Parse header | 189 | // Parse header | ||
187 | do { | 190 | do { | ||
188 | len = io->ioDevice()->readLine(line, MAXLINE); | 191 | len = device()->readLine(line, MAXLINE); | ||
189 | 192 | | |||
190 | /*if (strcmp(line, "#?RADIANCE\n") == 0 || strcmp(line, "#?RGBE\n") == 0) | 193 | /*if (strcmp(line, "#?RADIANCE\n") == 0 || strcmp(line, "#?RGBE\n") == 0) | ||
191 | { | 194 | { | ||
Context not available. | |||||
199 | 202 | | |||
200 | if (/*!validHeader ||*/ !validFormat) { | 203 | if (/*!validHeader ||*/ !validFormat) { | ||
201 | // qDebug() << "Unknown HDR format."; | 204 | // qDebug() << "Unknown HDR format."; | ||
202 | io->setImage(0); | 205 | return false; | ||
203 | io->setStatus(-1); | | |||
204 | return; | | |||
205 | } | 206 | } | ||
206 | 207 | | |||
207 | io->ioDevice()->readLine(line, MAXLINE); | 208 | device()->readLine(line, MAXLINE); | ||
208 | 209 | | |||
209 | char s1[3], s2[3]; | 210 | char s1[3], s2[3]; | ||
210 | int width, height; | 211 | int width, height; | ||
Context not available. | |||||
212 | //if( sscanf(line, "-Y %d +X %d", &height, &width) < 2 ) | 213 | //if( sscanf(line, "-Y %d +X %d", &height, &width) < 2 ) | ||
213 | { | 214 | { | ||
214 | // qDebug() << "Invalid HDR file."; | 215 | // qDebug() << "Invalid HDR file."; | ||
215 | io->setImage(0); | 216 | return false; | ||
216 | io->setStatus(-1); | | |||
217 | return; | | |||
218 | } | 217 | } | ||
219 | 218 | | |||
220 | QDataStream s(io->ioDevice()); | 219 | QDataStream s(device()); | ||
221 | 220 | | |||
222 | QImage img; | 221 | QImage img; | ||
223 | if (!LoadHDR(s, width, height, img)) { | 222 | if (!LoadHDR(s, width, height, img)) { | ||
224 | // qDebug() << "Error loading HDR file."; | 223 | // qDebug() << "Error loading HDR file."; | ||
225 | io->setImage(0); | 224 | return false; | ||
226 | io->setStatus(-1); | 225 | } | ||
227 | return; | 226 | | ||
227 | *outImage = img; | ||||
228 | return true; | ||||
229 | } | ||||
230 | | ||||
231 | HDRHandler::HDRHandler() | ||||
232 | { | ||||
233 | } | ||||
234 | | ||||
235 | bool HDRHandler::canRead() const | ||||
236 | { | ||||
237 | if (canRead(device())) { | ||||
238 | setFormat("hdr"); | ||||
239 | return true; | ||||
240 | } | ||||
241 | return false; | ||||
242 | } | ||||
243 | | ||||
244 | bool HDRHandler::canRead(QIODevice *device) | ||||
245 | { | ||||
246 | if (!device) { | ||||
247 | qWarning("HDRHandler::canRead() called with no device"); | ||||
248 | return false; | ||||
228 | } | 249 | } | ||
229 | 250 | | |||
230 | io->setImage(img); | 251 | return device->peek(11) == "#?RADIANCE\n" || device->peek(7) == "#?RGBE\n"; | ||
231 | io->setStatus(0); | | |||
232 | } | 252 | } | ||
233 | 253 | | |||
234 | Q_DECL_EXPORT void kimgio_hdr_write(QImageIO *) | 254 | QImageIOPlugin::Capabilities HDRPlugin::capabilities(QIODevice *device, const QByteArray &format) const | ||
235 | { | 255 | { | ||
236 | // intentionally not implemented (since writing low dynamic range data to a HDR file is nonsense.) | 256 | if (format == "hdr") { | ||
257 | return Capabilities(CanRead); | ||||
258 | } | ||||
259 | if (!format.isEmpty()) { | ||||
260 | return {}; | ||||
261 | } | ||||
262 | if (!device->isOpen()) { | ||||
263 | return {}; | ||||
264 | } | ||||
265 | | ||||
266 | Capabilities cap; | ||||
267 | if (device->isReadable() && HDRHandler::canRead(device)) { | ||||
268 | cap |= CanRead; | ||||
269 | } | ||||
270 | return cap; | ||||
237 | } | 271 | } | ||
238 | 272 | | |||
273 | QImageIOHandler *HDRPlugin::create(QIODevice *device, const QByteArray &format) const | ||||
274 | { | ||||
275 | QImageIOHandler *handler = new HDRHandler; | ||||
276 | handler->setDevice(device); | ||||
277 | handler->setFormat(format); | ||||
278 | return handler; | ||||
279 | } | ||||
Context not available. |