diff options
Diffstat (limited to 'kernel/kls_openexr')
-rw-r--r-- | kernel/kls_openexr/Makefile.am | 11 | ||||
-rw-r--r-- | kernel/kls_openexr/fmt_codec_openexr.cpp | 303 | ||||
-rw-r--r-- | kernel/kls_openexr/fmt_codec_openexr_defs.h | 27 |
3 files changed, 341 insertions, 0 deletions
diff --git a/kernel/kls_openexr/Makefile.am b/kernel/kls_openexr/Makefile.am new file mode 100644 index 0000000..debce0e --- /dev/null +++ b/kernel/kls_openexr/Makefile.am @@ -0,0 +1,11 @@ +CXXFLAGS = @CXXFLAGS@ -fexceptions + +INCLUDES = -I../include @SQ_EXR_CFLAGS@ + +pkglib_LTLIBRARIES = libkls_openexr.la + +libkls_openexr_la_SOURCES = fmt_codec_openexr.cpp fmt_codec_openexr_defs.h + +libkls_openexr_la_LDFLAGS = ${SQ_RELEASE} + +libkls_openexr_la_LIBADD = @SQ_EXR_LDFLAGS@ ${SQ_LOCAL_RPATH}
\ No newline at end of file diff --git a/kernel/kls_openexr/fmt_codec_openexr.cpp b/kernel/kls_openexr/fmt_codec_openexr.cpp new file mode 100644 index 0000000..58a9586 --- /dev/null +++ b/kernel/kls_openexr/fmt_codec_openexr.cpp @@ -0,0 +1,303 @@ +/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net) + + Copyright (c) 2005 Dmitry Baryshev <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later + version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <iostream> +#include <exception> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "ksquirrel-libs/fmt_types.h" +#include "ksquirrel-libs/fileio.h" +#include "ksquirrel-libs/fmt_utils.h" + +#include <ImfStandardAttributes.h> +#include <ImathBox.h> +#include <ImfInputFile.h> +#include <ImfBoxAttribute.h> +#include <ImfChannelListAttribute.h> +#include <ImfCompressionAttribute.h> +#include <ImfFloatAttribute.h> +#include <ImfIntAttribute.h> +#include <ImfLineOrderAttribute.h> +#include <ImfStringAttribute.h> +#include <ImfVecAttribute.h> +#include <ImfConvert.h> + +#include "fmt_codec_openexr_defs.h" +#include "fmt_codec_openexr.h" + +#include "ksquirrel-libs/error.h" + +#include "../xpm/codec_openexr.xpm" + +RGBA RgbaToRGBA(struct Rgba); + +/* + * + * A high-dynamic-range image format from Industrial Light & Magic + * for use in digital visual effects production. + * + */ + +fmt_codec::fmt_codec() : fmt_codec_base() +{} + +fmt_codec::~fmt_codec() +{} + +void fmt_codec::options(codec_options *o) +{ + o->version = "0.2.1"; + o->name = "OpenEXR"; + o->filter = "*.exr "; + o->config = ""; + o->mime = ""; + o->mimetype = "image/x-exr"; + o->pixmap = codec_openexr; + o->readable = true; + o->canbemultiple = false; + o->writestatic = false; + o->writeanimated = false; + o->needtempfile = false; +} + +s32 fmt_codec::read_init(const std::string &fl) +{ + frs.open(fl.c_str(), ios::binary | ios::in); + + if(!frs.good()) + return SQE_R_NOFILE; + + frs.close(); + + currentImage = -1; + read_error = false; + + pixels = 0; + file = fl; + + finfo.animated = false; + + return SQE_OK; +} + +s32 fmt_codec::read_next() +{ + currentImage++; + + if(currentImage) + return SQE_NOTOK; + + fmt_image image; + + s32 width, height; + + RgbaInputFile *in = NULL; + + pixels = new Array2D<Rgba>; + + try + { + in = new RgbaInputFile(file.c_str()); + + Imath::Box2i dw = in->dataWindow(); + + width = dw.max.x - dw.min.x + 1; + height = dw.max.y - dw.min.y + 1; + + pixels->resizeErase(height, width); + + in->setFrameBuffer(&(*pixels)[0][0] - dw.min.x - dw.min.y * width, 1, width); + + in->readPixels(dw.min.y, dw.max.y); + } + catch(const exception &e) + { + cerr << e.what() << endl; + + delete in; + + return SQE_R_BADFILE; + } + + switch(in->compression()) + { + case Imf::NO_COMPRESSION: + image.compression = "-"; + break; + + case Imf::RLE_COMPRESSION: + image.compression = "RLE"; + break; + + case Imf::ZIPS_COMPRESSION: + image.compression = "ZIPS"; + break; + + case Imf::ZIP_COMPRESSION: + image.compression = "ZIP"; + break; + + case Imf::PIZ_COMPRESSION: + image.compression = "PIZ"; + break; + + case Imf::PXR24_COMPRESSION: + image.compression = "PXR24"; + break; + + case Imf::NUM_COMPRESSION_METHODS: + image.compression = "Different methods"; + break; + + default: + image.compression = "Unknown"; + } + + image.colorspace = "RGBA"; + image.bpp = 32; + image.w = width; + image.h = height; + + finfo.image.push_back(image); + + line = -1; + + delete in; + + return SQE_OK; +} + +s32 fmt_codec::read_next_pass() +{ + return SQE_OK; +} + +s32 fmt_codec::read_scanline(RGBA *scan) +{ + RGBA rgba; + fmt_image *im = image(currentImage); + fmt_utils::fillAlpha(scan, im->w); + + line++; + + for(s32 x = 0; x < im->w; x++) + { + rgba = RgbaToRGBA((*pixels)[line][x]); + memcpy(scan+x, &rgba, sizeof(RGBA)); + } + + return SQE_OK; +} + +void fmt_codec::read_close() +{ + finfo.meta.clear(); + finfo.image.clear(); + + delete pixels; + pixels = 0; +} + +/* + * This function is taken from exr plugin for KImageIO, kdelibs-3.4.0: + * + * KImageIO Routines to read (and perhaps in the future, write) images + * in the high dynamic range EXR format. + * Copyright (c) 2003, Brad Hards <[email protected]> + * + * This library is distributed under the conditions of the GNU LGPL. + * + * $Id: exr.cpp,v 1.4 2004/11/22 03:48:27 mueller Exp $ + */ + +/* + * utility function + * + * this does a conversion from the ILM Half (equal to Nvidia Half) + * format into the normal 32 bit pixel format. Process is from the + * ILM code. + * + */ + +RGBA RgbaToRGBA(struct Rgba imagePixel) +{ + float r,g,b,a; + + // 1) Compensate for fogging by subtracting defog + // from the raw pixel values. + // Response: We work with defog of 0.0, so this is a no-op + + // 2) Multiply the defogged pixel values by + // 2^(exposure + 2.47393). + // Response: We work with exposure of 0.0. + // (2^2.47393) is 5.55555 + r = imagePixel.r * 5.55555; + g = imagePixel.g * 5.55555; + b = imagePixel.b * 5.55555; + a = imagePixel.a * 5.55555; + + // 3) Values, which are now 1.0, are called "middle gray". + // If defog and exposure are both set to 0.0, then + // middle gray corresponds to a raw pixel value of 0.18. + // In step 6, middle gray values will be mapped to an + // intensity 3.5 f-stops below the display's maximum + // intensity. + // Response: no apparent content. + + // 4) Apply a knee function. The knee function has two + // parameters, kneeLow and kneeHigh. Pixel values + // below 2^kneeLow are not changed by the knee + // function. Pixel values above kneeLow are lowered + // according to a logarithmic curve, such that the + // value 2^kneeHigh is mapped to 2^3.5 (in step 6, + // this value will be mapped to the the display's + // maximum intensity). + // Response: kneeLow = 0.0 (2^0.0 => 1); kneeHigh = 5.0 (2^5 =>32) + if (r > 1.0) + r = 1.0 + Imath::Math<float>::log ((r-1.0) * 0.184874 + 1) / 0.184874; + if (g > 1.0) + g = 1.0 + Imath::Math<float>::log ((g-1.0) * 0.184874 + 1) / 0.184874; + if (b > 1.0) + b = 1.0 + Imath::Math<float>::log ((b-1.0) * 0.184874 + 1) / 0.184874; + if (a > 1.0) + a = 1.0 + Imath::Math<float>::log ((a-1.0) * 0.184874 + 1) / 0.184874; +// +// 5) Gamma-correct the pixel values, assuming that the +// screen's gamma is 0.4545 (or 1/2.2). + r = Imath::Math<float>::pow (r, 0.4545); + g = Imath::Math<float>::pow (g, 0.4545); + b = Imath::Math<float>::pow (b, 0.4545); + a = Imath::Math<float>::pow (a, 0.4545); + +// 6) Scale the values such that pixels middle gray +// pixels are mapped to 84.66 (or 3.5 f-stops below +// the display's maximum intensity). +// +// 7) Clamp the values to [0, 255]. + return RGBA( s8 (Imath::clamp ( r * 84.66f, 0.f, 255.f ) ), + s8 (Imath::clamp ( g * 84.66f, 0.f, 255.f ) ), + s8 (Imath::clamp ( b * 84.66f, 0.f, 255.f ) ), + s8 (Imath::clamp ( a * 84.66f, 0.f, 255.f ) ) ); +} + +#include "fmt_codec_cd_func.h" diff --git a/kernel/kls_openexr/fmt_codec_openexr_defs.h b/kernel/kls_openexr/fmt_codec_openexr_defs.h new file mode 100644 index 0000000..7b52b11 --- /dev/null +++ b/kernel/kls_openexr/fmt_codec_openexr_defs.h @@ -0,0 +1,27 @@ +/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net) + + Copyright (c) 2005 Dmitry Baryshev <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later + version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSQUIRREL_CODEC_DEFS_openexr +#define KSQUIRREL_CODEC_DEFS_openexr + +// define constants here + +#endif |