15 #include <ImfRgbaFile.h>
16 #include <ImfStandardAttributes.h>
18 #include <ImfInputFile.h>
19 #include <ImfBoxAttribute.h>
20 #include <ImfChannelListAttribute.h>
21 #include <ImfCompressionAttribute.h>
22 #include <ImfFloatAttribute.h>
23 #include <ImfIntAttribute.h>
24 #include <ImfLineOrderAttribute.h>
25 #include <ImfStringAttribute.h>
26 #include <ImfVecAttribute.h>
28 #include <ImfConvert.h>
29 #include <ImfVersion.h>
30 #include <IexThrowErrnoExc.h>
38 #include <QDataStream>
39 #include <QImageIOPlugin>
41 class K_IStream:
public Imf::IStream
44 K_IStream( QIODevice *dev,
const QByteArray& fileName ):
45 IStream( fileName.data() ), m_dev ( dev )
48 virtual bool read(
char c[],
int n );
49 virtual Imf::Int64 tellg( );
50 virtual void seekg( Imf::Int64 pos );
51 virtual void clear( );
57 bool K_IStream::read(
char c[],
int n )
59 qint64 result = m_dev->read( c, n );
62 }
else if ( result == 0 ) {
63 throw Iex::InputExc(
"Unexpected end of file" );
65 Iex::throwErrnoExc(
"Error in read", result );
69 Imf::Int64 K_IStream::tellg( )
74 void K_IStream::seekg( Imf::Int64 pos )
79 void K_IStream::clear( )
100 r = imagePixel.r * 5.55555;
101 g = imagePixel.g * 5.55555;
102 b = imagePixel.b * 5.55555;
103 a = imagePixel.a * 5.55555;
123 r = 1.0 + Imath::Math<float>::log ((r-1.0) * 0.184874 + 1) / 0.184874;
125 g = 1.0 + Imath::Math<float>::log ((g-1.0) * 0.184874 + 1) / 0.184874;
127 b = 1.0 + Imath::Math<float>::log ((b-1.0) * 0.184874 + 1) / 0.184874;
129 a = 1.0 + Imath::Math<float>::log ((a-1.0) * 0.184874 + 1) / 0.184874;
133 r = Imath::Math<float>::pow (r, 0.4545);
134 g = Imath::Math<float>::pow (g, 0.4545);
135 b = Imath::Math<float>::pow (b, 0.4545);
136 a = Imath::Math<float>::pow (a, 0.4545);
143 return qRgba( (
unsigned char) (Imath::clamp ( r * 84.66f, 0.f, 255.f ) ),
144 (
unsigned char) (Imath::clamp ( g * 84.66f, 0.f, 255.f ) ),
145 (
unsigned char) (Imath::clamp ( b * 84.66f, 0.f, 255.f ) ),
146 (
unsigned char) (Imath::clamp ( a * 84.66f, 0.f, 255.f ) ) );
165 return QByteArray(
"exr");
174 K_IStream istr( device(), QByteArray() );
175 Imf::RgbaInputFile file( istr );
176 Imath::Box2i dw = file.dataWindow();
178 width = dw.max.x - dw.min.x + 1;
179 height = dw.max.y - dw.min.y + 1;
181 Imf::Array2D<Imf::Rgba> pixels;
182 pixels.resizeErase (height, width);
184 file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
185 file.readPixels (dw.min.y, dw.max.y);
187 QImage image(width, height, QImage::Format_RGB32);
192 for (
int y=0; y < height; y++ ) {
193 for (
int x=0; x < width; x++ ) {
195 image.setPixel( x, y,
RgbaToQrgba( pixels[y][x] ) );
203 catch (
const std::exception &exc)
205 kDebug() << exc.what();
222 qWarning(
"EXRHandler::canRead() called with no device");
226 const QByteArray head = device->peek(4);
228 return Imf::isImfMagic( head.data() );
234 QStringList EXRPlugin::keys()
const
236 return QStringList() <<
"exr" <<
"EXR";
240 QImageIOPlugin::Capabilities EXRPlugin::capabilities(QIODevice *device,
const QByteArray &format)
const
242 if ( format ==
"exr" || format ==
"EXR" )
243 return Capabilities(CanRead);
244 if ( !format.isEmpty() )
246 if ( !device->isOpen() )
255 QImageIOHandler *EXRPlugin::create(QIODevice *device,
const QByteArray &format)
const
258 handler->setDevice(device);
259 handler->setFormat(format);
263 Q_EXPORT_STATIC_PLUGIN( EXRPlugin )
264 Q_EXPORT_PLUGIN2( exr, EXRPlugin )
QRgb RgbaToQrgba(struct Imf::Rgba imagePixel)
bool read(QImage *outImage)
Read contents from the file / stream into an image.
QImageIO Routines to read (and perhaps in the future, write) images in the high definition EXR format...
bool write(const QImage &image)
Write the contents of an image into the file / stream.
bool canRead() const
Test if the file / stream can potentially read more data.
QRgb qRgba(const QRgb &rgb, int a)
Change a QRgb value's alpha only.
QByteArray name() const
The name of this plugin.