--- /dev/null
+/* This source file must have a .cpp extension so that all C++ compilers
+ recognize the extension without flags. Borland does not know .cxx for
+ example. */
+#ifndef __cplusplus
+# error "A C compiler has been selected for C++."
+#endif
+
+/* Version number components: V=Version, R=Revision, P=Patch
+ Version date components: YYYY=Year, MM=Month, DD=Day */
+
+#if defined(__COMO__)
+# define COMPILER_ID "Comeau"
+ /* __COMO_VERSION__ = VRR */
+# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
+# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
+
+#elif defined(__INTEL_COMPILER) || defined(__ICC)
+# define COMPILER_ID "Intel"
+ /* __INTEL_COMPILER = VRP */
+# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
+# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
+# if defined(__INTEL_COMPILER_BUILD_DATE)
+ /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
+# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
+# endif
+
+#elif defined(__PATHCC__)
+# define COMPILER_ID "PathScale"
+# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
+# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
+# if defined(__PATHCC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
+# endif
+
+#elif defined(__clang__)
+# define COMPILER_ID "Clang"
+# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
+# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
+# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
+
+#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
+# define COMPILER_ID "Embarcadero"
+# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
+# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
+# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF)
+
+#elif defined(__BORLANDC__)
+# define COMPILER_ID "Borland"
+ /* __BORLANDC__ = 0xVRR */
+# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
+# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
+
+#elif defined(__WATCOMC__)
+# define COMPILER_ID "Watcom"
+ /* __WATCOMC__ = VVRR */
+# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
+# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100)
+
+#elif defined(__SUNPRO_CC)
+# define COMPILER_ID "SunPro"
+# if __SUNPRO_CC >= 0x5100
+ /* __SUNPRO_CC = 0xVRRP */
+# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
+# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
+# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
+# else
+ /* __SUNPRO_CC = 0xVRP */
+# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
+# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
+# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
+# endif
+
+#elif defined(__HP_aCC)
+# define COMPILER_ID "HP"
+ /* __HP_aCC = VVRRPP */
+# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
+# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
+# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
+
+#elif defined(__DECCXX)
+# define COMPILER_ID "Compaq"
+ /* __DECCXX_VER = VVRRTPPPP */
+# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
+# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
+# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
+
+#elif defined(__IBMCPP__)
+# if defined(__COMPILER_VER__)
+# define COMPILER_ID "zOS"
+# else
+# if __IBMCPP__ >= 800
+# define COMPILER_ID "XL"
+# else
+# define COMPILER_ID "VisualAge"
+# endif
+ /* __IBMCPP__ = VRP */
+# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
+# endif
+
+#elif defined(__PGI)
+# define COMPILER_ID "PGI"
+# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
+# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
+# endif
+
+#elif defined(_CRAYC)
+# define COMPILER_ID "Cray"
+# define COMPILER_VERSION_MAJOR DEC(_RELEASE)
+# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
+
+#elif defined(__TI_COMPILER_VERSION__)
+# define COMPILER_ID "TI"
+ /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
+# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
+# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
+# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
+
+#elif defined(__SCO_VERSION__)
+# define COMPILER_ID "SCO"
+
+#elif defined(__GNUC__)
+# define COMPILER_ID "GNU"
+# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
+# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+# endif
+
+#elif defined(_MSC_VER)
+# define COMPILER_ID "MSVC"
+ /* _MSC_VER = VVRR */
+# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
+# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
+# if defined(_MSC_FULL_VER)
+# if _MSC_VER >= 1400
+ /* _MSC_FULL_VER = VVRRPPPPP */
+# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
+# else
+ /* _MSC_FULL_VER = VVRRPPPP */
+# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
+# endif
+# endif
+# if defined(_MSC_BUILD)
+# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
+# endif
+
+/* Analog VisualDSP++ >= 4.5.6 */
+#elif defined(__VISUALDSPVERSION__)
+# define COMPILER_ID "ADSP"
+ /* __VISUALDSPVERSION__ = 0xVVRRPP00 */
+# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
+# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
+# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
+
+/* Analog VisualDSP++ < 4.5.6 */
+#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
+# define COMPILER_ID "ADSP"
+
+#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
+# define COMPILER_ID "MIPSpro"
+# if defined(_SGI_COMPILER_VERSION)
+ /* _SGI_COMPILER_VERSION = VRP */
+# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100)
+# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10)
+# else
+ /* _COMPILER_VERSION = VRP */
+# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100)
+# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10)
+# endif
+
+/* This compiler is either not known or is too old to define an
+ identification macro. Try to identify the platform and guess that
+ it is the native compiler. */
+#elif defined(__sgi)
+# define COMPILER_ID "MIPSpro"
+
+#elif defined(__hpux) || defined(__hpua)
+# define COMPILER_ID "HP"
+
+#else /* unknown compiler */
+# define COMPILER_ID ""
+
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+
+/* Identify known platforms by name. */
+#if defined(__linux) || defined(__linux__) || defined(linux)
+# define PLATFORM_ID "Linux"
+
+#elif defined(__CYGWIN__)
+# define PLATFORM_ID "Cygwin"
+
+#elif defined(__MINGW32__)
+# define PLATFORM_ID "MinGW"
+
+#elif defined(__APPLE__)
+# define PLATFORM_ID "Darwin"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define PLATFORM_ID "Windows"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+# define PLATFORM_ID "FreeBSD"
+
+#elif defined(__NetBSD__) || defined(__NetBSD)
+# define PLATFORM_ID "NetBSD"
+
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+# define PLATFORM_ID "OpenBSD"
+
+#elif defined(__sun) || defined(sun)
+# define PLATFORM_ID "SunOS"
+
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+# define PLATFORM_ID "AIX"
+
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+# define PLATFORM_ID "IRIX"
+
+#elif defined(__hpux) || defined(__hpux__)
+# define PLATFORM_ID "HP-UX"
+
+#elif defined(__HAIKU__)
+# define PLATFORM_ID "Haiku"
+
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+# define PLATFORM_ID "BeOS"
+
+#elif defined(__QNX__) || defined(__QNXNTO__)
+# define PLATFORM_ID "QNX"
+
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+# define PLATFORM_ID "Tru64"
+
+#elif defined(__riscos) || defined(__riscos__)
+# define PLATFORM_ID "RISCos"
+
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+# define PLATFORM_ID "SINIX"
+
+#elif defined(__UNIX_SV__)
+# define PLATFORM_ID "UNIX_SV"
+
+#elif defined(__bsdos__)
+# define PLATFORM_ID "BSDOS"
+
+#elif defined(_MPRAS) || defined(MPRAS)
+# define PLATFORM_ID "MP-RAS"
+
+#elif defined(__osf) || defined(__osf__)
+# define PLATFORM_ID "OSF1"
+
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+# define PLATFORM_ID "SCO_SV"
+
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+# define PLATFORM_ID "ULTRIX"
+
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+# define PLATFORM_ID "Xenix"
+
+#else /* unknown platform */
+# define PLATFORM_ID ""
+
+#endif
+
+/* For windows compilers MSVC and Intel we can determine
+ the architecture of the compiler being used. This is because
+ the compilers do not have flags that can change the architecture,
+ but rather depend on which compiler is being used
+*/
+#if defined(_WIN32) && defined(_MSC_VER)
+# if defined(_M_IA64)
+# define ARCHITECTURE_ID "IA64"
+
+# elif defined(_M_X64) || defined(_M_AMD64)
+# define ARCHITECTURE_ID "x64"
+
+# elif defined(_M_IX86)
+# define ARCHITECTURE_ID "X86"
+
+# elif defined(_M_ARM)
+# define ARCHITECTURE_ID "ARM"
+
+# elif defined(_M_MIPS)
+# define ARCHITECTURE_ID "MIPS"
+
+# elif defined(_M_SH)
+# define ARCHITECTURE_ID "SHx"
+
+# else /* unknown architecture */
+# define ARCHITECTURE_ID ""
+# endif
+
+#else
+# define ARCHITECTURE_ID ""
+#endif
+
+/* Convert integer to decimal digit literals. */
+#define DEC(n) \
+ ('0' + (((n) / 10000000)%10)), \
+ ('0' + (((n) / 1000000)%10)), \
+ ('0' + (((n) / 100000)%10)), \
+ ('0' + (((n) / 10000)%10)), \
+ ('0' + (((n) / 1000)%10)), \
+ ('0' + (((n) / 100)%10)), \
+ ('0' + (((n) / 10)%10)), \
+ ('0' + ((n) % 10))
+
+/* Convert integer to hex digit literals. */
+#define HEX(n) \
+ ('0' + ((n)>>28 & 0xF)), \
+ ('0' + ((n)>>24 & 0xF)), \
+ ('0' + ((n)>>20 & 0xF)), \
+ ('0' + ((n)>>16 & 0xF)), \
+ ('0' + ((n)>>12 & 0xF)), \
+ ('0' + ((n)>>8 & 0xF)), \
+ ('0' + ((n)>>4 & 0xF)), \
+ ('0' + ((n) & 0xF))
+
+/* Construct a string literal encoding the version number components. */
+#ifdef COMPILER_VERSION_MAJOR
+char const info_version[] = {
+ 'I', 'N', 'F', 'O', ':',
+ 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
+ COMPILER_VERSION_MAJOR,
+# ifdef COMPILER_VERSION_MINOR
+ '.', COMPILER_VERSION_MINOR,
+# ifdef COMPILER_VERSION_PATCH
+ '.', COMPILER_VERSION_PATCH,
+# ifdef COMPILER_VERSION_TWEAK
+ '.', COMPILER_VERSION_TWEAK,
+# endif
+# endif
+# endif
+ ']','\0'};
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
+char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
+
+
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+#ifdef COMPILER_VERSION_MAJOR
+ require += info_version[argc];
+#endif
+ (void)argv;
+ return require;
+}
file(GLOB grfmt_srcs src/grfmt*.cpp)
list(APPEND grfmt_hdrs src/bitstrm.hpp)
list(APPEND grfmt_srcs src/bitstrm.cpp)
+list(APPEND grfmt_hdrs src/rgbe.hpp)
+list(APPEND grfmt_srcs src/rgbe.cpp)
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "grfmt_hdr.hpp"
+#include "rgbe.hpp"
+
+namespace cv
+{
+HdrDecoder::HdrDecoder()
+{
+ m_signature = "#?RGBE";
+ m_signature_alt = "#?RADIANCE";
+ file = NULL;
+ m_type = CV_32FC3;
+}
+
+HdrDecoder::~HdrDecoder()
+{
+}
+
+size_t HdrDecoder::signatureLength() const
+{
+ return m_signature.size() > m_signature_alt.size() ?
+ m_signature.size() : m_signature_alt.size();
+}
+
+bool HdrDecoder::readHeader()
+{
+ file = fopen(m_filename.c_str(), "rb");
+ if(!file) {
+ CV_Error(Error::StsError, "HDR decoder: can't open file");
+ }
+ RGBE_ReadHeader(file, &m_width, &m_height, NULL);
+ if(m_width <= 0 || m_height <= 0) {
+ CV_Error(Error::StsError, "HDR decoder: invalid image size");
+ }
+ return true;
+}
+
+bool HdrDecoder::readData(Mat& img)
+{
+ if(!file) {
+ readHeader();
+ }
+ if(img.cols != m_width || img.rows != m_height ||
+ img.type() != CV_32FC3) {
+ CV_Error(Error::StsError, "HDR decoder: bad mat");
+ }
+ RGBE_ReadPixels_RLE(file, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
+ fclose(file); file = NULL;
+ return true;
+}
+
+bool HdrDecoder::checkSignature( const String& signature ) const
+{
+ if(signature.size() >= (m_signature.size()) &&
+ !memcmp(signature.c_str(), m_signature.c_str(), m_signature.size()))
+ return true;
+ if(signature.size() >= (m_signature.size()) &&
+ !memcmp(signature.c_str(), m_signature_alt.c_str(), m_signature_alt.size()))
+ return true;
+ return false;
+}
+
+ImageDecoder HdrDecoder::newDecoder() const
+{
+ return new HdrDecoder;
+}
+
+HdrEncoder::HdrEncoder()
+{
+ m_description = "Radiance HDR (*.hdr;*.pic)";
+}
+
+HdrEncoder::~HdrEncoder()
+{
+}
+
+bool HdrEncoder::write( const Mat& img, const std::vector<int>& params )
+{
+ if(img.type() != CV_32FC3) {
+ CV_Error(Error::StsBadArg, "HDR encoder: need 32FC3 mat");
+ }
+ if(!(params.empty() || params[0] == HDR_NONE || params[0] == HDR_RLE)) {
+ CV_Error(Error::StsBadArg, "HDR encoder: wrong compression param");
+ }
+
+ FILE *fout = fopen(m_filename.c_str(), "wb");
+ if(!fout) {
+ CV_Error(Error::StsError, "HDR encoder: can't open file");
+ }
+
+ RGBE_WriteHeader(fout, img.cols, img.rows, NULL);
+ if(params.empty() || params[0] == HDR_RLE) {
+ RGBE_WritePixels_RLE(fout, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
+ } else {
+ RGBE_WritePixels(fout, const_cast<float*>(img.ptr<float>()), img.cols * img.rows);
+ }
+
+ fclose(fout);
+ return true;
+}
+
+ImageEncoder HdrEncoder::newEncoder() const
+{
+ return new HdrEncoder;
+}
+
+bool HdrEncoder::isFormatSupported( int depth ) const {
+ return depth == CV_32F;
+}
+
+}
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef _GRFMT_HDR_H_
+#define _GRFMT_HDR_H_
+
+#include "grfmt_base.hpp"
+
+namespace cv
+{
+
+enum HdrCompression
+{
+ HDR_NONE = 0,
+ HDR_RLE = 1
+};
+
+// Radiance rgbe (.hdr) reader
+class HdrDecoder : public BaseImageDecoder
+{
+public:
+ HdrDecoder();
+ ~HdrDecoder();
+ bool readHeader();
+ bool readData( Mat& img );
+ bool checkSignature( const String& signature ) const;
+ ImageDecoder newDecoder() const;
+ size_t signatureLength() const;
+protected:
+ String m_signature_alt;
+ FILE *file;
+};
+
+// ... writer
+class HdrEncoder : public BaseImageEncoder
+{
+public:
+ HdrEncoder();
+ ~HdrEncoder();
+ bool write( const Mat& img, const std::vector<int>& params );
+ ImageEncoder newEncoder() const;
+ bool isFormatSupported( int depth ) const;
+protected:
+
+};
+
+}
+
+#endif/*_GRFMT_HDR_H_*/
\ No newline at end of file
TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
}
+ m_hdr = false;
}
m_width = wdth;
m_height = hght;
+ if((bpp == 32 && ncn == 3) || photometric == PHOTOMETRIC_LOGLUV)
+ {
+ m_type = CV_32FC3;
+ m_hdr = true;
+ return true;
+ }
+ m_hdr = false;
+
if( bpp > 8 &&
((photometric != 2 && photometric != 1) ||
(ncn != 1 && ncn != 3 && ncn != 4)))
bool TiffDecoder::readData( Mat& img )
{
+ if(m_hdr && img.type() == CV_32FC3)
+ {
+ return readHdrData(img);
+ }
bool result = false;
bool color = img.channels() > 1;
uchar* data = img.data;
return result;
}
+bool TiffDecoder::readHdrData(Mat& img)
+{
+ int rows_per_strip = 0, photometric = 0;
+ if(!m_tif)
+ {
+ return false;
+ }
+ TIFF *tif = static_cast<TIFF*>(m_tif);
+ TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
+ TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
+ int size = 3 * m_width * m_height * sizeof (float);
+ int strip_size = 3 * m_width * rows_per_strip;
+ float *ptr = img.ptr<float>();
+ for (size_t i = 0; i < TIFFNumberOfStrips(tif); i++, ptr += strip_size)
+ {
+ TIFFReadEncodedStrip(tif, i, ptr, size);
+ size -= strip_size * sizeof(float);
+ }
+ close();
+ ptr = img.ptr<float>();
+ for(size_t i = 0; i < img.total(); i++, ptr += 3)
+ {
+ if(photometric == PHOTOMETRIC_LOGLUV)
+ {
+ float r = 3.240479f * ptr[0] + -1.537150f * ptr[1] + -0.498535f * ptr[2];
+ float g = -0.969256f * ptr[0] + 1.875991f * ptr[1] + 0.041556f * ptr[2];
+ float b = 0.055648f * ptr[0] + -0.204043f * ptr[1] + 1.057311f * ptr[2];
+ ptr[0] = b; ptr[1] = g; ptr[2] = r;
+ }
+ else
+ {
+ float tmp = ptr[0];
+ ptr[0] = ptr[2];
+ ptr[2] = tmp;
+ }
+ }
+ return true;
+}
+
#endif
//////////////////////////////////////////////////////////////////////////////////////////
bool TiffEncoder::isFormatSupported( int depth ) const
{
- return depth == CV_8U || depth == CV_16U;
+#ifdef HAVE_TIFF
+ return depth == CV_8U || depth == CV_16U || depth == CV_32F;
+#else
+ return depth == CV_8U || depth == CV_16U;
+#endif
}
void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
return true;
}
+bool TiffEncoder::writeHdr(const Mat& img)
+{
+ float *ptr = const_cast<float*>(img.ptr<float>());
+ for(size_t i = 0; i < img.total(); i++, ptr += 3)
+ {
+ float x = 0.412453f * ptr[2] + 0.357580f * ptr[1] + 0.180423f * ptr[0];
+ float y = 0.212671f * ptr[2] + 0.715160f * ptr[1] + 0.072169f * ptr[0];
+ float z = 0.019334f * ptr[2] + 0.119193f * ptr[1] + 0.950227f * ptr[0];
+ ptr[0] = x; ptr[1] = y; ptr[2] = z;
+ }
+ TIFF* tif = TIFFOpen(m_filename.c_str(), "w");
+ if (!tif)
+ {
+ return false;
+ }
+ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.cols);
+ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.rows);
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_SGILOG);
+ TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_LOGLUV);
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+ int strip_size = 3 * img.cols;
+ ptr = const_cast<float*>(img.ptr<float>());
+ for (int i = 0; i < img.rows; i++, ptr += strip_size)
+ {
+ TIFFWriteEncodedStrip(tif, i, ptr, strip_size * sizeof(float));
+ }
+ TIFFClose(tif);
+ return true;
+}
+
#endif
#ifdef HAVE_TIFF
int channels = img.channels();
int width = img.cols, height = img.rows;
int depth = img.depth();
+#ifdef HAVE_TIFF
+ if(img.type() == CV_32FC3)
+ {
+ return writeHdr(img);
+ }
+#endif
if (depth != CV_8U && depth != CV_16U)
return false;
{
TIFF_UNCOMP = 1,
TIFF_HUFFMAN = 2,
- TIFF_PACKBITS = 32773
+ TIFF_PACKBITS = 32773,
};
enum TiffByteOrder
protected:
void* m_tif;
int normalizeChannelsNumber(int channels) const;
+ bool readHdrData(Mat& img);
+ bool m_hdr;
};
#endif
int count, int value );
bool writeLibTiff( const Mat& img, const std::vector<int>& params );
+ bool writeHdr( const Mat& img );
};
}
#include "grfmt_jpeg2000.hpp"
#include "grfmt_exr.hpp"
#include "grfmt_webp.hpp"
+#include "grfmt_hdr.hpp"
#endif/*_GRFMTS_H_*/
#include "grfmts.hpp"
#undef min
#undef max
+#include <iostream>
/****************************************************************************************\
* Image Codecs *
{
decoders.push_back( new BmpDecoder );
encoders.push_back( new BmpEncoder );
+ decoders.push_back( new HdrDecoder );
+ encoders.push_back( new HdrEncoder );
#ifdef HAVE_JPEG
decoders.push_back( new JpegDecoder );
encoders.push_back( new JpegEncoder );
decoder->setSource(filename);
if( !decoder->readHeader() )
return 0;
-
CvSize size;
size.width = decoder->width();
size.height = decoder->height();
ImageEncoder encoder = findEncoder( filename );
if( encoder.empty() )
CV_Error( CV_StsError, "could not find a writer for the specified extension" );
-
if( !encoder->isFormatSupported(image.depth()) )
{
CV_Assert( encoder->isFormatSupported(CV_8U) );
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "rgbe.hpp"
+#include <math.h>
+#include <malloc.h>
+#include <string.h>
+#include <ctype.h>
+
+// This file contains code to read and write four byte rgbe file format
+// developed by Greg Ward. It handles the conversions between rgbe and
+// pixels consisting of floats. The data is assumed to be an array of floats.
+// By default there are three floats per pixel in the order red, green, blue.
+// (RGBE_DATA_??? values control this.) Only the mimimal header reading and
+// writing is implemented. Each routine does error checking and will return
+// a status value as defined below. This code is intended as a skeleton so
+// feel free to modify it to suit your needs.
+
+// Some opencv specific changes have been added:
+// inline define specified, channel order changed (to ger bgr by default),
+// error handler uses CV_Error.
+//
+// posted to http://www.graphics.cornell.edu/~bjw/
+// written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95
+// based on code written by Greg Ward
+
+#define INLINE inline
+
+/* offsets to red, green, and blue components in a data (float) pixel */
+#define RGBE_DATA_RED 2
+#define RGBE_DATA_GREEN 1
+#define RGBE_DATA_BLUE 0
+/* number of floats per pixel */
+#define RGBE_DATA_SIZE 3
+
+enum rgbe_error_codes {
+ rgbe_read_error,
+ rgbe_write_error,
+ rgbe_format_error,
+ rgbe_memory_error,
+};
+
+/* default error routine. change this to change error handling */
+static int rgbe_error(int rgbe_error_code, char *msg)
+{
+ switch (rgbe_error_code) {
+ case rgbe_read_error:
+ CV_Error(cv::Error::StsError, "RGBE read error");
+ break;
+ case rgbe_write_error:
+ CV_Error(cv::Error::StsError, "RGBE write error");
+ break;
+ case rgbe_format_error:
+ CV_Error(cv::Error::StsError, cv::String("RGBE bad file format: ") +
+ cv::String(msg));
+ break;
+ default:
+ case rgbe_memory_error:
+ CV_Error(cv::Error::StsError, cv::String("RGBE error: \n") +
+ cv::String(msg));
+ }
+ return RGBE_RETURN_FAILURE;
+}
+
+/* standard conversion from float pixels to rgbe pixels */
+/* note: you can remove the "inline"s if your compiler complains about it */
+static INLINE void
+float2rgbe(unsigned char rgbe[4], float red, float green, float blue)
+{
+ float v;
+ int e;
+
+ v = red;
+ if (green > v) v = green;
+ if (blue > v) v = blue;
+ if (v < 1e-32) {
+ rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
+ }
+ else {
+ v = frexp(v,&e) * 256.0/v;
+ rgbe[0] = (unsigned char) (red * v);
+ rgbe[1] = (unsigned char) (green * v);
+ rgbe[2] = (unsigned char) (blue * v);
+ rgbe[3] = (unsigned char) (e + 128);
+ }
+}
+
+/* standard conversion from rgbe to float pixels */
+/* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */
+/* in the range [0,1] to map back into the range [0,1]. */
+static INLINE void
+rgbe2float(float *red, float *green, float *blue, unsigned char rgbe[4])
+{
+ float f;
+
+ if (rgbe[3]) { /*nonzero pixel*/
+ f = ldexp(1.0,rgbe[3]-(int)(128+8));
+ *red = rgbe[0] * f;
+ *green = rgbe[1] * f;
+ *blue = rgbe[2] * f;
+ }
+ else
+ *red = *green = *blue = 0.0;
+}
+
+/* default minimal header. modify if you want more information in header */
+int RGBE_WriteHeader(FILE *fp, int width, int height, rgbe_header_info *info)
+{
+ char *programtype = "RGBE";
+
+ if (info && (info->valid & RGBE_VALID_PROGRAMTYPE))
+ programtype = info->programtype;
+ if (fprintf(fp,"#?%s\n",programtype) < 0)
+ return rgbe_error(rgbe_write_error,NULL);
+ /* The #? is to identify file type, the programtype is optional. */
+ if (info && (info->valid & RGBE_VALID_GAMMA)) {
+ if (fprintf(fp,"GAMMA=%g\n",info->gamma) < 0)
+ return rgbe_error(rgbe_write_error,NULL);
+ }
+ if (info && (info->valid & RGBE_VALID_EXPOSURE)) {
+ if (fprintf(fp,"EXPOSURE=%g\n",info->exposure) < 0)
+ return rgbe_error(rgbe_write_error,NULL);
+ }
+ if (fprintf(fp,"FORMAT=32-bit_rle_rgbe\n\n") < 0)
+ return rgbe_error(rgbe_write_error,NULL);
+ if (fprintf(fp, "-Y %d +X %d\n", height, width) < 0)
+ return rgbe_error(rgbe_write_error,NULL);
+ return RGBE_RETURN_SUCCESS;
+}
+
+/* minimal header reading. modify if you want to parse more information */
+int RGBE_ReadHeader(FILE *fp, int *width, int *height, rgbe_header_info *info)
+{
+ char buf[128];
+ int found_format;
+ float tempf;
+ int i;
+
+ found_format = 0;
+ if (info) {
+ info->valid = 0;
+ info->programtype[0] = 0;
+ info->gamma = info->exposure = 1.0;
+ }
+ if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == NULL)
+ return rgbe_error(rgbe_read_error,NULL);
+ if ((buf[0] != '#')||(buf[1] != '?')) {
+ /* if you want to require the magic token then uncomment the next line */
+ /*return rgbe_error(rgbe_format_error,"bad initial token"); */
+ }
+ else if (info) {
+ info->valid |= RGBE_VALID_PROGRAMTYPE;
+ for(i=0;i<sizeof(info->programtype)-1;i++) {
+ if ((buf[i+2] == 0) || isspace(buf[i+2]))
+ break;
+ info->programtype[i] = buf[i+2];
+ }
+ info->programtype[i] = 0;
+ if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+ return rgbe_error(rgbe_read_error,NULL);
+ }
+ for(;;) {
+ if ((buf[0] == 0)||(buf[0] == '\n'))
+ return rgbe_error(rgbe_format_error,"no FORMAT specifier found");
+ else if (strcmp(buf,"FORMAT=32-bit_rle_rgbe\n") == 0)
+ break; /* format found so break out of loop */
+ else if (info && (sscanf(buf,"GAMMA=%g",&tempf) == 1)) {
+ info->gamma = tempf;
+ info->valid |= RGBE_VALID_GAMMA;
+ }
+ else if (info && (sscanf(buf,"EXPOSURE=%g",&tempf) == 1)) {
+ info->exposure = tempf;
+ info->valid |= RGBE_VALID_EXPOSURE;
+ }
+ if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+ return rgbe_error(rgbe_read_error,NULL);
+ }
+ if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+ return rgbe_error(rgbe_read_error,NULL);
+ if (strcmp(buf,"\n") != 0)
+ return rgbe_error(rgbe_format_error,
+ "missing blank line after FORMAT specifier");
+ if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
+ return rgbe_error(rgbe_read_error,NULL);
+ if (sscanf(buf,"-Y %d +X %d",height,width) < 2)
+ return rgbe_error(rgbe_format_error,"missing image size specifier");
+ return RGBE_RETURN_SUCCESS;
+}
+
+/* simple write routine that does not use run length encoding */
+/* These routines can be made faster by allocating a larger buffer and
+ fread-ing and fwrite-ing the data in larger chunks */
+int RGBE_WritePixels(FILE *fp, float *data, int numpixels)
+{
+ unsigned char rgbe[4];
+
+ while (numpixels-- > 0) {
+ float2rgbe(rgbe,data[RGBE_DATA_RED],
+ data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
+ data += RGBE_DATA_SIZE;
+ if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1)
+ return rgbe_error(rgbe_write_error,NULL);
+ }
+ return RGBE_RETURN_SUCCESS;
+}
+
+/* simple read routine. will not correctly handle run length encoding */
+int RGBE_ReadPixels(FILE *fp, float *data, int numpixels)
+{
+ unsigned char rgbe[4];
+
+ while(numpixels-- > 0) {
+ if (fread(rgbe, sizeof(rgbe), 1, fp) < 1)
+ return rgbe_error(rgbe_read_error,NULL);
+ rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],
+ &data[RGBE_DATA_BLUE],rgbe);
+ data += RGBE_DATA_SIZE;
+ }
+ return RGBE_RETURN_SUCCESS;
+}
+
+/* The code below is only needed for the run-length encoded files. */
+/* Run length encoding adds considerable complexity but does */
+/* save some space. For each scanline, each channel (r,g,b,e) is */
+/* encoded separately for better compression. */
+
+static int RGBE_WriteBytes_RLE(FILE *fp, unsigned char *data, int numbytes)
+{
+#define MINRUNLENGTH 4
+ int cur, beg_run, run_count, old_run_count, nonrun_count;
+ unsigned char buf[2];
+
+ cur = 0;
+ while(cur < numbytes) {
+ beg_run = cur;
+ /* find next run of length at least 4 if one exists */
+ run_count = old_run_count = 0;
+ while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
+ beg_run += run_count;
+ old_run_count = run_count;
+ run_count = 1;
+ while( (beg_run + run_count < numbytes) && (run_count < 127)
+ && (data[beg_run] == data[beg_run + run_count]))
+ run_count++;
+ }
+ /* if data before next big run is a short run then write it as such */
+ if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) {
+ buf[0] = 128 + old_run_count; /*write short run*/
+ buf[1] = data[cur];
+ if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1)
+ return rgbe_error(rgbe_write_error,NULL);
+ cur = beg_run;
+ }
+ /* write out bytes until we reach the start of the next run */
+ while(cur < beg_run) {
+ nonrun_count = beg_run - cur;
+ if (nonrun_count > 128)
+ nonrun_count = 128;
+ buf[0] = nonrun_count;
+ if (fwrite(buf,sizeof(buf[0]),1,fp) < 1)
+ return rgbe_error(rgbe_write_error,NULL);
+ if (fwrite(&data[cur],sizeof(data[0])*nonrun_count,1,fp) < 1)
+ return rgbe_error(rgbe_write_error,NULL);
+ cur += nonrun_count;
+ }
+ /* write out next run if one was found */
+ if (run_count >= MINRUNLENGTH) {
+ buf[0] = 128 + run_count;
+ buf[1] = data[beg_run];
+ if (fwrite(buf,sizeof(buf[0])*2,1,fp) < 1)
+ return rgbe_error(rgbe_write_error,NULL);
+ cur += run_count;
+ }
+ }
+ return RGBE_RETURN_SUCCESS;
+#undef MINRUNLENGTH
+}
+
+int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
+ int num_scanlines)
+{
+ unsigned char rgbe[4];
+ unsigned char *buffer;
+ int i, err;
+
+ if ((scanline_width < 8)||(scanline_width > 0x7fff))
+ /* run length encoding is not allowed so write flat*/
+ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines);
+ buffer = (unsigned char *)malloc(sizeof(unsigned char)*4*scanline_width);
+ if (buffer == NULL)
+ /* no buffer space so write flat */
+ return RGBE_WritePixels(fp,data,scanline_width*num_scanlines);
+ while(num_scanlines-- > 0) {
+ rgbe[0] = 2;
+ rgbe[1] = 2;
+ rgbe[2] = scanline_width >> 8;
+ rgbe[3] = scanline_width & 0xFF;
+ if (fwrite(rgbe, sizeof(rgbe), 1, fp) < 1) {
+ free(buffer);
+ return rgbe_error(rgbe_write_error,NULL);
+ }
+ for(i=0;i<scanline_width;i++) {
+ float2rgbe(rgbe,data[RGBE_DATA_RED],
+ data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
+ buffer[i] = rgbe[0];
+ buffer[i+scanline_width] = rgbe[1];
+ buffer[i+2*scanline_width] = rgbe[2];
+ buffer[i+3*scanline_width] = rgbe[3];
+ data += RGBE_DATA_SIZE;
+ }
+ /* write out each of the four channels separately run length encoded */
+ /* first red, then green, then blue, then exponent */
+ for(i=0;i<4;i++) {
+ if ((err = RGBE_WriteBytes_RLE(fp,&buffer[i*scanline_width],
+ scanline_width)) != RGBE_RETURN_SUCCESS) {
+ free(buffer);
+ return err;
+ }
+ }
+ }
+ free(buffer);
+ return RGBE_RETURN_SUCCESS;
+}
+
+int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
+ int num_scanlines)
+{
+ unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end;
+ int i, count;
+ unsigned char buf[2];
+
+ if ((scanline_width < 8)||(scanline_width > 0x7fff))
+ /* run length encoding is not allowed so read flat*/
+ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines);
+ scanline_buffer = NULL;
+ /* read in each successive scanline */
+ while(num_scanlines > 0) {
+ if (fread(rgbe,sizeof(rgbe),1,fp) < 1) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_read_error,NULL);
+ }
+ if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) {
+ /* this file is not run length encoded */
+ rgbe2float(&data[0],&data[1],&data[2],rgbe);
+ data += RGBE_DATA_SIZE;
+ free(scanline_buffer);
+ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1);
+ }
+ if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_format_error,"wrong scanline width");
+ }
+ if (scanline_buffer == NULL)
+ scanline_buffer = (unsigned char *)
+ malloc(sizeof(unsigned char)*4*scanline_width);
+ if (scanline_buffer == NULL)
+ return rgbe_error(rgbe_memory_error,"unable to allocate buffer space");
+
+ ptr = &scanline_buffer[0];
+ /* read each of the four channels for the scanline into the buffer */
+ for(i=0;i<4;i++) {
+ ptr_end = &scanline_buffer[(i+1)*scanline_width];
+ while(ptr < ptr_end) {
+ if (fread(buf,sizeof(buf[0])*2,1,fp) < 1) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_read_error,NULL);
+ }
+ if (buf[0] > 128) {
+ /* a run of the same value */
+ count = buf[0]-128;
+ if ((count == 0)||(count > ptr_end - ptr)) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_format_error,"bad scanline data");
+ }
+ while(count-- > 0)
+ *ptr++ = buf[1];
+ }
+ else {
+ /* a non-run */
+ count = buf[0];
+ if ((count == 0)||(count > ptr_end - ptr)) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_format_error,"bad scanline data");
+ }
+ *ptr++ = buf[1];
+ if (--count > 0) {
+ if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) {
+ free(scanline_buffer);
+ return rgbe_error(rgbe_read_error,NULL);
+ }
+ ptr += count;
+ }
+ }
+ }
+ }
+ /* now convert data from buffer into floats */
+ for(i=0;i<scanline_width;i++) {
+ rgbe[0] = scanline_buffer[i];
+ rgbe[1] = scanline_buffer[i+scanline_width];
+ rgbe[2] = scanline_buffer[i+2*scanline_width];
+ rgbe[3] = scanline_buffer[i+3*scanline_width];
+ rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],
+ &data[RGBE_DATA_BLUE],rgbe);
+ data += RGBE_DATA_SIZE;
+ }
+ num_scanlines--;
+ }
+ free(scanline_buffer);
+ return RGBE_RETURN_SUCCESS;
+}
+
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef _RGBE_HDR_H_
+#define _RGBE_HDR_H_
+
+// posted to http://www.graphics.cornell.edu/~bjw/
+// written by Bruce Walter (bjw@graphics.cornell.edu) 5/26/95
+// based on code written by Greg Ward
+
+#include <stdio.h>
+
+typedef struct {
+ int valid; /* indicate which fields are valid */
+ char programtype[16]; /* listed at beginning of file to identify it
+ * after "#?". defaults to "RGBE" */
+ float gamma; /* image has already been gamma corrected with
+ * given gamma. defaults to 1.0 (no correction) */
+ float exposure; /* a value of 1.0 in an image corresponds to
+ * <exposure> watts/steradian/m^2.
+ * defaults to 1.0 */
+} rgbe_header_info;
+
+/* flags indicating which fields in an rgbe_header_info are valid */
+#define RGBE_VALID_PROGRAMTYPE 0x01
+#define RGBE_VALID_GAMMA 0x02
+#define RGBE_VALID_EXPOSURE 0x04
+
+/* return codes for rgbe routines */
+#define RGBE_RETURN_SUCCESS 0
+#define RGBE_RETURN_FAILURE -1
+
+/* read or write headers */
+/* you may set rgbe_header_info to null if you want to */
+int RGBE_WriteHeader(FILE *fp, int width, int height, rgbe_header_info *info);
+int RGBE_ReadHeader(FILE *fp, int *width, int *height, rgbe_header_info *info);
+
+/* read or write pixels */
+/* can read or write pixels in chunks of any size including single pixels*/
+int RGBE_WritePixels(FILE *fp, float *data, int numpixels);
+int RGBE_ReadPixels(FILE *fp, float *data, int numpixels);
+
+/* read or write run length encoded files */
+/* must be called to read or write whole scanlines */
+int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
+ int num_scanlines);
+int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
+ int num_scanlines);
+
+#endif/*_RGBE_HDR_H_*/
+
+
+
float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21);
+CV_EXPORTS_W void makeHDR(InputArrayOfArrays srcImgs, std::vector<float> expTimes, OutputArray dst);
+
} // cv
#endif
--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "opencv2/photo.hpp"
+#include "opencv2/imgproc.hpp"
+
+namespace cv
+{
+
+static void triangleWeights(float weights[])
+{
+ for(int i = 0; i < 128; i++) {
+ weights[i] = i + 1.0f;
+ }
+ for(int i = 128; i < 256; i++) {
+ weights[i] = 256.0f - i;
+ }
+}
+
+static void generateResponce(float responce[])
+{
+ for(int i = 0; i < 256; i++) {
+ responce[i] = log((float)i);
+ }
+ responce[0] = responce[1];
+}
+
+void makeHDR(InputArrayOfArrays _images, std::vector<float> exp_times, OutputArray _dst)
+{
+ std::vector<Mat> images;
+ _images.getMatVector(images);
+ if(images.empty()) {
+ printf("Need at least one vector image.");
+ }
+ if(images.size() != exp_times.size()) {
+ printf("Number of images and number of exposure times must be equal.");
+ }
+ int width = images[0].cols;
+ int height = images[0].rows;
+ for(size_t i = 0; i < images.size(); i++) {
+
+ if(images[i].cols != width || images[i].rows != height) {
+ printf("Image dimensions must be equal.");
+ }
+ if(images[i].type() != CV_8UC3) {
+ printf("Images must have CV_8UC3 type.");
+ }
+ }
+ _dst.create(images[0].size(), CV_32FC3);
+ Mat result = _dst.getMat();
+ float weights[256], responce[256];
+ triangleWeights(weights);
+ generateResponce(responce);
+
+ float *res_ptr = result.ptr<float>();
+ for(size_t pos = 0; pos < result.total(); pos++, res_ptr += 3) {
+
+ float sum[3] = {0, 0, 0};
+ float weight_sum = 0;
+ for(size_t im = 0; im < images.size(); im++) {
+
+ uchar *img_ptr = images[im].ptr() + 3 * pos;
+ float w = (weights[img_ptr[0]] + weights[img_ptr[1]] +
+ weights[img_ptr[2]]) / 3;
+ weight_sum += w;
+ for(int channel = 0; channel < 3; channel++) {
+ sum[channel] += w * (responce[img_ptr[channel]] - log(exp_times[im]));
+ }
+ }
+ for(int channel = 0; channel < 3; channel++) {
+ res_ptr[channel] = exp(sum[channel] / weight_sum);
+ }
+ }
+}
+
+};
\ No newline at end of file