Extract imgcodecs module from highgui
This commit is contained in:
@@ -1,582 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
const int BS_DEF_BLOCK_SIZE = 1<<15;
|
||||
|
||||
bool bsIsBigEndian( void )
|
||||
{
|
||||
return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
|
||||
}
|
||||
|
||||
///////////////////////// RBaseStream ////////////////////////////
|
||||
|
||||
bool RBaseStream::isOpened()
|
||||
{
|
||||
return m_is_opened;
|
||||
}
|
||||
|
||||
void RBaseStream::allocate()
|
||||
{
|
||||
if( !m_allocated )
|
||||
{
|
||||
m_start = new uchar[m_block_size];
|
||||
m_end = m_start + m_block_size;
|
||||
m_current = m_end;
|
||||
m_allocated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RBaseStream::RBaseStream()
|
||||
{
|
||||
m_start = m_end = m_current = 0;
|
||||
m_file = 0;
|
||||
m_block_size = BS_DEF_BLOCK_SIZE;
|
||||
m_is_opened = false;
|
||||
m_allocated = false;
|
||||
}
|
||||
|
||||
|
||||
RBaseStream::~RBaseStream()
|
||||
{
|
||||
close(); // Close files
|
||||
release(); // free buffers
|
||||
}
|
||||
|
||||
|
||||
void RBaseStream::readBlock()
|
||||
{
|
||||
setPos( getPos() ); // normalize position
|
||||
|
||||
if( m_file == 0 )
|
||||
{
|
||||
if( m_block_pos == 0 && m_current < m_end )
|
||||
return;
|
||||
throw RBS_THROW_EOS;
|
||||
}
|
||||
|
||||
fseek( m_file, m_block_pos, SEEK_SET );
|
||||
size_t readed = fread( m_start, 1, m_block_size, m_file );
|
||||
m_end = m_start + readed;
|
||||
m_current = m_start;
|
||||
|
||||
if( readed == 0 || m_current >= m_end )
|
||||
throw RBS_THROW_EOS;
|
||||
}
|
||||
|
||||
|
||||
bool RBaseStream::open( const String& filename )
|
||||
{
|
||||
close();
|
||||
allocate();
|
||||
|
||||
m_file = fopen( filename.c_str(), "rb" );
|
||||
if( m_file )
|
||||
{
|
||||
m_is_opened = true;
|
||||
setPos(0);
|
||||
readBlock();
|
||||
}
|
||||
return m_file != 0;
|
||||
}
|
||||
|
||||
bool RBaseStream::open( const Mat& buf )
|
||||
{
|
||||
close();
|
||||
if( buf.empty() )
|
||||
return false;
|
||||
CV_Assert(buf.isContinuous());
|
||||
m_start = buf.data;
|
||||
m_end = m_start + buf.cols*buf.rows*buf.elemSize();
|
||||
m_allocated = false;
|
||||
m_is_opened = true;
|
||||
setPos(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RBaseStream::close()
|
||||
{
|
||||
if( m_file )
|
||||
{
|
||||
fclose( m_file );
|
||||
m_file = 0;
|
||||
}
|
||||
m_is_opened = false;
|
||||
if( !m_allocated )
|
||||
m_start = m_end = m_current = 0;
|
||||
}
|
||||
|
||||
|
||||
void RBaseStream::release()
|
||||
{
|
||||
if( m_allocated )
|
||||
delete[] m_start;
|
||||
m_start = m_end = m_current = 0;
|
||||
m_allocated = false;
|
||||
}
|
||||
|
||||
|
||||
void RBaseStream::setPos( int pos )
|
||||
{
|
||||
assert( isOpened() && pos >= 0 );
|
||||
|
||||
if( !m_file )
|
||||
{
|
||||
m_current = m_start + pos;
|
||||
m_block_pos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = pos % m_block_size;
|
||||
m_block_pos = pos - offset;
|
||||
m_current = m_start + offset;
|
||||
}
|
||||
|
||||
|
||||
int RBaseStream::getPos()
|
||||
{
|
||||
assert( isOpened() );
|
||||
return m_block_pos + (int)(m_current - m_start);
|
||||
}
|
||||
|
||||
void RBaseStream::skip( int bytes )
|
||||
{
|
||||
assert( bytes >= 0 );
|
||||
m_current += bytes;
|
||||
}
|
||||
|
||||
///////////////////////// RLByteStream ////////////////////////////
|
||||
|
||||
RLByteStream::~RLByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
int RLByteStream::getByte()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current >= m_end )
|
||||
{
|
||||
readBlock();
|
||||
current = m_current;
|
||||
}
|
||||
|
||||
val = *((uchar*)current);
|
||||
m_current = current + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int RLByteStream::getBytes( void* buffer, int count )
|
||||
{
|
||||
uchar* data = (uchar*)buffer;
|
||||
int readed = 0;
|
||||
assert( count >= 0 );
|
||||
|
||||
while( count > 0 )
|
||||
{
|
||||
int l;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
l = (int)(m_end - m_current);
|
||||
if( l > count ) l = count;
|
||||
if( l > 0 ) break;
|
||||
readBlock();
|
||||
}
|
||||
memcpy( data, m_current, l );
|
||||
m_current += l;
|
||||
data += l;
|
||||
count -= l;
|
||||
readed += l;
|
||||
}
|
||||
return readed;
|
||||
}
|
||||
|
||||
|
||||
//////////// RLByteStream & RMByteStream <Get[d]word>s ////////////////
|
||||
|
||||
RMByteStream::~RMByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int RLByteStream::getWord()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current+1 < m_end )
|
||||
{
|
||||
val = current[0] + (current[1] << 8);
|
||||
m_current = current + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = getByte();
|
||||
val|= getByte() << 8;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int RLByteStream::getDWord()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current+3 < m_end )
|
||||
{
|
||||
val = current[0] + (current[1] << 8) +
|
||||
(current[2] << 16) + (current[3] << 24);
|
||||
m_current = current + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = getByte();
|
||||
val |= getByte() << 8;
|
||||
val |= getByte() << 16;
|
||||
val |= getByte() << 24;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int RMByteStream::getWord()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current+1 < m_end )
|
||||
{
|
||||
val = (current[0] << 8) + current[1];
|
||||
m_current = current + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = getByte() << 8;
|
||||
val|= getByte();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int RMByteStream::getDWord()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current+3 < m_end )
|
||||
{
|
||||
val = (current[0] << 24) + (current[1] << 16) +
|
||||
(current[2] << 8) + current[3];
|
||||
m_current = current + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = getByte() << 24;
|
||||
val |= getByte() << 16;
|
||||
val |= getByte() << 8;
|
||||
val |= getByte();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/////////////////////////// WBaseStream /////////////////////////////////
|
||||
|
||||
// WBaseStream - base class for output streams
|
||||
WBaseStream::WBaseStream()
|
||||
{
|
||||
m_start = m_end = m_current = 0;
|
||||
m_file = 0;
|
||||
m_block_size = BS_DEF_BLOCK_SIZE;
|
||||
m_is_opened = false;
|
||||
m_buf = 0;
|
||||
}
|
||||
|
||||
|
||||
WBaseStream::~WBaseStream()
|
||||
{
|
||||
close();
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
bool WBaseStream::isOpened()
|
||||
{
|
||||
return m_is_opened;
|
||||
}
|
||||
|
||||
|
||||
void WBaseStream::allocate()
|
||||
{
|
||||
if( !m_start )
|
||||
m_start = new uchar[m_block_size];
|
||||
|
||||
m_end = m_start + m_block_size;
|
||||
m_current = m_start;
|
||||
}
|
||||
|
||||
|
||||
void WBaseStream::writeBlock()
|
||||
{
|
||||
int size = (int)(m_current - m_start);
|
||||
|
||||
assert( isOpened() );
|
||||
if( size == 0 )
|
||||
return;
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
size_t sz = m_buf->size();
|
||||
m_buf->resize( sz + size );
|
||||
memcpy( &(*m_buf)[sz], m_start, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite( m_start, 1, size, m_file );
|
||||
}
|
||||
m_current = m_start;
|
||||
m_block_pos += size;
|
||||
}
|
||||
|
||||
|
||||
bool WBaseStream::open( const String& filename )
|
||||
{
|
||||
close();
|
||||
allocate();
|
||||
|
||||
m_file = fopen( filename.c_str(), "wb" );
|
||||
if( m_file )
|
||||
{
|
||||
m_is_opened = true;
|
||||
m_block_pos = 0;
|
||||
m_current = m_start;
|
||||
}
|
||||
return m_file != 0;
|
||||
}
|
||||
|
||||
bool WBaseStream::open( std::vector<uchar>& buf )
|
||||
{
|
||||
close();
|
||||
allocate();
|
||||
|
||||
m_buf = &buf;
|
||||
m_is_opened = true;
|
||||
m_block_pos = 0;
|
||||
m_current = m_start;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WBaseStream::close()
|
||||
{
|
||||
if( m_is_opened )
|
||||
writeBlock();
|
||||
if( m_file )
|
||||
{
|
||||
fclose( m_file );
|
||||
m_file = 0;
|
||||
}
|
||||
m_buf = 0;
|
||||
m_is_opened = false;
|
||||
}
|
||||
|
||||
|
||||
void WBaseStream::release()
|
||||
{
|
||||
if( m_start )
|
||||
delete[] m_start;
|
||||
m_start = m_end = m_current = 0;
|
||||
}
|
||||
|
||||
|
||||
int WBaseStream::getPos()
|
||||
{
|
||||
assert( isOpened() );
|
||||
return m_block_pos + (int)(m_current - m_start);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// WLByteStream ///////////////////////////////////
|
||||
|
||||
WLByteStream::~WLByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
void WLByteStream::putByte( int val )
|
||||
{
|
||||
*m_current++ = (uchar)val;
|
||||
if( m_current >= m_end )
|
||||
writeBlock();
|
||||
}
|
||||
|
||||
|
||||
void WLByteStream::putBytes( const void* buffer, int count )
|
||||
{
|
||||
uchar* data = (uchar*)buffer;
|
||||
|
||||
assert( data && m_current && count >= 0 );
|
||||
|
||||
while( count )
|
||||
{
|
||||
int l = (int)(m_end - m_current);
|
||||
|
||||
if( l > count )
|
||||
l = count;
|
||||
|
||||
if( l > 0 )
|
||||
{
|
||||
memcpy( m_current, data, l );
|
||||
m_current += l;
|
||||
data += l;
|
||||
count -= l;
|
||||
}
|
||||
if( m_current == m_end )
|
||||
writeBlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WLByteStream::putWord( int val )
|
||||
{
|
||||
uchar *current = m_current;
|
||||
|
||||
if( current+1 < m_end )
|
||||
{
|
||||
current[0] = (uchar)val;
|
||||
current[1] = (uchar)(val >> 8);
|
||||
m_current = current + 2;
|
||||
if( m_current == m_end )
|
||||
writeBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
putByte(val);
|
||||
putByte(val >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WLByteStream::putDWord( int val )
|
||||
{
|
||||
uchar *current = m_current;
|
||||
|
||||
if( current+3 < m_end )
|
||||
{
|
||||
current[0] = (uchar)val;
|
||||
current[1] = (uchar)(val >> 8);
|
||||
current[2] = (uchar)(val >> 16);
|
||||
current[3] = (uchar)(val >> 24);
|
||||
m_current = current + 4;
|
||||
if( m_current == m_end )
|
||||
writeBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
putByte(val);
|
||||
putByte(val >> 8);
|
||||
putByte(val >> 16);
|
||||
putByte(val >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// WMByteStream ///////////////////////////////////
|
||||
|
||||
WMByteStream::~WMByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void WMByteStream::putWord( int val )
|
||||
{
|
||||
uchar *current = m_current;
|
||||
|
||||
if( current+1 < m_end )
|
||||
{
|
||||
current[0] = (uchar)(val >> 8);
|
||||
current[1] = (uchar)val;
|
||||
m_current = current + 2;
|
||||
if( m_current == m_end )
|
||||
writeBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
putByte(val >> 8);
|
||||
putByte(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WMByteStream::putDWord( int val )
|
||||
{
|
||||
uchar *current = m_current;
|
||||
|
||||
if( current+3 < m_end )
|
||||
{
|
||||
current[0] = (uchar)(val >> 24);
|
||||
current[1] = (uchar)(val >> 16);
|
||||
current[2] = (uchar)(val >> 8);
|
||||
current[3] = (uchar)val;
|
||||
m_current = current + 4;
|
||||
if( m_current == m_end )
|
||||
writeBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
putByte(val >> 24);
|
||||
putByte(val >> 16);
|
||||
putByte(val >> 8);
|
||||
putByte(val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*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 _BITSTRM_H_
|
||||
#define _BITSTRM_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
enum
|
||||
{
|
||||
RBS_THROW_EOS=-123, // <end of stream> exception code
|
||||
RBS_THROW_FORB=-124, // <forrbidden huffman code> exception code
|
||||
RBS_HUFF_FORB=2047, // forrbidden huffman code "value"
|
||||
RBS_BAD_HEADER=-125 // invalid header
|
||||
};
|
||||
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// class RBaseStream - base class for other reading streams.
|
||||
class RBaseStream
|
||||
{
|
||||
public:
|
||||
//methods
|
||||
RBaseStream();
|
||||
virtual ~RBaseStream();
|
||||
|
||||
virtual bool open( const String& filename );
|
||||
virtual bool open( const Mat& buf );
|
||||
virtual void close();
|
||||
bool isOpened();
|
||||
void setPos( int pos );
|
||||
int getPos();
|
||||
void skip( int bytes );
|
||||
|
||||
protected:
|
||||
|
||||
bool m_allocated;
|
||||
uchar* m_start;
|
||||
uchar* m_end;
|
||||
uchar* m_current;
|
||||
FILE* m_file;
|
||||
int m_block_size;
|
||||
int m_block_pos;
|
||||
bool m_is_opened;
|
||||
|
||||
virtual void readBlock();
|
||||
virtual void release();
|
||||
virtual void allocate();
|
||||
};
|
||||
|
||||
|
||||
// class RLByteStream - uchar-oriented stream.
|
||||
// l in prefix means that the least significant uchar of a multi-uchar value goes first
|
||||
class RLByteStream : public RBaseStream
|
||||
{
|
||||
public:
|
||||
virtual ~RLByteStream();
|
||||
|
||||
int getByte();
|
||||
int getBytes( void* buffer, int count );
|
||||
int getWord();
|
||||
int getDWord();
|
||||
};
|
||||
|
||||
// class RMBitStream - uchar-oriented stream.
|
||||
// m in prefix means that the most significant uchar of a multi-uchar value go first
|
||||
class RMByteStream : public RLByteStream
|
||||
{
|
||||
public:
|
||||
virtual ~RMByteStream();
|
||||
|
||||
int getWord();
|
||||
int getDWord();
|
||||
};
|
||||
|
||||
// WBaseStream - base class for output streams
|
||||
class WBaseStream
|
||||
{
|
||||
public:
|
||||
//methods
|
||||
WBaseStream();
|
||||
virtual ~WBaseStream();
|
||||
|
||||
virtual bool open( const String& filename );
|
||||
virtual bool open( std::vector<uchar>& buf );
|
||||
virtual void close();
|
||||
bool isOpened();
|
||||
int getPos();
|
||||
|
||||
protected:
|
||||
|
||||
uchar* m_start;
|
||||
uchar* m_end;
|
||||
uchar* m_current;
|
||||
int m_block_size;
|
||||
int m_block_pos;
|
||||
FILE* m_file;
|
||||
bool m_is_opened;
|
||||
std::vector<uchar>* m_buf;
|
||||
|
||||
virtual void writeBlock();
|
||||
virtual void release();
|
||||
virtual void allocate();
|
||||
};
|
||||
|
||||
|
||||
// class WLByteStream - uchar-oriented stream.
|
||||
// l in prefix means that the least significant uchar of a multi-byte value goes first
|
||||
class WLByteStream : public WBaseStream
|
||||
{
|
||||
public:
|
||||
virtual ~WLByteStream();
|
||||
|
||||
void putByte( int val );
|
||||
void putBytes( const void* buffer, int count );
|
||||
void putWord( int val );
|
||||
void putDWord( int val );
|
||||
};
|
||||
|
||||
|
||||
// class WLByteStream - uchar-oriented stream.
|
||||
// m in prefix means that the least significant uchar of a multi-byte value goes last
|
||||
class WMByteStream : public WLByteStream
|
||||
{
|
||||
public:
|
||||
virtual ~WMByteStream();
|
||||
void putWord( int val );
|
||||
void putDWord( int val );
|
||||
};
|
||||
|
||||
inline unsigned BSWAP(unsigned v)
|
||||
{
|
||||
return (v<<24)|((v&0xff00)<<8)|((v>>8)&0xff00)|((unsigned)v>>24);
|
||||
}
|
||||
|
||||
bool bsIsBigEndian( void );
|
||||
|
||||
}
|
||||
|
||||
#endif/*_BITSTRM_H_*/
|
||||
@@ -1,137 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 "precomp.hpp"
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
BaseImageDecoder::BaseImageDecoder()
|
||||
{
|
||||
m_width = m_height = 0;
|
||||
m_type = -1;
|
||||
m_buf_supported = false;
|
||||
}
|
||||
|
||||
bool BaseImageDecoder::setSource( const String& filename )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_buf.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseImageDecoder::setSource( const Mat& buf )
|
||||
{
|
||||
if( !m_buf_supported )
|
||||
return false;
|
||||
m_filename = String();
|
||||
m_buf = buf;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t BaseImageDecoder::signatureLength() const
|
||||
{
|
||||
return m_signature.size();
|
||||
}
|
||||
|
||||
bool BaseImageDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
size_t len = signatureLength();
|
||||
return signature.size() >= len && memcmp( signature.c_str(), m_signature.c_str(), len ) == 0;
|
||||
}
|
||||
|
||||
ImageDecoder BaseImageDecoder::newDecoder() const
|
||||
{
|
||||
return ImageDecoder();
|
||||
}
|
||||
|
||||
BaseImageEncoder::BaseImageEncoder()
|
||||
{
|
||||
m_buf_supported = false;
|
||||
}
|
||||
|
||||
bool BaseImageEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return depth == CV_8U;
|
||||
}
|
||||
|
||||
String BaseImageEncoder::getDescription() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
bool BaseImageEncoder::setDestination( const String& filename )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_buf = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseImageEncoder::setDestination( std::vector<uchar>& buf )
|
||||
{
|
||||
if( !m_buf_supported )
|
||||
return false;
|
||||
m_buf = &buf;
|
||||
m_buf->clear();
|
||||
m_filename = String();
|
||||
return true;
|
||||
}
|
||||
|
||||
ImageEncoder BaseImageEncoder::newEncoder() const
|
||||
{
|
||||
return ImageEncoder();
|
||||
}
|
||||
|
||||
void BaseImageEncoder::throwOnEror() const
|
||||
{
|
||||
if(!m_last_error.empty())
|
||||
{
|
||||
String msg = "Raw image encoder error: " + m_last_error;
|
||||
CV_Error( CV_BadImageSize, msg.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,117 +0,0 @@
|
||||
/*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_BASE_H_
|
||||
#define _GRFMT_BASE_H_
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class BaseImageDecoder;
|
||||
class BaseImageEncoder;
|
||||
typedef Ptr<BaseImageEncoder> ImageEncoder;
|
||||
typedef Ptr<BaseImageDecoder> ImageDecoder;
|
||||
|
||||
///////////////////////////////// base class for decoders ////////////////////////
|
||||
class BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
BaseImageDecoder();
|
||||
virtual ~BaseImageDecoder() {}
|
||||
|
||||
int width() const { return m_width; }
|
||||
int height() const { return m_height; }
|
||||
virtual int type() const { return m_type; }
|
||||
|
||||
virtual bool setSource( const String& filename );
|
||||
virtual bool setSource( const Mat& buf );
|
||||
virtual bool readHeader() = 0;
|
||||
virtual bool readData( Mat& img ) = 0;
|
||||
|
||||
virtual size_t signatureLength() const;
|
||||
virtual bool checkSignature( const String& signature ) const;
|
||||
virtual ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
int m_width; // width of the image ( filled by readHeader )
|
||||
int m_height; // height of the image ( filled by readHeader )
|
||||
int m_type;
|
||||
String m_filename;
|
||||
String m_signature;
|
||||
Mat m_buf;
|
||||
bool m_buf_supported;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////// base class for encoders ////////////////////////////
|
||||
class BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
BaseImageEncoder();
|
||||
virtual ~BaseImageEncoder() {}
|
||||
virtual bool isFormatSupported( int depth ) const;
|
||||
|
||||
virtual bool setDestination( const String& filename );
|
||||
virtual bool setDestination( std::vector<uchar>& buf );
|
||||
virtual bool write( const Mat& img, const std::vector<int>& params ) = 0;
|
||||
|
||||
virtual String getDescription() const;
|
||||
virtual ImageEncoder newEncoder() const;
|
||||
|
||||
virtual void throwOnEror() const;
|
||||
|
||||
protected:
|
||||
String m_description;
|
||||
|
||||
String m_filename;
|
||||
std::vector<uchar>* m_buf;
|
||||
bool m_buf_supported;
|
||||
|
||||
String m_last_error;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_BASE_H_*/
|
||||
@@ -1,565 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#include "grfmt_bmp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
static const char* fmtSignBmp = "BM";
|
||||
|
||||
/************************ BMP decoder *****************************/
|
||||
|
||||
BmpDecoder::BmpDecoder()
|
||||
{
|
||||
m_signature = fmtSignBmp;
|
||||
m_offset = -1;
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
BmpDecoder::~BmpDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BmpDecoder::close()
|
||||
{
|
||||
m_strm.close();
|
||||
}
|
||||
|
||||
ImageDecoder BmpDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<BmpDecoder>();
|
||||
}
|
||||
|
||||
bool BmpDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
bool iscolor = false;
|
||||
|
||||
if( !m_buf.empty() )
|
||||
{
|
||||
if( !m_strm.open( m_buf ) )
|
||||
return false;
|
||||
}
|
||||
else if( !m_strm.open( m_filename ))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
m_strm.skip( 10 );
|
||||
m_offset = m_strm.getDWord();
|
||||
|
||||
int size = m_strm.getDWord();
|
||||
|
||||
if( size >= 36 )
|
||||
{
|
||||
m_width = m_strm.getDWord();
|
||||
m_height = m_strm.getDWord();
|
||||
m_bpp = m_strm.getDWord() >> 16;
|
||||
m_rle_code = (BmpCompression)m_strm.getDWord();
|
||||
m_strm.skip(12);
|
||||
int clrused = m_strm.getDWord();
|
||||
m_strm.skip( size - 36 );
|
||||
|
||||
if( m_width > 0 && m_height != 0 &&
|
||||
(((m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
|
||||
m_bpp == 24 || m_bpp == 32 ) && m_rle_code == BMP_RGB) ||
|
||||
(m_bpp == 16 && (m_rle_code == BMP_RGB || m_rle_code == BMP_BITFIELDS)) ||
|
||||
(m_bpp == 4 && m_rle_code == BMP_RLE4) ||
|
||||
(m_bpp == 8 && m_rle_code == BMP_RLE8)))
|
||||
{
|
||||
iscolor = true;
|
||||
result = true;
|
||||
|
||||
if( m_bpp <= 8 )
|
||||
{
|
||||
memset( m_palette, 0, sizeof(m_palette));
|
||||
m_strm.getBytes( m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
|
||||
iscolor = IsColorPalette( m_palette, m_bpp );
|
||||
}
|
||||
else if( m_bpp == 16 && m_rle_code == BMP_BITFIELDS )
|
||||
{
|
||||
int redmask = m_strm.getDWord();
|
||||
int greenmask = m_strm.getDWord();
|
||||
int bluemask = m_strm.getDWord();
|
||||
|
||||
if( bluemask == 0x1f && greenmask == 0x3e0 && redmask == 0x7c00 )
|
||||
m_bpp = 15;
|
||||
else if( bluemask == 0x1f && greenmask == 0x7e0 && redmask == 0xf800 )
|
||||
;
|
||||
else
|
||||
result = false;
|
||||
}
|
||||
else if( m_bpp == 16 && m_rle_code == BMP_RGB )
|
||||
m_bpp = 15;
|
||||
}
|
||||
}
|
||||
else if( size == 12 )
|
||||
{
|
||||
m_width = m_strm.getWord();
|
||||
m_height = m_strm.getWord();
|
||||
m_bpp = m_strm.getDWord() >> 16;
|
||||
m_rle_code = BMP_RGB;
|
||||
|
||||
if( m_width > 0 && m_height != 0 &&
|
||||
(m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
|
||||
m_bpp == 24 || m_bpp == 32 ))
|
||||
{
|
||||
if( m_bpp <= 8 )
|
||||
{
|
||||
uchar buffer[256*3];
|
||||
int j, clrused = 1 << m_bpp;
|
||||
m_strm.getBytes( buffer, clrused*3 );
|
||||
for( j = 0; j < clrused; j++ )
|
||||
{
|
||||
m_palette[j].b = buffer[3*j+0];
|
||||
m_palette[j].g = buffer[3*j+1];
|
||||
m_palette[j].r = buffer[3*j+2];
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
|
||||
m_type = iscolor ? CV_8UC3 : CV_8UC1;
|
||||
m_origin = m_height > 0 ? IPL_ORIGIN_BL : IPL_ORIGIN_TL;
|
||||
m_height = std::abs(m_height);
|
||||
|
||||
if( !result )
|
||||
{
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool BmpDecoder::readData( Mat& img )
|
||||
{
|
||||
uchar* data = img.data;
|
||||
int step = (int)img.step;
|
||||
bool color = img.channels() > 1;
|
||||
uchar gray_palette[256];
|
||||
bool result = false;
|
||||
int src_pitch = ((m_width*(m_bpp != 15 ? m_bpp : 16) + 7)/8 + 3) & -4;
|
||||
int nch = color ? 3 : 1;
|
||||
int y, width3 = m_width*nch;
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
if( m_origin == IPL_ORIGIN_BL )
|
||||
{
|
||||
data += (m_height - 1)*step;
|
||||
step = -step;
|
||||
}
|
||||
|
||||
AutoBuffer<uchar> _src, _bgr;
|
||||
_src.allocate(src_pitch + 32);
|
||||
|
||||
if( !color )
|
||||
{
|
||||
if( m_bpp <= 8 )
|
||||
{
|
||||
CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
|
||||
}
|
||||
_bgr.allocate(m_width*3 + 32);
|
||||
}
|
||||
uchar *src = _src, *bgr = _bgr;
|
||||
|
||||
try
|
||||
{
|
||||
m_strm.setPos( m_offset );
|
||||
|
||||
switch( m_bpp )
|
||||
{
|
||||
/************************* 1 BPP ************************/
|
||||
case 1:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
FillColorRow1( color ? data : bgr, src, m_width, m_palette );
|
||||
if( !color )
|
||||
icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
|
||||
/************************* 4 BPP ************************/
|
||||
case 4:
|
||||
if( m_rle_code == BMP_RGB )
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( color )
|
||||
FillColorRow4( data, src, m_width, m_palette );
|
||||
else
|
||||
FillGrayRow4( data, src, m_width, gray_palette );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else if( m_rle_code == BMP_RLE4 ) // rle4 compression
|
||||
{
|
||||
uchar* line_end = data + width3;
|
||||
y = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int code = m_strm.getWord();
|
||||
int len = code & 255;
|
||||
code >>= 8;
|
||||
if( len != 0 ) // encoded mode
|
||||
{
|
||||
PaletteEntry clr[2];
|
||||
uchar gray_clr[2];
|
||||
int t = 0;
|
||||
|
||||
clr[0] = m_palette[code >> 4];
|
||||
clr[1] = m_palette[code & 15];
|
||||
gray_clr[0] = gray_palette[code >> 4];
|
||||
gray_clr[1] = gray_palette[code & 15];
|
||||
|
||||
uchar* end = data + len*nch;
|
||||
if( end > line_end ) goto decode_rle4_bad;
|
||||
do
|
||||
{
|
||||
if( color )
|
||||
WRITE_PIX( data, clr[t] );
|
||||
else
|
||||
*data = gray_clr[t];
|
||||
t ^= 1;
|
||||
}
|
||||
while( (data += nch) < end );
|
||||
}
|
||||
else if( code > 2 ) // absolute mode
|
||||
{
|
||||
if( data + code*nch > line_end ) goto decode_rle4_bad;
|
||||
m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 );
|
||||
if( color )
|
||||
data = FillColorRow4( data, src, code, m_palette );
|
||||
else
|
||||
data = FillGrayRow4( data, src, code, gray_palette );
|
||||
}
|
||||
else
|
||||
{
|
||||
int x_shift3 = (int)(line_end - data);
|
||||
int y_shift = m_height - y;
|
||||
|
||||
if( code == 2 )
|
||||
{
|
||||
x_shift3 = m_strm.getByte()*nch;
|
||||
y_shift = m_strm.getByte();
|
||||
}
|
||||
|
||||
len = x_shift3 + ((y_shift * width3) & ((code == 0) - 1));
|
||||
|
||||
if( color )
|
||||
data = FillUniColor( data, line_end, step, width3,
|
||||
y, m_height, x_shift3,
|
||||
m_palette[0] );
|
||||
else
|
||||
data = FillUniGray( data, line_end, step, width3,
|
||||
y, m_height, x_shift3,
|
||||
gray_palette[0] );
|
||||
|
||||
if( y >= m_height )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
decode_rle4_bad: ;
|
||||
}
|
||||
break;
|
||||
|
||||
/************************* 8 BPP ************************/
|
||||
case 8:
|
||||
if( m_rle_code == BMP_RGB )
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( color )
|
||||
FillColorRow8( data, src, m_width, m_palette );
|
||||
else
|
||||
FillGrayRow8( data, src, m_width, gray_palette );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else if( m_rle_code == BMP_RLE8 ) // rle8 compression
|
||||
{
|
||||
uchar* line_end = data + width3;
|
||||
int line_end_flag = 0;
|
||||
y = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int code = m_strm.getWord();
|
||||
int len = code & 255;
|
||||
code >>= 8;
|
||||
if( len != 0 ) // encoded mode
|
||||
{
|
||||
int prev_y = y;
|
||||
len *= nch;
|
||||
|
||||
if( data + len > line_end )
|
||||
goto decode_rle8_bad;
|
||||
|
||||
if( color )
|
||||
data = FillUniColor( data, line_end, step, width3,
|
||||
y, m_height, len,
|
||||
m_palette[code] );
|
||||
else
|
||||
data = FillUniGray( data, line_end, step, width3,
|
||||
y, m_height, len,
|
||||
gray_palette[code] );
|
||||
|
||||
line_end_flag = y - prev_y;
|
||||
}
|
||||
else if( code > 2 ) // absolute mode
|
||||
{
|
||||
int prev_y = y;
|
||||
int code3 = code*nch;
|
||||
|
||||
if( data + code3 > line_end )
|
||||
goto decode_rle8_bad;
|
||||
m_strm.getBytes( src, (code + 1) & -2 );
|
||||
if( color )
|
||||
data = FillColorRow8( data, src, code, m_palette );
|
||||
else
|
||||
data = FillGrayRow8( data, src, code, gray_palette );
|
||||
|
||||
line_end_flag = y - prev_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
int x_shift3 = (int)(line_end - data);
|
||||
int y_shift = m_height - y;
|
||||
|
||||
if( code || !line_end_flag || x_shift3 < width3 )
|
||||
{
|
||||
if( code == 2 )
|
||||
{
|
||||
x_shift3 = m_strm.getByte()*nch;
|
||||
y_shift = m_strm.getByte();
|
||||
}
|
||||
|
||||
x_shift3 += (y_shift * width3) & ((code == 0) - 1);
|
||||
|
||||
if( y >= m_height )
|
||||
break;
|
||||
|
||||
if( color )
|
||||
data = FillUniColor( data, line_end, step, width3,
|
||||
y, m_height, x_shift3,
|
||||
m_palette[0] );
|
||||
else
|
||||
data = FillUniGray( data, line_end, step, width3,
|
||||
y, m_height, x_shift3,
|
||||
gray_palette[0] );
|
||||
|
||||
if( y >= m_height )
|
||||
break;
|
||||
}
|
||||
|
||||
line_end_flag = 0;
|
||||
if( y >= m_height )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
decode_rle8_bad: ;
|
||||
}
|
||||
break;
|
||||
/************************* 15 BPP ************************/
|
||||
case 15:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( !color )
|
||||
icvCvt_BGR5552Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
icvCvt_BGR5552BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
/************************* 16 BPP ************************/
|
||||
case 16:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( !color )
|
||||
icvCvt_BGR5652Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
icvCvt_BGR5652BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
/************************* 24 BPP ************************/
|
||||
case 24:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if(!color)
|
||||
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
memcpy( data, src, m_width*3 );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
/************************* 32 BPP ************************/
|
||||
case 32:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
|
||||
if( !color )
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BmpEncoder::BmpEncoder()
|
||||
{
|
||||
m_description = "Windows bitmap (*.bmp;*.dib)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
BmpEncoder::~BmpEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageEncoder BmpEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<BmpEncoder>();
|
||||
}
|
||||
|
||||
bool BmpEncoder::write( const Mat& img, const std::vector<int>& )
|
||||
{
|
||||
int width = img.cols, height = img.rows, channels = img.channels();
|
||||
int fileStep = (width*channels + 3) & -4;
|
||||
uchar zeropad[] = "\0\0\0\0";
|
||||
WLByteStream strm;
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
if( !strm.open( *m_buf ) )
|
||||
return false;
|
||||
}
|
||||
else if( !strm.open( m_filename ))
|
||||
return false;
|
||||
|
||||
int bitmapHeaderSize = 40;
|
||||
int paletteSize = channels > 1 ? 0 : 1024;
|
||||
int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize;
|
||||
int fileSize = fileStep*height + headerSize;
|
||||
PaletteEntry palette[256];
|
||||
|
||||
if( m_buf )
|
||||
m_buf->reserve( alignSize(fileSize + 16, 256) );
|
||||
|
||||
// write signature 'BM'
|
||||
strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) );
|
||||
|
||||
// write file header
|
||||
strm.putDWord( fileSize ); // file size
|
||||
strm.putDWord( 0 );
|
||||
strm.putDWord( headerSize );
|
||||
|
||||
// write bitmap header
|
||||
strm.putDWord( bitmapHeaderSize );
|
||||
strm.putDWord( width );
|
||||
strm.putDWord( height );
|
||||
strm.putWord( 1 );
|
||||
strm.putWord( channels << 3 );
|
||||
strm.putDWord( BMP_RGB );
|
||||
strm.putDWord( 0 );
|
||||
strm.putDWord( 0 );
|
||||
strm.putDWord( 0 );
|
||||
strm.putDWord( 0 );
|
||||
strm.putDWord( 0 );
|
||||
|
||||
if( channels == 1 )
|
||||
{
|
||||
FillGrayPalette( palette, 8 );
|
||||
strm.putBytes( palette, sizeof(palette));
|
||||
}
|
||||
|
||||
width *= channels;
|
||||
for( int y = height - 1; y >= 0; y-- )
|
||||
{
|
||||
strm.putBytes( img.data + img.step*y, width );
|
||||
if( fileStep > width )
|
||||
strm.putBytes( zeropad, fileStep - width );
|
||||
}
|
||||
|
||||
strm.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*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_BMP_H_
|
||||
#define _GRFMT_BMP_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
enum BmpCompression
|
||||
{
|
||||
BMP_RGB = 0,
|
||||
BMP_RLE8 = 1,
|
||||
BMP_RLE4 = 2,
|
||||
BMP_BITFIELDS = 3
|
||||
};
|
||||
|
||||
|
||||
// Windows Bitmap reader
|
||||
class BmpDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
BmpDecoder();
|
||||
~BmpDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
|
||||
RLByteStream m_strm;
|
||||
PaletteEntry m_palette[256];
|
||||
int m_origin;
|
||||
int m_bpp;
|
||||
int m_offset;
|
||||
BmpCompression m_rle_code;
|
||||
};
|
||||
|
||||
|
||||
// ... writer
|
||||
class BmpEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
BmpEncoder();
|
||||
~BmpEncoder();
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_BMP_H_*/
|
||||
@@ -1,736 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
|
||||
#ifdef HAVE_OPENEXR
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1200
|
||||
# pragma warning( disable: 4100 4244 4267 )
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && defined __APPLE__
|
||||
# pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
|
||||
#include <ImfHeader.h>
|
||||
#include <ImfInputFile.h>
|
||||
#include <ImfOutputFile.h>
|
||||
#include <ImfChannelList.h>
|
||||
#include <ImfStandardAttributes.h>
|
||||
#include <half.h>
|
||||
#include "grfmt_exr.hpp"
|
||||
|
||||
#if defined _WIN32
|
||||
|
||||
#undef UINT
|
||||
#define UINT ((Imf::PixelType)0)
|
||||
#undef HALF
|
||||
#define HALF ((Imf::PixelType)1)
|
||||
#undef FLOAT
|
||||
#define FLOAT ((Imf::PixelType)2)
|
||||
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/////////////////////// ExrDecoder ///////////////////
|
||||
|
||||
ExrDecoder::ExrDecoder()
|
||||
{
|
||||
m_signature = "\x76\x2f\x31\x01";
|
||||
m_file = 0;
|
||||
m_red = m_green = m_blue = 0;
|
||||
}
|
||||
|
||||
|
||||
ExrDecoder::~ExrDecoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void ExrDecoder::close()
|
||||
{
|
||||
if( m_file )
|
||||
{
|
||||
delete m_file;
|
||||
m_file = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ExrDecoder::type() const
|
||||
{
|
||||
return CV_MAKETYPE((m_isfloat ? CV_32F : CV_32S), m_iscolor ? 3 : 1);
|
||||
}
|
||||
|
||||
|
||||
bool ExrDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
m_file = new InputFile( m_filename.c_str() );
|
||||
|
||||
if( !m_file ) // probably paranoid
|
||||
return false;
|
||||
|
||||
m_datawindow = m_file->header().dataWindow();
|
||||
m_width = m_datawindow.max.x - m_datawindow.min.x + 1;
|
||||
m_height = m_datawindow.max.y - m_datawindow.min.y + 1;
|
||||
|
||||
// the type HALF is converted to 32 bit float
|
||||
// and the other types supported by OpenEXR are 32 bit anyway
|
||||
m_bit_depth = 32;
|
||||
|
||||
if( hasChromaticities( m_file->header() ))
|
||||
m_chroma = chromaticities( m_file->header() );
|
||||
|
||||
const ChannelList &channels = m_file->header().channels();
|
||||
m_red = channels.findChannel( "R" );
|
||||
m_green = channels.findChannel( "G" );
|
||||
m_blue = channels.findChannel( "B" );
|
||||
if( m_red || m_green || m_blue )
|
||||
{
|
||||
m_iscolor = true;
|
||||
m_ischroma = false;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_green = channels.findChannel( "Y" );
|
||||
if( m_green )
|
||||
{
|
||||
m_ischroma = true;
|
||||
m_red = channels.findChannel( "RY" );
|
||||
m_blue = channels.findChannel( "BY" );
|
||||
m_iscolor = (m_blue || m_red);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
}
|
||||
|
||||
if( result )
|
||||
{
|
||||
int uintcnt = 0;
|
||||
int chcnt = 0;
|
||||
if( m_red )
|
||||
{
|
||||
chcnt++;
|
||||
uintcnt += ( m_red->type == UINT );
|
||||
}
|
||||
if( m_green )
|
||||
{
|
||||
chcnt++;
|
||||
uintcnt += ( m_green->type == UINT );
|
||||
}
|
||||
if( m_blue )
|
||||
{
|
||||
chcnt++;
|
||||
uintcnt += ( m_blue->type == UINT );
|
||||
}
|
||||
m_type = (chcnt == uintcnt) ? UINT : FLOAT;
|
||||
|
||||
m_isfloat = (m_type == FLOAT);
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool ExrDecoder::readData( Mat& img )
|
||||
{
|
||||
m_native_depth = CV_MAT_DEPTH(type()) == img.depth();
|
||||
bool color = img.channels() > 1;
|
||||
|
||||
uchar* data = img.data;
|
||||
int step = img.step;
|
||||
bool justcopy = m_native_depth;
|
||||
bool chromatorgb = false;
|
||||
bool rgbtogray = false;
|
||||
bool result = true;
|
||||
FrameBuffer frame;
|
||||
int xsample[3] = {1, 1, 1};
|
||||
char *buffer;
|
||||
int xstep;
|
||||
int ystep;
|
||||
|
||||
xstep = m_native_depth ? 4 : 1;
|
||||
|
||||
if( !m_native_depth || (!color && m_iscolor ))
|
||||
{
|
||||
buffer = (char *)new float[ m_width * 3 ];
|
||||
ystep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = (char *)data;
|
||||
ystep = step;
|
||||
}
|
||||
|
||||
if( m_ischroma )
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( m_iscolor )
|
||||
{
|
||||
if( m_blue )
|
||||
{
|
||||
frame.insert( "BY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
|
||||
12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
|
||||
xsample[0] = m_blue->ySampling;
|
||||
}
|
||||
if( m_green )
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
|
||||
12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[1] = m_green->ySampling;
|
||||
}
|
||||
if( m_red )
|
||||
{
|
||||
frame.insert( "RY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
|
||||
12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
|
||||
xsample[2] = m_red->ySampling;
|
||||
}
|
||||
chromatorgb = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
|
||||
12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
|
||||
12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
|
||||
12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[0] = m_green->ySampling;
|
||||
xsample[1] = m_green->ySampling;
|
||||
xsample[2] = m_green->ySampling;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 4 - m_datawindow.min.y * ystep,
|
||||
4, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[0] = m_green->ySampling;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_blue )
|
||||
{
|
||||
frame.insert( "B", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
|
||||
12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
|
||||
xsample[0] = m_blue->ySampling;
|
||||
}
|
||||
if( m_green )
|
||||
{
|
||||
frame.insert( "G", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
|
||||
12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[1] = m_green->ySampling;
|
||||
}
|
||||
if( m_red )
|
||||
{
|
||||
frame.insert( "R", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
|
||||
12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
|
||||
xsample[2] = m_red->ySampling;
|
||||
}
|
||||
if(color == 0)
|
||||
{
|
||||
rgbtogray = true;
|
||||
justcopy = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_file->setFrameBuffer( frame );
|
||||
if( justcopy )
|
||||
{
|
||||
m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y );
|
||||
|
||||
if( color )
|
||||
{
|
||||
if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )
|
||||
UpSample( data, 3, step / xstep, xsample[0], m_blue->ySampling );
|
||||
if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSample( data + xstep, 3, step / xstep, xsample[1], m_green->ySampling );
|
||||
if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
|
||||
UpSample( data + 2 * xstep, 3, step / xstep, xsample[2], m_red->ySampling );
|
||||
}
|
||||
else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSample( data, 1, step / xstep, xsample[0], m_green->ySampling );
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar *out = data;
|
||||
int x, y;
|
||||
for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ )
|
||||
{
|
||||
m_file->readPixels( y, y );
|
||||
|
||||
if( rgbtogray )
|
||||
{
|
||||
if( xsample[0] != 1 )
|
||||
UpSampleX( (float *)buffer, 3, xsample[0] );
|
||||
if( xsample[1] != 1 )
|
||||
UpSampleX( (float *)buffer + 4, 3, xsample[1] );
|
||||
if( xsample[2] != 1 )
|
||||
UpSampleX( (float *)buffer + 8, 3, xsample[2] );
|
||||
|
||||
RGBToGray( (float *)buffer, (float *)out );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xsample[0] != 1 )
|
||||
UpSampleX( (float *)buffer, 3, xsample[0] );
|
||||
if( xsample[1] != 1 )
|
||||
UpSampleX( (float *)(buffer + 4), 3, xsample[1] );
|
||||
if( xsample[2] != 1 )
|
||||
UpSampleX( (float *)(buffer + 8), 3, xsample[2] );
|
||||
|
||||
if( chromatorgb )
|
||||
ChromaToBGR( (float *)buffer, 1, step );
|
||||
|
||||
if( m_type == FLOAT )
|
||||
{
|
||||
float *fi = (float *)buffer;
|
||||
for( x = 0; x < m_width * 3; x++)
|
||||
{
|
||||
out[x] = cv::saturate_cast<uchar>(fi[x]*5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned *ui = (unsigned *)buffer;
|
||||
for( x = 0; x < m_width * 3; x++)
|
||||
{
|
||||
out[x] = cv::saturate_cast<uchar>(ui[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out += step;
|
||||
}
|
||||
if( color )
|
||||
{
|
||||
if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )
|
||||
UpSampleY( data, 3, step / xstep, m_blue->ySampling );
|
||||
if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSampleY( data + xstep, 3, step / xstep, m_green->ySampling );
|
||||
if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
|
||||
UpSampleY( data + 2 * xstep, 3, step / xstep, m_red->ySampling );
|
||||
}
|
||||
else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSampleY( data, 1, step / xstep, m_green->ySampling );
|
||||
}
|
||||
|
||||
if( chromatorgb )
|
||||
ChromaToBGR( (float *)data, m_height, step / xstep );
|
||||
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
// on entry pixel values are stored packed in the upper left corner of the image
|
||||
// this functions expands them by duplication to cover the whole image
|
||||
*/
|
||||
void ExrDecoder::UpSample( uchar *data, int xstep, int ystep, int xsample, int ysample )
|
||||
{
|
||||
for( int y = (m_height - 1) / ysample, yre = m_height - ysample; y >= 0; y--, yre -= ysample )
|
||||
{
|
||||
for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample )
|
||||
{
|
||||
for( int i = 0; i < ysample; i++ )
|
||||
{
|
||||
for( int n = 0; n < xsample; n++ )
|
||||
{
|
||||
if( !m_native_depth )
|
||||
data[(yre + i) * ystep + (xre + n) * xstep] = data[y * ystep + x * xstep];
|
||||
else if( m_type == FLOAT )
|
||||
((float *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((float *)data)[y * ystep + x * xstep];
|
||||
else
|
||||
((unsigned *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((unsigned *)data)[y * ystep + x * xstep];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
// on entry pixel values are stored packed in the upper left corner of the image
|
||||
// this functions expands them by duplication to cover the whole image
|
||||
*/
|
||||
void ExrDecoder::UpSampleX( float *data, int xstep, int xsample )
|
||||
{
|
||||
for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample )
|
||||
{
|
||||
for( int n = 0; n < xsample; n++ )
|
||||
{
|
||||
if( m_type == FLOAT )
|
||||
((float *)data)[(xre + n) * xstep] = ((float *)data)[x * xstep];
|
||||
else
|
||||
((unsigned *)data)[(xre + n) * xstep] = ((unsigned *)data)[x * xstep];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
// on entry pixel values are stored packed in the upper left corner of the image
|
||||
// this functions expands them by duplication to cover the whole image
|
||||
*/
|
||||
void ExrDecoder::UpSampleY( uchar *data, int xstep, int ystep, int ysample )
|
||||
{
|
||||
for( int y = m_height - ysample, yre = m_height - ysample; y >= 0; y -= ysample, yre -= ysample )
|
||||
{
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
{
|
||||
for( int i = 1; i < ysample; i++ )
|
||||
{
|
||||
if( !m_native_depth )
|
||||
data[(yre + i) * ystep + x * xstep] = data[y * ystep + x * xstep];
|
||||
else if( m_type == FLOAT )
|
||||
((float *)data)[(yre + i) * ystep + x * xstep] = ((float *)data)[y * ystep + x * xstep];
|
||||
else
|
||||
((unsigned *)data)[(yre + i) * ystep + x * xstep] = ((unsigned *)data)[y * ystep + x * xstep];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
// algorithm from ImfRgbaYca.cpp
|
||||
*/
|
||||
void ExrDecoder::ChromaToBGR( float *data, int numlines, int step )
|
||||
{
|
||||
for( int y = 0; y < numlines; y++ )
|
||||
{
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
{
|
||||
double b, Y, r;
|
||||
if( !m_native_depth )
|
||||
{
|
||||
b = ((uchar *)data)[y * step + x * 3];
|
||||
Y = ((uchar *)data)[y * step + x * 3 + 1];
|
||||
r = ((uchar *)data)[y * step + x * 3 + 2];
|
||||
}
|
||||
else if( m_type == FLOAT )
|
||||
{
|
||||
b = data[y * step + x * 3];
|
||||
Y = data[y * step + x * 3 + 1];
|
||||
r = data[y * step + x * 3 + 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
b = ((unsigned *)data)[y * step + x * 3];
|
||||
Y = ((unsigned *)data)[y * step + x * 3 + 1];
|
||||
r = ((unsigned *)data)[y * step + x * 3 + 2];
|
||||
}
|
||||
r = (r + 1) * Y;
|
||||
b = (b + 1) * Y;
|
||||
Y = (Y - b * m_chroma.blue[1] - r * m_chroma.red[1]) / m_chroma.green[1];
|
||||
|
||||
if( !m_native_depth )
|
||||
{
|
||||
((uchar *)data)[y * step + x * 3 + 0] = cv::saturate_cast<uchar>(b);
|
||||
((uchar *)data)[y * step + x * 3 + 1] = cv::saturate_cast<uchar>(Y);
|
||||
((uchar *)data)[y * step + x * 3 + 2] = cv::saturate_cast<uchar>(r);
|
||||
}
|
||||
else if( m_type == FLOAT )
|
||||
{
|
||||
data[y * step + x * 3] = (float)b;
|
||||
data[y * step + x * 3 + 1] = (float)Y;
|
||||
data[y * step + x * 3 + 2] = (float)r;
|
||||
}
|
||||
else
|
||||
{
|
||||
int t = cvRound(b);
|
||||
((unsigned *)data)[y * step + x * 3 + 0] = (unsigned)MAX(t, 0);
|
||||
t = cvRound(Y);
|
||||
((unsigned *)data)[y * step + x * 3 + 1] = (unsigned)MAX(t, 0);
|
||||
t = cvRound(r);
|
||||
((unsigned *)data)[y * step + x * 3 + 2] = (unsigned)MAX(t, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
// convert one row to gray
|
||||
*/
|
||||
void ExrDecoder::RGBToGray( float *in, float *out )
|
||||
{
|
||||
if( m_type == FLOAT )
|
||||
{
|
||||
if( m_native_depth )
|
||||
{
|
||||
for( int i = 0, n = 0; i < m_width; i++, n += 3 )
|
||||
out[i] = in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar *o = (uchar *)out;
|
||||
for( int i = 0, n = 0; i < m_width; i++, n += 3 )
|
||||
o[i] = (uchar) (in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0]);
|
||||
}
|
||||
}
|
||||
else // UINT
|
||||
{
|
||||
if( m_native_depth )
|
||||
{
|
||||
unsigned *ui = (unsigned *)in;
|
||||
for( int i = 0; i < m_width * 3; i++ )
|
||||
ui[i] -= 0x80000000;
|
||||
int *si = (int *)in;
|
||||
for( int i = 0, n = 0; i < m_width; i++, n += 3 )
|
||||
((int *)out)[i] = int(si[n] * m_chroma.blue[0] + si[n + 1] * m_chroma.green[0] + si[n + 2] * m_chroma.red[0]);
|
||||
}
|
||||
else // how to best convert float to uchar?
|
||||
{
|
||||
unsigned *ui = (unsigned *)in;
|
||||
for( int i = 0, n = 0; i < m_width; i++, n += 3 )
|
||||
((uchar *)out)[i] = uchar((ui[n] * m_chroma.blue[0] + ui[n + 1] * m_chroma.green[0] + ui[n + 2] * m_chroma.red[0]) * (256.0 / 4294967296.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageDecoder ExrDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<ExrDecoder>();
|
||||
}
|
||||
|
||||
/////////////////////// ExrEncoder ///////////////////
|
||||
|
||||
|
||||
ExrEncoder::ExrEncoder()
|
||||
{
|
||||
m_description = "OpenEXR Image files (*.exr)";
|
||||
}
|
||||
|
||||
|
||||
ExrEncoder::~ExrEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool ExrEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return CV_MAT_DEPTH(depth) >= CV_8U && CV_MAT_DEPTH(depth) < CV_64F;
|
||||
}
|
||||
|
||||
|
||||
// TODO scale appropriately
|
||||
bool ExrEncoder::write( const Mat& img, const std::vector<int>& )
|
||||
{
|
||||
int width = img.cols, height = img.rows;
|
||||
int depth = img.depth(), channels = img.channels();
|
||||
bool result = false;
|
||||
bool issigned = depth == CV_8S || depth == CV_16S || depth == CV_32S;
|
||||
bool isfloat = depth == CV_32F || depth == CV_64F;
|
||||
depth = CV_ELEM_SIZE1(depth)*8;
|
||||
uchar* data = img.data;
|
||||
int step = img.step;
|
||||
|
||||
Header header( width, height );
|
||||
Imf::PixelType type;
|
||||
|
||||
if(depth == 8)
|
||||
type = HALF;
|
||||
else if(isfloat)
|
||||
type = FLOAT;
|
||||
else
|
||||
type = UINT;
|
||||
|
||||
if( channels == 3 )
|
||||
{
|
||||
header.channels().insert( "R", Channel( type ));
|
||||
header.channels().insert( "G", Channel( type ));
|
||||
header.channels().insert( "B", Channel( type ));
|
||||
//printf("bunt\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
header.channels().insert( "Y", Channel( type ));
|
||||
//printf("gray\n");
|
||||
}
|
||||
|
||||
OutputFile file( m_filename.c_str(), header );
|
||||
|
||||
FrameBuffer frame;
|
||||
|
||||
char *buffer;
|
||||
int bufferstep;
|
||||
int size;
|
||||
if( type == FLOAT && depth == 32 )
|
||||
{
|
||||
buffer = (char *)const_cast<uchar *>(data);
|
||||
bufferstep = step;
|
||||
size = 4;
|
||||
}
|
||||
else if( depth > 16 || type == UINT )
|
||||
{
|
||||
buffer = (char *)new unsigned[width * channels];
|
||||
bufferstep = 0;
|
||||
size = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = (char *)new half[width * channels];
|
||||
bufferstep = 0;
|
||||
size = 2;
|
||||
}
|
||||
|
||||
//printf("depth %d %s\n", depth, types[type]);
|
||||
|
||||
if( channels == 3 )
|
||||
{
|
||||
frame.insert( "B", Slice( type, buffer, size * 3, bufferstep ));
|
||||
frame.insert( "G", Slice( type, buffer + size, size * 3, bufferstep ));
|
||||
frame.insert( "R", Slice( type, buffer + size * 2, size * 3, bufferstep ));
|
||||
}
|
||||
else
|
||||
frame.insert( "Y", Slice( type, buffer, size, bufferstep ));
|
||||
|
||||
file.setFrameBuffer( frame );
|
||||
|
||||
int offset = issigned ? 1 << (depth - 1) : 0;
|
||||
|
||||
result = true;
|
||||
if( type == FLOAT && depth == 32 )
|
||||
{
|
||||
try
|
||||
{
|
||||
file.writePixels( height );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// int scale = 1 << (32 - depth);
|
||||
// printf("scale %d\n", scale);
|
||||
for(int line = 0; line < height; line++)
|
||||
{
|
||||
if(type == UINT)
|
||||
{
|
||||
unsigned *buf = (unsigned*)buffer; // FIXME 64-bit problems
|
||||
|
||||
if( depth <= 8 )
|
||||
{
|
||||
for(int i = 0; i < width * channels; i++)
|
||||
buf[i] = data[i] + offset;
|
||||
}
|
||||
else if( depth <= 16 )
|
||||
{
|
||||
unsigned short *sd = (unsigned short *)data;
|
||||
for(int i = 0; i < width * channels; i++)
|
||||
buf[i] = sd[i] + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
int *sd = (int *)data; // FIXME 64-bit problems
|
||||
for(int i = 0; i < width * channels; i++)
|
||||
buf[i] = (unsigned) sd[i] + offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
half *buf = (half *)buffer;
|
||||
|
||||
if( depth <= 8 )
|
||||
{
|
||||
for(int i = 0; i < width * channels; i++)
|
||||
buf[i] = data[i];
|
||||
}
|
||||
else if( depth <= 16 )
|
||||
{
|
||||
unsigned short *sd = (unsigned short *)data;
|
||||
for(int i = 0; i < width * channels; i++)
|
||||
buf[i] = sd[i];
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
file.writePixels( 1 );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
data += step;
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ImageEncoder ExrEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<ExrEncoder>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,117 +0,0 @@
|
||||
/*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_EXR_H_
|
||||
#define _GRFMT_EXR_H_
|
||||
|
||||
#ifdef HAVE_OPENEXR
|
||||
|
||||
#if defined __GNUC__ && defined __APPLE__
|
||||
# pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
|
||||
#include <ImfChromaticities.h>
|
||||
#include <ImfInputFile.h>
|
||||
#include <ImfChannelList.h>
|
||||
#include <ImathBox.h>
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
using namespace Imf;
|
||||
using namespace Imath;
|
||||
|
||||
/* libpng version only */
|
||||
|
||||
class ExrDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
ExrDecoder();
|
||||
~ExrDecoder();
|
||||
|
||||
int type() const;
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
void UpSample( uchar *data, int xstep, int ystep, int xsample, int ysample );
|
||||
void UpSampleX( float *data, int xstep, int xsample );
|
||||
void UpSampleY( uchar *data, int xstep, int ystep, int ysample );
|
||||
void ChromaToBGR( float *data, int numlines, int step );
|
||||
void RGBToGray( float *in, float *out );
|
||||
|
||||
InputFile *m_file;
|
||||
Imf::PixelType m_type;
|
||||
Box2i m_datawindow;
|
||||
bool m_ischroma;
|
||||
const Channel *m_red;
|
||||
const Channel *m_green;
|
||||
const Channel *m_blue;
|
||||
Chromaticities m_chroma;
|
||||
int m_bit_depth;
|
||||
bool m_native_depth;
|
||||
bool m_iscolor;
|
||||
bool m_isfloat;
|
||||
};
|
||||
|
||||
|
||||
class ExrEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
ExrEncoder();
|
||||
~ExrEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const;
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_EXR_H_*/
|
||||
@@ -1,164 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#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) {
|
||||
return false;
|
||||
}
|
||||
RGBE_ReadHeader(file, &m_width, &m_height, NULL);
|
||||
if(m_width <= 0 || m_height <= 0) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HdrDecoder::readData(Mat& _img)
|
||||
{
|
||||
Mat img(m_height, m_width, CV_32FC3);
|
||||
if(!file) {
|
||||
if(!readHeader()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
RGBE_ReadPixels_RLE(file, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
|
||||
fclose(file); file = NULL;
|
||||
|
||||
if(_img.depth() == img.depth()) {
|
||||
img.convertTo(_img, _img.type());
|
||||
} else {
|
||||
img.convertTo(_img, _img.type(), 255);
|
||||
}
|
||||
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()) ||
|
||||
!memcmp(signature.c_str(), m_signature_alt.c_str(), m_signature_alt.size())))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageDecoder HdrDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<HdrDecoder>();
|
||||
}
|
||||
|
||||
HdrEncoder::HdrEncoder()
|
||||
{
|
||||
m_description = "Radiance HDR (*.hdr;*.pic)";
|
||||
}
|
||||
|
||||
HdrEncoder::~HdrEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
bool HdrEncoder::write( const Mat& input_img, const std::vector<int>& params )
|
||||
{
|
||||
Mat img;
|
||||
CV_Assert(input_img.channels() == 3 || input_img.channels() == 1);
|
||||
if(input_img.channels() == 1) {
|
||||
std::vector<Mat> splitted(3, input_img);
|
||||
merge(splitted, img);
|
||||
} else {
|
||||
input_img.copyTo(img);
|
||||
}
|
||||
if(img.depth() != CV_32F) {
|
||||
img.convertTo(img, CV_32FC3, 1/255.0f);
|
||||
}
|
||||
CV_Assert(params.empty() || params[0] == HDR_NONE || params[0] == HDR_RLE);
|
||||
FILE *fout = fopen(m_filename.c_str(), "wb");
|
||||
if(!fout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 makePtr<HdrEncoder>();
|
||||
}
|
||||
|
||||
bool HdrEncoder::isFormatSupported( int depth ) const {
|
||||
return depth != CV_64F;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*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_*/
|
||||
@@ -1,676 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 "precomp.hpp"
|
||||
#include "grfmt_jpeg.hpp"
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning(disable: 4611)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
// the following defines are a hack to avoid multiple problems with frame ponter handling and setjmp
|
||||
// see http://gcc.gnu.org/ml/gcc/2011-10/msg00324.html for some details
|
||||
#define mingw_getsp(...) 0
|
||||
#define __builtin_frame_address(...) 0
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define XMD_H // prevent redefinition of INT32
|
||||
#undef FAR // prevent FAR redefinition
|
||||
|
||||
#endif
|
||||
|
||||
#if defined WIN32 && defined __GNUC__
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
|
||||
#undef FALSE
|
||||
#undef TRUE
|
||||
|
||||
extern "C" {
|
||||
#include "jpeglib.h"
|
||||
}
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4324) //structure was padded due to __declspec(align())
|
||||
#endif
|
||||
struct JpegErrorMgr
|
||||
{
|
||||
struct jpeg_error_mgr pub;
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct JpegSource
|
||||
{
|
||||
struct jpeg_source_mgr pub;
|
||||
int skip;
|
||||
};
|
||||
|
||||
struct JpegState
|
||||
{
|
||||
jpeg_decompress_struct cinfo; // IJG JPEG codec structure
|
||||
JpegErrorMgr jerr; // error processing manager state
|
||||
JpegSource source; // memory buffer source
|
||||
};
|
||||
|
||||
/////////////////////// Error processing /////////////////////
|
||||
|
||||
METHODDEF(void)
|
||||
stub(j_decompress_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
METHODDEF(boolean)
|
||||
fill_input_buffer(j_decompress_ptr)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// emulating memory input stream
|
||||
|
||||
METHODDEF(void)
|
||||
skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
JpegSource* source = (JpegSource*) cinfo->src;
|
||||
|
||||
if( num_bytes > (long)source->pub.bytes_in_buffer )
|
||||
{
|
||||
// We need to skip more data than we have in the buffer.
|
||||
// This will force the JPEG library to suspend decoding.
|
||||
source->skip = (int)(num_bytes - source->pub.bytes_in_buffer);
|
||||
source->pub.next_input_byte += source->pub.bytes_in_buffer;
|
||||
source->pub.bytes_in_buffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip portion of the buffer
|
||||
source->pub.bytes_in_buffer -= num_bytes;
|
||||
source->pub.next_input_byte += num_bytes;
|
||||
source->skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void jpeg_buffer_src(j_decompress_ptr cinfo, JpegSource* source)
|
||||
{
|
||||
cinfo->src = &source->pub;
|
||||
|
||||
// Prepare for suspending reader
|
||||
source->pub.init_source = stub;
|
||||
source->pub.fill_input_buffer = fill_input_buffer;
|
||||
source->pub.skip_input_data = skip_input_data;
|
||||
source->pub.resync_to_restart = jpeg_resync_to_restart;
|
||||
source->pub.term_source = stub;
|
||||
source->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read
|
||||
|
||||
source->skip = 0;
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
JpegErrorMgr* err_mgr = (JpegErrorMgr*)(cinfo->err);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp( err_mgr->setjmp_buffer, 1 );
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// JpegDecoder ///////////////////
|
||||
|
||||
|
||||
JpegDecoder::JpegDecoder()
|
||||
{
|
||||
m_signature = "\xFF\xD8\xFF";
|
||||
m_state = 0;
|
||||
m_f = 0;
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
JpegDecoder::~JpegDecoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void JpegDecoder::close()
|
||||
{
|
||||
if( m_state )
|
||||
{
|
||||
JpegState* state = (JpegState*)m_state;
|
||||
jpeg_destroy_decompress( &state->cinfo );
|
||||
delete state;
|
||||
m_state = 0;
|
||||
}
|
||||
|
||||
if( m_f )
|
||||
{
|
||||
fclose( m_f );
|
||||
m_f = 0;
|
||||
}
|
||||
|
||||
m_width = m_height = 0;
|
||||
m_type = -1;
|
||||
}
|
||||
|
||||
ImageDecoder JpegDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<JpegDecoder>();
|
||||
}
|
||||
|
||||
bool JpegDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
close();
|
||||
|
||||
JpegState* state = new JpegState;
|
||||
m_state = state;
|
||||
state->cinfo.err = jpeg_std_error(&state->jerr.pub);
|
||||
state->jerr.pub.error_exit = error_exit;
|
||||
|
||||
if( setjmp( state->jerr.setjmp_buffer ) == 0 )
|
||||
{
|
||||
jpeg_create_decompress( &state->cinfo );
|
||||
|
||||
if( !m_buf.empty() )
|
||||
{
|
||||
jpeg_buffer_src(&state->cinfo, &state->source);
|
||||
state->source.pub.next_input_byte = m_buf.data;
|
||||
state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_f = fopen( m_filename.c_str(), "rb" );
|
||||
if( m_f )
|
||||
jpeg_stdio_src( &state->cinfo, m_f );
|
||||
}
|
||||
|
||||
if (state->cinfo.src != 0)
|
||||
{
|
||||
jpeg_read_header( &state->cinfo, TRUE );
|
||||
|
||||
m_width = state->cinfo.image_width;
|
||||
m_height = state->cinfo.image_height;
|
||||
m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* following code is for supporting MJPEG image files
|
||||
* based on a message of Laurent Pinchart on the video4linux mailing list
|
||||
***************************************************************************/
|
||||
|
||||
/* JPEG DHT Segment for YCrCb omitted from MJPEG data */
|
||||
static
|
||||
unsigned char my_jpeg_odml_dht[0x1a4] = {
|
||||
0xff, 0xc4, 0x01, 0xa2,
|
||||
|
||||
0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
|
||||
0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
|
||||
0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
|
||||
0x04, 0x00, 0x00, 0x01, 0x7d,
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
|
||||
0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1,
|
||||
0x15, 0x52, 0xd1, 0xf0,
|
||||
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a,
|
||||
0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
|
||||
0x46, 0x47, 0x48, 0x49,
|
||||
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
|
||||
0x66, 0x67, 0x68, 0x69,
|
||||
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
|
||||
0x86, 0x87, 0x88, 0x89,
|
||||
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
|
||||
0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
|
||||
0xc2, 0xc3, 0xc4, 0xc5,
|
||||
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
|
||||
0xd9, 0xda, 0xe1, 0xe2,
|
||||
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
|
||||
0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa,
|
||||
|
||||
0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
|
||||
0x04, 0x00, 0x01, 0x02, 0x77,
|
||||
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
|
||||
0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
|
||||
0x23, 0x33, 0x52, 0xf0,
|
||||
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x26,
|
||||
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
|
||||
0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
|
||||
0x65, 0x66, 0x67, 0x68,
|
||||
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
|
||||
0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
|
||||
0xa2, 0xa3, 0xa4, 0xa5,
|
||||
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
|
||||
0xb9, 0xba, 0xc2, 0xc3,
|
||||
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
|
||||
0xd7, 0xd8, 0xd9, 0xda,
|
||||
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
|
||||
0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse the DHT table.
|
||||
* This code comes from jpeg6b (jdmarker.c).
|
||||
*/
|
||||
static
|
||||
int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
|
||||
JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
|
||||
{
|
||||
unsigned int length = (dht[2] << 8) + dht[3] - 2;
|
||||
unsigned int pos = 4;
|
||||
unsigned int count, i;
|
||||
int index;
|
||||
|
||||
JHUFF_TBL **hufftbl;
|
||||
unsigned char bits[17];
|
||||
unsigned char huffval[256];
|
||||
|
||||
while (length > 16)
|
||||
{
|
||||
bits[0] = 0;
|
||||
index = dht[pos++];
|
||||
count = 0;
|
||||
for (i = 1; i <= 16; ++i)
|
||||
{
|
||||
bits[i] = dht[pos++];
|
||||
count += bits[i];
|
||||
}
|
||||
length -= 17;
|
||||
|
||||
if (count > 256 || count > length)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
huffval[i] = dht[pos++];
|
||||
length -= count;
|
||||
|
||||
if (index & 0x10)
|
||||
{
|
||||
index -= 0x10;
|
||||
hufftbl = &ac_tables[index];
|
||||
}
|
||||
else
|
||||
hufftbl = &dc_tables[index];
|
||||
|
||||
if (index < 0 || index >= NUM_HUFF_TBLS)
|
||||
return -1;
|
||||
|
||||
if (*hufftbl == NULL)
|
||||
*hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
|
||||
if (*hufftbl == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
|
||||
memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* end of code for supportting MJPEG image files
|
||||
* based on a message of Laurent Pinchart on the video4linux mailing list
|
||||
***************************************************************************/
|
||||
|
||||
bool JpegDecoder::readData( Mat& img )
|
||||
{
|
||||
bool result = false;
|
||||
int step = (int)img.step;
|
||||
bool color = img.channels() > 1;
|
||||
|
||||
if( m_state && m_width && m_height )
|
||||
{
|
||||
jpeg_decompress_struct* cinfo = &((JpegState*)m_state)->cinfo;
|
||||
JpegErrorMgr* jerr = &((JpegState*)m_state)->jerr;
|
||||
JSAMPARRAY buffer = 0;
|
||||
|
||||
if( setjmp( jerr->setjmp_buffer ) == 0 )
|
||||
{
|
||||
/* check if this is a mjpeg image format */
|
||||
if ( cinfo->ac_huff_tbl_ptrs[0] == NULL &&
|
||||
cinfo->ac_huff_tbl_ptrs[1] == NULL &&
|
||||
cinfo->dc_huff_tbl_ptrs[0] == NULL &&
|
||||
cinfo->dc_huff_tbl_ptrs[1] == NULL )
|
||||
{
|
||||
/* yes, this is a mjpeg image format, so load the correct
|
||||
huffman table */
|
||||
my_jpeg_load_dht( cinfo,
|
||||
my_jpeg_odml_dht,
|
||||
cinfo->ac_huff_tbl_ptrs,
|
||||
cinfo->dc_huff_tbl_ptrs );
|
||||
}
|
||||
|
||||
if( color )
|
||||
{
|
||||
if( cinfo->num_components != 4 )
|
||||
{
|
||||
cinfo->out_color_space = JCS_RGB;
|
||||
cinfo->out_color_components = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
cinfo->out_color_space = JCS_CMYK;
|
||||
cinfo->out_color_components = 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cinfo->num_components != 4 )
|
||||
{
|
||||
cinfo->out_color_space = JCS_GRAYSCALE;
|
||||
cinfo->out_color_components = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cinfo->out_color_space = JCS_CMYK;
|
||||
cinfo->out_color_components = 4;
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_start_decompress( cinfo );
|
||||
|
||||
buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
|
||||
JPOOL_IMAGE, m_width*4, 1 );
|
||||
|
||||
uchar* data = img.data;
|
||||
for( ; m_height--; data += step )
|
||||
{
|
||||
jpeg_read_scanlines( cinfo, buffer, 1 );
|
||||
if( color )
|
||||
{
|
||||
if( cinfo->out_color_components == 3 )
|
||||
icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cinfo->out_color_components == 1 )
|
||||
memcpy( data, buffer[0], m_width );
|
||||
else
|
||||
icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
jpeg_finish_decompress( cinfo );
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// JpegEncoder ///////////////////
|
||||
|
||||
struct JpegDestination
|
||||
{
|
||||
struct jpeg_destination_mgr pub;
|
||||
std::vector<uchar> *buf, *dst;
|
||||
};
|
||||
|
||||
METHODDEF(void)
|
||||
stub(j_compress_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
term_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
JpegDestination* dest = (JpegDestination*)cinfo->dest;
|
||||
size_t sz = dest->dst->size(), bufsz = dest->buf->size() - dest->pub.free_in_buffer;
|
||||
if( bufsz > 0 )
|
||||
{
|
||||
dest->dst->resize(sz + bufsz);
|
||||
memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
|
||||
}
|
||||
}
|
||||
|
||||
METHODDEF(boolean)
|
||||
empty_output_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
JpegDestination* dest = (JpegDestination*)cinfo->dest;
|
||||
size_t sz = dest->dst->size(), bufsz = dest->buf->size();
|
||||
dest->dst->resize(sz + bufsz);
|
||||
memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
|
||||
|
||||
dest->pub.next_output_byte = &(*dest->buf)[0];
|
||||
dest->pub.free_in_buffer = bufsz;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void jpeg_buffer_dest(j_compress_ptr cinfo, JpegDestination* destination)
|
||||
{
|
||||
cinfo->dest = &destination->pub;
|
||||
|
||||
destination->pub.init_destination = stub;
|
||||
destination->pub.empty_output_buffer = empty_output_buffer;
|
||||
destination->pub.term_destination = term_destination;
|
||||
}
|
||||
|
||||
|
||||
JpegEncoder::JpegEncoder()
|
||||
{
|
||||
m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
JpegEncoder::~JpegEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageEncoder JpegEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<JpegEncoder>();
|
||||
}
|
||||
|
||||
bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
{
|
||||
m_last_error.clear();
|
||||
|
||||
struct fileWrapper
|
||||
{
|
||||
FILE* f;
|
||||
|
||||
fileWrapper() : f(0) {}
|
||||
~fileWrapper() { if(f) fclose(f); }
|
||||
};
|
||||
bool result = false;
|
||||
fileWrapper fw;
|
||||
int width = img.cols, height = img.rows;
|
||||
|
||||
std::vector<uchar> out_buf(1 << 12);
|
||||
AutoBuffer<uchar> _buffer;
|
||||
uchar* buffer;
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
JpegErrorMgr jerr;
|
||||
JpegDestination dest;
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = error_exit;
|
||||
|
||||
if( !m_buf )
|
||||
{
|
||||
fw.f = fopen( m_filename.c_str(), "wb" );
|
||||
if( !fw.f )
|
||||
goto _exit_;
|
||||
jpeg_stdio_dest( &cinfo, fw.f );
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.dst = m_buf;
|
||||
dest.buf = &out_buf;
|
||||
|
||||
jpeg_buffer_dest( &cinfo, &dest );
|
||||
|
||||
dest.pub.next_output_byte = &out_buf[0];
|
||||
dest.pub.free_in_buffer = out_buf.size();
|
||||
}
|
||||
|
||||
if( setjmp( jerr.setjmp_buffer ) == 0 )
|
||||
{
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
|
||||
int _channels = img.channels();
|
||||
int channels = _channels > 1 ? 3 : 1;
|
||||
cinfo.input_components = channels;
|
||||
cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
|
||||
|
||||
int quality = 95;
|
||||
int progressive = 0;
|
||||
int optimize = 0;
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
if( params[i] == CV_IMWRITE_JPEG_QUALITY )
|
||||
{
|
||||
quality = params[i+1];
|
||||
quality = MIN(MAX(quality, 0), 100);
|
||||
}
|
||||
|
||||
if( params[i] == CV_IMWRITE_JPEG_PROGRESSIVE )
|
||||
{
|
||||
progressive = params[i+1];
|
||||
}
|
||||
|
||||
if( params[i] == CV_IMWRITE_JPEG_OPTIMIZE )
|
||||
{
|
||||
optimize = params[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_set_defaults( &cinfo );
|
||||
jpeg_set_quality( &cinfo, quality,
|
||||
TRUE /* limit to baseline-JPEG values */ );
|
||||
if( progressive )
|
||||
jpeg_simple_progression( &cinfo );
|
||||
if( optimize )
|
||||
cinfo.optimize_coding = TRUE;
|
||||
jpeg_start_compress( &cinfo, TRUE );
|
||||
|
||||
if( channels > 1 )
|
||||
_buffer.allocate(width*channels);
|
||||
buffer = _buffer;
|
||||
|
||||
for( int y = 0; y < height; y++ )
|
||||
{
|
||||
uchar *data = img.data + img.step*y, *ptr = data;
|
||||
|
||||
if( _channels == 3 )
|
||||
{
|
||||
icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) );
|
||||
ptr = buffer;
|
||||
}
|
||||
else if( _channels == 4 )
|
||||
{
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, cvSize(width,1), 2 );
|
||||
ptr = buffer;
|
||||
}
|
||||
|
||||
jpeg_write_scanlines( &cinfo, &ptr, 1 );
|
||||
}
|
||||
|
||||
jpeg_finish_compress( &cinfo );
|
||||
result = true;
|
||||
}
|
||||
|
||||
_exit_:
|
||||
|
||||
if(!result)
|
||||
{
|
||||
char jmsg_buf[JMSG_LENGTH_MAX];
|
||||
jerr.pub.format_message((j_common_ptr)&cinfo, jmsg_buf);
|
||||
m_last_error = jmsg_buf;
|
||||
}
|
||||
|
||||
jpeg_destroy_compress( &cinfo );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,90 +0,0 @@
|
||||
/*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_JPEG_H_
|
||||
#define _GRFMT_JPEG_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
// IJG-based Jpeg codec
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class JpegDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
JpegDecoder();
|
||||
virtual ~JpegDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
|
||||
FILE* m_f;
|
||||
void* m_state;
|
||||
};
|
||||
|
||||
|
||||
class JpegEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
JpegEncoder();
|
||||
virtual ~JpegEncoder();
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_JPEG_H_*/
|
||||
@@ -1,523 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
|
||||
#ifdef HAVE_JASPER
|
||||
|
||||
#include "grfmt_jpeg2000.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#define JAS_WIN_MSVC_BUILD 1
|
||||
#ifdef __GNUC__
|
||||
#define HAVE_STDINT_H 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef VERSION
|
||||
|
||||
#include <jasper/jasper.h>
|
||||
// FIXME bad hack
|
||||
#undef uchar
|
||||
#undef ulong
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
struct JasperInitializer
|
||||
{
|
||||
JasperInitializer() { jas_init(); }
|
||||
~JasperInitializer() { jas_cleanup(); }
|
||||
};
|
||||
|
||||
static JasperInitializer initialize_jasper;
|
||||
|
||||
|
||||
/////////////////////// Jpeg2KDecoder ///////////////////
|
||||
|
||||
Jpeg2KDecoder::Jpeg2KDecoder()
|
||||
{
|
||||
m_signature = '\0' + String() + '\0' + String() + '\0' + String("\x0cjP \r\n\x87\n");
|
||||
m_stream = 0;
|
||||
m_image = 0;
|
||||
}
|
||||
|
||||
|
||||
Jpeg2KDecoder::~Jpeg2KDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KDecoder>();
|
||||
}
|
||||
|
||||
void Jpeg2KDecoder::close()
|
||||
{
|
||||
if( m_stream )
|
||||
{
|
||||
jas_stream_close( (jas_stream_t*)m_stream );
|
||||
m_stream = 0;
|
||||
}
|
||||
|
||||
if( m_image )
|
||||
{
|
||||
jas_image_destroy( (jas_image_t*)m_image );
|
||||
m_image = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
close();
|
||||
jas_stream_t* stream = jas_stream_fopen( m_filename.c_str(), "rb" );
|
||||
m_stream = stream;
|
||||
|
||||
if( stream )
|
||||
{
|
||||
jas_image_t* image = jas_image_decode( stream, -1, 0 );
|
||||
m_image = image;
|
||||
if( image ) {
|
||||
m_width = jas_image_width( image );
|
||||
m_height = jas_image_height( image );
|
||||
|
||||
int cntcmpts = 0; // count the known components
|
||||
int numcmpts = jas_image_numcmpts( image );
|
||||
int depth = 0;
|
||||
for( int i = 0; i < numcmpts; i++ )
|
||||
{
|
||||
int depth_i = jas_image_cmptprec( image, i );
|
||||
depth = MAX(depth, depth_i);
|
||||
if( jas_image_cmpttype( image, i ) > 2 )
|
||||
continue;
|
||||
cntcmpts++;
|
||||
}
|
||||
|
||||
if( cntcmpts )
|
||||
{
|
||||
m_type = CV_MAKETYPE(depth <= 8 ? CV_8U : CV_16U, cntcmpts > 1 ? 3 : 1);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readData( Mat& img )
|
||||
{
|
||||
bool result = false;
|
||||
int color = img.channels() > 1;
|
||||
uchar* data = img.data;
|
||||
int step = (int)img.step;
|
||||
jas_stream_t* stream = (jas_stream_t*)m_stream;
|
||||
jas_image_t* image = (jas_image_t*)m_image;
|
||||
|
||||
if( stream && image )
|
||||
{
|
||||
bool convert;
|
||||
int colorspace;
|
||||
if( color )
|
||||
{
|
||||
convert = (jas_image_clrspc( image ) != JAS_CLRSPC_SRGB);
|
||||
colorspace = JAS_CLRSPC_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
convert = (jas_clrspc_fam( jas_image_clrspc( image ) ) != JAS_CLRSPC_FAM_GRAY);
|
||||
colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY?
|
||||
}
|
||||
|
||||
// convert to the desired colorspace
|
||||
if( convert )
|
||||
{
|
||||
jas_cmprof_t *clrprof = jas_cmprof_createfromclrspc( colorspace );
|
||||
if( clrprof )
|
||||
{
|
||||
jas_image_t *_img = jas_image_chclrspc( image, clrprof, JAS_CMXFORM_INTENT_RELCLR );
|
||||
if( _img )
|
||||
{
|
||||
jas_image_destroy( image );
|
||||
m_image = image = _img;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n");
|
||||
jas_cmprof_destroy( clrprof );
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n");
|
||||
}
|
||||
else
|
||||
result = true;
|
||||
|
||||
if( result )
|
||||
{
|
||||
int ncmpts;
|
||||
int cmptlut[3];
|
||||
if( color )
|
||||
{
|
||||
cmptlut[0] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_B );
|
||||
cmptlut[1] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_G );
|
||||
cmptlut[2] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_RGB_R );
|
||||
if( cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[2] < 0 )
|
||||
result = false;
|
||||
ncmpts = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmptlut[0] = jas_image_getcmptbytype( image, JAS_IMAGE_CT_GRAY_Y );
|
||||
if( cmptlut[0] < 0 )
|
||||
result = false;
|
||||
ncmpts = 1;
|
||||
}
|
||||
|
||||
if( result )
|
||||
{
|
||||
for( int i = 0; i < ncmpts; i++ )
|
||||
{
|
||||
int maxval = 1 << jas_image_cmptprec( image, cmptlut[i] );
|
||||
int offset = jas_image_cmptsgnd( image, cmptlut[i] ) ? maxval / 2 : 0;
|
||||
|
||||
int yend = jas_image_cmptbry( image, cmptlut[i] );
|
||||
int ystep = jas_image_cmptvstep( image, cmptlut[i] );
|
||||
int xend = jas_image_cmptbrx( image, cmptlut[i] );
|
||||
int xstep = jas_image_cmpthstep( image, cmptlut[i] );
|
||||
|
||||
jas_matrix_t *buffer = jas_matrix_create( yend / ystep, xend / xstep );
|
||||
if( buffer )
|
||||
{
|
||||
if( !jas_image_readcmpt( image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer ))
|
||||
{
|
||||
if( img.depth() == CV_8U )
|
||||
result = readComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts );
|
||||
else
|
||||
result = readComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts );
|
||||
if( !result )
|
||||
{
|
||||
i = ncmpts;
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
jas_matrix_destroy( buffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" );
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readComponent8u( uchar *data, void *_buffer,
|
||||
int step, int cmpt,
|
||||
int maxval, int offset, int ncmpts )
|
||||
{
|
||||
jas_matrix_t* buffer = (jas_matrix_t*)_buffer;
|
||||
jas_image_t* image = (jas_image_t*)m_image;
|
||||
int xstart = jas_image_cmpttlx( image, cmpt );
|
||||
int xend = jas_image_cmptbrx( image, cmpt );
|
||||
int xstep = jas_image_cmpthstep( image, cmpt );
|
||||
int xoffset = jas_image_tlx( image );
|
||||
int ystart = jas_image_cmpttly( image, cmpt );
|
||||
int yend = jas_image_cmptbry( image, cmpt );
|
||||
int ystep = jas_image_cmptvstep( image, cmpt );
|
||||
int yoffset = jas_image_tly( image );
|
||||
int x, y, x1, y1, j;
|
||||
int rshift = cvRound(std::log(maxval/256.)/std::log(2.));
|
||||
int lshift = MAX(0, -rshift);
|
||||
rshift = MAX(0, rshift);
|
||||
int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset;
|
||||
|
||||
for( y = 0; y < yend - ystart; )
|
||||
{
|
||||
jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 );
|
||||
uchar* dst = data + (y - yoffset) * step - xoffset;
|
||||
|
||||
if( xstep == 1 )
|
||||
{
|
||||
if( maxval == 256 && offset == 0 )
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
{
|
||||
int pix = pix_row[x];
|
||||
dst[x*ncmpts] = cv::saturate_cast<uchar>(pix);
|
||||
}
|
||||
else
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
{
|
||||
int pix = ((pix_row[x] + delta) >> rshift) << lshift;
|
||||
dst[x*ncmpts] = cv::saturate_cast<uchar>(pix);
|
||||
}
|
||||
}
|
||||
else if( xstep == 2 && offset == 0 )
|
||||
for( x = 0, j = 0; x < xend - xstart; x += 2, j++ )
|
||||
{
|
||||
int pix = ((pix_row[j] + delta) >> rshift) << lshift;
|
||||
dst[x*ncmpts] = dst[(x+1)*ncmpts] = cv::saturate_cast<uchar>(pix);
|
||||
}
|
||||
else
|
||||
for( x = 0, j = 0; x < xend - xstart; j++ )
|
||||
{
|
||||
int pix = ((pix_row[j] + delta) >> rshift) << lshift;
|
||||
pix = cv::saturate_cast<uchar>(pix);
|
||||
for( x1 = x + xstep; x < x1; x++ )
|
||||
dst[x*ncmpts] = (uchar)pix;
|
||||
}
|
||||
y1 = y + ystep;
|
||||
for( ++y; y < y1; y++, dst += step )
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
dst[x*ncmpts + step] = dst[x*ncmpts];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readComponent16u( unsigned short *data, void *_buffer,
|
||||
int step, int cmpt,
|
||||
int maxval, int offset, int ncmpts )
|
||||
{
|
||||
jas_matrix_t* buffer = (jas_matrix_t*)_buffer;
|
||||
jas_image_t* image = (jas_image_t*)m_image;
|
||||
int xstart = jas_image_cmpttlx( image, cmpt );
|
||||
int xend = jas_image_cmptbrx( image, cmpt );
|
||||
int xstep = jas_image_cmpthstep( image, cmpt );
|
||||
int xoffset = jas_image_tlx( image );
|
||||
int ystart = jas_image_cmpttly( image, cmpt );
|
||||
int yend = jas_image_cmptbry( image, cmpt );
|
||||
int ystep = jas_image_cmptvstep( image, cmpt );
|
||||
int yoffset = jas_image_tly( image );
|
||||
int x, y, x1, y1, j;
|
||||
int rshift = cvRound(std::log(maxval/65536.)/std::log(2.));
|
||||
int lshift = MAX(0, -rshift);
|
||||
rshift = MAX(0, rshift);
|
||||
int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset;
|
||||
|
||||
for( y = 0; y < yend - ystart; )
|
||||
{
|
||||
jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 );
|
||||
ushort* dst = data + (y - yoffset) * step - xoffset;
|
||||
|
||||
if( xstep == 1 )
|
||||
{
|
||||
if( maxval == 65536 && offset == 0 )
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
{
|
||||
int pix = pix_row[x];
|
||||
dst[x*ncmpts] = cv::saturate_cast<ushort>(pix);
|
||||
}
|
||||
else
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
{
|
||||
int pix = ((pix_row[x] + delta) >> rshift) << lshift;
|
||||
dst[x*ncmpts] = cv::saturate_cast<ushort>(pix);
|
||||
}
|
||||
}
|
||||
else if( xstep == 2 && offset == 0 )
|
||||
for( x = 0, j = 0; x < xend - xstart; x += 2, j++ )
|
||||
{
|
||||
int pix = ((pix_row[j] + delta) >> rshift) << lshift;
|
||||
dst[x*ncmpts] = dst[(x+1)*ncmpts] = cv::saturate_cast<ushort>(pix);
|
||||
}
|
||||
else
|
||||
for( x = 0, j = 0; x < xend - xstart; j++ )
|
||||
{
|
||||
int pix = ((pix_row[j] + delta) >> rshift) << lshift;
|
||||
pix = cv::saturate_cast<ushort>(pix);
|
||||
for( x1 = x + xstep; x < x1; x++ )
|
||||
dst[x*ncmpts] = (ushort)pix;
|
||||
}
|
||||
y1 = y + ystep;
|
||||
for( ++y; y < y1; y++, dst += step )
|
||||
for( x = 0; x < xend - xstart; x++ )
|
||||
dst[x*ncmpts + step] = dst[x*ncmpts];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// Jpeg2KEncoder ///////////////////
|
||||
|
||||
|
||||
Jpeg2KEncoder::Jpeg2KEncoder()
|
||||
{
|
||||
m_description = "JPEG-2000 files (*.jp2)";
|
||||
}
|
||||
|
||||
|
||||
Jpeg2KEncoder::~Jpeg2KEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageEncoder Jpeg2KEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KEncoder>();
|
||||
}
|
||||
|
||||
bool Jpeg2KEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return depth == CV_8U || depth == CV_16U;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KEncoder::write( const Mat& _img, const std::vector<int>& )
|
||||
{
|
||||
int width = _img.cols, height = _img.rows;
|
||||
int depth = _img.depth(), channels = _img.channels();
|
||||
depth = depth == CV_8U ? 8 : 16;
|
||||
|
||||
if( channels > 3 || channels < 1 )
|
||||
return false;
|
||||
|
||||
jas_image_cmptparm_t component_info[3];
|
||||
for( int i = 0; i < channels; i++ )
|
||||
{
|
||||
component_info[i].tlx = 0;
|
||||
component_info[i].tly = 0;
|
||||
component_info[i].hstep = 1;
|
||||
component_info[i].vstep = 1;
|
||||
component_info[i].width = width;
|
||||
component_info[i].height = height;
|
||||
component_info[i].prec = depth;
|
||||
component_info[i].sgnd = 0;
|
||||
}
|
||||
jas_image_t *img = jas_image_create( channels, component_info, (channels == 1) ? JAS_CLRSPC_SGRAY : JAS_CLRSPC_SRGB );
|
||||
if( !img )
|
||||
return false;
|
||||
|
||||
if(channels == 1)
|
||||
jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_GRAY_Y );
|
||||
else
|
||||
{
|
||||
jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_RGB_B );
|
||||
jas_image_setcmpttype( img, 1, JAS_IMAGE_CT_RGB_G );
|
||||
jas_image_setcmpttype( img, 2, JAS_IMAGE_CT_RGB_R );
|
||||
}
|
||||
|
||||
bool result;
|
||||
if( depth == 8 )
|
||||
result = writeComponent8u( img, _img );
|
||||
else
|
||||
result = writeComponent16u( img, _img );
|
||||
if( result )
|
||||
{
|
||||
jas_stream_t *stream = jas_stream_fopen( m_filename.c_str(), "wb" );
|
||||
if( stream )
|
||||
{
|
||||
result = !jas_image_encode( img, stream, jas_image_strtofmt( (char*)"jp2" ), (char*)"" );
|
||||
|
||||
jas_stream_close( stream );
|
||||
}
|
||||
|
||||
}
|
||||
jas_image_destroy( img );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KEncoder::writeComponent8u( void *__img, const Mat& _img )
|
||||
{
|
||||
jas_image_t* img = (jas_image_t*)__img;
|
||||
int w = _img.cols, h = _img.rows, ncmpts = _img.channels();
|
||||
jas_matrix_t *row = jas_matrix_create( 1, w );
|
||||
if(!row)
|
||||
return false;
|
||||
|
||||
for( int y = 0; y < h; y++ )
|
||||
{
|
||||
uchar* data = _img.data + _img.step*y;
|
||||
for( int i = 0; i < ncmpts; i++ )
|
||||
{
|
||||
for( int x = 0; x < w; x++)
|
||||
jas_matrix_setv( row, x, data[x * ncmpts + i] );
|
||||
jas_image_writecmpt( img, i, 0, y, w, 1, row );
|
||||
}
|
||||
}
|
||||
|
||||
jas_matrix_destroy( row );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KEncoder::writeComponent16u( void *__img, const Mat& _img )
|
||||
{
|
||||
jas_image_t* img = (jas_image_t*)__img;
|
||||
int w = _img.cols, h = _img.rows, ncmpts = _img.channels();
|
||||
jas_matrix_t *row = jas_matrix_create( 1, w );
|
||||
if(!row)
|
||||
return false;
|
||||
|
||||
for( int y = 0; y < h; y++ )
|
||||
{
|
||||
uchar* data = _img.data + _img.step*y;
|
||||
for( int i = 0; i < ncmpts; i++ )
|
||||
{
|
||||
for( int x = 0; x < w; x++)
|
||||
jas_matrix_setv( row, x, data[x * ncmpts + i] );
|
||||
jas_image_writecmpt( img, i, 0, y, w, 1, row );
|
||||
}
|
||||
}
|
||||
|
||||
jas_matrix_destroy( row );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,95 +0,0 @@
|
||||
/*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_JASPER_H_
|
||||
#define _GRFMT_JASPER_H_
|
||||
|
||||
#ifdef HAVE_JASPER
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class Jpeg2KDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
Jpeg2KDecoder();
|
||||
virtual ~Jpeg2KDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
bool readComponent8u( uchar *data, void *buffer, int step, int cmpt,
|
||||
int maxval, int offset, int ncmpts );
|
||||
bool readComponent16u( unsigned short *data, void *buffer, int step, int cmpt,
|
||||
int maxval, int offset, int ncmpts );
|
||||
|
||||
void *m_stream;
|
||||
void *m_image;
|
||||
};
|
||||
|
||||
|
||||
class Jpeg2KEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
Jpeg2KEncoder();
|
||||
virtual ~Jpeg2KEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const;
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
ImageEncoder newEncoder() const;
|
||||
|
||||
protected:
|
||||
bool writeComponent8u( void *img, const Mat& _img );
|
||||
bool writeComponent16u( void *img, const Mat& _img );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_JASPER_H_*/
|
||||
@@ -1,449 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
/****************************************************************************************\
|
||||
This part of the file implements PNG codec on base of libpng library,
|
||||
in particular, this code is based on example.c from libpng
|
||||
(see otherlibs/_graphics/readme.txt for copyright notice)
|
||||
and png2bmp sample from libpng distribution (Copyright (C) 1999-2001 MIYASAKA Masaru)
|
||||
\****************************************************************************************/
|
||||
|
||||
#ifndef _LFS64_LARGEFILE
|
||||
# define _LFS64_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBPNG_PNG_H
|
||||
#include <libpng/png.h>
|
||||
#else
|
||||
#include <png.h>
|
||||
#endif
|
||||
#include <zlib.h>
|
||||
|
||||
#include "grfmt_png.hpp"
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1200
|
||||
// interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable: 4611 )
|
||||
#endif
|
||||
|
||||
// the following defines are a hack to avoid multiple problems with frame ponter handling and setjmp
|
||||
// see http://gcc.gnu.org/ml/gcc/2011-10/msg00324.html for some details
|
||||
#define mingw_getsp(...) 0
|
||||
#define __builtin_frame_address(...) 0
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/////////////////////// PngDecoder ///////////////////
|
||||
|
||||
PngDecoder::PngDecoder()
|
||||
{
|
||||
m_signature = "\x89\x50\x4e\x47\xd\xa\x1a\xa";
|
||||
m_color_type = 0;
|
||||
m_png_ptr = 0;
|
||||
m_info_ptr = m_end_info = 0;
|
||||
m_f = 0;
|
||||
m_buf_supported = true;
|
||||
m_buf_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
PngDecoder::~PngDecoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
ImageDecoder PngDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<PngDecoder>();
|
||||
}
|
||||
|
||||
void PngDecoder::close()
|
||||
{
|
||||
if( m_f )
|
||||
{
|
||||
fclose( m_f );
|
||||
m_f = 0;
|
||||
}
|
||||
|
||||
if( m_png_ptr )
|
||||
{
|
||||
png_structp png_ptr = (png_structp)m_png_ptr;
|
||||
png_infop info_ptr = (png_infop)m_info_ptr;
|
||||
png_infop end_info = (png_infop)m_end_info;
|
||||
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
|
||||
m_png_ptr = m_info_ptr = m_end_info = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PngDecoder::readDataFromBuf( void* _png_ptr, uchar* dst, size_t size )
|
||||
{
|
||||
png_structp png_ptr = (png_structp)_png_ptr;
|
||||
PngDecoder* decoder = (PngDecoder*)(png_get_io_ptr(png_ptr));
|
||||
CV_Assert( decoder );
|
||||
const Mat& buf = decoder->m_buf;
|
||||
if( decoder->m_buf_pos + size > buf.cols*buf.rows*buf.elemSize() )
|
||||
{
|
||||
png_error(png_ptr, "PNG input buffer is incomplete");
|
||||
return;
|
||||
}
|
||||
memcpy( dst, &decoder->m_buf.data[decoder->m_buf_pos], size );
|
||||
decoder->m_buf_pos += size;
|
||||
}
|
||||
|
||||
bool PngDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
close();
|
||||
|
||||
png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
|
||||
|
||||
if( png_ptr )
|
||||
{
|
||||
png_infop info_ptr = png_create_info_struct( png_ptr );
|
||||
png_infop end_info = png_create_info_struct( png_ptr );
|
||||
|
||||
m_png_ptr = png_ptr;
|
||||
m_info_ptr = info_ptr;
|
||||
m_end_info = end_info;
|
||||
m_buf_pos = 0;
|
||||
|
||||
if( info_ptr && end_info )
|
||||
{
|
||||
if( setjmp( png_jmpbuf( png_ptr ) ) == 0 )
|
||||
{
|
||||
if( !m_buf.empty() )
|
||||
png_set_read_fn(png_ptr, this, (png_rw_ptr)readDataFromBuf );
|
||||
else
|
||||
{
|
||||
m_f = fopen( m_filename.c_str(), "rb" );
|
||||
if( m_f )
|
||||
png_init_io( png_ptr, m_f );
|
||||
}
|
||||
|
||||
if( !m_buf.empty() || m_f )
|
||||
{
|
||||
png_uint_32 wdth, hght;
|
||||
int bit_depth, color_type, num_trans=0;
|
||||
png_bytep trans;
|
||||
png_color_16p trans_values;
|
||||
|
||||
png_read_info( png_ptr, info_ptr );
|
||||
|
||||
png_get_IHDR( png_ptr, info_ptr, &wdth, &hght,
|
||||
&bit_depth, &color_type, 0, 0, 0 );
|
||||
|
||||
m_width = (int)wdth;
|
||||
m_height = (int)hght;
|
||||
m_color_type = color_type;
|
||||
m_bit_depth = bit_depth;
|
||||
|
||||
if( bit_depth <= 8 || bit_depth == 16 )
|
||||
{
|
||||
switch(color_type)
|
||||
{
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
m_type = CV_8UC3;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
png_get_tRNS( png_ptr, info_ptr, &trans, &num_trans, &trans_values);
|
||||
//Check if there is a transparency value in the palette
|
||||
if ( num_trans > 0 )
|
||||
m_type = CV_8UC4;
|
||||
else
|
||||
m_type = CV_8UC3;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
m_type = CV_8UC4;
|
||||
break;
|
||||
default:
|
||||
m_type = CV_8UC1;
|
||||
}
|
||||
if( bit_depth == 16 )
|
||||
m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool PngDecoder::readData( Mat& img )
|
||||
{
|
||||
bool result = false;
|
||||
AutoBuffer<uchar*> _buffer(m_height);
|
||||
uchar** buffer = _buffer;
|
||||
int color = img.channels() > 1;
|
||||
uchar* data = img.data;
|
||||
int step = (int)img.step;
|
||||
|
||||
if( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height )
|
||||
{
|
||||
png_structp png_ptr = (png_structp)m_png_ptr;
|
||||
png_infop info_ptr = (png_infop)m_info_ptr;
|
||||
png_infop end_info = (png_infop)m_end_info;
|
||||
|
||||
if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 )
|
||||
{
|
||||
int y;
|
||||
|
||||
if( img.depth() == CV_8U && m_bit_depth == 16 )
|
||||
png_set_strip_16( png_ptr );
|
||||
else if( !isBigEndian() )
|
||||
png_set_swap( png_ptr );
|
||||
|
||||
if(img.channels() < 4)
|
||||
{
|
||||
/* observation: png_read_image() writes 400 bytes beyond
|
||||
* end of data when reading a 400x118 color png
|
||||
* "mpplus_sand.png". OpenCV crashes even with demo
|
||||
* programs. Looking at the loaded image I'd say we get 4
|
||||
* bytes per pixel instead of 3 bytes per pixel. Test
|
||||
* indicate that it is a good idea to always ask for
|
||||
* stripping alpha.. 18.11.2004 Axel Walthelm
|
||||
*/
|
||||
png_set_strip_alpha( png_ptr );
|
||||
}
|
||||
|
||||
if( m_color_type == PNG_COLOR_TYPE_PALETTE )
|
||||
png_set_palette_to_rgb( png_ptr );
|
||||
|
||||
if( m_color_type == PNG_COLOR_TYPE_GRAY && m_bit_depth < 8 )
|
||||
#if (PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE >= 10209) || \
|
||||
(PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR == 0 && PNG_LIBPNG_VER_RELEASE >= 18)
|
||||
png_set_expand_gray_1_2_4_to_8( png_ptr );
|
||||
#else
|
||||
png_set_gray_1_2_4_to_8( png_ptr );
|
||||
#endif
|
||||
|
||||
if( CV_MAT_CN(m_type) > 1 && color )
|
||||
png_set_bgr( png_ptr ); // convert RGB to BGR
|
||||
else if( color )
|
||||
png_set_gray_to_rgb( png_ptr ); // Gray->RGB
|
||||
else
|
||||
png_set_rgb_to_gray( png_ptr, 1, 0.299, 0.587 ); // RGB->Gray
|
||||
|
||||
png_set_interlace_handling( png_ptr );
|
||||
png_read_update_info( png_ptr, info_ptr );
|
||||
|
||||
for( y = 0; y < m_height; y++ )
|
||||
buffer[y] = data + y*step;
|
||||
|
||||
png_read_image( png_ptr, buffer );
|
||||
png_read_end( png_ptr, end_info );
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// PngEncoder ///////////////////
|
||||
|
||||
|
||||
PngEncoder::PngEncoder()
|
||||
{
|
||||
m_description = "Portable Network Graphics files (*.png)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
PngEncoder::~PngEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PngEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return depth == CV_8U || depth == CV_16U;
|
||||
}
|
||||
|
||||
ImageEncoder PngEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<PngEncoder>();
|
||||
}
|
||||
|
||||
|
||||
void PngEncoder::writeDataToBuf(void* _png_ptr, uchar* src, size_t size)
|
||||
{
|
||||
if( size == 0 )
|
||||
return;
|
||||
png_structp png_ptr = (png_structp)_png_ptr;
|
||||
PngEncoder* encoder = (PngEncoder*)(png_get_io_ptr(png_ptr));
|
||||
CV_Assert( encoder && encoder->m_buf );
|
||||
size_t cursz = encoder->m_buf->size();
|
||||
encoder->m_buf->resize(cursz + size);
|
||||
memcpy( &(*encoder->m_buf)[cursz], src, size );
|
||||
}
|
||||
|
||||
|
||||
void PngEncoder::flushBuf(void*)
|
||||
{
|
||||
}
|
||||
|
||||
bool PngEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
{
|
||||
png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
|
||||
png_infop info_ptr = 0;
|
||||
FILE* f = 0;
|
||||
int y, width = img.cols, height = img.rows;
|
||||
int depth = img.depth(), channels = img.channels();
|
||||
bool result = false;
|
||||
AutoBuffer<uchar*> buffer;
|
||||
|
||||
if( depth != CV_8U && depth != CV_16U )
|
||||
return false;
|
||||
|
||||
if( png_ptr )
|
||||
{
|
||||
info_ptr = png_create_info_struct( png_ptr );
|
||||
|
||||
if( info_ptr )
|
||||
{
|
||||
if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 )
|
||||
{
|
||||
if( m_buf )
|
||||
{
|
||||
png_set_write_fn(png_ptr, this,
|
||||
(png_rw_ptr)writeDataToBuf, (png_flush_ptr)flushBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
f = fopen( m_filename.c_str(), "wb" );
|
||||
if( f )
|
||||
png_init_io( png_ptr, f );
|
||||
}
|
||||
|
||||
int compression_level = -1; // Invalid value to allow setting 0-9 as valid
|
||||
int compression_strategy = Z_RLE; // Default strategy
|
||||
bool isBilevel = false;
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
if( params[i] == CV_IMWRITE_PNG_COMPRESSION )
|
||||
{
|
||||
compression_level = params[i+1];
|
||||
compression_level = MIN(MAX(compression_level, 0), Z_BEST_COMPRESSION);
|
||||
}
|
||||
if( params[i] == CV_IMWRITE_PNG_STRATEGY )
|
||||
{
|
||||
compression_strategy = params[i+1];
|
||||
compression_strategy = MIN(MAX(compression_strategy, 0), Z_FIXED);
|
||||
}
|
||||
if( params[i] == CV_IMWRITE_PNG_BILEVEL )
|
||||
{
|
||||
isBilevel = params[i+1] != 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_buf || f )
|
||||
{
|
||||
if( compression_level >= 0 )
|
||||
{
|
||||
png_set_compression_level( png_ptr, compression_level );
|
||||
}
|
||||
else
|
||||
{
|
||||
// tune parameters for speed
|
||||
// (see http://wiki.linuxquestions.org/wiki/Libpng)
|
||||
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB);
|
||||
png_set_compression_level(png_ptr, Z_BEST_SPEED);
|
||||
}
|
||||
png_set_compression_strategy(png_ptr, compression_strategy);
|
||||
|
||||
png_set_IHDR( png_ptr, info_ptr, width, height, depth == CV_8U ? isBilevel?1:8 : 16,
|
||||
channels == 1 ? PNG_COLOR_TYPE_GRAY :
|
||||
channels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT );
|
||||
|
||||
png_write_info( png_ptr, info_ptr );
|
||||
|
||||
if (isBilevel)
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
png_set_bgr( png_ptr );
|
||||
if( !isBigEndian() )
|
||||
png_set_swap( png_ptr );
|
||||
|
||||
buffer.allocate(height);
|
||||
for( y = 0; y < height; y++ )
|
||||
buffer[y] = img.data + y*img.step;
|
||||
|
||||
png_write_image( png_ptr, buffer );
|
||||
png_write_end( png_ptr, info_ptr );
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
png_destroy_write_struct( &png_ptr, &info_ptr );
|
||||
if(f) fclose( f );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,101 +0,0 @@
|
||||
/*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_PNG_H_
|
||||
#define _GRFMT_PNG_H_
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class PngDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
PngDecoder();
|
||||
virtual ~PngDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
|
||||
static void readDataFromBuf(void* png_ptr, uchar* dst, size_t size);
|
||||
|
||||
int m_bit_depth;
|
||||
void* m_png_ptr; // pointer to decompression structure
|
||||
void* m_info_ptr; // pointer to image information structure
|
||||
void* m_end_info; // pointer to one more image information structure
|
||||
FILE* m_f;
|
||||
int m_color_type;
|
||||
size_t m_buf_pos;
|
||||
};
|
||||
|
||||
|
||||
class PngEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PngEncoder();
|
||||
virtual ~PngEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const;
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
|
||||
ImageEncoder newEncoder() const;
|
||||
|
||||
protected:
|
||||
static void writeDataToBuf(void* png_ptr, uchar* src, size_t size);
|
||||
static void flushBuf(void* png_ptr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_PNG_H_*/
|
||||
@@ -1,513 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "grfmt_pxm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
///////////////////////// P?M reader //////////////////////////////
|
||||
|
||||
static int ReadNumber( RLByteStream& strm, int maxdigits )
|
||||
{
|
||||
int code;
|
||||
int val = 0;
|
||||
int digits = 0;
|
||||
|
||||
code = strm.getByte();
|
||||
|
||||
if( !isdigit(code))
|
||||
{
|
||||
do
|
||||
{
|
||||
if( code == '#' )
|
||||
{
|
||||
do
|
||||
{
|
||||
code = strm.getByte();
|
||||
}
|
||||
while( code != '\n' && code != '\r' );
|
||||
}
|
||||
|
||||
code = strm.getByte();
|
||||
|
||||
while( isspace(code))
|
||||
code = strm.getByte();
|
||||
}
|
||||
while( !isdigit( code ));
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
val = val*10 + code - '0';
|
||||
if( ++digits >= maxdigits ) break;
|
||||
code = strm.getByte();
|
||||
}
|
||||
while( isdigit(code));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
PxMDecoder::PxMDecoder()
|
||||
{
|
||||
m_offset = -1;
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
PxMDecoder::~PxMDecoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
size_t PxMDecoder::signatureLength() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool PxMDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
return signature.size() >= 3 && signature[0] == 'P' &&
|
||||
'1' <= signature[1] && signature[1] <= '6' &&
|
||||
isspace(signature[2]);
|
||||
}
|
||||
|
||||
ImageDecoder PxMDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<PxMDecoder>();
|
||||
}
|
||||
|
||||
void PxMDecoder::close()
|
||||
{
|
||||
m_strm.close();
|
||||
}
|
||||
|
||||
|
||||
bool PxMDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if( !m_buf.empty() )
|
||||
{
|
||||
if( !m_strm.open(m_buf) )
|
||||
return false;
|
||||
}
|
||||
else if( !m_strm.open( m_filename ))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
int code = m_strm.getByte();
|
||||
if( code != 'P' )
|
||||
throw RBS_BAD_HEADER;
|
||||
|
||||
code = m_strm.getByte();
|
||||
switch( code )
|
||||
{
|
||||
case '1': case '4': m_bpp = 1; break;
|
||||
case '2': case '5': m_bpp = 8; break;
|
||||
case '3': case '6': m_bpp = 24; break;
|
||||
default: throw RBS_BAD_HEADER;
|
||||
}
|
||||
|
||||
m_binary = code >= '4';
|
||||
m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
|
||||
|
||||
m_width = ReadNumber( m_strm, INT_MAX );
|
||||
m_height = ReadNumber( m_strm, INT_MAX );
|
||||
|
||||
m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX );
|
||||
if( m_maxval > 65535 )
|
||||
throw RBS_BAD_HEADER;
|
||||
|
||||
//if( m_maxval > 255 ) m_binary = false; nonsense
|
||||
if( m_maxval > 255 )
|
||||
m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type));
|
||||
|
||||
if( m_width > 0 && m_height > 0 && m_maxval > 0 && m_maxval < (1 << 16))
|
||||
{
|
||||
m_offset = m_strm.getPos();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool PxMDecoder::readData( Mat& img )
|
||||
{
|
||||
int color = img.channels() > 1;
|
||||
uchar* data = img.data;
|
||||
int step = (int)img.step;
|
||||
PaletteEntry palette[256];
|
||||
bool result = false;
|
||||
int bit_depth = CV_ELEM_SIZE1(m_type)*8;
|
||||
int src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8;
|
||||
int nch = CV_MAT_CN(m_type);
|
||||
int width3 = m_width*nch;
|
||||
int i, x, y;
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
AutoBuffer<uchar> _src(src_pitch + 32);
|
||||
uchar* src = _src;
|
||||
AutoBuffer<uchar> _gray_palette;
|
||||
uchar* gray_palette = _gray_palette;
|
||||
|
||||
// create LUT for converting colors
|
||||
if( bit_depth == 8 )
|
||||
{
|
||||
_gray_palette.allocate(m_maxval + 1);
|
||||
gray_palette = _gray_palette;
|
||||
|
||||
for( i = 0; i <= m_maxval; i++ )
|
||||
gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0));
|
||||
|
||||
FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_strm.setPos( m_offset );
|
||||
|
||||
switch( m_bpp )
|
||||
{
|
||||
////////////////////////// 1 BPP /////////////////////////
|
||||
case 1:
|
||||
if( !m_binary )
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
for( x = 0; x < m_width; x++ )
|
||||
src[x] = ReadNumber( m_strm, 1 ) != 0;
|
||||
|
||||
if( color )
|
||||
FillColorRow8( data, src, m_width, palette );
|
||||
else
|
||||
FillGrayRow8( data, src, m_width, gray_palette );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
|
||||
if( color )
|
||||
FillColorRow1( data, src, m_width, palette );
|
||||
else
|
||||
FillGrayRow1( data, src, m_width, gray_palette );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
|
||||
////////////////////////// 8 BPP /////////////////////////
|
||||
case 8:
|
||||
case 24:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
if( !m_binary )
|
||||
{
|
||||
for( x = 0; x < width3; x++ )
|
||||
{
|
||||
int code = ReadNumber( m_strm, INT_MAX );
|
||||
if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval;
|
||||
if( bit_depth == 8 )
|
||||
src[x] = gray_palette[code];
|
||||
else
|
||||
((ushort *)src)[x] = (ushort)code;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( bit_depth == 16 && !isBigEndian() )
|
||||
{
|
||||
for( x = 0; x < width3; x++ )
|
||||
{
|
||||
uchar v = src[x * 2];
|
||||
src[x * 2] = src[x * 2 + 1];
|
||||
src[x * 2 + 1] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( img.depth() == CV_8U && bit_depth == 16 )
|
||||
{
|
||||
for( x = 0; x < width3; x++ )
|
||||
{
|
||||
int v = ((ushort *)src)[x];
|
||||
src[x] = (uchar)(v >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
if( m_bpp == 8 ) // image has one channel
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( img.depth() == CV_8U ) {
|
||||
uchar *d = data, *s = src, *end = src + m_width;
|
||||
for( ; s < end; d += 3, s++)
|
||||
d[0] = d[1] = d[2] = *s;
|
||||
} else {
|
||||
ushort *d = (ushort *)data, *s = (ushort *)src, *end = ((ushort *)src) + m_width;
|
||||
for( ; s < end; s++, d += 3)
|
||||
d[0] = d[1] = d[2] = *s;
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy( data, src, m_width*(bit_depth/8) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( img.depth() == CV_8U )
|
||||
icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
else
|
||||
icvCvt_RGB2BGR_16u_C3R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
else if( img.depth() == CV_8U )
|
||||
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 );
|
||||
else
|
||||
icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1), 3, 2 );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PxMEncoder::PxMEncoder()
|
||||
{
|
||||
m_description = "Portable image format (*.pbm;*.pgm;*.ppm;*.pxm;*.pnm)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
PxMEncoder::~PxMEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ImageEncoder PxMEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<PxMEncoder>();
|
||||
}
|
||||
|
||||
|
||||
bool PxMEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return depth == CV_8U || depth == CV_16U;
|
||||
}
|
||||
|
||||
|
||||
bool PxMEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
{
|
||||
bool isBinary = true;
|
||||
|
||||
int width = img.cols, height = img.rows;
|
||||
int _channels = img.channels(), depth = (int)img.elemSize1()*8;
|
||||
int channels = _channels > 1 ? 3 : 1;
|
||||
int fileStep = width*(int)img.elemSize();
|
||||
int x, y;
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
if( params[i] == CV_IMWRITE_PXM_BINARY )
|
||||
isBinary = params[i+1] != 0;
|
||||
|
||||
WLByteStream strm;
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
if( !strm.open(*m_buf) )
|
||||
return false;
|
||||
int t = CV_MAKETYPE(img.depth(), channels);
|
||||
m_buf->reserve( alignSize(256 + (isBinary ? fileStep*height :
|
||||
((t == CV_8UC1 ? 4 : t == CV_8UC3 ? 4*3+2 :
|
||||
t == CV_16UC1 ? 6 : 6*3+2)*width+1)*height), 256));
|
||||
}
|
||||
else if( !strm.open(m_filename) )
|
||||
return false;
|
||||
|
||||
int lineLength;
|
||||
int bufferSize = 128; // buffer that should fit a header
|
||||
|
||||
if( isBinary )
|
||||
lineLength = width * (int)img.elemSize();
|
||||
else
|
||||
lineLength = (6 * channels + (channels > 1 ? 2 : 0)) * width + 32;
|
||||
|
||||
if( bufferSize < lineLength )
|
||||
bufferSize = lineLength;
|
||||
|
||||
AutoBuffer<char> _buffer(bufferSize);
|
||||
char* buffer = _buffer;
|
||||
|
||||
// write header;
|
||||
sprintf( buffer, "P%c\n%d %d\n%d\n",
|
||||
'2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0),
|
||||
width, height, (1 << depth) - 1 );
|
||||
|
||||
strm.putBytes( buffer, (int)strlen(buffer) );
|
||||
|
||||
for( y = 0; y < height; y++ )
|
||||
{
|
||||
uchar* data = img.data + img.step*y;
|
||||
if( isBinary )
|
||||
{
|
||||
if( _channels == 3 )
|
||||
{
|
||||
if( depth == 8 )
|
||||
icvCvt_BGR2RGB_8u_C3R( (uchar*)data, 0,
|
||||
(uchar*)buffer, 0, cvSize(width,1) );
|
||||
else
|
||||
icvCvt_BGR2RGB_16u_C3R( (ushort*)data, 0,
|
||||
(ushort*)buffer, 0, cvSize(width,1) );
|
||||
}
|
||||
|
||||
// swap endianness if necessary
|
||||
if( depth == 16 && !isBigEndian() )
|
||||
{
|
||||
if( _channels == 1 )
|
||||
memcpy( buffer, data, fileStep );
|
||||
for( x = 0; x < width*channels*2; x += 2 )
|
||||
{
|
||||
uchar v = buffer[x];
|
||||
buffer[x] = buffer[x + 1];
|
||||
buffer[x + 1] = v;
|
||||
}
|
||||
}
|
||||
strm.putBytes( (channels > 1 || depth > 8) ? buffer : (char*)data, fileStep );
|
||||
}
|
||||
else
|
||||
{
|
||||
char* ptr = buffer;
|
||||
|
||||
if( channels > 1 )
|
||||
{
|
||||
if( depth == 8 )
|
||||
{
|
||||
for( x = 0; x < width*channels; x += channels )
|
||||
{
|
||||
sprintf( ptr, "% 4d", data[x + 2] );
|
||||
ptr += 4;
|
||||
sprintf( ptr, "% 4d", data[x + 1] );
|
||||
ptr += 4;
|
||||
sprintf( ptr, "% 4d", data[x] );
|
||||
ptr += 4;
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( x = 0; x < width*channels; x += channels )
|
||||
{
|
||||
sprintf( ptr, "% 6d", ((ushort *)data)[x + 2] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((ushort *)data)[x + 1] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((ushort *)data)[x] );
|
||||
ptr += 6;
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( depth == 8 )
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
sprintf( ptr, "% 4d", data[x] );
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
sprintf( ptr, "% 6d", ((ushort *)data)[x] );
|
||||
ptr += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++ = '\n';
|
||||
|
||||
strm.putBytes( buffer, (int)(ptr - buffer) );
|
||||
}
|
||||
}
|
||||
|
||||
strm.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*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_PxM_H_
|
||||
#define _GRFMT_PxM_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class PxMDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
PxMDecoder();
|
||||
virtual ~PxMDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
size_t signatureLength() const;
|
||||
bool checkSignature( const String& signature ) const;
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
|
||||
RLByteStream m_strm;
|
||||
PaletteEntry m_palette[256];
|
||||
int m_bpp;
|
||||
int m_offset;
|
||||
bool m_binary;
|
||||
int m_maxval;
|
||||
};
|
||||
|
||||
|
||||
class PxMEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PxMEncoder();
|
||||
virtual ~PxMEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const;
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_PxM_H_*/
|
||||
@@ -1,425 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#include "grfmt_sunras.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
static const char* fmtSignSunRas = "\x59\xA6\x6A\x95";
|
||||
|
||||
/************************ Sun Raster reader *****************************/
|
||||
|
||||
SunRasterDecoder::SunRasterDecoder()
|
||||
{
|
||||
m_offset = -1;
|
||||
m_signature = fmtSignSunRas;
|
||||
}
|
||||
|
||||
|
||||
SunRasterDecoder::~SunRasterDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageDecoder SunRasterDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<SunRasterDecoder>();
|
||||
}
|
||||
|
||||
void SunRasterDecoder::close()
|
||||
{
|
||||
m_strm.close();
|
||||
}
|
||||
|
||||
|
||||
bool SunRasterDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if( !m_strm.open( m_filename )) return false;
|
||||
|
||||
try
|
||||
{
|
||||
m_strm.skip( 4 );
|
||||
m_width = m_strm.getDWord();
|
||||
m_height = m_strm.getDWord();
|
||||
m_bpp = m_strm.getDWord();
|
||||
int palSize = 3*(1 << m_bpp);
|
||||
|
||||
m_strm.skip( 4 );
|
||||
m_encoding = (SunRasType)m_strm.getDWord();
|
||||
m_maptype = (SunRasMapType)m_strm.getDWord();
|
||||
m_maplength = m_strm.getDWord();
|
||||
|
||||
if( m_width > 0 && m_height > 0 &&
|
||||
(m_bpp == 1 || m_bpp == 8 || m_bpp == 24 || m_bpp == 32) &&
|
||||
(m_encoding == RAS_OLD || m_encoding == RAS_STANDARD ||
|
||||
(m_type == RAS_BYTE_ENCODED && m_bpp == 8) || m_type == RAS_FORMAT_RGB) &&
|
||||
((m_maptype == RMT_NONE && m_maplength == 0) ||
|
||||
(m_maptype == RMT_EQUAL_RGB && m_maplength <= palSize && m_bpp <= 8)))
|
||||
{
|
||||
memset( m_palette, 0, sizeof(m_palette));
|
||||
|
||||
if( m_maplength != 0 )
|
||||
{
|
||||
uchar buffer[256*3];
|
||||
|
||||
if( m_strm.getBytes( buffer, m_maplength ) == m_maplength )
|
||||
{
|
||||
int i;
|
||||
palSize = m_maplength/3;
|
||||
|
||||
for( i = 0; i < palSize; i++ )
|
||||
{
|
||||
m_palette[i].b = buffer[i + 2*palSize];
|
||||
m_palette[i].g = buffer[i + palSize];
|
||||
m_palette[i].r = buffer[i];
|
||||
m_palette[i].a = 0;
|
||||
}
|
||||
|
||||
m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1;
|
||||
m_offset = m_strm.getPos();
|
||||
|
||||
assert( m_offset == 32 + m_maplength );
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
|
||||
|
||||
if( CV_MAT_CN(m_type) == 1 )
|
||||
FillGrayPalette( m_palette, m_bpp );
|
||||
|
||||
m_offset = m_strm.getPos();
|
||||
|
||||
assert( m_offset == 32 + m_maplength );
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool SunRasterDecoder::readData( Mat& img )
|
||||
{
|
||||
int color = img.channels() > 1;
|
||||
uchar* data = img.data;
|
||||
int step = (int)img.step;
|
||||
uchar gray_palette[256];
|
||||
bool result = false;
|
||||
int src_pitch = ((m_width*m_bpp + 7)/8 + 1) & -2;
|
||||
int nch = color ? 3 : 1;
|
||||
int width3 = m_width*nch;
|
||||
int y;
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
AutoBuffer<uchar> _src(src_pitch + 32);
|
||||
uchar* src = _src;
|
||||
AutoBuffer<uchar> _bgr(m_width*3 + 32);
|
||||
uchar* bgr = _bgr;
|
||||
|
||||
if( !color && m_maptype == RMT_EQUAL_RGB )
|
||||
CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
|
||||
|
||||
try
|
||||
{
|
||||
m_strm.setPos( m_offset );
|
||||
|
||||
switch( m_bpp )
|
||||
{
|
||||
/************************* 1 BPP ************************/
|
||||
case 1:
|
||||
if( m_type != RAS_BYTE_ENCODED )
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( color )
|
||||
FillColorRow1( data, src, m_width, m_palette );
|
||||
else
|
||||
FillGrayRow1( data, src, m_width, gray_palette );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar* line_end = src + (m_width*m_bpp + 7)/8;
|
||||
uchar* tsrc = src;
|
||||
y = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int max_count = (int)(line_end - tsrc);
|
||||
int code = 0, len = 0, len1 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
code = m_strm.getByte();
|
||||
if( code == 0x80 )
|
||||
{
|
||||
len = m_strm.getByte();
|
||||
if( len != 0 ) break;
|
||||
}
|
||||
tsrc[len1] = (uchar)code;
|
||||
}
|
||||
while( ++len1 < max_count );
|
||||
|
||||
tsrc += len1;
|
||||
|
||||
if( len > 0 ) // encoded mode
|
||||
{
|
||||
++len;
|
||||
code = m_strm.getByte();
|
||||
if( len > line_end - tsrc )
|
||||
{
|
||||
assert(0);
|
||||
goto bad_decoding_1bpp;
|
||||
}
|
||||
|
||||
memset( tsrc, code, len );
|
||||
tsrc += len;
|
||||
}
|
||||
|
||||
if( tsrc >= line_end )
|
||||
{
|
||||
tsrc = src;
|
||||
if( color )
|
||||
FillColorRow1( data, src, m_width, m_palette );
|
||||
else
|
||||
FillGrayRow1( data, src, m_width, gray_palette );
|
||||
data += step;
|
||||
if( ++y >= m_height ) break;
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
bad_decoding_1bpp:
|
||||
;
|
||||
}
|
||||
break;
|
||||
/************************* 8 BPP ************************/
|
||||
case 8:
|
||||
if( m_type != RAS_BYTE_ENCODED )
|
||||
{
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
if( color )
|
||||
FillColorRow8( data, src, m_width, m_palette );
|
||||
else
|
||||
FillGrayRow8( data, src, m_width, gray_palette );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else // RLE-encoded
|
||||
{
|
||||
uchar* line_end = data + width3;
|
||||
y = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int max_count = (int)(line_end - data);
|
||||
int code = 0, len = 0, len1;
|
||||
uchar* tsrc = src;
|
||||
|
||||
do
|
||||
{
|
||||
code = m_strm.getByte();
|
||||
if( code == 0x80 )
|
||||
{
|
||||
len = m_strm.getByte();
|
||||
if( len != 0 ) break;
|
||||
}
|
||||
*tsrc++ = (uchar)code;
|
||||
}
|
||||
while( (max_count -= nch) > 0 );
|
||||
|
||||
len1 = (int)(tsrc - src);
|
||||
|
||||
if( len1 > 0 )
|
||||
{
|
||||
if( color )
|
||||
FillColorRow8( data, src, len1, m_palette );
|
||||
else
|
||||
FillGrayRow8( data, src, len1, gray_palette );
|
||||
data += len1*nch;
|
||||
}
|
||||
|
||||
if( len > 0 ) // encoded mode
|
||||
{
|
||||
len = (len + 1)*nch;
|
||||
code = m_strm.getByte();
|
||||
|
||||
if( color )
|
||||
data = FillUniColor( data, line_end, step, width3,
|
||||
y, m_height, len,
|
||||
m_palette[code] );
|
||||
else
|
||||
data = FillUniGray( data, line_end, step, width3,
|
||||
y, m_height, len,
|
||||
gray_palette[code] );
|
||||
if( y >= m_height )
|
||||
break;
|
||||
}
|
||||
|
||||
if( data == line_end )
|
||||
{
|
||||
if( m_strm.getByte() != 0 )
|
||||
goto bad_decoding_end;
|
||||
line_end += step;
|
||||
data = line_end - width3;
|
||||
if( ++y >= m_height ) break;
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
bad_decoding_end:
|
||||
;
|
||||
}
|
||||
break;
|
||||
/************************* 24 BPP ************************/
|
||||
case 24:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
m_strm.getBytes( color ? data : bgr, src_pitch );
|
||||
|
||||
if( color )
|
||||
{
|
||||
if( m_type == RAS_FORMAT_RGB )
|
||||
icvCvt_RGB2BGR_8u_C3R( data, 0, data, 0, cvSize(m_width,1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1),
|
||||
m_type == RAS_FORMAT_RGB ? 2 : 0 );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
/************************* 32 BPP ************************/
|
||||
case 32:
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
/* hack: a0 b0 g0 r0 a1 b1 g1 r1 ... are written to src + 3,
|
||||
so when we look at src + 4, we see b0 g0 r0 x b1 g1 g1 x ... */
|
||||
m_strm.getBytes( src + 3, src_pitch );
|
||||
|
||||
if( color )
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( src + 4, 0, data, 0, cvSize(m_width,1),
|
||||
m_type == RAS_FORMAT_RGB ? 2 : 0 );
|
||||
else
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, cvSize(m_width,1),
|
||||
m_type == RAS_FORMAT_RGB ? 2 : 0 );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SunRasterEncoder::SunRasterEncoder()
|
||||
{
|
||||
m_description = "Sun raster files (*.sr;*.ras)";
|
||||
}
|
||||
|
||||
|
||||
ImageEncoder SunRasterEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<SunRasterEncoder>();
|
||||
}
|
||||
|
||||
SunRasterEncoder::~SunRasterEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
bool SunRasterEncoder::write( const Mat& img, const std::vector<int>& )
|
||||
{
|
||||
bool result = false;
|
||||
int y, width = img.cols, height = img.rows, channels = img.channels();
|
||||
int fileStep = (width*channels + 1) & -2;
|
||||
WMByteStream strm;
|
||||
|
||||
if( strm.open(m_filename) )
|
||||
{
|
||||
strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) );
|
||||
strm.putDWord( width );
|
||||
strm.putDWord( height );
|
||||
strm.putDWord( channels*8 );
|
||||
strm.putDWord( fileStep*height );
|
||||
strm.putDWord( RAS_STANDARD );
|
||||
strm.putDWord( RMT_NONE );
|
||||
strm.putDWord( 0 );
|
||||
|
||||
for( y = 0; y < height; y++ )
|
||||
strm.putBytes( img.data + img.step*y, fileStep );
|
||||
|
||||
strm.close();
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*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_SUNRAS_H_
|
||||
#define _GRFMT_SUNRAS_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
enum SunRasType
|
||||
{
|
||||
RAS_OLD = 0,
|
||||
RAS_STANDARD = 1,
|
||||
RAS_BYTE_ENCODED = 2, /* RLE encoded */
|
||||
RAS_FORMAT_RGB = 3 /* RGB instead of BGR */
|
||||
};
|
||||
|
||||
enum SunRasMapType
|
||||
{
|
||||
RMT_NONE = 0, /* direct color encoding */
|
||||
RMT_EQUAL_RGB = 1 /* paletted image */
|
||||
};
|
||||
|
||||
|
||||
// Sun Raster Reader
|
||||
class SunRasterDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
SunRasterDecoder();
|
||||
virtual ~SunRasterDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
|
||||
RMByteStream m_strm;
|
||||
PaletteEntry m_palette[256];
|
||||
int m_bpp;
|
||||
int m_offset;
|
||||
SunRasType m_encoding;
|
||||
SunRasMapType m_maptype;
|
||||
int m_maplength;
|
||||
};
|
||||
|
||||
|
||||
class SunRasterEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
SunRasterEncoder();
|
||||
virtual ~SunRasterEncoder();
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_SUNRAS_H_*/
|
||||
@@ -1,843 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/****************************************************************************************\
|
||||
A part of the file implements TIFF reader on base of libtiff library
|
||||
(see otherlibs/_graphics/readme.txt for copyright notice)
|
||||
\****************************************************************************************/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "grfmt_tiff.hpp"
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
static const char fmtSignTiffII[] = "II\x2a\x00";
|
||||
static const char fmtSignTiffMM[] = "MM\x00\x2a";
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include "tiff.h"
|
||||
#include "tiffio.h"
|
||||
|
||||
static int grfmt_tiff_err_handler_init = 0;
|
||||
static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {}
|
||||
|
||||
TiffDecoder::TiffDecoder()
|
||||
{
|
||||
m_tif = 0;
|
||||
if( !grfmt_tiff_err_handler_init )
|
||||
{
|
||||
grfmt_tiff_err_handler_init = 1;
|
||||
|
||||
TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
|
||||
TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
|
||||
}
|
||||
m_hdr = false;
|
||||
}
|
||||
|
||||
|
||||
void TiffDecoder::close()
|
||||
{
|
||||
if( m_tif )
|
||||
{
|
||||
TIFF* tif = (TIFF*)m_tif;
|
||||
TIFFClose( tif );
|
||||
m_tif = 0;
|
||||
}
|
||||
}
|
||||
|
||||
TiffDecoder::~TiffDecoder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
size_t TiffDecoder::signatureLength() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool TiffDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
return signature.size() >= 4 &&
|
||||
(memcmp(signature.c_str(), fmtSignTiffII, 4) == 0 ||
|
||||
memcmp(signature.c_str(), fmtSignTiffMM, 4) == 0);
|
||||
}
|
||||
|
||||
int TiffDecoder::normalizeChannelsNumber(int channels) const
|
||||
{
|
||||
return channels > 4 ? 4 : channels;
|
||||
}
|
||||
|
||||
ImageDecoder TiffDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<TiffDecoder>();
|
||||
}
|
||||
|
||||
bool TiffDecoder::readHeader()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
close();
|
||||
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
|
||||
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
|
||||
TIFF* tif = TIFFOpen( m_filename.c_str(), "r" );
|
||||
|
||||
if( tif )
|
||||
{
|
||||
uint32 wdth = 0, hght = 0;
|
||||
uint16 photometric = 0;
|
||||
m_tif = tif;
|
||||
|
||||
if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) &&
|
||||
TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) &&
|
||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
|
||||
{
|
||||
uint16 bpp=8, ncn = photometric > 1 ? 3 : 1;
|
||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||
|
||||
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)))
|
||||
bpp = 8;
|
||||
|
||||
int wanted_channels = normalizeChannelsNumber(ncn);
|
||||
switch(bpp)
|
||||
{
|
||||
case 8:
|
||||
m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? wanted_channels : 1);
|
||||
break;
|
||||
case 16:
|
||||
m_type = CV_MAKETYPE(CV_16U, photometric > 1 ? 3 : 1);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
m_type = CV_MAKETYPE(CV_32F, photometric > 1 ? 3 : 1);
|
||||
break;
|
||||
case 64:
|
||||
m_type = CV_MAKETYPE(CV_64F, photometric > 1 ? 3 : 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F )
|
||||
return false;
|
||||
|
||||
if( m_tif && m_width && m_height )
|
||||
{
|
||||
TIFF* tif = (TIFF*)m_tif;
|
||||
uint32 tile_width0 = m_width, tile_height0 = 0;
|
||||
int x, y, i;
|
||||
int is_tiled = TIFFIsTiled(tif);
|
||||
uint16 photometric;
|
||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
|
||||
uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1;
|
||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||
const int bitsPerByte = 8;
|
||||
int dst_bpp = (int)(img.elemSize1() * bitsPerByte);
|
||||
int wanted_channels = normalizeChannelsNumber(img.channels());
|
||||
|
||||
if(dst_bpp == 8)
|
||||
{
|
||||
char errmsg[1024];
|
||||
if(!TIFFRGBAImageOK( tif, errmsg ))
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( (!is_tiled) ||
|
||||
(is_tiled &&
|
||||
TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
|
||||
TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 )))
|
||||
{
|
||||
if(!is_tiled)
|
||||
TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 );
|
||||
|
||||
if( tile_width0 <= 0 )
|
||||
tile_width0 = m_width;
|
||||
|
||||
if( tile_height0 <= 0 )
|
||||
tile_height0 = m_height;
|
||||
|
||||
AutoBuffer<uchar> _buffer( size_t(8) * tile_height0*tile_width0);
|
||||
uchar* buffer = _buffer;
|
||||
ushort* buffer16 = (ushort*)buffer;
|
||||
float* buffer32 = (float*)buffer;
|
||||
double* buffer64 = (double*)buffer;
|
||||
int tileidx = 0;
|
||||
|
||||
for( y = 0; y < m_height; y += tile_height0, data += img.step*tile_height0 )
|
||||
{
|
||||
int tile_height = tile_height0;
|
||||
|
||||
if( y + tile_height > m_height )
|
||||
tile_height = m_height - y;
|
||||
|
||||
for( x = 0; x < m_width; x += tile_width0, tileidx++ )
|
||||
{
|
||||
int tile_width = tile_width0, ok;
|
||||
|
||||
if( x + tile_width > m_width )
|
||||
tile_width = m_width - x;
|
||||
|
||||
switch(dst_bpp)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
uchar * bstart = buffer;
|
||||
if( !is_tiled )
|
||||
ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
|
||||
else
|
||||
{
|
||||
ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );
|
||||
//Tiles fill the buffer from the bottom up
|
||||
bstart += (tile_height0 - tile_height) * tile_width0 * 4;
|
||||
}
|
||||
if( !ok )
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 0; i < tile_height; i++ )
|
||||
if( color )
|
||||
{
|
||||
if (wanted_channels == 4)
|
||||
{
|
||||
icvCvt_BGRA2RGBA_8u_C4R( bstart + i*tile_width0*4, 0,
|
||||
data + x*4 + img.step*(tile_height - i - 1), 0,
|
||||
cvSize(tile_width,1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( bstart + i*tile_width0*4, 0,
|
||||
data + x*3 + img.step*(tile_height - i - 1), 0,
|
||||
cvSize(tile_width,1), 2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( bstart + i*tile_width0*4, 0,
|
||||
data + x + img.step*(tile_height - i - 1), 0,
|
||||
cvSize(tile_width,1), 2 );
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
if( !is_tiled )
|
||||
ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;
|
||||
else
|
||||
ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;
|
||||
|
||||
if( !ok )
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 0; i < tile_height; i++ )
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( ncn == 1 )
|
||||
{
|
||||
icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width0*ncn, 0,
|
||||
(ushort*)(data + img.step*i) + x*3, 0,
|
||||
cvSize(tile_width,1) );
|
||||
}
|
||||
else if( ncn == 3 )
|
||||
{
|
||||
icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width0*ncn, 0,
|
||||
(ushort*)(data + img.step*i) + x*3, 0,
|
||||
cvSize(tile_width,1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width0*ncn, 0,
|
||||
(ushort*)(data + img.step*i) + x*3, 0,
|
||||
cvSize(tile_width,1), 2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ncn == 1 )
|
||||
{
|
||||
memcpy((ushort*)(data + img.step*i)+x,
|
||||
buffer16 + i*tile_width0*ncn,
|
||||
tile_width*sizeof(buffer16[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width0*ncn, 0,
|
||||
(ushort*)(data + img.step*i) + x, 0,
|
||||
cvSize(tile_width,1), ncn, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 32:
|
||||
case 64:
|
||||
{
|
||||
if( !is_tiled )
|
||||
ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;
|
||||
else
|
||||
ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;
|
||||
|
||||
if( !ok || ncn != 1 )
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
for( i = 0; i < tile_height; i++ )
|
||||
{
|
||||
if(dst_bpp == 32)
|
||||
{
|
||||
memcpy((float*)(data + img.step*i)+x,
|
||||
buffer32 + i*tile_width0*ncn,
|
||||
tile_width*sizeof(buffer32[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy((double*)(data + img.step*i)+x,
|
||||
buffer64 + i*tile_width0*ncn,
|
||||
tile_width*sizeof(buffer64[0]));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
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);
|
||||
tstrip_t strip_size = 3 * m_width * rows_per_strip;
|
||||
float *ptr = img.ptr<float>();
|
||||
for (tstrip_t i = 0; i < TIFFNumberOfStrips(tif); i++, ptr += strip_size)
|
||||
{
|
||||
TIFFReadEncodedStrip(tif, i, ptr, size);
|
||||
size -= strip_size * sizeof(float);
|
||||
}
|
||||
close();
|
||||
if(photometric == PHOTOMETRIC_LOGLUV)
|
||||
{
|
||||
cvtColor(img, img, COLOR_XYZ2BGR);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvtColor(img, img, COLOR_RGB2BGR);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TiffEncoder::TiffEncoder()
|
||||
{
|
||||
m_description = "TIFF Files (*.tiff;*.tif)";
|
||||
#ifdef HAVE_TIFF
|
||||
m_buf_supported = false;
|
||||
#else
|
||||
m_buf_supported = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
TiffEncoder::~TiffEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageEncoder TiffEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<TiffEncoder>();
|
||||
}
|
||||
|
||||
bool TiffEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
#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,
|
||||
TiffFieldType fieldType,
|
||||
int count, int value )
|
||||
{
|
||||
strm.putWord( tag );
|
||||
strm.putWord( fieldType );
|
||||
strm.putDWord( count );
|
||||
strm.putDWord( value );
|
||||
}
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
static void readParam(const std::vector<int>& params, int key, int& value)
|
||||
{
|
||||
for(size_t i = 0; i + 1 < params.size(); i += 2)
|
||||
if(params[i] == key)
|
||||
{
|
||||
value = params[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool TiffEncoder::writeLibTiff( const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
int channels = img.channels();
|
||||
int width = img.cols, height = img.rows;
|
||||
int depth = img.depth();
|
||||
|
||||
int bitsPerChannel = -1;
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8U:
|
||||
{
|
||||
bitsPerChannel = 8;
|
||||
break;
|
||||
}
|
||||
case CV_16U:
|
||||
{
|
||||
bitsPerChannel = 16;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const int bitsPerByte = 8;
|
||||
size_t fileStep = (width * channels * bitsPerChannel) / bitsPerByte;
|
||||
|
||||
int rowsPerStrip = (int)((1 << 13)/fileStep);
|
||||
readParam(params, TIFFTAG_ROWSPERSTRIP, rowsPerStrip);
|
||||
|
||||
if( rowsPerStrip < 1 )
|
||||
rowsPerStrip = 1;
|
||||
|
||||
if( rowsPerStrip > height )
|
||||
rowsPerStrip = height;
|
||||
|
||||
|
||||
// do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
|
||||
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
|
||||
TIFF* pTiffHandle = TIFFOpen(m_filename.c_str(), "w");
|
||||
if (!pTiffHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// defaults for now, maybe base them on params in the future
|
||||
int compression = COMPRESSION_LZW;
|
||||
int predictor = PREDICTOR_HORIZONTAL;
|
||||
|
||||
readParam(params, TIFFTAG_COMPRESSION, compression);
|
||||
readParam(params, TIFFTAG_PREDICTOR, predictor);
|
||||
|
||||
int colorspace = channels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
|
||||
|
||||
if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip)
|
||||
|| !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor)
|
||||
)
|
||||
{
|
||||
TIFFClose(pTiffHandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
// row buffer, because TIFFWriteScanline modifies the original data!
|
||||
size_t scanlineSize = TIFFScanlineSize(pTiffHandle);
|
||||
AutoBuffer<uchar> _buffer(scanlineSize+32);
|
||||
uchar* buffer = _buffer;
|
||||
if (!buffer)
|
||||
{
|
||||
TIFFClose(pTiffHandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
switch(channels)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
memcpy(buffer, img.data + img.step * y, scanlineSize);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
if (depth == CV_8U)
|
||||
icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
|
||||
else
|
||||
icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (depth == CV_8U)
|
||||
icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
|
||||
else
|
||||
icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
TIFFClose(pTiffHandle);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int writeResult = TIFFWriteScanline(pTiffHandle, buffer, y, 0);
|
||||
if (writeResult != 1)
|
||||
{
|
||||
TIFFClose(pTiffHandle);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TIFFClose(pTiffHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TiffEncoder::writeHdr(const Mat& _img)
|
||||
{
|
||||
Mat img;
|
||||
cvtColor(_img, img, COLOR_BGR2XYZ);
|
||||
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;
|
||||
float *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
|
||||
bool TiffEncoder::write( const Mat& img, const std::vector<int>& params)
|
||||
#else
|
||||
bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
|
||||
int bytesPerChannel = depth == CV_8U ? 1 : 2;
|
||||
int fileStep = width * channels * bytesPerChannel;
|
||||
|
||||
WLByteStream strm;
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
if( !strm.open(*m_buf) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_TIFF
|
||||
return writeLibTiff(img, params);
|
||||
#else
|
||||
if( !strm.open(m_filename) )
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int rowsPerStrip = (1 << 13)/fileStep;
|
||||
|
||||
if( rowsPerStrip < 1 )
|
||||
rowsPerStrip = 1;
|
||||
|
||||
if( rowsPerStrip > height )
|
||||
rowsPerStrip = height;
|
||||
|
||||
int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
|
||||
|
||||
if( m_buf )
|
||||
m_buf->reserve( alignSize(stripCount*8 + fileStep*height + 256, 256) );
|
||||
|
||||
/*#if defined _DEBUG || !defined WIN32
|
||||
int uncompressedRowSize = rowsPerStrip * fileStep;
|
||||
#endif*/
|
||||
int directoryOffset = 0;
|
||||
|
||||
AutoBuffer<int> stripOffsets(stripCount);
|
||||
AutoBuffer<short> stripCounts(stripCount);
|
||||
AutoBuffer<uchar> _buffer(fileStep+32);
|
||||
uchar* buffer = _buffer;
|
||||
int stripOffsetsOffset = 0;
|
||||
int stripCountsOffset = 0;
|
||||
int bitsPerSample = 8 * bytesPerChannel;
|
||||
int y = 0;
|
||||
|
||||
strm.putBytes( fmtSignTiffII, 4 );
|
||||
strm.putDWord( directoryOffset );
|
||||
|
||||
// write an image data first (the most reasonable way
|
||||
// for compressed images)
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
{
|
||||
int limit = y + rowsPerStrip;
|
||||
|
||||
if( limit > height )
|
||||
limit = height;
|
||||
|
||||
stripOffsets[i] = strm.getPos();
|
||||
|
||||
for( ; y < limit; y++ )
|
||||
{
|
||||
if( channels == 3 )
|
||||
{
|
||||
if (depth == CV_8U)
|
||||
icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
|
||||
else
|
||||
icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channels == 4 )
|
||||
{
|
||||
if (depth == CV_8U)
|
||||
icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
|
||||
else
|
||||
icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
|
||||
}
|
||||
}
|
||||
|
||||
strm.putBytes( channels > 1 ? buffer : img.data + img.step*y, fileStep );
|
||||
}
|
||||
|
||||
stripCounts[i] = (short)(strm.getPos() - stripOffsets[i]);
|
||||
/*assert( stripCounts[i] == uncompressedRowSize ||
|
||||
stripCounts[i] < uncompressedRowSize &&
|
||||
i == stripCount - 1);*/
|
||||
}
|
||||
|
||||
if( stripCount > 2 )
|
||||
{
|
||||
stripOffsetsOffset = strm.getPos();
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
strm.putDWord( stripOffsets[i] );
|
||||
|
||||
stripCountsOffset = strm.getPos();
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
strm.putWord( stripCounts[i] );
|
||||
}
|
||||
else if(stripCount == 2)
|
||||
{
|
||||
stripOffsetsOffset = strm.getPos();
|
||||
for (i = 0; i < stripCount; i++)
|
||||
{
|
||||
strm.putDWord (stripOffsets [i]);
|
||||
}
|
||||
stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
stripOffsetsOffset = stripOffsets[0];
|
||||
stripCountsOffset = stripCounts[0];
|
||||
}
|
||||
|
||||
if( channels > 1 )
|
||||
{
|
||||
int bitsPerSamplePos = strm.getPos();
|
||||
strm.putWord(bitsPerSample);
|
||||
strm.putWord(bitsPerSample);
|
||||
strm.putWord(bitsPerSample);
|
||||
if( channels == 4 )
|
||||
strm.putWord(bitsPerSample);
|
||||
bitsPerSample = bitsPerSamplePos;
|
||||
}
|
||||
|
||||
directoryOffset = strm.getPos();
|
||||
|
||||
// write header
|
||||
strm.putWord( 9 );
|
||||
|
||||
/* warning: specification 5.0 of Tiff want to have tags in
|
||||
ascending order. This is a non-fatal error, but this cause
|
||||
warning with some tools. So, keep this in ascending order */
|
||||
|
||||
writeTag( strm, TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width );
|
||||
writeTag( strm, TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height );
|
||||
writeTag( strm, TIFF_TAG_BITS_PER_SAMPLE,
|
||||
TIFF_TYPE_SHORT, channels, bitsPerSample );
|
||||
writeTag( strm, TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
|
||||
writeTag( strm, TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 );
|
||||
|
||||
writeTag( strm, TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
|
||||
stripCount, stripOffsetsOffset );
|
||||
|
||||
writeTag( strm, TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels );
|
||||
writeTag( strm, TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
|
||||
|
||||
writeTag( strm, TIFF_TAG_STRIP_COUNTS,
|
||||
stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG,
|
||||
stripCount, stripCountsOffset );
|
||||
|
||||
strm.putDWord(0);
|
||||
strm.close();
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
(*m_buf)[4] = (uchar)directoryOffset;
|
||||
(*m_buf)[5] = (uchar)(directoryOffset >> 8);
|
||||
(*m_buf)[6] = (uchar)(directoryOffset >> 16);
|
||||
(*m_buf)[7] = (uchar)(directoryOffset >> 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
// write directory offset
|
||||
FILE* f = fopen( m_filename.c_str(), "r+b" );
|
||||
buffer[0] = (uchar)directoryOffset;
|
||||
buffer[1] = (uchar)(directoryOffset >> 8);
|
||||
buffer[2] = (uchar)(directoryOffset >> 16);
|
||||
buffer[3] = (uchar)(directoryOffset >> 24);
|
||||
|
||||
fseek( f, 4, SEEK_SET );
|
||||
fwrite( buffer, 1, 4, f );
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*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_TIFF_H_
|
||||
#define _GRFMT_TIFF_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// native simple TIFF codec
|
||||
enum TiffCompression
|
||||
{
|
||||
TIFF_UNCOMP = 1,
|
||||
TIFF_HUFFMAN = 2,
|
||||
TIFF_PACKBITS = 32773
|
||||
};
|
||||
|
||||
enum TiffByteOrder
|
||||
{
|
||||
TIFF_ORDER_II = 0x4949,
|
||||
TIFF_ORDER_MM = 0x4d4d
|
||||
};
|
||||
|
||||
|
||||
enum TiffTag
|
||||
{
|
||||
TIFF_TAG_WIDTH = 256,
|
||||
TIFF_TAG_HEIGHT = 257,
|
||||
TIFF_TAG_BITS_PER_SAMPLE = 258,
|
||||
TIFF_TAG_COMPRESSION = 259,
|
||||
TIFF_TAG_PHOTOMETRIC = 262,
|
||||
TIFF_TAG_STRIP_OFFSETS = 273,
|
||||
TIFF_TAG_STRIP_COUNTS = 279,
|
||||
TIFF_TAG_SAMPLES_PER_PIXEL = 277,
|
||||
TIFF_TAG_ROWS_PER_STRIP = 278,
|
||||
TIFF_TAG_PLANAR_CONFIG = 284,
|
||||
TIFF_TAG_COLOR_MAP = 320
|
||||
};
|
||||
|
||||
|
||||
enum TiffFieldType
|
||||
{
|
||||
TIFF_TYPE_BYTE = 1,
|
||||
TIFF_TYPE_SHORT = 3,
|
||||
TIFF_TYPE_LONG = 4
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
// libtiff based TIFF codec
|
||||
|
||||
class TiffDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
TiffDecoder();
|
||||
virtual ~TiffDecoder();
|
||||
|
||||
bool readHeader();
|
||||
bool readData( Mat& img );
|
||||
void close();
|
||||
|
||||
size_t signatureLength() const;
|
||||
bool checkSignature( const String& signature ) const;
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
void* m_tif;
|
||||
int normalizeChannelsNumber(int channels) const;
|
||||
bool readHdrData(Mat& img);
|
||||
bool m_hdr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// ... and writer
|
||||
class TiffEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
TiffEncoder();
|
||||
virtual ~TiffEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const;
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params );
|
||||
ImageEncoder newEncoder() const;
|
||||
|
||||
protected:
|
||||
void writeTag( WLByteStream& strm, TiffTag tag,
|
||||
TiffFieldType fieldType,
|
||||
int count, int value );
|
||||
|
||||
bool writeLibTiff( const Mat& img, const std::vector<int>& params );
|
||||
bool writeHdr( const Mat& img );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_TIFF_H_*/
|
||||
@@ -1,306 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
#ifdef HAVE_WEBP
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include <webp/decode.h>
|
||||
#include <webp/encode.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "grfmt_webp.hpp"
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
const size_t WEBP_HEADER_SIZE = 32;
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
WebPDecoder::WebPDecoder()
|
||||
{
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
WebPDecoder::~WebPDecoder() {}
|
||||
|
||||
size_t WebPDecoder::signatureLength() const
|
||||
{
|
||||
return WEBP_HEADER_SIZE;
|
||||
}
|
||||
|
||||
bool WebPDecoder::checkSignature(const String & signature) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if(signature.size() >= WEBP_HEADER_SIZE)
|
||||
{
|
||||
WebPBitstreamFeatures features;
|
||||
if(VP8_STATUS_OK == WebPGetFeatures((uint8_t *)signature.c_str(),
|
||||
WEBP_HEADER_SIZE, &features))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ImageDecoder WebPDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<WebPDecoder>();
|
||||
}
|
||||
|
||||
bool WebPDecoder::readHeader()
|
||||
{
|
||||
if (m_buf.empty())
|
||||
{
|
||||
FILE * wfile = NULL;
|
||||
|
||||
wfile = fopen(m_filename.c_str(), "rb");
|
||||
|
||||
if(wfile == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(wfile, 0, SEEK_END);
|
||||
long int wfile_size = ftell(wfile);
|
||||
fseek(wfile, 0, SEEK_SET);
|
||||
|
||||
if(wfile_size > static_cast<long int>(INT_MAX))
|
||||
{
|
||||
fclose(wfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
data.create(1, wfile_size, CV_8U);
|
||||
|
||||
size_t data_size = fread(data.data, 1, wfile_size, wfile);
|
||||
|
||||
if(wfile)
|
||||
{
|
||||
fclose(wfile);
|
||||
}
|
||||
|
||||
if(static_cast<long int>(data_size) != wfile_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m_buf;
|
||||
}
|
||||
|
||||
WebPBitstreamFeatures features;
|
||||
if(VP8_STATUS_OK == WebPGetFeatures(data.data, WEBP_HEADER_SIZE, &features))
|
||||
{
|
||||
m_width = features.width;
|
||||
m_height = features.height;
|
||||
|
||||
if (features.has_alpha)
|
||||
{
|
||||
m_type = CV_8UC4;
|
||||
channels = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = CV_8UC3;
|
||||
channels = 3;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebPDecoder::readData(Mat &img)
|
||||
{
|
||||
if( m_width > 0 && m_height > 0 )
|
||||
{
|
||||
if (img.cols != m_width || img.rows != m_height || img.type() != m_type)
|
||||
{
|
||||
img.create(m_height, m_width, m_type);
|
||||
}
|
||||
|
||||
uchar* out_data = img.data;
|
||||
size_t out_data_size = img.cols * img.rows * img.elemSize();
|
||||
|
||||
uchar *res_ptr = 0;
|
||||
if (channels == 3)
|
||||
{
|
||||
res_ptr = WebPDecodeBGRInto(data.data, data.total(), out_data,
|
||||
(int)out_data_size, (int)img.step);
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
res_ptr = WebPDecodeBGRAInto(data.data, data.total(), out_data,
|
||||
(int)out_data_size, (int)img.step);
|
||||
}
|
||||
|
||||
if(res_ptr == out_data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
WebPEncoder::WebPEncoder()
|
||||
{
|
||||
m_description = "WebP files (*.webp)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
WebPEncoder::~WebPEncoder() { }
|
||||
|
||||
ImageEncoder WebPEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<WebPEncoder>();
|
||||
}
|
||||
|
||||
bool WebPEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
int channels = img.channels(), depth = img.depth();
|
||||
int width = img.cols, height = img.rows;
|
||||
|
||||
const Mat *image = &img;
|
||||
Mat temp;
|
||||
size_t size = 0;
|
||||
|
||||
bool comp_lossless = true;
|
||||
float quality = 100.0f;
|
||||
|
||||
if (params.size() > 1)
|
||||
{
|
||||
if (params[0] == CV_IMWRITE_WEBP_QUALITY)
|
||||
{
|
||||
comp_lossless = false;
|
||||
quality = static_cast<float>(params[1]);
|
||||
if (quality < 1.0f)
|
||||
{
|
||||
quality = 1.0f;
|
||||
}
|
||||
if (quality > 100.0f)
|
||||
{
|
||||
comp_lossless = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *out = NULL;
|
||||
|
||||
if(depth != CV_8U)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(channels == 1)
|
||||
{
|
||||
cvtColor(*image, temp, CV_GRAY2BGR);
|
||||
image = &temp;
|
||||
channels = 3;
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (comp_lossless)
|
||||
{
|
||||
if(channels == 3)
|
||||
{
|
||||
size = WebPEncodeLosslessBGR(image->data, width, height, (int)image->step, &out);
|
||||
}
|
||||
else if(channels == 4)
|
||||
{
|
||||
size = WebPEncodeLosslessBGRA(image->data, width, height, (int)image->step, &out);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(channels == 3)
|
||||
{
|
||||
size = WebPEncodeBGR(image->data, width, height, (int)image->step, quality, &out);
|
||||
}
|
||||
else if(channels == 4)
|
||||
{
|
||||
size = WebPEncodeBGRA(image->data, width, height, (int)image->step, quality, &out);
|
||||
}
|
||||
}
|
||||
|
||||
if(size > 0)
|
||||
{
|
||||
if(m_buf)
|
||||
{
|
||||
m_buf->resize(size);
|
||||
memcpy(&(*m_buf)[0], out, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *fd = fopen(m_filename.c_str(), "wb");
|
||||
if(fd != NULL)
|
||||
{
|
||||
fwrite(out, size, sizeof(uint8_t), fd);
|
||||
fclose(fd); fd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out != NULL)
|
||||
{
|
||||
free(out);
|
||||
out = NULL;
|
||||
}
|
||||
|
||||
return size > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/*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_WEBP_H_
|
||||
#define _GRFMT_WEBP_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
#ifdef HAVE_WEBP
|
||||
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class WebPDecoder : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
WebPDecoder();
|
||||
~WebPDecoder();
|
||||
|
||||
bool readData( Mat& img );
|
||||
bool readHeader();
|
||||
void close();
|
||||
|
||||
size_t signatureLength() const;
|
||||
bool checkSignature( const String& signature) const;
|
||||
|
||||
ImageDecoder newDecoder() const;
|
||||
|
||||
protected:
|
||||
Mat data;
|
||||
int channels;
|
||||
};
|
||||
|
||||
class WebPEncoder : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
WebPEncoder();
|
||||
~WebPEncoder();
|
||||
|
||||
bool write(const Mat& img, const std::vector<int>& params);
|
||||
|
||||
ImageEncoder newEncoder() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GRFMT_WEBP_H_ */
|
||||
@@ -1,57 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 _GRFMTS_H_
|
||||
#define _GRFMTS_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "grfmt_bmp.hpp"
|
||||
#include "grfmt_sunras.hpp"
|
||||
#include "grfmt_jpeg.hpp"
|
||||
#include "grfmt_pxm.hpp"
|
||||
#include "grfmt_tiff.hpp"
|
||||
#include "grfmt_png.hpp"
|
||||
#include "grfmt_jpeg2000.hpp"
|
||||
#include "grfmt_exr.hpp"
|
||||
#include "grfmt_webp.hpp"
|
||||
#include "grfmt_hdr.hpp"
|
||||
|
||||
#endif/*_GRFMTS_H_*/
|
||||
@@ -1,117 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
#import "opencv2/highgui/cap_ios.h"
|
||||
#include "precomp.hpp"
|
||||
|
||||
UIImage* MatToUIImage(const cv::Mat& image) {
|
||||
|
||||
NSData *data = [NSData dataWithBytes:image.data
|
||||
length:image.elemSize()*image.total()];
|
||||
|
||||
CGColorSpaceRef colorSpace;
|
||||
|
||||
if (image.elemSize() == 1) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
} else {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
}
|
||||
|
||||
CGDataProviderRef provider =
|
||||
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
|
||||
|
||||
// Creating CGImage from cv::Mat
|
||||
CGImageRef imageRef = CGImageCreate(image.cols,
|
||||
image.rows,
|
||||
8,
|
||||
8 * image.elemSize(),
|
||||
image.step.p[0],
|
||||
colorSpace,
|
||||
kCGImageAlphaNone|
|
||||
kCGBitmapByteOrderDefault,
|
||||
provider,
|
||||
NULL,
|
||||
false,
|
||||
kCGRenderingIntentDefault
|
||||
);
|
||||
|
||||
|
||||
// Getting UIImage from CGImage
|
||||
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CGDataProviderRelease(provider);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return finalImage;
|
||||
}
|
||||
|
||||
void UIImageToMat(const UIImage* image,
|
||||
cv::Mat& m, bool alphaExist) {
|
||||
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
|
||||
CGFloat cols = image.size.width, rows = image.size.height;
|
||||
CGContextRef contextRef;
|
||||
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
|
||||
if (CGColorSpaceGetModel(colorSpace) == 0)
|
||||
{
|
||||
m.create(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
|
||||
bitmapInfo = kCGImageAlphaNone;
|
||||
if (!alphaExist)
|
||||
bitmapInfo = kCGImageAlphaNone;
|
||||
contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
|
||||
m.step[0], colorSpace,
|
||||
bitmapInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
|
||||
if (!alphaExist)
|
||||
bitmapInfo = kCGImageAlphaNoneSkipLast |
|
||||
kCGBitmapByteOrderDefault;
|
||||
contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
|
||||
m.step[0], colorSpace,
|
||||
bitmapInfo);
|
||||
}
|
||||
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows),
|
||||
image.CGImage);
|
||||
CGContextRelease(contextRef);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
}
|
||||
@@ -1,544 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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*/
|
||||
|
||||
//
|
||||
// Loading and saving IPL images.
|
||||
//
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "grfmts.hpp"
|
||||
#undef min
|
||||
#undef max
|
||||
#include <iostream>
|
||||
|
||||
/****************************************************************************************\
|
||||
* Image Codecs *
|
||||
\****************************************************************************************/
|
||||
namespace cv
|
||||
{
|
||||
|
||||
struct ImageCodecInitializer
|
||||
{
|
||||
ImageCodecInitializer()
|
||||
{
|
||||
decoders.push_back( makePtr<BmpDecoder>() );
|
||||
encoders.push_back( makePtr<BmpEncoder>() );
|
||||
decoders.push_back( makePtr<HdrDecoder>() );
|
||||
encoders.push_back( makePtr<HdrEncoder>() );
|
||||
#ifdef HAVE_JPEG
|
||||
decoders.push_back( makePtr<JpegDecoder>() );
|
||||
encoders.push_back( makePtr<JpegEncoder>() );
|
||||
#endif
|
||||
#ifdef HAVE_WEBP
|
||||
decoders.push_back( makePtr<WebPDecoder>() );
|
||||
encoders.push_back( makePtr<WebPEncoder>() );
|
||||
#endif
|
||||
decoders.push_back( makePtr<SunRasterDecoder>() );
|
||||
encoders.push_back( makePtr<SunRasterEncoder>() );
|
||||
decoders.push_back( makePtr<PxMDecoder>() );
|
||||
encoders.push_back( makePtr<PxMEncoder>() );
|
||||
#ifdef HAVE_TIFF
|
||||
decoders.push_back( makePtr<TiffDecoder>() );
|
||||
#endif
|
||||
encoders.push_back( makePtr<TiffEncoder>() );
|
||||
#ifdef HAVE_PNG
|
||||
decoders.push_back( makePtr<PngDecoder>() );
|
||||
encoders.push_back( makePtr<PngEncoder>() );
|
||||
#endif
|
||||
#ifdef HAVE_JASPER
|
||||
decoders.push_back( makePtr<Jpeg2KDecoder>() );
|
||||
encoders.push_back( makePtr<Jpeg2KEncoder>() );
|
||||
#endif
|
||||
#ifdef HAVE_OPENEXR
|
||||
decoders.push_back( makePtr<ExrDecoder>() );
|
||||
encoders.push_back( makePtr<ExrEncoder>() );
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<ImageDecoder> decoders;
|
||||
std::vector<ImageEncoder> encoders;
|
||||
};
|
||||
|
||||
static ImageCodecInitializer codecs;
|
||||
|
||||
static ImageDecoder findDecoder( const String& filename )
|
||||
{
|
||||
size_t i, maxlen = 0;
|
||||
for( i = 0; i < codecs.decoders.size(); i++ )
|
||||
{
|
||||
size_t len = codecs.decoders[i]->signatureLength();
|
||||
maxlen = std::max(maxlen, len);
|
||||
}
|
||||
|
||||
FILE* f= fopen( filename.c_str(), "rb" );
|
||||
if( !f )
|
||||
return ImageDecoder();
|
||||
String signature(maxlen, ' ');
|
||||
maxlen = fread( (void*)signature.c_str(), 1, maxlen, f );
|
||||
fclose(f);
|
||||
signature = signature.substr(0, maxlen);
|
||||
|
||||
for( i = 0; i < codecs.decoders.size(); i++ )
|
||||
{
|
||||
if( codecs.decoders[i]->checkSignature(signature) )
|
||||
return codecs.decoders[i]->newDecoder();
|
||||
}
|
||||
|
||||
return ImageDecoder();
|
||||
}
|
||||
|
||||
static ImageDecoder findDecoder( const Mat& buf )
|
||||
{
|
||||
size_t i, maxlen = 0;
|
||||
|
||||
if( buf.rows*buf.cols < 1 || !buf.isContinuous() )
|
||||
return ImageDecoder();
|
||||
|
||||
for( i = 0; i < codecs.decoders.size(); i++ )
|
||||
{
|
||||
size_t len = codecs.decoders[i]->signatureLength();
|
||||
maxlen = std::max(maxlen, len);
|
||||
}
|
||||
|
||||
size_t bufSize = buf.rows*buf.cols*buf.elemSize();
|
||||
maxlen = std::min(maxlen, bufSize);
|
||||
String signature(maxlen, ' ');
|
||||
memcpy( (void*)signature.c_str(), buf.data, maxlen );
|
||||
|
||||
for( i = 0; i < codecs.decoders.size(); i++ )
|
||||
{
|
||||
if( codecs.decoders[i]->checkSignature(signature) )
|
||||
return codecs.decoders[i]->newDecoder();
|
||||
}
|
||||
|
||||
return ImageDecoder();
|
||||
}
|
||||
|
||||
static ImageEncoder findEncoder( const String& _ext )
|
||||
{
|
||||
if( _ext.size() <= 1 )
|
||||
return ImageEncoder();
|
||||
|
||||
const char* ext = strrchr( _ext.c_str(), '.' );
|
||||
if( !ext )
|
||||
return ImageEncoder();
|
||||
int len = 0;
|
||||
for( ext++; isalnum(ext[len]) && len < 128; len++ )
|
||||
;
|
||||
|
||||
for( size_t i = 0; i < codecs.encoders.size(); i++ )
|
||||
{
|
||||
String description = codecs.encoders[i]->getDescription();
|
||||
const char* descr = strchr( description.c_str(), '(' );
|
||||
|
||||
while( descr )
|
||||
{
|
||||
descr = strchr( descr + 1, '.' );
|
||||
if( !descr )
|
||||
break;
|
||||
int j = 0;
|
||||
for( descr++; isalnum(descr[j]) && j < len; j++ )
|
||||
{
|
||||
int c1 = tolower(ext[j]);
|
||||
int c2 = tolower(descr[j]);
|
||||
if( c1 != c2 )
|
||||
break;
|
||||
}
|
||||
if( j == len && !isalnum(descr[j]))
|
||||
return codecs.encoders[i]->newEncoder();
|
||||
descr += j;
|
||||
}
|
||||
}
|
||||
|
||||
return ImageEncoder();
|
||||
}
|
||||
|
||||
enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 };
|
||||
|
||||
static void*
|
||||
imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
|
||||
{
|
||||
IplImage* image = 0;
|
||||
CvMat *matrix = 0;
|
||||
Mat temp, *data = &temp;
|
||||
|
||||
ImageDecoder decoder = findDecoder(filename);
|
||||
if( !decoder )
|
||||
return 0;
|
||||
decoder->setSource(filename);
|
||||
if( !decoder->readHeader() )
|
||||
return 0;
|
||||
CvSize size;
|
||||
size.width = decoder->width();
|
||||
size.height = decoder->height();
|
||||
|
||||
int type = decoder->type();
|
||||
if( flags != -1 )
|
||||
{
|
||||
if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 )
|
||||
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
|
||||
|
||||
if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||
|
||||
((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )
|
||||
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
|
||||
else
|
||||
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
|
||||
}
|
||||
|
||||
if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT )
|
||||
{
|
||||
if( hdrtype == LOAD_CVMAT )
|
||||
{
|
||||
matrix = cvCreateMat( size.height, size.width, type );
|
||||
temp = cvarrToMat(matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat->create( size.height, size.width, type );
|
||||
data = mat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) );
|
||||
temp = cvarrToMat(image);
|
||||
}
|
||||
|
||||
if( !decoder->readData( *data ))
|
||||
{
|
||||
cvReleaseImage( &image );
|
||||
cvReleaseMat( &matrix );
|
||||
if( mat )
|
||||
mat->release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hdrtype == LOAD_CVMAT ? (void*)matrix :
|
||||
hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat;
|
||||
}
|
||||
|
||||
Mat imread( const String& filename, int flags )
|
||||
{
|
||||
Mat img;
|
||||
imread_( filename, flags, LOAD_MAT, &img );
|
||||
return img;
|
||||
}
|
||||
|
||||
static bool imwrite_( const String& filename, const Mat& image,
|
||||
const std::vector<int>& params, bool flipv )
|
||||
{
|
||||
Mat temp;
|
||||
const Mat* pimage = ℑ
|
||||
|
||||
CV_Assert( image.channels() == 1 || image.channels() == 3 || image.channels() == 4 );
|
||||
|
||||
ImageEncoder encoder = findEncoder( filename );
|
||||
if( !encoder )
|
||||
CV_Error( CV_StsError, "could not find a writer for the specified extension" );
|
||||
if( !encoder->isFormatSupported(image.depth()) )
|
||||
{
|
||||
CV_Assert( encoder->isFormatSupported(CV_8U) );
|
||||
image.convertTo( temp, CV_8U );
|
||||
pimage = &temp;
|
||||
}
|
||||
|
||||
if( flipv )
|
||||
{
|
||||
flip(*pimage, temp, 0);
|
||||
pimage = &temp;
|
||||
}
|
||||
|
||||
encoder->setDestination( filename );
|
||||
bool code = encoder->write( *pimage, params );
|
||||
|
||||
// CV_Assert( code );
|
||||
return code;
|
||||
}
|
||||
|
||||
bool imwrite( const String& filename, InputArray _img,
|
||||
const std::vector<int>& params )
|
||||
{
|
||||
Mat img = _img.getMat();
|
||||
return imwrite_(filename, img, params, false);
|
||||
}
|
||||
|
||||
static void*
|
||||
imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
|
||||
{
|
||||
CV_Assert(buf.data && buf.isContinuous());
|
||||
IplImage* image = 0;
|
||||
CvMat *matrix = 0;
|
||||
Mat temp, *data = &temp;
|
||||
String filename;
|
||||
|
||||
ImageDecoder decoder = findDecoder(buf);
|
||||
if( !decoder )
|
||||
return 0;
|
||||
|
||||
if( !decoder->setSource(buf) )
|
||||
{
|
||||
filename = tempfile();
|
||||
FILE* f = fopen( filename.c_str(), "wb" );
|
||||
if( !f )
|
||||
return 0;
|
||||
size_t bufSize = buf.cols*buf.rows*buf.elemSize();
|
||||
fwrite( &buf.data[0], 1, bufSize, f );
|
||||
fclose(f);
|
||||
decoder->setSource(filename);
|
||||
}
|
||||
|
||||
if( !decoder->readHeader() )
|
||||
{
|
||||
if( !filename.empty() )
|
||||
remove(filename.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
CvSize size;
|
||||
size.width = decoder->width();
|
||||
size.height = decoder->height();
|
||||
|
||||
int type = decoder->type();
|
||||
if( flags != -1 )
|
||||
{
|
||||
if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 )
|
||||
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
|
||||
|
||||
if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||
|
||||
((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )
|
||||
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
|
||||
else
|
||||
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
|
||||
}
|
||||
|
||||
if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT )
|
||||
{
|
||||
if( hdrtype == LOAD_CVMAT )
|
||||
{
|
||||
matrix = cvCreateMat( size.height, size.width, type );
|
||||
temp = cvarrToMat(matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat->create( size.height, size.width, type );
|
||||
data = mat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) );
|
||||
temp = cvarrToMat(image);
|
||||
}
|
||||
|
||||
bool code = decoder->readData( *data );
|
||||
if( !filename.empty() )
|
||||
remove(filename.c_str());
|
||||
|
||||
if( !code )
|
||||
{
|
||||
cvReleaseImage( &image );
|
||||
cvReleaseMat( &matrix );
|
||||
if( mat )
|
||||
mat->release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hdrtype == LOAD_CVMAT ? (void*)matrix :
|
||||
hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat;
|
||||
}
|
||||
|
||||
|
||||
Mat imdecode( InputArray _buf, int flags )
|
||||
{
|
||||
Mat buf = _buf.getMat(), img;
|
||||
imdecode_( buf, flags, LOAD_MAT, &img );
|
||||
return img;
|
||||
}
|
||||
|
||||
Mat imdecode( InputArray _buf, int flags, Mat* dst )
|
||||
{
|
||||
Mat buf = _buf.getMat(), img;
|
||||
dst = dst ? dst : &img;
|
||||
imdecode_( buf, flags, LOAD_MAT, dst );
|
||||
return *dst;
|
||||
}
|
||||
|
||||
bool imencode( const String& ext, InputArray _image,
|
||||
std::vector<uchar>& buf, const std::vector<int>& params )
|
||||
{
|
||||
Mat image = _image.getMat();
|
||||
|
||||
int channels = image.channels();
|
||||
CV_Assert( channels == 1 || channels == 3 || channels == 4 );
|
||||
|
||||
ImageEncoder encoder = findEncoder( ext );
|
||||
if( !encoder )
|
||||
CV_Error( CV_StsError, "could not find encoder for the specified extension" );
|
||||
|
||||
if( !encoder->isFormatSupported(image.depth()) )
|
||||
{
|
||||
CV_Assert( encoder->isFormatSupported(CV_8U) );
|
||||
Mat temp;
|
||||
image.convertTo(temp, CV_8U);
|
||||
image = temp;
|
||||
}
|
||||
|
||||
bool code;
|
||||
if( encoder->setDestination(buf) )
|
||||
{
|
||||
code = encoder->write(image, params);
|
||||
encoder->throwOnEror();
|
||||
CV_Assert( code );
|
||||
}
|
||||
else
|
||||
{
|
||||
String filename = tempfile();
|
||||
code = encoder->setDestination(filename);
|
||||
CV_Assert( code );
|
||||
|
||||
code = encoder->write(image, params);
|
||||
encoder->throwOnEror();
|
||||
CV_Assert( code );
|
||||
|
||||
FILE* f = fopen( filename.c_str(), "rb" );
|
||||
CV_Assert(f != 0);
|
||||
fseek( f, 0, SEEK_END );
|
||||
long pos = ftell(f);
|
||||
buf.resize((size_t)pos);
|
||||
fseek( f, 0, SEEK_SET );
|
||||
buf.resize(fread( &buf[0], 1, buf.size(), f ));
|
||||
fclose(f);
|
||||
remove(filename.c_str());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* HighGUI loading & saving function implementation *
|
||||
\****************************************************************************************/
|
||||
|
||||
CV_IMPL int
|
||||
cvHaveImageReader( const char* filename )
|
||||
{
|
||||
cv::ImageDecoder decoder = cv::findDecoder(filename);
|
||||
return !decoder.empty();
|
||||
}
|
||||
|
||||
CV_IMPL int cvHaveImageWriter( const char* filename )
|
||||
{
|
||||
cv::ImageEncoder encoder = cv::findEncoder(filename);
|
||||
return !encoder.empty();
|
||||
}
|
||||
|
||||
CV_IMPL IplImage*
|
||||
cvLoadImage( const char* filename, int iscolor )
|
||||
{
|
||||
return (IplImage*)cv::imread_(filename, iscolor, cv::LOAD_IMAGE );
|
||||
}
|
||||
|
||||
CV_IMPL CvMat*
|
||||
cvLoadImageM( const char* filename, int iscolor )
|
||||
{
|
||||
return (CvMat*)cv::imread_( filename, iscolor, cv::LOAD_CVMAT );
|
||||
}
|
||||
|
||||
CV_IMPL int
|
||||
cvSaveImage( const char* filename, const CvArr* arr, const int* _params )
|
||||
{
|
||||
int i = 0;
|
||||
if( _params )
|
||||
{
|
||||
for( ; _params[i] > 0; i += 2 )
|
||||
;
|
||||
}
|
||||
return cv::imwrite_(filename, cv::cvarrToMat(arr),
|
||||
i > 0 ? std::vector<int>(_params, _params+i) : std::vector<int>(),
|
||||
CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL );
|
||||
}
|
||||
|
||||
/* decode image stored in the buffer */
|
||||
CV_IMPL IplImage*
|
||||
cvDecodeImage( const CvMat* _buf, int iscolor )
|
||||
{
|
||||
CV_Assert( _buf && CV_IS_MAT_CONT(_buf->type) );
|
||||
cv::Mat buf(1, _buf->rows*_buf->cols*CV_ELEM_SIZE(_buf->type), CV_8U, _buf->data.ptr);
|
||||
return (IplImage*)cv::imdecode_(buf, iscolor, cv::LOAD_IMAGE );
|
||||
}
|
||||
|
||||
CV_IMPL CvMat*
|
||||
cvDecodeImageM( const CvMat* _buf, int iscolor )
|
||||
{
|
||||
CV_Assert( _buf && CV_IS_MAT_CONT(_buf->type) );
|
||||
cv::Mat buf(1, _buf->rows*_buf->cols*CV_ELEM_SIZE(_buf->type), CV_8U, _buf->data.ptr);
|
||||
return (CvMat*)cv::imdecode_(buf, iscolor, cv::LOAD_CVMAT );
|
||||
}
|
||||
|
||||
CV_IMPL CvMat*
|
||||
cvEncodeImage( const char* ext, const CvArr* arr, const int* _params )
|
||||
{
|
||||
int i = 0;
|
||||
if( _params )
|
||||
{
|
||||
for( ; _params[i] > 0; i += 2 )
|
||||
;
|
||||
}
|
||||
cv::Mat img = cv::cvarrToMat(arr);
|
||||
if( CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL )
|
||||
{
|
||||
cv::Mat temp;
|
||||
cv::flip(img, temp, 0);
|
||||
img = temp;
|
||||
}
|
||||
std::vector<uchar> buf;
|
||||
|
||||
bool code = cv::imencode(ext, img, buf,
|
||||
i > 0 ? std::vector<int>(_params, _params+i) : std::vector<int>() );
|
||||
if( !code )
|
||||
return 0;
|
||||
CvMat* _buf = cvCreateMat(1, (int)buf.size(), CV_8U);
|
||||
memcpy( _buf->data.ptr, &buf[0], buf.size() );
|
||||
|
||||
return _buf;
|
||||
}
|
||||
|
||||
/* End of file. */
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "opencv2/core/private.hpp"
|
||||
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/imgcodecs/imgcodecs_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,450 +0,0 @@
|
||||
/*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 "precomp.hpp"
|
||||
#include "rgbe.hpp"
|
||||
#include <math.h>
|
||||
#if !defined(__APPLE__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#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, error handler uses CV_Error,
|
||||
// defines changed to work in bgr color space.
|
||||
//
|
||||
// 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, const 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 = static_cast<float>(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 = static_cast<float>(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)
|
||||
{
|
||||
const 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];
|
||||
float tempf;
|
||||
int i;
|
||||
|
||||
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<static_cast<int>(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] = static_cast<unsigned char>(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] = static_cast<unsigned char>(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] = static_cast<unsigned char>(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] = static_cast<unsigned char>(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[RGBE_DATA_RED],&data[RGBE_DATA_GREEN],&data[RGBE_DATA_BLUE],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;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*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_*/
|
||||
@@ -1,689 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 "precomp.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#define SCALE 14
|
||||
#define cR (int)(0.299*(1 << SCALE) + 0.5)
|
||||
#define cG (int)(0.587*(1 << SCALE) + 0.5)
|
||||
#define cB ((1 << SCALE) - cR - cG)
|
||||
|
||||
void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step,
|
||||
uchar* gray, int gray_step,
|
||||
CvSize size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
int swap_rb = _swap_rb ? 2 : 0;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, rgb += 3 )
|
||||
{
|
||||
int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
|
||||
rgb += rgb_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step,
|
||||
ushort* gray, int gray_step,
|
||||
CvSize size, int ncn, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
int swap_rb = _swap_rb ? 2 : 0;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, rgb += ncn )
|
||||
{
|
||||
int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE );
|
||||
gray[i] = (ushort)t;
|
||||
}
|
||||
|
||||
rgb += rgb_step - size.width*ncn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step,
|
||||
uchar* gray, int gray_step,
|
||||
CvSize size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
int swap_rb = _swap_rb ? 2 : 0;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, rgba += 4 )
|
||||
{
|
||||
int t = descale( rgba[swap_rb]*cB + rgba[1]*cG + rgba[swap_rb^2]*cR, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
|
||||
rgba += rgba_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
|
||||
uchar* bgr, int bgr_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3 )
|
||||
{
|
||||
bgr[0] = bgr[1] = bgr[2] = gray[i];
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
|
||||
ushort* bgr, int bgr_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step/sizeof(gray[0]) )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3 )
|
||||
{
|
||||
bgr[0] = bgr[1] = bgr[2] = gray[i];
|
||||
}
|
||||
bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
|
||||
uchar* bgr, int bgr_step,
|
||||
CvSize size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
int swap_rb = _swap_rb ? 2 : 0;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 )
|
||||
{
|
||||
uchar t0 = bgra[swap_rb], t1 = bgra[1];
|
||||
bgr[0] = t0; bgr[1] = t1;
|
||||
t0 = bgra[swap_rb^2]; bgr[2] = t0;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
bgra += bgra_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
|
||||
ushort* bgr, int bgr_step,
|
||||
CvSize size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
int swap_rb = _swap_rb ? 2 : 0;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 )
|
||||
{
|
||||
ushort t0 = bgra[swap_rb], t1 = bgra[1];
|
||||
bgr[0] = t0; bgr[1] = t1;
|
||||
t0 = bgra[swap_rb^2]; bgr[2] = t0;
|
||||
}
|
||||
bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
|
||||
bgra += bgra_step/sizeof(bgra[0]) - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
|
||||
uchar* rgba, int rgba_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 )
|
||||
{
|
||||
uchar t0 = bgra[0], t1 = bgra[1];
|
||||
uchar t2 = bgra[2], t3 = bgra[3];
|
||||
rgba[0] = t2; rgba[1] = t1;
|
||||
rgba[2] = t0; rgba[3] = t3;
|
||||
}
|
||||
bgra += bgra_step - size.width*4;
|
||||
rgba += rgba_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step,
|
||||
ushort* rgba, int rgba_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 )
|
||||
{
|
||||
ushort t0 = bgra[0], t1 = bgra[1];
|
||||
ushort t2 = bgra[2], t3 = bgra[3];
|
||||
|
||||
rgba[0] = t2; rgba[1] = t1;
|
||||
rgba[2] = t0; rgba[3] = t3;
|
||||
}
|
||||
bgra += bgra_step/sizeof(bgra[0]) - size.width*4;
|
||||
rgba += rgba_step/sizeof(rgba[0]) - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
|
||||
uchar* rgb, int rgb_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 )
|
||||
{
|
||||
uchar t0 = bgr[0], t1 = bgr[1], t2 = bgr[2];
|
||||
rgb[2] = t0; rgb[1] = t1; rgb[0] = t2;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
rgb += rgb_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step,
|
||||
ushort* rgb, int rgb_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 )
|
||||
{
|
||||
ushort t0 = bgr[0], t1 = bgr[1], t2 = bgr[2];
|
||||
rgb[2] = t0; rgb[1] = t1; rgb[0] = t2;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
rgb += rgb_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef unsigned short ushort;
|
||||
|
||||
void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
|
||||
uchar* gray, int gray_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step, bgr555 += bgr555_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++ )
|
||||
{
|
||||
int t = descale( ((((ushort*)bgr555)[i] << 3) & 0xf8)*cB +
|
||||
((((ushort*)bgr555)[i] >> 2) & 0xf8)*cG +
|
||||
((((ushort*)bgr555)[i] >> 7) & 0xf8)*cR, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* gray, int gray_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step, bgr565 += bgr565_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++ )
|
||||
{
|
||||
int t = descale( ((((ushort*)bgr565)[i] << 3) & 0xf8)*cB +
|
||||
((((ushort*)bgr565)[i] >> 3) & 0xfc)*cG +
|
||||
((((ushort*)bgr565)[i] >> 8) & 0xf8)*cR, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
|
||||
uchar* bgr, int bgr_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; bgr555 += bgr555_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3 )
|
||||
{
|
||||
int t0 = (((ushort*)bgr555)[i] << 3) & 0xf8;
|
||||
int t1 = (((ushort*)bgr555)[i] >> 2) & 0xf8;
|
||||
int t2 = (((ushort*)bgr555)[i] >> 7) & 0xf8;
|
||||
bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* bgr, int bgr_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; bgr565 += bgr565_step )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3 )
|
||||
{
|
||||
int t0 = (((ushort*)bgr565)[i] << 3) & 0xf8;
|
||||
int t1 = (((ushort*)bgr565)[i] >> 3) & 0xfc;
|
||||
int t2 = (((ushort*)bgr565)[i] >> 8) & 0xf8;
|
||||
bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
|
||||
uchar* bgr, int bgr_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, bgr += 3, cmyk += 4 )
|
||||
{
|
||||
int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
|
||||
c = k - ((255 - c)*k>>8);
|
||||
m = k - ((255 - m)*k>>8);
|
||||
y = k - ((255 - y)*k>>8);
|
||||
bgr[2] = (uchar)c; bgr[1] = (uchar)m; bgr[0] = (uchar)y;
|
||||
}
|
||||
bgr += bgr_step - size.width*3;
|
||||
cmyk += cmyk_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* cmyk, int cmyk_step,
|
||||
uchar* gray, int gray_step, CvSize size )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; )
|
||||
{
|
||||
for( i = 0; i < size.width; i++, cmyk += 4 )
|
||||
{
|
||||
int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
|
||||
c = k - ((255 - c)*k>>8);
|
||||
m = k - ((255 - m)*k>>8);
|
||||
y = k - ((255 - y)*k>>8);
|
||||
int t = descale( y*cB + m*cG + c*cR, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
gray += gray_step;
|
||||
cmyk += cmyk_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < entries; i++ )
|
||||
{
|
||||
icvCvt_BGR2Gray_8u_C3C1R( (uchar*)(palette + i), 0, grayPalette + i, 0, cvSize(1,1) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative )
|
||||
{
|
||||
int i, length = 1 << bpp;
|
||||
int xor_mask = negative ? 255 : 0;
|
||||
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
int val = (i * 255/(length - 1)) ^ xor_mask;
|
||||
palette[i].b = palette[i].g = palette[i].r = (uchar)val;
|
||||
palette[i].a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IsColorPalette( PaletteEntry* palette, int bpp )
|
||||
{
|
||||
int i, length = 1 << bpp;
|
||||
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
if( palette[i].b != palette[i].g ||
|
||||
palette[i].b != palette[i].r )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillUniColor( uchar* data, uchar*& line_end,
|
||||
int step, int width3,
|
||||
int& y, int height,
|
||||
int count3, PaletteEntry clr )
|
||||
{
|
||||
do
|
||||
{
|
||||
uchar* end = data + count3;
|
||||
|
||||
if( end > line_end )
|
||||
end = line_end;
|
||||
|
||||
count3 -= (int)(end - data);
|
||||
|
||||
for( ; data < end; data += 3 )
|
||||
{
|
||||
WRITE_PIX( data, clr );
|
||||
}
|
||||
|
||||
if( data >= line_end )
|
||||
{
|
||||
line_end += step;
|
||||
data = line_end - width3;
|
||||
if( ++y >= height ) break;
|
||||
}
|
||||
}
|
||||
while( count3 > 0 );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillUniGray( uchar* data, uchar*& line_end,
|
||||
int step, int width,
|
||||
int& y, int height,
|
||||
int count, uchar clr )
|
||||
{
|
||||
do
|
||||
{
|
||||
uchar* end = data + count;
|
||||
|
||||
if( end > line_end )
|
||||
end = line_end;
|
||||
|
||||
count -= (int)(end - data);
|
||||
|
||||
for( ; data < end; data++ )
|
||||
{
|
||||
*data = clr;
|
||||
}
|
||||
|
||||
if( data >= line_end )
|
||||
{
|
||||
line_end += step;
|
||||
data = line_end - width;
|
||||
if( ++y >= height ) break;
|
||||
}
|
||||
}
|
||||
while( count > 0 );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette )
|
||||
{
|
||||
uchar* end = data + len*3;
|
||||
while( (data += 3) < end )
|
||||
{
|
||||
*((PaletteEntry*)(data-3)) = palette[*indices++];
|
||||
}
|
||||
PaletteEntry clr = palette[indices[0]];
|
||||
WRITE_PIX( data - 3, clr );
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < len; i++ )
|
||||
{
|
||||
data[i] = palette[indices[i]];
|
||||
}
|
||||
return data + len;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillColorRow4( uchar* data, uchar* indices, int len, PaletteEntry* palette )
|
||||
{
|
||||
uchar* end = data + len*3;
|
||||
|
||||
while( (data += 6) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
*((PaletteEntry*)(data-6)) = palette[idx >> 4];
|
||||
*((PaletteEntry*)(data-3)) = palette[idx & 15];
|
||||
}
|
||||
|
||||
int idx = indices[0];
|
||||
PaletteEntry clr = palette[idx >> 4];
|
||||
WRITE_PIX( data - 6, clr );
|
||||
|
||||
if( data == end )
|
||||
{
|
||||
clr = palette[idx & 15];
|
||||
WRITE_PIX( data - 3, clr );
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillGrayRow4( uchar* data, uchar* indices, int len, uchar* palette )
|
||||
{
|
||||
uchar* end = data + len;
|
||||
while( (data += 2) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
data[-2] = palette[idx >> 4];
|
||||
data[-1] = palette[idx & 15];
|
||||
}
|
||||
|
||||
int idx = indices[0];
|
||||
uchar clr = palette[idx >> 4];
|
||||
data[-2] = clr;
|
||||
|
||||
if( data == end )
|
||||
{
|
||||
clr = palette[idx & 15];
|
||||
data[-1] = clr;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palette )
|
||||
{
|
||||
uchar* end = data + len*3;
|
||||
|
||||
while( (data += 24) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
*((PaletteEntry*)(data - 24)) = palette[(idx & 128) != 0];
|
||||
*((PaletteEntry*)(data - 21)) = palette[(idx & 64) != 0];
|
||||
*((PaletteEntry*)(data - 18)) = palette[(idx & 32) != 0];
|
||||
*((PaletteEntry*)(data - 15)) = palette[(idx & 16) != 0];
|
||||
*((PaletteEntry*)(data - 12)) = palette[(idx & 8) != 0];
|
||||
*((PaletteEntry*)(data - 9)) = palette[(idx & 4) != 0];
|
||||
*((PaletteEntry*)(data - 6)) = palette[(idx & 2) != 0];
|
||||
*((PaletteEntry*)(data - 3)) = palette[(idx & 1) != 0];
|
||||
}
|
||||
|
||||
int idx = indices[0] << 24;
|
||||
for( data -= 24; data < end; data += 3, idx += idx )
|
||||
{
|
||||
PaletteEntry clr = palette[idx < 0];
|
||||
WRITE_PIX( data, clr );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
|
||||
{
|
||||
uchar* end = data + len;
|
||||
|
||||
while( (data += 8) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
*((uchar*)(data - 8)) = palette[(idx & 128) != 0];
|
||||
*((uchar*)(data - 7)) = palette[(idx & 64) != 0];
|
||||
*((uchar*)(data - 6)) = palette[(idx & 32) != 0];
|
||||
*((uchar*)(data - 5)) = palette[(idx & 16) != 0];
|
||||
*((uchar*)(data - 4)) = palette[(idx & 8) != 0];
|
||||
*((uchar*)(data - 3)) = palette[(idx & 4) != 0];
|
||||
*((uchar*)(data - 2)) = palette[(idx & 2) != 0];
|
||||
*((uchar*)(data - 1)) = palette[(idx & 1) != 0];
|
||||
}
|
||||
|
||||
int idx = indices[0] << 24;
|
||||
for( data -= 8; data < end; data++, idx += idx )
|
||||
{
|
||||
data[0] = palette[idx < 0];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
CV_IMPL void
|
||||
cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags )
|
||||
{
|
||||
CvMat* temp = 0;
|
||||
|
||||
CV_FUNCNAME( "cvConvertImage" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvMat srcstub, *src;
|
||||
CvMat dststub, *dst;
|
||||
int src_cn, dst_cn, swap_rb = flags & CV_CVTIMG_SWAP_RB;
|
||||
|
||||
CV_CALL( src = cvGetMat( srcarr, &srcstub ));
|
||||
CV_CALL( dst = cvGetMat( dstarr, &dststub ));
|
||||
|
||||
src_cn = CV_MAT_CN( src->type );
|
||||
dst_cn = CV_MAT_CN( dst->type );
|
||||
|
||||
if( src_cn != 1 && src_cn != 3 && src_cn != 4 )
|
||||
CV_ERROR( CV_BadNumChannels, "Source image must have 1, 3 or 4 channels" );
|
||||
|
||||
if( CV_MAT_DEPTH( dst->type ) != CV_8U )
|
||||
CV_ERROR( CV_BadDepth, "Destination image must be 8u" );
|
||||
|
||||
if( CV_MAT_CN(dst->type) != 1 && CV_MAT_CN(dst->type) != 3 )
|
||||
CV_ERROR( CV_BadNumChannels, "Destination image must have 1 or 3 channels" );
|
||||
|
||||
if( !CV_ARE_DEPTHS_EQ( src, dst ))
|
||||
{
|
||||
int src_depth = CV_MAT_DEPTH(src->type);
|
||||
double scale = src_depth <= CV_8S ? 1 : src_depth <= CV_32S ? 1./256 : 255;
|
||||
double shift = src_depth == CV_8S || src_depth == CV_16S ? 128 : 0;
|
||||
|
||||
if( !CV_ARE_CNS_EQ( src, dst ))
|
||||
{
|
||||
temp = cvCreateMat( src->height, src->width,
|
||||
(src->type & CV_MAT_CN_MASK)|(dst->type & CV_MAT_DEPTH_MASK));
|
||||
cvConvertScale( src, temp, scale, shift );
|
||||
src = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
cvConvertScale( src, dst, scale, shift );
|
||||
src = dst;
|
||||
}
|
||||
}
|
||||
|
||||
if( src_cn != dst_cn || (src_cn == 3 && swap_rb) )
|
||||
{
|
||||
uchar *s = src->data.ptr, *d = dst->data.ptr;
|
||||
int s_step = src->step, d_step = dst->step;
|
||||
int code = src_cn*10 + dst_cn;
|
||||
CvSize size(src->cols, src->rows);
|
||||
|
||||
if( CV_IS_MAT_CONT(src->type & dst->type) )
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
s_step = d_step = /*CV_STUB_STEP*/ (1 << 30);
|
||||
}
|
||||
|
||||
switch( code )
|
||||
{
|
||||
case 13:
|
||||
icvCvt_Gray2BGR_8u_C1C3R( s, s_step, d, d_step, size );
|
||||
break;
|
||||
case 31:
|
||||
icvCvt_BGR2Gray_8u_C3C1R( s, s_step, d, d_step, size, swap_rb );
|
||||
break;
|
||||
case 33:
|
||||
assert( swap_rb );
|
||||
icvCvt_RGB2BGR_8u_C3R( s, s_step, d, d_step, size );
|
||||
break;
|
||||
case 41:
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( s, s_step, d, d_step, size, swap_rb );
|
||||
break;
|
||||
case 43:
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( s, s_step, d, d_step, size, swap_rb );
|
||||
break;
|
||||
default:
|
||||
CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input/output formats" );
|
||||
}
|
||||
src = dst;
|
||||
}
|
||||
|
||||
if( flags & CV_CVTIMG_FLIP )
|
||||
{
|
||||
CV_CALL( cvFlip( src, dst, 0 ));
|
||||
}
|
||||
else if( src != dst )
|
||||
{
|
||||
CV_CALL( cvCopy( src, dst ));
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
cvReleaseMat( &temp );
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
struct PaletteEntry
|
||||
{
|
||||
unsigned char b, g, r, a;
|
||||
};
|
||||
|
||||
#define WRITE_PIX( ptr, clr ) \
|
||||
(((uchar*)(ptr))[0] = (clr).b, \
|
||||
((uchar*)(ptr))[1] = (clr).g, \
|
||||
((uchar*)(ptr))[2] = (clr).r)
|
||||
|
||||
#define descale(x,n) (((x) + (1 << ((n)-1))) >> (n))
|
||||
#define saturate(x) (uchar)(((x) & ~255) == 0 ? (x) : ~((x)>>31))
|
||||
|
||||
void icvCvt_BGR2Gray_8u_C3C1R( const uchar* bgr, int bgr_step,
|
||||
uchar* gray, int gray_step,
|
||||
CvSize size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int bgra_step,
|
||||
uchar* gray, int gray_step,
|
||||
CvSize size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgra, int bgra_step,
|
||||
ushort* gray, int gray_step,
|
||||
CvSize size, int ncn, int swap_rb=0 );
|
||||
|
||||
void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
|
||||
uchar* bgr, int bgr_step, CvSize size );
|
||||
void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
|
||||
ushort* bgr, int bgr_step, CvSize size );
|
||||
|
||||
void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
|
||||
uchar* bgr, int bgr_step,
|
||||
CvSize size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
|
||||
ushort* bgr, int bgr_step,
|
||||
CvSize size, int _swap_rb );
|
||||
|
||||
void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
|
||||
uchar* rgb, int rgb_step, CvSize size );
|
||||
#define icvCvt_RGB2BGR_8u_C3R icvCvt_BGR2RGB_8u_C3R
|
||||
void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step,
|
||||
ushort* rgb, int rgb_step, CvSize size );
|
||||
#define icvCvt_RGB2BGR_16u_C3R icvCvt_BGR2RGB_16u_C3R
|
||||
|
||||
void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
|
||||
uchar* rgba, int rgba_step, CvSize size );
|
||||
#define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R
|
||||
|
||||
void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step,
|
||||
ushort* rgba, int rgba_step, CvSize size );
|
||||
#define icvCvt_RGBA2BGRA_16u_C4R icvCvt_BGRA2RGBA_16u_C4R
|
||||
|
||||
void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
|
||||
uchar* gray, int gray_step, CvSize size );
|
||||
void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* gray, int gray_step, CvSize size );
|
||||
void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
|
||||
uchar* bgr, int bgr_step, CvSize size );
|
||||
void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* bgr, int bgr_step, CvSize size );
|
||||
void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
|
||||
uchar* bgr, int bgr_step, CvSize size );
|
||||
void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* ycck, int ycck_step,
|
||||
uchar* gray, int gray_step, CvSize size );
|
||||
|
||||
void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative = false );
|
||||
bool IsColorPalette( PaletteEntry* palette, int bpp );
|
||||
void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries );
|
||||
uchar* FillUniColor( uchar* data, uchar*& line_end, int step, int width3,
|
||||
int& y, int height, int count3, PaletteEntry clr );
|
||||
uchar* FillUniGray( uchar* data, uchar*& line_end, int step, int width3,
|
||||
int& y, int height, int count3, uchar clr );
|
||||
|
||||
uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette );
|
||||
uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette );
|
||||
uchar* FillColorRow4( uchar* data, uchar* indices, int len, PaletteEntry* palette );
|
||||
uchar* FillGrayRow4( uchar* data, uchar* indices, int len, uchar* palette );
|
||||
uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palette );
|
||||
uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette );
|
||||
|
||||
CV_INLINE bool isBigEndian( void )
|
||||
{
|
||||
return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
|
||||
}
|
||||
|
||||
#endif/*_UTILS_H_*/
|
||||
Reference in New Issue
Block a user