diff --git a/CMakeFiles/2.8.11.1/CompilerIdCXX/CMakeCXXCompilerId.cpp b/CMakeFiles/2.8.11.1/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 000000000..17c8fd9d1 --- /dev/null +++ b/CMakeFiles/2.8.11.1/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,372 @@ +/* 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; +} diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index 824466095..aec364a00 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -55,6 +55,8 @@ file(GLOB grfmt_hdrs src/grfmt*.hpp) 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}) diff --git a/modules/highgui/src/grfmt_hdr.cpp b/modules/highgui/src/grfmt_hdr.cpp new file mode 100644 index 000000000..a5aab3057 --- /dev/null +++ b/modules/highgui/src/grfmt_hdr.cpp @@ -0,0 +1,152 @@ +/*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(img.ptr()), 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& 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(img.ptr()), img.cols, img.rows); + } else { + RGBE_WritePixels(fout, const_cast(img.ptr()), 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; +} + +} diff --git a/modules/highgui/src/grfmt_hdr.hpp b/modules/highgui/src/grfmt_hdr.hpp new file mode 100644 index 000000000..526778259 --- /dev/null +++ b/modules/highgui/src/grfmt_hdr.hpp @@ -0,0 +1,88 @@ +/*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& params ); + ImageEncoder newEncoder() const; + bool isFormatSupported( int depth ) const; +protected: + +}; + +} + +#endif/*_GRFMT_HDR_H_*/ \ No newline at end of file diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index a0d53f3db..51d17cee7 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -71,6 +71,7 @@ TiffDecoder::TiffDecoder() TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler ); TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler ); } + m_hdr = false; } @@ -133,6 +134,14 @@ bool TiffDecoder::readHeader() 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))) @@ -171,6 +180,10 @@ bool TiffDecoder::readHeader() 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; @@ -380,6 +393,46 @@ bool TiffDecoder::readData( Mat& img ) return result; } +bool TiffDecoder::readHdrData(Mat& img) +{ + int rows_per_strip = 0, photometric = 0; + if(!m_tif) + { + return false; + } + TIFF *tif = static_cast(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(); + 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(); + 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 ////////////////////////////////////////////////////////////////////////////////////////// @@ -405,7 +458,11 @@ ImageEncoder TiffEncoder::newEncoder() const 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, @@ -557,6 +614,39 @@ bool TiffEncoder::writeLibTiff( const Mat& img, const std::vector& params) return true; } +bool TiffEncoder::writeHdr(const Mat& img) +{ + float *ptr = const_cast(img.ptr()); + 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(img.ptr()); + 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 @@ -568,6 +658,12 @@ bool TiffEncoder::write( const Mat& img, const std::vector& /*params*/) 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; diff --git a/modules/highgui/src/grfmt_tiff.hpp b/modules/highgui/src/grfmt_tiff.hpp index d3745a9f8..b6f7fa099 100644 --- a/modules/highgui/src/grfmt_tiff.hpp +++ b/modules/highgui/src/grfmt_tiff.hpp @@ -53,7 +53,7 @@ enum TiffCompression { TIFF_UNCOMP = 1, TIFF_HUFFMAN = 2, - TIFF_PACKBITS = 32773 + TIFF_PACKBITS = 32773, }; enum TiffByteOrder @@ -108,6 +108,8 @@ public: protected: void* m_tif; int normalizeChannelsNumber(int channels) const; + bool readHdrData(Mat& img); + bool m_hdr; }; #endif @@ -130,6 +132,7 @@ protected: int count, int value ); bool writeLibTiff( const Mat& img, const std::vector& params ); + bool writeHdr( const Mat& img ); }; } diff --git a/modules/highgui/src/grfmts.hpp b/modules/highgui/src/grfmts.hpp index 659ceb76f..799a4758a 100644 --- a/modules/highgui/src/grfmts.hpp +++ b/modules/highgui/src/grfmts.hpp @@ -52,5 +52,6 @@ #include "grfmt_jpeg2000.hpp" #include "grfmt_exr.hpp" #include "grfmt_webp.hpp" +#include "grfmt_hdr.hpp" #endif/*_GRFMTS_H_*/ diff --git a/modules/highgui/src/loadsave.cpp b/modules/highgui/src/loadsave.cpp index a548df54d..c75691698 100644 --- a/modules/highgui/src/loadsave.cpp +++ b/modules/highgui/src/loadsave.cpp @@ -47,6 +47,7 @@ #include "grfmts.hpp" #undef min #undef max +#include /****************************************************************************************\ * Image Codecs * @@ -60,6 +61,8 @@ struct ImageCodecInitializer { 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 ); @@ -203,7 +206,6 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) decoder->setSource(filename); if( !decoder->readHeader() ) return 0; - CvSize size; size.width = decoder->width(); size.height = decoder->height(); @@ -271,7 +273,6 @@ static bool imwrite_( const String& filename, const Mat& image, 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) ); diff --git a/modules/highgui/src/rgbe.cpp b/modules/highgui/src/rgbe.cpp new file mode 100644 index 000000000..2403be71e --- /dev/null +++ b/modules/highgui/src/rgbe.cpp @@ -0,0 +1,450 @@ +/*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 +#include +#include +#include + +// 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;iprogramtype)-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 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 + +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 + * 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_*/ + + + diff --git a/modules/photo/include/opencv2/photo.hpp b/modules/photo/include/opencv2/photo.hpp index 185b8dcc9..b05140c96 100644 --- a/modules/photo/include/opencv2/photo.hpp +++ b/modules/photo/include/opencv2/photo.hpp @@ -80,6 +80,8 @@ CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, float h = 3, float hColor = 3, int templateWindowSize = 7, int searchWindowSize = 21); +CV_EXPORTS_W void makeHDR(InputArrayOfArrays srcImgs, std::vector expTimes, OutputArray dst); + } // cv #endif diff --git a/modules/photo/src/hdr_fusion.cpp b/modules/photo/src/hdr_fusion.cpp new file mode 100644 index 000000000..ba0a4c94c --- /dev/null +++ b/modules/photo/src/hdr_fusion.cpp @@ -0,0 +1,115 @@ +/*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 exp_times, OutputArray _dst) +{ + std::vector 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(); + 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