feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
11
3rdparty/opencv-4.5.4/modules/imgcodecs/src/apple_conversions.h
vendored
Normal file
11
3rdparty/opencv-4.5.4/modules/imgcodecs/src/apple_conversions.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#import <Accelerate/Accelerate.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
CV_EXPORTS CGImageRef MatToCGImage(const cv::Mat& image) CF_RETURNS_RETAINED;
|
||||
CV_EXPORTS void CGImageToMat(const CGImageRef image, cv::Mat& m, bool alphaExist);
|
94
3rdparty/opencv-4.5.4/modules/imgcodecs/src/apple_conversions.mm
vendored
Normal file
94
3rdparty/opencv-4.5.4/modules/imgcodecs/src/apple_conversions.mm
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "apple_conversions.h"
|
||||
#include "precomp.hpp"
|
||||
|
||||
CGImageRef MatToCGImage(const cv::Mat& image) {
|
||||
NSData *data = [NSData dataWithBytes:image.data
|
||||
length:image.step.p[0] * image.rows];
|
||||
|
||||
CGColorSpaceRef colorSpace;
|
||||
|
||||
if (image.elemSize() == 1) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
} else {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
}
|
||||
|
||||
CGDataProviderRef provider =
|
||||
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
|
||||
|
||||
// Preserve alpha transparency, if exists
|
||||
bool alpha = image.channels() == 4;
|
||||
CGBitmapInfo bitmapInfo = (alpha ? kCGImageAlphaLast : kCGImageAlphaNone) | kCGBitmapByteOrderDefault;
|
||||
|
||||
// Creating CGImage from cv::Mat
|
||||
CGImageRef imageRef = CGImageCreate(image.cols,
|
||||
image.rows,
|
||||
8 * image.elemSize1(),
|
||||
8 * image.elemSize(),
|
||||
image.step.p[0],
|
||||
colorSpace,
|
||||
bitmapInfo,
|
||||
provider,
|
||||
NULL,
|
||||
false,
|
||||
kCGRenderingIntentDefault
|
||||
);
|
||||
|
||||
CGDataProviderRelease(provider);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return imageRef;
|
||||
}
|
||||
|
||||
void CGImageToMat(const CGImageRef image, cv::Mat& m, bool alphaExist) {
|
||||
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image);
|
||||
CGFloat cols = CGImageGetWidth(image), rows = CGImageGetHeight(image);
|
||||
CGContextRef contextRef;
|
||||
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
|
||||
if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome)
|
||||
{
|
||||
m.create(rows, cols, CV_8UC1); // 8 bits per component, 1 channel
|
||||
bitmapInfo = kCGImageAlphaNone;
|
||||
if (!alphaExist)
|
||||
bitmapInfo = kCGImageAlphaNone;
|
||||
else
|
||||
m = cv::Scalar(0);
|
||||
contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
|
||||
m.step[0], colorSpace,
|
||||
bitmapInfo);
|
||||
}
|
||||
else if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelIndexed)
|
||||
{
|
||||
// CGBitmapContextCreate() does not support indexed color spaces.
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
|
||||
if (!alphaExist)
|
||||
bitmapInfo = kCGImageAlphaNoneSkipLast |
|
||||
kCGBitmapByteOrderDefault;
|
||||
else
|
||||
m = cv::Scalar(0);
|
||||
contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
|
||||
m.step[0], colorSpace,
|
||||
bitmapInfo);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
|
||||
if (!alphaExist)
|
||||
bitmapInfo = kCGImageAlphaNoneSkipLast |
|
||||
kCGBitmapByteOrderDefault;
|
||||
else
|
||||
m = cv::Scalar(0);
|
||||
contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8,
|
||||
m.step[0], colorSpace,
|
||||
bitmapInfo);
|
||||
}
|
||||
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows),
|
||||
image);
|
||||
CGContextRelease(contextRef);
|
||||
}
|
594
3rdparty/opencv-4.5.4/modules/imgcodecs/src/bitstrm.cpp
vendored
Normal file
594
3rdparty/opencv-4.5.4/modules/imgcodecs/src/bitstrm.cpp
vendored
Normal file
@ -0,0 +1,594 @@
|
||||
/*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"
|
||||
#include "utils.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_pos = 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;
|
||||
|
||||
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 )
|
||||
{
|
||||
CV_Assert(isOpened() && pos >= 0);
|
||||
|
||||
if( !m_file )
|
||||
{
|
||||
m_current = m_start + pos;
|
||||
m_block_pos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = pos % m_block_size;
|
||||
int old_block_pos = m_block_pos;
|
||||
m_block_pos = pos - offset;
|
||||
m_current = m_start + offset;
|
||||
if (old_block_pos != m_block_pos)
|
||||
readBlock();
|
||||
}
|
||||
|
||||
|
||||
int RBaseStream::getPos()
|
||||
{
|
||||
CV_Assert(isOpened());
|
||||
int pos = validateToInt((m_current - m_start) + m_block_pos);
|
||||
CV_Assert(pos >= m_block_pos); // overflow check
|
||||
CV_Assert(pos >= 0); // overflow check
|
||||
return pos;
|
||||
}
|
||||
|
||||
void RBaseStream::skip( int bytes )
|
||||
{
|
||||
CV_Assert(bytes >= 0);
|
||||
uchar* old = m_current;
|
||||
m_current += bytes;
|
||||
CV_Assert(m_current >= old); // overflow check
|
||||
}
|
||||
|
||||
///////////////////////// RLByteStream ////////////////////////////
|
||||
|
||||
RLByteStream::~RLByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
int RLByteStream::getByte()
|
||||
{
|
||||
uchar *current = m_current;
|
||||
int val;
|
||||
|
||||
if( current >= m_end )
|
||||
{
|
||||
readBlock();
|
||||
current = m_current;
|
||||
}
|
||||
|
||||
CV_Assert(current < m_end);
|
||||
|
||||
val = *((uchar*)current);
|
||||
m_current = current + 1;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int RLByteStream::getBytes( void* buffer, int count )
|
||||
{
|
||||
uchar* data = (uchar*)buffer;
|
||||
int readed = 0;
|
||||
CV_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_pos = 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);
|
||||
|
||||
CV_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()
|
||||
{
|
||||
CV_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;
|
||||
|
||||
CV_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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
189
3rdparty/opencv-4.5.4/modules/imgcodecs/src/bitstrm.hpp
vendored
Normal file
189
3rdparty/opencv-4.5.4/modules/imgcodecs/src/bitstrm.hpp
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
/*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
|
||||
{
|
||||
|
||||
#define DECLARE_RBS_EXCEPTION(name) \
|
||||
class RBS_ ## name ## _Exception : public cv::Exception \
|
||||
{ \
|
||||
public: \
|
||||
RBS_ ## name ## _Exception(int code_, const String& err_, const String& func_, const String& file_, int line_) : \
|
||||
cv::Exception(code_, err_, func_, file_, line_) \
|
||||
{} \
|
||||
};
|
||||
DECLARE_RBS_EXCEPTION(THROW_EOS)
|
||||
#define RBS_THROW_EOS RBS_THROW_EOS_Exception(cv::Error::StsError, "Unexpected end of input stream", CV_Func, __FILE__, __LINE__)
|
||||
DECLARE_RBS_EXCEPTION(THROW_FORB)
|
||||
#define RBS_THROW_FORB RBS_THROW_FORB_Exception(cv::Error::StsError, "Forrbidden huffman code", CV_Func, __FILE__, __LINE__)
|
||||
DECLARE_RBS_EXCEPTION(BAD_HEADER)
|
||||
#define RBS_BAD_HEADER RBS_BAD_HEADER_Exception(cv::Error::StsError, "Invalid header", CV_Func, __FILE__, __LINE__)
|
||||
|
||||
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_*/
|
535
3rdparty/opencv-4.5.4/modules/imgcodecs/src/exif.cpp
vendored
Normal file
535
3rdparty/opencv-4.5.4/modules/imgcodecs/src/exif.cpp
vendored
Normal file
@ -0,0 +1,535 @@
|
||||
/*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 "exif.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
class ExifParsingError {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
ExifEntry_t::ExifEntry_t() :
|
||||
field_float(0), field_double(0), field_u32(0), field_s32(0),
|
||||
tag(INVALID_TAG), field_u16(0), field_s16(0), field_u8(0), field_s8(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ExifReader constructor
|
||||
*/
|
||||
ExifReader::ExifReader() : m_format(NONE)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ExifReader destructor
|
||||
*/
|
||||
ExifReader::~ExifReader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get tag value by tag number
|
||||
*
|
||||
* @param [in] tag The tag number
|
||||
*
|
||||
* @return ExifEntru_t structure. Caller has to know what tag it calls in order to extract proper field from the structure ExifEntry_t
|
||||
*
|
||||
*/
|
||||
ExifEntry_t ExifReader::getTag(const ExifTagName tag) const
|
||||
{
|
||||
ExifEntry_t entry;
|
||||
std::map<int, ExifEntry_t>::const_iterator it = m_exif.find(tag);
|
||||
|
||||
if( it != m_exif.end() )
|
||||
{
|
||||
entry = it->second;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parsing the exif data buffer and prepare (internal) exif directory
|
||||
*
|
||||
* @param [in] data The data buffer to read EXIF data starting with endianness
|
||||
* @param [in] size The size of the data buffer
|
||||
*
|
||||
* @return true if parsing was successful
|
||||
* false in case of unsuccessful parsing
|
||||
*/
|
||||
bool ExifReader::parseExif(unsigned char* data, const size_t size)
|
||||
{
|
||||
// Populate m_data, then call parseExif() (private)
|
||||
if( data && size > 0 )
|
||||
{
|
||||
m_data.assign(data, data + size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
parseExif();
|
||||
if( !m_exif.empty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch( ExifParsingError& ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Filling m_exif member with exif directory elements
|
||||
* This is internal function and is not exposed to client
|
||||
*
|
||||
* @return The function doesn't return any value. In case of unsuccessful parsing
|
||||
* the m_exif member is not filled up
|
||||
*/
|
||||
void ExifReader::parseExif()
|
||||
{
|
||||
m_format = getFormat();
|
||||
|
||||
if( !checkTagMark() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t offset = getStartOffset();
|
||||
|
||||
size_t numEntry = getNumDirEntry( offset );
|
||||
|
||||
offset += 2; //go to start of tag fields
|
||||
|
||||
for( size_t entry = 0; entry < numEntry; entry++ )
|
||||
{
|
||||
ExifEntry_t exifEntry = parseExifEntry( offset );
|
||||
m_exif.insert( std::make_pair( exifEntry.tag, exifEntry ) );
|
||||
offset += tiffFieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get endianness of exif information
|
||||
* This is internal function and is not exposed to client
|
||||
*
|
||||
* @return INTEL, MOTO or NONE
|
||||
*/
|
||||
Endianess_t ExifReader::getFormat() const
|
||||
{
|
||||
if (m_data.size() < 1)
|
||||
return NONE;
|
||||
|
||||
if( m_data.size() > 1 && m_data[0] != m_data[1] )
|
||||
{
|
||||
return NONE;
|
||||
}
|
||||
|
||||
if( m_data[0] == 'I' )
|
||||
{
|
||||
return INTEL;
|
||||
}
|
||||
|
||||
if( m_data[0] == 'M' )
|
||||
{
|
||||
return MOTO;
|
||||
}
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checking whether Tag Mark (0x002A) correspond to one contained in the Jpeg file
|
||||
* This is internal function and is not exposed to client
|
||||
*
|
||||
* @return true if tag mark equals 0x002A, false otherwise
|
||||
*/
|
||||
bool ExifReader::checkTagMark() const
|
||||
{
|
||||
uint16_t tagMark = getU16( 2 );
|
||||
|
||||
if( tagMark != tagMarkRequired )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The utility function for extracting actual offset exif IFD0 info is started from
|
||||
* This is internal function and is not exposed to client
|
||||
*
|
||||
* @return offset of IFD0 field
|
||||
*/
|
||||
uint32_t ExifReader::getStartOffset() const
|
||||
{
|
||||
return getU32( 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the number of Directory Entries in Jpeg file
|
||||
*
|
||||
* @return The number of directory entries
|
||||
*/
|
||||
size_t ExifReader::getNumDirEntry(const size_t offsetNumDir) const
|
||||
{
|
||||
return getU16( offsetNumDir );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parsing particular entry in exif directory
|
||||
* This is internal function and is not exposed to client
|
||||
*
|
||||
* Entries are divided into 12-bytes blocks each
|
||||
* Each block corresponds the following structure:
|
||||
*
|
||||
* +------+-------------+-------------------+------------------------+
|
||||
* | Type | Data format | Num of components | Data or offset to data |
|
||||
* +======+=============+===================+========================+
|
||||
* | TTTT | ffff | NNNNNNNN | DDDDDDDD |
|
||||
* +------+-------------+-------------------+------------------------+
|
||||
*
|
||||
* Details can be found here: http://www.media.mit.edu/pia/Research/deepview/exif.html
|
||||
*
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return ExifEntry_t structure which corresponds to particular entry
|
||||
*
|
||||
*/
|
||||
ExifEntry_t ExifReader::parseExifEntry(const size_t offset)
|
||||
{
|
||||
ExifEntry_t entry;
|
||||
uint16_t tagNum = getExifTag( offset );
|
||||
entry.tag = tagNum;
|
||||
|
||||
switch( tagNum )
|
||||
{
|
||||
case IMAGE_DESCRIPTION:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case MAKE:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case MODEL:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case ORIENTATION:
|
||||
entry.field_u16 = getOrientation( offset );
|
||||
break;
|
||||
case XRESOLUTION:
|
||||
entry.field_u_rational = getResolution( offset );
|
||||
break;
|
||||
case YRESOLUTION:
|
||||
entry.field_u_rational = getResolution( offset );
|
||||
break;
|
||||
case RESOLUTION_UNIT:
|
||||
entry.field_u16 = getResolutionUnit( offset );
|
||||
break;
|
||||
case SOFTWARE:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case DATE_TIME:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case WHITE_POINT:
|
||||
entry.field_u_rational = getWhitePoint( offset );
|
||||
break;
|
||||
case PRIMARY_CHROMATICIES:
|
||||
entry.field_u_rational = getPrimaryChromaticies( offset );
|
||||
break;
|
||||
case Y_CB_CR_COEFFICIENTS:
|
||||
entry.field_u_rational = getYCbCrCoeffs( offset );
|
||||
break;
|
||||
case Y_CB_CR_POSITIONING:
|
||||
entry.field_u16 = getYCbCrPos( offset );
|
||||
break;
|
||||
case REFERENCE_BLACK_WHITE:
|
||||
entry.field_u_rational = getRefBW( offset );
|
||||
break;
|
||||
case COPYRIGHT:
|
||||
entry.field_str = getString( offset );
|
||||
break;
|
||||
case EXIF_OFFSET:
|
||||
break;
|
||||
default:
|
||||
entry.tag = INVALID_TAG;
|
||||
break;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get tag number from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return tag number
|
||||
*/
|
||||
uint16_t ExifReader::getExifTag(const size_t offset) const
|
||||
{
|
||||
return getU16( offset );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get string information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return string value
|
||||
*/
|
||||
std::string ExifReader::getString(const size_t offset) const
|
||||
{
|
||||
size_t size = getU32( offset + 4 );
|
||||
size_t dataOffset = 8; // position of data in the field
|
||||
if( size > maxDataSize )
|
||||
{
|
||||
dataOffset = getU32( offset + 8 );
|
||||
}
|
||||
if (dataOffset > m_data.size() || dataOffset + size > m_data.size()) {
|
||||
throw ExifParsingError();
|
||||
}
|
||||
std::vector<uint8_t>::const_iterator it = m_data.begin() + dataOffset;
|
||||
std::string result( it, it + size ); //copy vector content into result
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get unsigned short data from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return Unsigned short data
|
||||
*/
|
||||
uint16_t ExifReader::getU16(const size_t offset) const
|
||||
{
|
||||
if (offset + 1 >= m_data.size())
|
||||
throw ExifParsingError();
|
||||
|
||||
if( m_format == INTEL )
|
||||
{
|
||||
return m_data[offset] + ( m_data[offset + 1] << 8 );
|
||||
}
|
||||
return ( m_data[offset] << 8 ) + m_data[offset + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get unsigned 32-bit data from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return Unsigned 32-bit data
|
||||
*/
|
||||
uint32_t ExifReader::getU32(const size_t offset) const
|
||||
{
|
||||
if (offset + 3 >= m_data.size())
|
||||
throw ExifParsingError();
|
||||
|
||||
if( m_format == INTEL )
|
||||
{
|
||||
return m_data[offset] +
|
||||
( m_data[offset + 1] << 8 ) +
|
||||
( m_data[offset + 2] << 16 ) +
|
||||
( m_data[offset + 3] << 24 );
|
||||
}
|
||||
|
||||
return ( m_data[offset] << 24 ) +
|
||||
( m_data[offset + 1] << 16 ) +
|
||||
( m_data[offset + 2] << 8 ) +
|
||||
m_data[offset + 3];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get unsigned rational data from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return Unsigned rational data
|
||||
*
|
||||
* "rational" means a fractional value, it contains 2 signed/unsigned long integer value,
|
||||
* and the first represents the numerator, the second, the denominator.
|
||||
*/
|
||||
u_rational_t ExifReader::getURational(const size_t offset) const
|
||||
{
|
||||
uint32_t numerator = getU32( offset );
|
||||
uint32_t denominator = getU32( offset + 4 );
|
||||
|
||||
return std::make_pair( numerator, denominator );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get orientation information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return orientation number
|
||||
*/
|
||||
uint16_t ExifReader::getOrientation(const size_t offset) const
|
||||
{
|
||||
return getU16( offset + 8 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resolution information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return resolution value
|
||||
*/
|
||||
std::vector<u_rational_t> ExifReader::getResolution(const size_t offset) const
|
||||
{
|
||||
std::vector<u_rational_t> result;
|
||||
uint32_t rationalOffset = getU32( offset + 8 );
|
||||
result.push_back( getURational( rationalOffset ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get resolution unit from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return resolution unit value
|
||||
*/
|
||||
uint16_t ExifReader::getResolutionUnit(const size_t offset) const
|
||||
{
|
||||
return getU16( offset + 8 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get White Point information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return White Point value
|
||||
*
|
||||
* If the image uses CIE Standard Illumination D65(known as international
|
||||
* standard of 'daylight'), the values are '3127/10000,3290/10000'.
|
||||
*/
|
||||
std::vector<u_rational_t> ExifReader::getWhitePoint(const size_t offset) const
|
||||
{
|
||||
std::vector<u_rational_t> result;
|
||||
uint32_t rationalOffset = getU32( offset + 8 );
|
||||
result.push_back( getURational( rationalOffset ) );
|
||||
result.push_back( getURational( rationalOffset + 8 ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Primary Chromaticies information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return vector with primary chromaticies values
|
||||
*
|
||||
*/
|
||||
std::vector<u_rational_t> ExifReader::getPrimaryChromaticies(const size_t offset) const
|
||||
{
|
||||
std::vector<u_rational_t> result;
|
||||
uint32_t rationalOffset = getU32( offset + 8 );
|
||||
for( size_t i = 0; i < primaryChromaticiesComponents; i++ )
|
||||
{
|
||||
result.push_back( getURational( rationalOffset ) );
|
||||
rationalOffset += 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get YCbCr Coefficients information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return vector with YCbCr coefficients values
|
||||
*
|
||||
*/
|
||||
std::vector<u_rational_t> ExifReader::getYCbCrCoeffs(const size_t offset) const
|
||||
{
|
||||
std::vector<u_rational_t> result;
|
||||
uint32_t rationalOffset = getU32( offset + 8 );
|
||||
for( size_t i = 0; i < ycbcrCoeffs; i++ )
|
||||
{
|
||||
result.push_back( getURational( rationalOffset ) );
|
||||
rationalOffset += 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get YCbCr Positioning information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return vector with YCbCr positioning value
|
||||
*
|
||||
*/
|
||||
uint16_t ExifReader::getYCbCrPos(const size_t offset) const
|
||||
{
|
||||
return getU16( offset + 8 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Reference Black&White point information from raw exif data
|
||||
* This is internal function and is not exposed to client
|
||||
* @param [in] offset Offset to entry in bytes inside raw exif data
|
||||
* @return vector with reference BW points
|
||||
*
|
||||
* In case of YCbCr format, first 2 show black/white of Y, next 2 are Cb,
|
||||
* last 2 are Cr. In case of RGB format, first 2 show black/white of R,
|
||||
* next 2 are G, last 2 are B.
|
||||
*
|
||||
*/
|
||||
std::vector<u_rational_t> ExifReader::getRefBW(const size_t offset) const
|
||||
{
|
||||
const size_t rationalFieldSize = 8;
|
||||
std::vector<u_rational_t> result;
|
||||
uint32_t rationalOffset = getU32( offset + rationalFieldSize );
|
||||
for( size_t i = 0; i < refBWComponents; i++ )
|
||||
{
|
||||
result.push_back( getURational( rationalOffset ) );
|
||||
rationalOffset += rationalFieldSize;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} //namespace cv
|
233
3rdparty/opencv-4.5.4/modules/imgcodecs/src/exif.hpp
vendored
Normal file
233
3rdparty/opencv-4.5.4/modules/imgcodecs/src/exif.hpp
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
/*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 _OPENCV_EXIF_HPP_
|
||||
#define _OPENCV_EXIF_HPP_
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Base Exif tags used by IFD0 (main image)
|
||||
*/
|
||||
enum ExifTagName
|
||||
{
|
||||
IMAGE_DESCRIPTION = 0x010E, ///< Image Description: ASCII string
|
||||
MAKE = 0x010F, ///< Description of manufacturer: ASCII string
|
||||
MODEL = 0x0110, ///< Description of camera model: ASCII string
|
||||
ORIENTATION = 0x0112, ///< Orientation of the image: unsigned short
|
||||
XRESOLUTION = 0x011A, ///< Resolution of the image across X axis: unsigned rational
|
||||
YRESOLUTION = 0x011B, ///< Resolution of the image across Y axis: unsigned rational
|
||||
RESOLUTION_UNIT = 0x0128, ///< Resolution units. '1' no-unit, '2' inch, '3' centimeter
|
||||
SOFTWARE = 0x0131, ///< Shows firmware(internal software of digicam) version number
|
||||
DATE_TIME = 0x0132, ///< Date/Time of image was last modified
|
||||
WHITE_POINT = 0x013E, ///< Chromaticity of white point of the image
|
||||
PRIMARY_CHROMATICIES = 0x013F, ///< Chromaticity of the primaries of the image
|
||||
Y_CB_CR_COEFFICIENTS = 0x0211, ///< constant to translate an image from YCbCr to RGB format
|
||||
Y_CB_CR_POSITIONING = 0x0213, ///< Chroma sample point of subsampling pixel array
|
||||
REFERENCE_BLACK_WHITE = 0x0214, ///< Reference value of black point/white point
|
||||
COPYRIGHT = 0x8298, ///< Copyright information
|
||||
EXIF_OFFSET = 0x8769, ///< Offset to Exif Sub IFD
|
||||
INVALID_TAG = 0xFFFF ///< Shows that the tag was not recognized
|
||||
};
|
||||
|
||||
enum Endianess_t
|
||||
{
|
||||
INTEL = 0x49,
|
||||
MOTO = 0x4D,
|
||||
NONE = 0x00
|
||||
};
|
||||
|
||||
typedef std::pair<uint32_t, uint32_t> u_rational_t;
|
||||
|
||||
/**
|
||||
* @brief Entry which contains possible values for different exif tags
|
||||
*/
|
||||
struct ExifEntry_t
|
||||
{
|
||||
ExifEntry_t();
|
||||
|
||||
std::vector<u_rational_t> field_u_rational; ///< vector of rational fields
|
||||
std::string field_str; ///< any kind of textual information
|
||||
|
||||
float field_float; ///< Currently is not used
|
||||
double field_double; ///< Currently is not used
|
||||
|
||||
uint32_t field_u32; ///< Unsigned 32-bit value
|
||||
int32_t field_s32; ///< Signed 32-bit value
|
||||
|
||||
uint16_t tag; ///< Tag number
|
||||
|
||||
uint16_t field_u16; ///< Unsigned 16-bit value
|
||||
int16_t field_s16; ///< Signed 16-bit value
|
||||
uint8_t field_u8; ///< Unsigned 8-bit value
|
||||
int8_t field_s8; ///< Signed 8-bit value
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Picture orientation which may be taken from EXIF
|
||||
* Orientation usually matters when the picture is taken by
|
||||
* smartphone or other camera with orientation sensor support
|
||||
* Corresponds to EXIF 2.3 Specification
|
||||
*/
|
||||
enum ImageOrientation
|
||||
{
|
||||
IMAGE_ORIENTATION_TL = 1, ///< Horizontal (normal)
|
||||
IMAGE_ORIENTATION_TR = 2, ///< Mirrored horizontal
|
||||
IMAGE_ORIENTATION_BR = 3, ///< Rotate 180
|
||||
IMAGE_ORIENTATION_BL = 4, ///< Mirrored vertical
|
||||
IMAGE_ORIENTATION_LT = 5, ///< Mirrored horizontal & rotate 270 CW
|
||||
IMAGE_ORIENTATION_RT = 6, ///< Rotate 90 CW
|
||||
IMAGE_ORIENTATION_RB = 7, ///< Mirrored horizontal & rotate 90 CW
|
||||
IMAGE_ORIENTATION_LB = 8 ///< Rotate 270 CW
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Reading exif information from Jpeg file
|
||||
*
|
||||
* Usage example for getting the orientation of the image:
|
||||
*
|
||||
* @code
|
||||
* std::ifstream stream(filename,std::ios_base::in | std::ios_base::binary);
|
||||
* ExifReader reader(stream);
|
||||
* if( reader.parse() )
|
||||
* {
|
||||
* int orientation = reader.getTag(Orientation).field_u16;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
class ExifReader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief ExifReader constructor. Constructs an object of exif reader
|
||||
*/
|
||||
ExifReader();
|
||||
~ExifReader();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse the file with exif info
|
||||
*
|
||||
* @param [in] data The data buffer to read EXIF data starting with endianness
|
||||
* @param [in] size The size of the data buffer
|
||||
*
|
||||
* @return true if successful parsing
|
||||
* false if parsing error
|
||||
*/
|
||||
|
||||
bool parseExif(unsigned char* data, const size_t size);
|
||||
|
||||
/**
|
||||
* @brief Get tag info by tag number
|
||||
*
|
||||
* @param [in] tag The tag number
|
||||
* @return ExifEntru_t structure. Caller has to know what tag it calls in order to extract proper field from the structure ExifEntry_t
|
||||
*/
|
||||
ExifEntry_t getTag( const ExifTagName tag ) const;
|
||||
|
||||
|
||||
private:
|
||||
std::vector<unsigned char> m_data;
|
||||
std::map<int, ExifEntry_t > m_exif;
|
||||
Endianess_t m_format;
|
||||
|
||||
void parseExif();
|
||||
bool checkTagMark() const;
|
||||
|
||||
size_t getNumDirEntry( const size_t offsetNumDir ) const;
|
||||
uint32_t getStartOffset() const;
|
||||
uint16_t getExifTag( const size_t offset ) const;
|
||||
uint16_t getU16( const size_t offset ) const;
|
||||
uint32_t getU32( const size_t offset ) const;
|
||||
uint16_t getOrientation( const size_t offset ) const;
|
||||
uint16_t getResolutionUnit( const size_t offset ) const;
|
||||
uint16_t getYCbCrPos( const size_t offset ) const;
|
||||
|
||||
Endianess_t getFormat() const;
|
||||
|
||||
ExifEntry_t parseExifEntry( const size_t offset );
|
||||
|
||||
u_rational_t getURational( const size_t offset ) const;
|
||||
|
||||
std::string getString( const size_t offset ) const;
|
||||
std::vector<u_rational_t> getResolution( const size_t offset ) const;
|
||||
std::vector<u_rational_t> getWhitePoint( const size_t offset ) const;
|
||||
std::vector<u_rational_t> getPrimaryChromaticies( const size_t offset ) const;
|
||||
std::vector<u_rational_t> getYCbCrCoeffs( const size_t offset ) const;
|
||||
std::vector<u_rational_t> getRefBW( const size_t offset ) const;
|
||||
|
||||
private:
|
||||
static const uint16_t tagMarkRequired = 0x2A;
|
||||
|
||||
//max size of data in tag.
|
||||
//'DDDDDDDD' contains the value of that Tag. If its size is over 4bytes,
|
||||
//'DDDDDDDD' contains the offset to data stored address.
|
||||
static const size_t maxDataSize = 4;
|
||||
|
||||
//bytes per tag field
|
||||
static const size_t tiffFieldSize = 12;
|
||||
|
||||
//number of primary chromaticies components
|
||||
static const size_t primaryChromaticiesComponents = 6;
|
||||
|
||||
//number of YCbCr coefficients in field
|
||||
static const size_t ycbcrCoeffs = 3;
|
||||
|
||||
//number of Reference Black&White components
|
||||
static const size_t refBWComponents = 6;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* _OPENCV_EXIF_HPP_ */
|
156
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_base.cpp
vendored
Normal file
156
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_base.cpp
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*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;
|
||||
m_scale_denom = 1;
|
||||
}
|
||||
|
||||
|
||||
ExifEntry_t BaseImageDecoder::getExifTag(const ExifTagName tag) const
|
||||
{
|
||||
return m_exif.getTag(tag);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
int BaseImageDecoder::setScale( const int& scale_denom )
|
||||
{
|
||||
int temp = m_scale_denom;
|
||||
m_scale_denom = scale_denom;
|
||||
return temp;
|
||||
}
|
||||
|
||||
ImageDecoder BaseImageDecoder::newDecoder() const
|
||||
{
|
||||
return ImageDecoder();
|
||||
}
|
||||
|
||||
BaseImageEncoder::BaseImageEncoder()
|
||||
{
|
||||
m_buf = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
bool BaseImageEncoder::writemulti(const std::vector<Mat>&, const std::vector<int>& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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( Error::BadImageSize, msg.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* End of file. */
|
126
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_base.hpp
vendored
Normal file
126
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_base.hpp
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/*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"
|
||||
#include "exif.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; }
|
||||
|
||||
ExifEntry_t getExifTag(const ExifTagName tag) const;
|
||||
virtual bool setSource( const String& filename );
|
||||
virtual bool setSource( const Mat& buf );
|
||||
virtual int setScale( const int& scale_denom );
|
||||
virtual bool readHeader() = 0;
|
||||
virtual bool readData( Mat& img ) = 0;
|
||||
|
||||
/// Called after readData to advance to the next page, if any.
|
||||
virtual bool nextPage() { return false; }
|
||||
|
||||
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;
|
||||
int m_scale_denom;
|
||||
String m_filename;
|
||||
String m_signature;
|
||||
Mat m_buf;
|
||||
bool m_buf_supported;
|
||||
ExifReader m_exif;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////// 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 bool writemulti(const std::vector<Mat>& img_vec, const std::vector<int>& params);
|
||||
|
||||
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_*/
|
588
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_bmp.cpp
vendored
Normal file
588
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_bmp.cpp
vendored
Normal file
@ -0,0 +1,588 @@
|
||||
/*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;
|
||||
m_origin = ORIGIN_TL;
|
||||
m_bpp = 0;
|
||||
m_rle_code = BMP_RGB;
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
CV_Assert(size > 0); // overflow, 2Gb limit
|
||||
|
||||
if( size >= 36 )
|
||||
{
|
||||
m_width = m_strm.getDWord();
|
||||
m_height = m_strm.getDWord();
|
||||
m_bpp = m_strm.getDWord() >> 16;
|
||||
int m_rle_code_ = m_strm.getDWord();
|
||||
CV_Assert(m_rle_code_ >= 0 && m_rle_code_ <= BMP_BITFIELDS);
|
||||
m_rle_code = (BmpCompression)m_rle_code_;
|
||||
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_bpp == 32) && (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 )
|
||||
{
|
||||
CV_Assert(clrused >= 0 && clrused <= 256);
|
||||
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 == 32 && m_rle_code == BMP_BITFIELDS)
|
||||
{
|
||||
// 32bit BMP not require to check something - we can simply allow it to use
|
||||
;
|
||||
}
|
||||
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(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
// in 32 bit case alpha channel is used - so require CV_8UC4 type
|
||||
m_type = iscolor ? (m_bpp == 32 ? CV_8UC4 : CV_8UC3 ) : CV_8UC1;
|
||||
m_origin = m_height > 0 ? ORIGIN_BL : 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.ptr();
|
||||
int step = validateToInt(img.step);
|
||||
bool color = img.channels() > 1;
|
||||
uchar gray_palette[256] = {0};
|
||||
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;
|
||||
|
||||
// FIXIT: use safe pointer arithmetic (avoid 'int'), use size_t, intptr_t, etc
|
||||
CV_Assert(((uint64)m_height * m_width * nch < (CV_BIG_UINT(1) << 30)) && "BMP reader implementation doesn't support large images >= 1Gb");
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
if( m_origin == ORIGIN_BL )
|
||||
{
|
||||
data += (m_height - 1)*(size_t)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.data(), *bgr = _bgr.data();
|
||||
|
||||
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, Size(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();
|
||||
const 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;
|
||||
int sz = (((code + 1)>>1) + 1) & (~1);
|
||||
CV_Assert((size_t)sz < _src.size());
|
||||
m_strm.getBytes(src, sz);
|
||||
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);
|
||||
|
||||
if( code == 2 )
|
||||
{
|
||||
x_shift3 = m_strm.getByte()*nch;
|
||||
m_strm.getByte();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if( y >= m_height )
|
||||
break;
|
||||
}
|
||||
else if( code > 2 ) // absolute mode
|
||||
{
|
||||
int prev_y = y;
|
||||
int code3 = code*nch;
|
||||
|
||||
if( data + code3 > line_end )
|
||||
goto decode_rle8_bad;
|
||||
int sz = (code + 1) & (~1);
|
||||
CV_Assert((size_t)sz < _src.size());
|
||||
m_strm.getBytes(src, sz);
|
||||
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, Size(m_width,1) );
|
||||
else
|
||||
icvCvt_BGR5552BGR_8u_C2C3R( src, 0, data, 0, Size(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, Size(m_width,1) );
|
||||
else
|
||||
icvCvt_BGR5652BGR_8u_C2C3R( src, 0, data, 0, Size(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, Size(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, Size(m_width,1) );
|
||||
else if( img.channels() == 3 )
|
||||
icvCvt_BGRA2BGR_8u_C4C3R(src, 0, data, 0, Size(m_width, 1));
|
||||
else if( img.channels() == 4 )
|
||||
memcpy(data, src, m_width * 4);
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
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;
|
||||
size_t fileSize = (size_t)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( validateToInt(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.ptr(y), width );
|
||||
if( fileStep > width )
|
||||
strm.putBytes( zeropad, fileStep - width );
|
||||
}
|
||||
|
||||
strm.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
105
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_bmp.hpp
vendored
Normal file
105
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_bmp.hpp
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
/*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 CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
BmpDecoder();
|
||||
~BmpDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
enum Origin
|
||||
{
|
||||
ORIGIN_TL = 0,
|
||||
ORIGIN_BL = 1
|
||||
};
|
||||
|
||||
RLByteStream m_strm;
|
||||
PaletteEntry m_palette[256];
|
||||
Origin m_origin;
|
||||
int m_bpp;
|
||||
int m_offset;
|
||||
BmpCompression m_rle_code;
|
||||
};
|
||||
|
||||
|
||||
// ... writer
|
||||
class BmpEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
BmpEncoder();
|
||||
~BmpEncoder() CV_OVERRIDE;
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif/*_GRFMT_BMP_H_*/
|
750
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_exr.cpp
vendored
Normal file
750
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_exr.cpp
vendored
Normal file
@ -0,0 +1,750 @@
|
||||
/*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
|
||||
|
||||
/// C++ Standard Libraries
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ImfFrameBuffer.h>
|
||||
#include <ImfHeader.h>
|
||||
#include <ImfInputFile.h>
|
||||
#include <ImfOutputFile.h>
|
||||
#include <ImfChannelList.h>
|
||||
#include <ImfStandardAttributes.h>
|
||||
#include <half.h>
|
||||
#include "grfmt_exr.hpp"
|
||||
#include "OpenEXRConfig.h"
|
||||
|
||||
#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 = m_alpha = 0;
|
||||
m_type = ((Imf::PixelType)0);
|
||||
m_iscolor = false;
|
||||
m_bit_depth = 0;
|
||||
m_isfloat = false;
|
||||
m_ischroma = false;
|
||||
m_hasalpha = false;
|
||||
m_native_depth = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
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 && m_hasalpha) ? 4 : m_iscolor ? 3 : m_hasalpha ? 2 : 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" );
|
||||
m_alpha = channels.findChannel( "A" );
|
||||
|
||||
if( m_alpha ) // alpha channel supported in RGB, Y, and YC scenarios
|
||||
m_hasalpha = true;
|
||||
|
||||
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_green = channels.findChannel( "Z" ); // Distance of the front of a sample from the viewer
|
||||
}
|
||||
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 )
|
||||
{
|
||||
m_type = 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() > 2; // output mat has 3+ channels; Y or YA are the 1 and 2 channel scenario
|
||||
bool alphasupported = ( img.channels() % 2 == 0 ); // even number of channels indicates alpha
|
||||
int channels = 0;
|
||||
uchar* data = img.ptr();
|
||||
size_t step = img.step;
|
||||
bool justcopy = ( m_native_depth && (color == m_iscolor) );
|
||||
bool chromatorgb = ( m_ischroma && color );
|
||||
bool rgbtogray = ( !m_ischroma && m_iscolor && !color );
|
||||
bool result = true;
|
||||
FrameBuffer frame;
|
||||
const int defaultchannels = 3;
|
||||
int xsample[defaultchannels] = {1, 1, 1};
|
||||
char *buffer;
|
||||
CV_Assert(m_type == FLOAT);
|
||||
const size_t floatsize = sizeof(float);
|
||||
size_t xstep = m_native_depth ? floatsize : 1; // 4 bytes if native depth (FLOAT), otherwise converting to 1 byte U8 depth
|
||||
size_t ystep = 0;
|
||||
const int channelstoread = ( (m_iscolor && alphasupported) ? 4 :
|
||||
( (m_iscolor && !m_ischroma) || color) ? 3 : alphasupported ? 2 : 1 ); // number of channels to read may exceed channels in output img
|
||||
size_t xStride = floatsize * channelstoread;
|
||||
|
||||
AutoBuffer<char> copy_buffer;
|
||||
|
||||
if( !justcopy )
|
||||
{
|
||||
copy_buffer.allocate(floatsize * m_width * defaultchannels);
|
||||
buffer = copy_buffer.data();
|
||||
ystep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = (char *)data;
|
||||
ystep = step;
|
||||
}
|
||||
|
||||
if( m_ischroma )
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( m_blue )
|
||||
{
|
||||
frame.insert( "BY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep,
|
||||
xStride, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
|
||||
xsample[0] = m_blue->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "BY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep,
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
if( m_green )
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + floatsize,
|
||||
xStride, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[1] = m_green->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + floatsize,
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
if( m_red )
|
||||
{
|
||||
frame.insert( "RY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + (floatsize * 2),
|
||||
xStride, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
|
||||
xsample[2] = m_red->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "RY", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + (floatsize * 2),
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "Y", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep,
|
||||
xStride, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[0] = m_green->xSampling;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_blue )
|
||||
{
|
||||
frame.insert( "B", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep,
|
||||
xStride, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
|
||||
xsample[0] = m_blue->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "B", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep,
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
if( m_green )
|
||||
{
|
||||
frame.insert( "G", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + floatsize,
|
||||
xStride, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
|
||||
xsample[1] = m_green->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "G", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + floatsize,
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
if( m_red )
|
||||
{
|
||||
frame.insert( "R", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + (floatsize * 2),
|
||||
xStride, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
|
||||
xsample[2] = m_red->xSampling;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.insert( "R", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + (floatsize * 2),
|
||||
xStride, ystep, 1, 1, 0.0 ));
|
||||
}
|
||||
}
|
||||
|
||||
if( justcopy && m_hasalpha && alphasupported )
|
||||
{ // alpha preserved only in justcopy scenario where alpha is desired (alphasupported)
|
||||
// and present in original file (m_hasalpha)
|
||||
CV_Assert(channelstoread == img.channels());
|
||||
int offset = (channelstoread - 1) * floatsize;
|
||||
frame.insert( "A", Slice( m_type,
|
||||
buffer - m_datawindow.min.x * xStride - m_datawindow.min.y * ystep + offset,
|
||||
xStride, ystep, m_alpha->xSampling, m_alpha->ySampling, 0.0 ));
|
||||
}
|
||||
|
||||
for (FrameBuffer::Iterator it = frame.begin(); it != frame.end(); it++) {
|
||||
channels++;
|
||||
}
|
||||
|
||||
CV_Assert(channels == channelstoread);
|
||||
|
||||
if( (channels != channelstoread) || (!justcopy && channels > defaultchannels) )
|
||||
{ // safety checking what ought to be true here
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_file->setFrameBuffer( frame );
|
||||
if( justcopy )
|
||||
{
|
||||
m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y );
|
||||
|
||||
if( m_iscolor )
|
||||
{
|
||||
if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )
|
||||
UpSample( data, channelstoread, step / xstep, m_blue->xSampling, m_blue->ySampling );
|
||||
if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSample( data + xstep, channelstoread, step / xstep, m_green->xSampling, m_green->ySampling );
|
||||
if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
|
||||
UpSample( data + 2 * xstep, channelstoread, step / xstep, m_red->xSampling, m_red->ySampling );
|
||||
}
|
||||
else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSample( data, channelstoread, step / xstep, m_green->xSampling, m_green->ySampling );
|
||||
|
||||
if( chromatorgb )
|
||||
ChromaToBGR( (float *)data, m_height, channelstoread, step / xstep );
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar *out = data;
|
||||
int x, y;
|
||||
for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ )
|
||||
{
|
||||
m_file->readPixels( y, y );
|
||||
|
||||
for( int i = 0; i < channels; i++ )
|
||||
{
|
||||
if( xsample[i] != 1 )
|
||||
UpSampleX( (float *)buffer + i, channels, xsample[i] );
|
||||
}
|
||||
if( rgbtogray )
|
||||
{
|
||||
RGBToGray( (float *)buffer, (float *)out );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( chromatorgb )
|
||||
ChromaToBGR( (float *)buffer, 1, defaultchannels, step );
|
||||
|
||||
if( m_type == FLOAT )
|
||||
{
|
||||
float *fi = (float *)buffer;
|
||||
for( x = 0; x < m_width * img.channels(); x++)
|
||||
{
|
||||
out[x] = cv::saturate_cast<uchar>(fi[x]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned *ui = (unsigned *)buffer;
|
||||
for( x = 0; x < m_width * img.channels(); 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, defaultchannels, step / xstep, m_blue->ySampling );
|
||||
if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
|
||||
UpSampleY( data + xstep, defaultchannels, step / xstep, m_green->ySampling );
|
||||
if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
|
||||
UpSampleY( data + 2 * xstep, defaultchannels, 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 );
|
||||
}
|
||||
|
||||
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 xstep, int ystep )
|
||||
{
|
||||
for( int y = 0; y < numlines; y++ )
|
||||
{
|
||||
for( int x = 0; x < m_width; x++ )
|
||||
{
|
||||
double b, Y, r;
|
||||
if( m_type == FLOAT )
|
||||
{
|
||||
b = data[y * ystep + x * xstep];
|
||||
Y = data[y * ystep + x * xstep + 1];
|
||||
r = data[y * ystep + x * xstep + 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
b = ((unsigned *)data)[y * ystep + x * xstep];
|
||||
Y = ((unsigned *)data)[y * ystep + x * xstep + 1];
|
||||
r = ((unsigned *)data)[y * ystep + x * xstep + 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_type == FLOAT )
|
||||
{
|
||||
data[y * ystep + x * xstep] = (float)b;
|
||||
data[y * ystep + x * xstep + 1] = (float)Y;
|
||||
data[y * ystep + x * xstep + 2] = (float)r;
|
||||
}
|
||||
else
|
||||
{
|
||||
int t = cvRound(b);
|
||||
((unsigned *)data)[y * ystep + x * xstep + 0] = (unsigned)MAX(t, 0);
|
||||
t = cvRound(Y);
|
||||
((unsigned *)data)[y * ystep + x * xstep + 1] = (unsigned)MAX(t, 0);
|
||||
t = cvRound(r);
|
||||
((unsigned *)data)[y * ystep + x * xstep + 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_32F );
|
||||
}
|
||||
|
||||
|
||||
bool ExrEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
{
|
||||
int width = img.cols, height = img.rows;
|
||||
int depth = img.depth();
|
||||
CV_Assert( depth == CV_32F );
|
||||
int channels = img.channels();
|
||||
bool result = false;
|
||||
Header header( width, height );
|
||||
Imf::PixelType type = FLOAT;
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
if( params[i] == CV_IMWRITE_EXR_TYPE )
|
||||
{
|
||||
switch( params[i+1] )
|
||||
{
|
||||
case IMWRITE_EXR_TYPE_HALF:
|
||||
type = HALF;
|
||||
break;
|
||||
case IMWRITE_EXR_TYPE_FLOAT:
|
||||
type = FLOAT;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "IMWRITE_EXR_TYPE is invalid or not supported");
|
||||
}
|
||||
}
|
||||
if ( params[i] == IMWRITE_EXR_COMPRESSION )
|
||||
{
|
||||
switch ( params[i + 1] )
|
||||
{
|
||||
case IMWRITE_EXR_COMPRESSION_NO:
|
||||
header.compression() = NO_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_RLE:
|
||||
header.compression() = RLE_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_ZIPS:
|
||||
header.compression() = ZIPS_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_ZIP:
|
||||
header.compression() = ZIP_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_PIZ:
|
||||
header.compression() = PIZ_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_PXR24:
|
||||
header.compression() = PXR24_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_B44:
|
||||
header.compression() = B44_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_B44A:
|
||||
header.compression() = B44A_COMPRESSION;
|
||||
break;
|
||||
#if ((OPENEXR_VERSION_MAJOR * 1000 + OPENEXR_VERSION_MINOR) >= (2 * 1000 + 2)) // available since version 2.2.0
|
||||
case IMWRITE_EXR_COMPRESSION_DWAA:
|
||||
header.compression() = DWAA_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_DWAB:
|
||||
header.compression() = DWAB_COMPRESSION;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "IMWRITE_EXR_COMPRESSION is invalid or not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( channels == 3 || channels == 4 )
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
if( channels % 2 == 0 )
|
||||
{ // even number of channels indicates Alpha
|
||||
header.channels().insert( "A", Channel( type ) );
|
||||
}
|
||||
|
||||
OutputFile file( m_filename.c_str(), header );
|
||||
|
||||
FrameBuffer frame;
|
||||
|
||||
char *buffer;
|
||||
size_t bufferstep;
|
||||
int size;
|
||||
Mat exrMat;
|
||||
if( type == HALF )
|
||||
{
|
||||
convertFp16(img, exrMat);
|
||||
buffer = (char *)const_cast<uchar *>( exrMat.ptr() );
|
||||
bufferstep = exrMat.step;
|
||||
size = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = (char *)const_cast<uchar *>( img.ptr() );
|
||||
bufferstep = img.step;
|
||||
size = 4;
|
||||
}
|
||||
|
||||
if( channels == 3 || channels == 4 )
|
||||
{
|
||||
frame.insert( "B", Slice( type, buffer, size * channels, bufferstep ));
|
||||
frame.insert( "G", Slice( type, buffer + size, size * channels, bufferstep ));
|
||||
frame.insert( "R", Slice( type, buffer + size * 2, size * channels, bufferstep ));
|
||||
}
|
||||
else
|
||||
frame.insert( "Y", Slice( type, buffer, size * channels, bufferstep ));
|
||||
|
||||
if( channels % 2 == 0 )
|
||||
{ // even channel count indicates Alpha channel
|
||||
frame.insert( "A", Slice( type, buffer + size * (channels - 1), size * channels, bufferstep ));
|
||||
}
|
||||
|
||||
file.setFrameBuffer( frame );
|
||||
|
||||
result = true;
|
||||
try
|
||||
{
|
||||
file.writePixels( height );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ImageEncoder ExrEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<ExrEncoder>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
123
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_exr.hpp
vendored
Normal file
123
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_exr.hpp
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
/*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 CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
ExrDecoder();
|
||||
~ExrDecoder() CV_OVERRIDE;
|
||||
|
||||
int type() const CV_OVERRIDE;
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
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 xstep, int ystep );
|
||||
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;
|
||||
const Channel *m_alpha;
|
||||
Chromaticities m_chroma;
|
||||
int m_bit_depth;
|
||||
bool m_native_depth;
|
||||
bool m_iscolor;
|
||||
bool m_isfloat;
|
||||
bool m_hasalpha;
|
||||
|
||||
private:
|
||||
ExrDecoder(const ExrDecoder &); // copy disabled
|
||||
ExrDecoder& operator=(const ExrDecoder &); // assign disabled
|
||||
};
|
||||
|
||||
|
||||
class ExrEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
ExrEncoder();
|
||||
~ExrEncoder() CV_OVERRIDE;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_EXR_H_*/
|
572
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdal.cpp
vendored
Normal file
572
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdal.cpp
vendored
Normal file
@ -0,0 +1,572 @@
|
||||
/*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"
|
||||
|
||||
// GDAL Macros
|
||||
#include "cvconfig.h"
|
||||
|
||||
#ifdef HAVE_GDAL
|
||||
|
||||
// Our Header
|
||||
#include "grfmt_gdal.hpp"
|
||||
|
||||
|
||||
/// C++ Standard Libraries
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace cv{
|
||||
|
||||
|
||||
/**
|
||||
* Convert GDAL Palette Interpretation to OpenCV Pixel Type
|
||||
*/
|
||||
int gdalPaletteInterpretation2OpenCV( GDALPaletteInterp const& paletteInterp, GDALDataType const& gdalType ){
|
||||
|
||||
switch( paletteInterp ){
|
||||
|
||||
/// GRAYSCALE
|
||||
case GPI_Gray:
|
||||
if( gdalType == GDT_Byte ){ return CV_8UC1; }
|
||||
if( gdalType == GDT_UInt16 ){ return CV_16UC1; }
|
||||
if( gdalType == GDT_Int16 ){ return CV_16SC1; }
|
||||
if( gdalType == GDT_UInt32 ){ return CV_32SC1; }
|
||||
if( gdalType == GDT_Int32 ){ return CV_32SC1; }
|
||||
if( gdalType == GDT_Float32 ){ return CV_32FC1; }
|
||||
if( gdalType == GDT_Float64 ){ return CV_64FC1; }
|
||||
return -1;
|
||||
|
||||
/// RGB
|
||||
case GPI_RGB:
|
||||
if( gdalType == GDT_Byte ){ return CV_8UC3; }
|
||||
if( gdalType == GDT_UInt16 ){ return CV_16UC3; }
|
||||
if( gdalType == GDT_Int16 ){ return CV_16SC3; }
|
||||
if( gdalType == GDT_UInt32 ){ return CV_32SC3; }
|
||||
if( gdalType == GDT_Int32 ){ return CV_32SC3; }
|
||||
if( gdalType == GDT_Float32 ){ return CV_32FC3; }
|
||||
if( gdalType == GDT_Float64 ){ return CV_64FC3; }
|
||||
return -1;
|
||||
|
||||
|
||||
/// otherwise
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert gdal type to opencv type
|
||||
*/
|
||||
int gdal2opencv( const GDALDataType& gdalType, const int& channels ){
|
||||
|
||||
switch( gdalType ){
|
||||
|
||||
/// UInt8
|
||||
case GDT_Byte:
|
||||
return CV_8UC(channels);
|
||||
|
||||
/// UInt16
|
||||
case GDT_UInt16:
|
||||
return CV_16UC(channels);
|
||||
|
||||
/// Int16
|
||||
case GDT_Int16:
|
||||
return CV_16SC(channels);
|
||||
|
||||
/// UInt32
|
||||
case GDT_UInt32:
|
||||
case GDT_Int32:
|
||||
return CV_32SC(channels);
|
||||
|
||||
case GDT_Float32:
|
||||
return CV_32FC(channels);
|
||||
|
||||
case GDT_Float64:
|
||||
return CV_64FC(channels);
|
||||
|
||||
default:
|
||||
std::cout << "Unknown GDAL Data Type" << std::endl;
|
||||
std::cout << "Type: " << GDALGetDataTypeName(gdalType) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GDAL Decoder Constructor
|
||||
*/
|
||||
GdalDecoder::GdalDecoder(){
|
||||
|
||||
// set a dummy signature
|
||||
m_signature="0";
|
||||
for( size_t i=0; i<160; i++ ){
|
||||
m_signature += "0";
|
||||
}
|
||||
|
||||
/// Register the driver
|
||||
GDALAllRegister();
|
||||
|
||||
m_driver = NULL;
|
||||
m_dataset = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* GDAL Decoder Destructor
|
||||
*/
|
||||
GdalDecoder::~GdalDecoder(){
|
||||
|
||||
if( m_dataset != NULL ){
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data range
|
||||
*/
|
||||
double range_cast( const GDALDataType& gdalType,
|
||||
const int& cvDepth,
|
||||
const double& value )
|
||||
{
|
||||
|
||||
// uint8 -> uint8
|
||||
if( gdalType == GDT_Byte && cvDepth == CV_8U ){
|
||||
return value;
|
||||
}
|
||||
// uint8 -> uint16
|
||||
if( gdalType == GDT_Byte && (cvDepth == CV_16U || cvDepth == CV_16S)){
|
||||
return (value*256);
|
||||
}
|
||||
|
||||
// uint8 -> uint32
|
||||
if( gdalType == GDT_Byte && (cvDepth == CV_32F || cvDepth == CV_32S)){
|
||||
return (value*16777216);
|
||||
}
|
||||
|
||||
// int16 -> uint8
|
||||
if( (gdalType == GDT_UInt16 || gdalType == GDT_Int16) && cvDepth == CV_8U ){
|
||||
return std::floor(value/256.0);
|
||||
}
|
||||
|
||||
// int16 -> int16
|
||||
if( (gdalType == GDT_UInt16 || gdalType == GDT_Int16) &&
|
||||
( cvDepth == CV_16U || cvDepth == CV_16S )){
|
||||
return value;
|
||||
}
|
||||
|
||||
// float32 -> float32
|
||||
// float64 -> float64
|
||||
if( (gdalType == GDT_Float32 || gdalType == GDT_Float64) &&
|
||||
( cvDepth == CV_32F || cvDepth == CV_64F )){
|
||||
return value;
|
||||
}
|
||||
|
||||
std::cout << GDALGetDataTypeName( gdalType ) << std::endl;
|
||||
std::cout << "warning: unknown range cast requested." << std::endl;
|
||||
return (value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* There are some better mpl techniques for doing this.
|
||||
*/
|
||||
void write_pixel( const double& pixelValue,
|
||||
const GDALDataType& gdalType,
|
||||
const int& gdalChannels,
|
||||
Mat& image,
|
||||
const int& row,
|
||||
const int& col,
|
||||
const int& channel ){
|
||||
|
||||
// convert the pixel
|
||||
double newValue = range_cast(gdalType, image.depth(), pixelValue );
|
||||
|
||||
// input: 1 channel, output: 1 channel
|
||||
if( gdalChannels == 1 && image.channels() == 1 ){
|
||||
if( image.depth() == CV_8U ){ image.ptr<uchar>(row)[col] = newValue; }
|
||||
else if( image.depth() == CV_16U ){ image.ptr<unsigned short>(row)[col] = newValue; }
|
||||
else if( image.depth() == CV_16S ){ image.ptr<short>(row)[col] = newValue; }
|
||||
else if( image.depth() == CV_32S ){ image.ptr<int>(row)[col] = newValue; }
|
||||
else if( image.depth() == CV_32F ){ image.ptr<float>(row)[col] = newValue; }
|
||||
else if( image.depth() == CV_64F ){ image.ptr<double>(row)[col] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: 1, img: 1"); }
|
||||
}
|
||||
|
||||
// input: 1 channel, output: 3 channel
|
||||
else if( gdalChannels == 1 && image.channels() == 3 ){
|
||||
if( image.depth() == CV_8U ){ image.ptr<Vec3b>(row)[col] = Vec3b(newValue,newValue,newValue); }
|
||||
else if( image.depth() == CV_16U ){ image.ptr<Vec3s>(row)[col] = Vec3s(newValue,newValue,newValue); }
|
||||
else if( image.depth() == CV_16S ){ image.ptr<Vec3s>(row)[col] = Vec3s(newValue,newValue,newValue); }
|
||||
else if( image.depth() == CV_32S ){ image.ptr<Vec3i>(row)[col] = Vec3i(newValue,newValue,newValue); }
|
||||
else if( image.depth() == CV_32F ){ image.ptr<Vec3f>(row)[col] = Vec3f(newValue,newValue,newValue); }
|
||||
else if( image.depth() == CV_64F ){ image.ptr<Vec3d>(row)[col] = Vec3d(newValue,newValue,newValue); }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal:1, img: 3"); }
|
||||
}
|
||||
|
||||
// input: 3 channel, output: 1 channel
|
||||
else if( gdalChannels == 3 && image.channels() == 1 ){
|
||||
if( image.depth() == CV_8U ){ image.ptr<uchar>(row)[col] += (newValue/3.0); }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal:3, img: 1"); }
|
||||
}
|
||||
|
||||
// input: 4 channel, output: 1 channel
|
||||
else if( gdalChannels == 4 && image.channels() == 1 ){
|
||||
if( image.depth() == CV_8U ){ image.ptr<uchar>(row)[col] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 1"); }
|
||||
}
|
||||
|
||||
// input: 3 channel, output: 3 channel
|
||||
else if( gdalChannels == 3 && image.channels() == 3 ){
|
||||
if( image.depth() == CV_8U ){ (*image.ptr<Vec3b>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16U ){ (*image.ptr<Vec3s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16S ){ (*image.ptr<Vec3s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32S ){ (*image.ptr<Vec3i>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32F ){ (*image.ptr<Vec3f>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_64F ){ (*image.ptr<Vec3d>(row,col))[channel] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: 3, image: 3"); }
|
||||
}
|
||||
|
||||
// input: 4 channel, output: 3 channel
|
||||
else if( gdalChannels == 4 && image.channels() == 3 ){
|
||||
if( channel >= 4 ){ return; }
|
||||
else if( image.depth() == CV_8U && channel < 4 ){ (*image.ptr<Vec3b>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16U && channel < 4 ){ (*image.ptr<Vec3s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16S && channel < 4 ){ (*image.ptr<Vec3s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32S && channel < 4 ){ (*image.ptr<Vec3i>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32F && channel < 4 ){ (*image.ptr<Vec3f>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_64F && channel < 4 ){ (*image.ptr<Vec3d>(row,col))[channel] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 3"); }
|
||||
}
|
||||
|
||||
// input: 4 channel, output: 4 channel
|
||||
else if( gdalChannels == 4 && image.channels() == 4 ){
|
||||
if( image.depth() == CV_8U ){ (*image.ptr<Vec4b>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16U ){ (*image.ptr<Vec4s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_16S ){ (*image.ptr<Vec4s>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32S ){ (*image.ptr<Vec4i>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_32F ){ (*image.ptr<Vec4f>(row,col))[channel] = newValue; }
|
||||
else if( image.depth() == CV_64F ){ (*image.ptr<Vec4d>(row,col))[channel] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 4"); }
|
||||
}
|
||||
|
||||
// input: > 4 channels, output: > 4 channels
|
||||
else if( gdalChannels > 4 && image.channels() > 4 ){
|
||||
if( image.depth() == CV_8U ){ image.ptr<uchar>(row,col)[channel] = newValue; }
|
||||
else if( image.depth() == CV_16U ){ image.ptr<unsigned short>(row,col)[channel] = newValue; }
|
||||
else if( image.depth() == CV_16S ){ image.ptr<short>(row,col)[channel] = newValue; }
|
||||
else if( image.depth() == CV_32S ){ image.ptr<int>(row,col)[channel] = newValue; }
|
||||
else if( image.depth() == CV_32F ){ image.ptr<float>(row,col)[channel] = newValue; }
|
||||
else if( image.depth() == CV_64F ){ image.ptr<double>(row,col)[channel] = newValue; }
|
||||
else{ throw std::runtime_error("Unknown image depth, gdal: N, img: N"); }
|
||||
}
|
||||
// otherwise, throw an error
|
||||
else{
|
||||
throw std::runtime_error("error: can't convert types.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void write_ctable_pixel( const double& pixelValue,
|
||||
const GDALDataType& gdalType,
|
||||
GDALColorTable const* gdalColorTable,
|
||||
Mat& image,
|
||||
const int& y,
|
||||
const int& x,
|
||||
const int& c ){
|
||||
|
||||
if( gdalColorTable == NULL ){
|
||||
write_pixel( pixelValue, gdalType, 1, image, y, x, c );
|
||||
}
|
||||
|
||||
// if we are Grayscale, then do a straight conversion
|
||||
if( gdalColorTable->GetPaletteInterpretation() == GPI_Gray ){
|
||||
write_pixel( pixelValue, gdalType, 1, image, y, x, c );
|
||||
}
|
||||
|
||||
// if we are rgb, then convert here
|
||||
else if( gdalColorTable->GetPaletteInterpretation() == GPI_RGB ){
|
||||
|
||||
// get the pixel
|
||||
short r = gdalColorTable->GetColorEntry( (int)pixelValue )->c1;
|
||||
short g = gdalColorTable->GetColorEntry( (int)pixelValue )->c2;
|
||||
short b = gdalColorTable->GetColorEntry( (int)pixelValue )->c3;
|
||||
short a = gdalColorTable->GetColorEntry( (int)pixelValue )->c4;
|
||||
|
||||
write_pixel( r, gdalType, 4, image, y, x, 2 );
|
||||
write_pixel( g, gdalType, 4, image, y, x, 1 );
|
||||
write_pixel( b, gdalType, 4, image, y, x, 0 );
|
||||
if( image.channels() > 3 ){
|
||||
write_pixel( a, gdalType, 4, image, y, x, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, set zeros
|
||||
else{
|
||||
write_pixel( pixelValue, gdalType, 1, image, y, x, c );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* read data
|
||||
*/
|
||||
bool GdalDecoder::readData( Mat& img ){
|
||||
|
||||
|
||||
// make sure the image is the proper size
|
||||
if( img.size() != Size(m_width, m_height) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the raster is alive
|
||||
if( m_dataset == NULL || m_driver == NULL ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the image to zero
|
||||
img = 0;
|
||||
|
||||
// iterate over each raster band
|
||||
// note that OpenCV does bgr rather than rgb
|
||||
int nChannels = m_dataset->GetRasterCount();
|
||||
|
||||
GDALColorTable* gdalColorTable = NULL;
|
||||
if( m_dataset->GetRasterBand(1)->GetColorTable() != NULL ){
|
||||
gdalColorTable = m_dataset->GetRasterBand(1)->GetColorTable();
|
||||
}
|
||||
|
||||
const GDALDataType gdalType = m_dataset->GetRasterBand(1)->GetRasterDataType();
|
||||
int nRows, nCols;
|
||||
|
||||
if( nChannels > img.channels() ){
|
||||
nChannels = img.channels();
|
||||
}
|
||||
|
||||
for( int c = 0; c<nChannels; c++ ){
|
||||
|
||||
// get the GDAL Band
|
||||
GDALRasterBand* band = m_dataset->GetRasterBand(c+1);
|
||||
|
||||
/* Map palette band and gray band to color index 0 and red, green,
|
||||
blue, alpha bands to BGRA indexes. Note: ignoring HSL, CMY,
|
||||
CMYK, and YCbCr color spaces, rather than converting them
|
||||
to BGR. */
|
||||
int color = 0;
|
||||
switch (band->GetColorInterpretation()) {
|
||||
case GCI_PaletteIndex:
|
||||
case GCI_GrayIndex:
|
||||
case GCI_BlueBand:
|
||||
color = 0;
|
||||
break;
|
||||
case GCI_GreenBand:
|
||||
color = 1;
|
||||
break;
|
||||
case GCI_RedBand:
|
||||
color = 2;
|
||||
break;
|
||||
case GCI_AlphaBand:
|
||||
color = 3;
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
}
|
||||
|
||||
// make sure the image band has the same dimensions as the image
|
||||
if( band->GetXSize() != m_width || band->GetYSize() != m_height ){ return false; }
|
||||
|
||||
// grab the raster size
|
||||
nRows = band->GetYSize();
|
||||
nCols = band->GetXSize();
|
||||
|
||||
// create a temporary scanline pointer to store data
|
||||
double* scanline = new double[nCols];
|
||||
|
||||
// iterate over each row and column
|
||||
for( int y=0; y<nRows; y++ ){
|
||||
|
||||
// get the entire row
|
||||
CPLErr err = band->RasterIO( GF_Read, 0, y, nCols, 1, scanline, nCols, 1, GDT_Float64, 0, 0);
|
||||
CV_Assert(err == CE_None);
|
||||
|
||||
// set inside the image
|
||||
for( int x=0; x<nCols; x++ ){
|
||||
|
||||
// set depending on image types
|
||||
// given boost, I would use enable_if to speed up. Avoid for now.
|
||||
if( hasColorTable == false ){
|
||||
write_pixel( scanline[x], gdalType, nChannels, img, y, x, color );
|
||||
}
|
||||
else{
|
||||
write_ctable_pixel( scanline[x], gdalType, gdalColorTable, img, y, x, color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete our temp pointer
|
||||
delete [] scanline;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read image header
|
||||
*/
|
||||
bool GdalDecoder::readHeader(){
|
||||
|
||||
// load the dataset
|
||||
m_dataset = (GDALDataset*) GDALOpen( m_filename.c_str(), GA_ReadOnly);
|
||||
|
||||
// if dataset is null, then there was a problem
|
||||
if( m_dataset == NULL ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure we have pixel data inside the raster
|
||||
if( m_dataset->GetRasterCount() <= 0 ){
|
||||
return false;
|
||||
}
|
||||
|
||||
//extract the driver information
|
||||
m_driver = m_dataset->GetDriver();
|
||||
|
||||
// if the driver failed, then exit
|
||||
if( m_driver == NULL ){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// get the image dimensions
|
||||
m_width = m_dataset->GetRasterXSize();
|
||||
m_height= m_dataset->GetRasterYSize();
|
||||
|
||||
// make sure we have at least one band/channel
|
||||
if( m_dataset->GetRasterCount() <= 0 ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if we have a color palette
|
||||
int tempType;
|
||||
if( m_dataset->GetRasterBand(1)->GetColorInterpretation() == GCI_PaletteIndex ){
|
||||
|
||||
// remember that we have a color palette
|
||||
hasColorTable = true;
|
||||
|
||||
// if the color tables does not exist, then we failed
|
||||
if( m_dataset->GetRasterBand(1)->GetColorTable() == NULL ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// otherwise, get the pixeltype
|
||||
else{
|
||||
// convert the palette interpretation to opencv type
|
||||
tempType = gdalPaletteInterpretation2OpenCV( m_dataset->GetRasterBand(1)->GetColorTable()->GetPaletteInterpretation(),
|
||||
m_dataset->GetRasterBand(1)->GetRasterDataType() );
|
||||
|
||||
if( tempType == -1 ){
|
||||
return false;
|
||||
}
|
||||
m_type = tempType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// otherwise, we have standard channels
|
||||
else{
|
||||
|
||||
// remember that we don't have a color table
|
||||
hasColorTable = false;
|
||||
|
||||
// convert the datatype to opencv
|
||||
tempType = gdal2opencv( m_dataset->GetRasterBand(1)->GetRasterDataType(), m_dataset->GetRasterCount() );
|
||||
if( tempType == -1 ){
|
||||
return false;
|
||||
}
|
||||
m_type = tempType;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the module
|
||||
*/
|
||||
void GdalDecoder::close(){
|
||||
|
||||
|
||||
GDALClose((GDALDatasetH)m_dataset);
|
||||
m_dataset = NULL;
|
||||
m_driver = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new decoder
|
||||
*/
|
||||
ImageDecoder GdalDecoder::newDecoder()const{
|
||||
return makePtr<GdalDecoder>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the file signature
|
||||
*/
|
||||
bool GdalDecoder::checkSignature( const String& signature )const{
|
||||
|
||||
// look for NITF
|
||||
std::string str(signature);
|
||||
if( str.substr(0,4).find("NITF") != std::string::npos ){
|
||||
return true;
|
||||
}
|
||||
|
||||
// look for DTED
|
||||
if( str.size() > 144 && str.substr(140,4) == "DTED" ){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} /// End of cv Namespace
|
||||
|
||||
#endif /**< End of HAVE_GDAL Definition */
|
166
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdal.hpp
vendored
Normal file
166
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdal.hpp
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
/*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 __GRFMT_GDAL_HPP__
|
||||
#define __GRFMT_GDAL_HPP__
|
||||
|
||||
/// OpenCV FMT Base Type
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
/// Macro to make sure we specified GDAL in CMake
|
||||
#ifdef HAVE_GDAL
|
||||
|
||||
/// C++ Libraries
|
||||
#include <iostream>
|
||||
|
||||
/// Geospatial Data Abstraction Library
|
||||
#include <cpl_conv.h>
|
||||
#include <gdal_priv.h>
|
||||
#include <gdal.h>
|
||||
|
||||
|
||||
/// Start of CV Namespace
|
||||
namespace cv {
|
||||
|
||||
/**
|
||||
* Convert GDAL Pixel Range to OpenCV Pixel Range
|
||||
*/
|
||||
double range_cast( const GDALDataType& gdalType,
|
||||
const int& cvDepth,
|
||||
const double& value );
|
||||
|
||||
/**
|
||||
* Convert GDAL Palette Interpretation to OpenCV Pixel Type
|
||||
*/
|
||||
int gdalPaletteInterpretation2OpenCV( GDALPaletteInterp const& paletteInterp,
|
||||
GDALDataType const& gdalType );
|
||||
|
||||
/**
|
||||
* Convert a GDAL Raster Type to OpenCV Type
|
||||
*/
|
||||
int gdal2opencv( const GDALDataType& gdalType, const int& channels );
|
||||
|
||||
/**
|
||||
* Write an image to pixel
|
||||
*/
|
||||
void write_pixel( const double& pixelValue,
|
||||
GDALDataType const& gdalType,
|
||||
const int& gdalChannels,
|
||||
Mat& image,
|
||||
const int& row,
|
||||
const int& col,
|
||||
const int& channel );
|
||||
|
||||
/**
|
||||
* Write a color table pixel to the image
|
||||
*/
|
||||
void write_ctable_pixel( const double& pixelValue,
|
||||
const GDALDataType& gdalType,
|
||||
const GDALColorTable* gdalColorTable,
|
||||
Mat& image,
|
||||
const int& y,
|
||||
const int& x,
|
||||
const int& c );
|
||||
|
||||
/**
|
||||
* Loader for GDAL
|
||||
*/
|
||||
class GdalDecoder CV_FINAL : public BaseImageDecoder{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
GdalDecoder();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~GdalDecoder() CV_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Read image data
|
||||
*/
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Read the image header
|
||||
*/
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Close the module
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Create a new decoder
|
||||
*/
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Test the file signature
|
||||
*
|
||||
* In general, this should be avoided as the user should specifically request GDAL.
|
||||
* The reason is that GDAL tends to overlap with other image formats and it is probably
|
||||
* safer to use other formats first.
|
||||
*/
|
||||
virtual bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
/// GDAL Dataset
|
||||
GDALDataset* m_dataset;
|
||||
|
||||
/// GDAL Driver
|
||||
GDALDriver* m_driver;
|
||||
|
||||
/// Check if we are reading from a color table
|
||||
bool hasColorTable;
|
||||
|
||||
}; /// End of GdalDecoder Class
|
||||
|
||||
} /// End of Namespace cv
|
||||
|
||||
#endif/*HAVE_GDAL*/
|
||||
|
||||
#endif/*__GRFMT_GDAL_HPP__*/
|
197
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdcm.cpp
vendored
Normal file
197
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdcm.cpp
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
/*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_gdcm.hpp"
|
||||
|
||||
#ifdef HAVE_GDCM
|
||||
|
||||
//#define DBG(...) printf(__VA_ARGS__)
|
||||
#define DBG(...)
|
||||
|
||||
#include <gdcmImageReader.h>
|
||||
|
||||
static const size_t preamble_skip = 128;
|
||||
static const size_t magic_len = 4;
|
||||
|
||||
inline cv::String getMagic()
|
||||
{
|
||||
return cv::String("\x44\x49\x43\x4D", 4);
|
||||
}
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/************************ DICOM decoder *****************************/
|
||||
|
||||
DICOMDecoder::DICOMDecoder()
|
||||
{
|
||||
// DICOM preamble is 128 bytes (can have any value, defaults to 0) + 4 bytes magic number (DICM)
|
||||
m_signature = String(preamble_skip, (char)'\x0') + getMagic();
|
||||
m_buf_supported = false;
|
||||
}
|
||||
|
||||
bool DICOMDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
if (signature.size() >= preamble_skip + magic_len)
|
||||
{
|
||||
if (signature.substr(preamble_skip, magic_len) == getMagic())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DBG("GDCM | Signature does not match\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageDecoder DICOMDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<DICOMDecoder>();
|
||||
}
|
||||
|
||||
bool DICOMDecoder::readHeader()
|
||||
{
|
||||
gdcm::ImageReader csImageReader;
|
||||
csImageReader.SetFileName(m_filename.c_str());
|
||||
if(!csImageReader.Read())
|
||||
{
|
||||
DBG("GDCM | Failed to open DICOM file\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
const gdcm::Image &csImage = csImageReader.GetImage();
|
||||
bool bOK = true;
|
||||
switch (csImage.GetPhotometricInterpretation().GetType())
|
||||
{
|
||||
case gdcm::PhotometricInterpretation::MONOCHROME1:
|
||||
case gdcm::PhotometricInterpretation::MONOCHROME2:
|
||||
{
|
||||
switch (csImage.GetPixelFormat().GetScalarType())
|
||||
{
|
||||
case gdcm::PixelFormat::INT8: m_type = CV_8SC1; break;
|
||||
case gdcm::PixelFormat::UINT8: m_type = CV_8UC1; break;
|
||||
case gdcm::PixelFormat::INT16: m_type = CV_16SC1; break;
|
||||
case gdcm::PixelFormat::UINT16: m_type = CV_16UC1; break;
|
||||
case gdcm::PixelFormat::INT32: m_type = CV_32SC1; break;
|
||||
case gdcm::PixelFormat::FLOAT32: m_type = CV_32FC1; break;
|
||||
case gdcm::PixelFormat::FLOAT64: m_type = CV_64FC1; break;
|
||||
default: bOK = false; DBG("GDCM | Monochrome scalar type not supported\n"); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gdcm::PhotometricInterpretation::RGB:
|
||||
{
|
||||
switch (csImage.GetPixelFormat().GetScalarType())
|
||||
{
|
||||
case gdcm::PixelFormat::UINT8: m_type = CV_8UC3; break;
|
||||
default: bOK = false; DBG("GDCM | RGB scalar type not supported\n"); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
bOK = false;
|
||||
DBG("GDCM | PI not supported: %s\n", csImage.GetPhotometricInterpretation().GetString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bOK)
|
||||
{
|
||||
unsigned int ndim = csImage.GetNumberOfDimensions();
|
||||
if (ndim != 2)
|
||||
{
|
||||
DBG("GDCM | Invalid dimensions number: %d\n", ndim);
|
||||
bOK = false;
|
||||
}
|
||||
}
|
||||
if (bOK)
|
||||
{
|
||||
const unsigned int *piDimension = csImage.GetDimensions();
|
||||
m_height = piDimension[0];
|
||||
m_width = piDimension[1];
|
||||
if( ( m_width <=0 ) || ( m_height <=0 ) )
|
||||
{
|
||||
DBG("GDCM | Invalid dimensions: %d x %d\n", piDimension[0], piDimension[1]);
|
||||
bOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
return(bOK);
|
||||
}
|
||||
|
||||
|
||||
bool DICOMDecoder::readData( Mat& csImage )
|
||||
{
|
||||
csImage.create(m_width,m_height,m_type);
|
||||
|
||||
gdcm::ImageReader csImageReader;
|
||||
csImageReader.SetFileName(m_filename.c_str());
|
||||
if(!csImageReader.Read())
|
||||
{
|
||||
DBG("GDCM | Failed to Read\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const gdcm::Image &img = csImageReader.GetImage();
|
||||
|
||||
unsigned long len = img.GetBufferLength();
|
||||
if (len > csImage.elemSize() * csImage.total())
|
||||
{
|
||||
DBG("GDCM | Buffer is bigger than Mat: %ld > %ld * %ld\n", len, csImage.elemSize(), csImage.total());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!img.GetBuffer((char*)csImage.ptr()))
|
||||
{
|
||||
DBG("GDCM | Failed to GetBuffer\n");
|
||||
return false;
|
||||
}
|
||||
DBG("GDCM | Read OK\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_GDCM
|
70
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdcm.hpp
vendored
Normal file
70
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_gdcm.hpp
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/*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 _GDCM_DICOM_H_
|
||||
#define _GDCM_DICOM_H_
|
||||
|
||||
#include "cvconfig.h"
|
||||
|
||||
#ifdef HAVE_GDCM
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// DICOM image reader using GDCM
|
||||
class DICOMDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
DICOMDecoder();
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
virtual bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_GDCM
|
||||
|
||||
#endif/*_GDCM_DICOM_H_*/
|
172
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_hdr.cpp
vendored
Normal file
172
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_hdr.cpp
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_HDR
|
||||
|
||||
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() &&
|
||||
0 == memcmp(signature.c_str(), m_signature.c_str(), m_signature.size())
|
||||
)
|
||||
return true;
|
||||
if (signature.size() >= m_signature_alt.size() &&
|
||||
0 == 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_HDR
|
92
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_hdr.hpp
vendored
Normal file
92
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_hdr.hpp
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_HDR
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
enum HdrCompression
|
||||
{
|
||||
HDR_NONE = 0,
|
||||
HDR_RLE = 1
|
||||
};
|
||||
|
||||
// Radiance rgbe (.hdr) reader
|
||||
class HdrDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
HdrDecoder();
|
||||
~HdrDecoder() CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
protected:
|
||||
String m_signature_alt;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
// ... writer
|
||||
class HdrEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
HdrEncoder();
|
||||
~HdrEncoder() CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_HDR
|
||||
|
||||
#endif/*_GRFMT_HDR_H_*/
|
765
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg.cpp
vendored
Normal file
765
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg.cpp
vendored
Normal file
@ -0,0 +1,765 @@
|
||||
/*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 pointer 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"
|
||||
}
|
||||
|
||||
#ifndef CV_MANUAL_JPEG_STD_HUFF_TABLES
|
||||
#if defined(LIBJPEG_TURBO_VERSION_NUMBER) && LIBJPEG_TURBO_VERSION_NUMBER >= 1003090
|
||||
#define CV_MANUAL_JPEG_STD_HUFF_TABLES 0 // libjpeg-turbo handles standard huffman tables itself (jstdhuff.c)
|
||||
#else
|
||||
#define CV_MANUAL_JPEG_STD_HUFF_TABLES 1
|
||||
#endif
|
||||
#endif
|
||||
#if CV_MANUAL_JPEG_STD_HUFF_TABLES == 0
|
||||
#undef CV_MANUAL_JPEG_STD_HUFF_TABLES
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
struct JpegErrorMgr
|
||||
{
|
||||
struct jpeg_error_mgr pub;
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
volatile 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.ptr();
|
||||
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_save_markers(&state->cinfo, APP1, 0xffff);
|
||||
jpeg_read_header( &state->cinfo, TRUE );
|
||||
|
||||
state->cinfo.scale_num=1;
|
||||
state->cinfo.scale_denom = m_scale_denom;
|
||||
m_scale_denom=1; // trick! to know which decoder used scale_denom see imread_
|
||||
jpeg_calc_output_dimensions(&state->cinfo);
|
||||
m_width = state->cinfo.output_width;
|
||||
m_height = state->cinfo.output_height;
|
||||
m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CV_MANUAL_JPEG_STD_HUFF_TABLES
|
||||
/***************************************************************************
|
||||
* 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] = {0};
|
||||
|
||||
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
|
||||
***************************************************************************/
|
||||
#endif // CV_MANUAL_JPEG_STD_HUFF_TABLES
|
||||
|
||||
bool JpegDecoder::readData( Mat& img )
|
||||
{
|
||||
volatile bool result = false;
|
||||
size_t step = 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 )
|
||||
{
|
||||
#ifdef CV_MANUAL_JPEG_STD_HUFF_TABLES
|
||||
/* 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 );
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Exif marker APP1
|
||||
jpeg_saved_marker_ptr exif_marker = NULL;
|
||||
jpeg_saved_marker_ptr cmarker = cinfo->marker_list;
|
||||
while( cmarker && exif_marker == NULL )
|
||||
{
|
||||
if (cmarker->marker == APP1)
|
||||
exif_marker = cmarker;
|
||||
|
||||
cmarker = cmarker->next;
|
||||
}
|
||||
|
||||
// Parse Exif data
|
||||
if( exif_marker )
|
||||
{
|
||||
const std::streamsize offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
|
||||
|
||||
if (exif_marker->data_length > offsetToTiffHeader)
|
||||
{
|
||||
m_exif.parseExif(exif_marker->data + offsetToTiffHeader, exif_marker->data_length - offsetToTiffHeader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jpeg_start_decompress( cinfo );
|
||||
|
||||
buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
|
||||
JPOOL_IMAGE, m_width*4, 1 );
|
||||
|
||||
uchar* data = img.ptr();
|
||||
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, Size(m_width,1) );
|
||||
else
|
||||
icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, Size(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, Size(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); }
|
||||
};
|
||||
volatile 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;
|
||||
int rst_interval = 0;
|
||||
int luma_quality = -1;
|
||||
int chroma_quality = -1;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
if( params[i] == CV_IMWRITE_JPEG_LUMA_QUALITY )
|
||||
{
|
||||
if (params[i+1] >= 0)
|
||||
{
|
||||
luma_quality = MIN(MAX(params[i+1], 0), 100);
|
||||
|
||||
quality = luma_quality;
|
||||
|
||||
if (chroma_quality < 0)
|
||||
{
|
||||
chroma_quality = luma_quality;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( params[i] == CV_IMWRITE_JPEG_CHROMA_QUALITY )
|
||||
{
|
||||
if (params[i+1] >= 0)
|
||||
{
|
||||
chroma_quality = MIN(MAX(params[i+1], 0), 100);
|
||||
}
|
||||
}
|
||||
|
||||
if( params[i] == CV_IMWRITE_JPEG_RST_INTERVAL )
|
||||
{
|
||||
rst_interval = params[i+1];
|
||||
rst_interval = MIN(MAX(rst_interval, 0), 65535L);
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_set_defaults( &cinfo );
|
||||
cinfo.restart_interval = rst_interval;
|
||||
|
||||
jpeg_set_quality( &cinfo, quality,
|
||||
TRUE /* limit to baseline-JPEG values */ );
|
||||
if( progressive )
|
||||
jpeg_simple_progression( &cinfo );
|
||||
if( optimize )
|
||||
cinfo.optimize_coding = TRUE;
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
if (luma_quality >= 0 && chroma_quality >= 0)
|
||||
{
|
||||
cinfo.q_scale_factor[0] = jpeg_quality_scaling(luma_quality);
|
||||
cinfo.q_scale_factor[1] = jpeg_quality_scaling(chroma_quality);
|
||||
if ( luma_quality != chroma_quality )
|
||||
{
|
||||
/* disable subsampling - ref. Libjpeg.txt */
|
||||
cinfo.comp_info[0].v_samp_factor = 1;
|
||||
cinfo.comp_info[0].h_samp_factor = 1;
|
||||
cinfo.comp_info[1].v_samp_factor = 1;
|
||||
cinfo.comp_info[1].h_samp_factor = 1;
|
||||
}
|
||||
jpeg_default_qtables( &cinfo, TRUE );
|
||||
}
|
||||
#endif // #if JPEG_LIB_VERSION >= 70
|
||||
|
||||
jpeg_start_compress( &cinfo, TRUE );
|
||||
|
||||
if( channels > 1 )
|
||||
_buffer.allocate(width*channels);
|
||||
buffer = _buffer.data();
|
||||
|
||||
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, Size(width,1) );
|
||||
ptr = buffer;
|
||||
}
|
||||
else if( _channels == 4 )
|
||||
{
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, Size(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. */
|
113
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg.hpp
vendored
Normal file
113
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg.hpp
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/*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
|
||||
{
|
||||
/**
|
||||
* @brief Jpeg markers that can be encountered in a Jpeg file
|
||||
*/
|
||||
enum AppMarkerTypes
|
||||
{
|
||||
SOI = 0xD8, SOF0 = 0xC0, SOF2 = 0xC2, DHT = 0xC4,
|
||||
DQT = 0xDB, DRI = 0xDD, SOS = 0xDA,
|
||||
|
||||
RST0 = 0xD0, RST1 = 0xD1, RST2 = 0xD2, RST3 = 0xD3,
|
||||
RST4 = 0xD4, RST5 = 0xD5, RST6 = 0xD6, RST7 = 0xD7,
|
||||
|
||||
APP0 = 0xE0, APP1 = 0xE1, APP2 = 0xE2, APP3 = 0xE3,
|
||||
APP4 = 0xE4, APP5 = 0xE5, APP6 = 0xE6, APP7 = 0xE7,
|
||||
APP8 = 0xE8, APP9 = 0xE9, APP10 = 0xEA, APP11 = 0xEB,
|
||||
APP12 = 0xEC, APP13 = 0xED, APP14 = 0xEE, APP15 = 0xEF,
|
||||
|
||||
COM = 0xFE, EOI = 0xD9
|
||||
};
|
||||
|
||||
|
||||
class JpegDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
JpegDecoder();
|
||||
virtual ~JpegDecoder();
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
FILE* m_f;
|
||||
void* m_state;
|
||||
|
||||
private:
|
||||
JpegDecoder(const JpegDecoder &); // copy disabled
|
||||
JpegDecoder& operator=(const JpegDecoder &); // assign disabled
|
||||
};
|
||||
|
||||
|
||||
class JpegEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
JpegEncoder();
|
||||
virtual ~JpegEncoder();
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_JPEG_H_*/
|
642
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000.cpp
vendored
Normal file
642
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000.cpp
vendored
Normal file
@ -0,0 +1,642 @@
|
||||
/*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 <sstream>
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include "grfmt_jpeg2000.hpp"
|
||||
#include "opencv2/imgproc.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& _initJasper()
|
||||
{
|
||||
static JasperInitializer initialize_jasper;
|
||||
return initialize_jasper;
|
||||
}
|
||||
|
||||
static bool isJasperEnabled()
|
||||
{
|
||||
static const bool PARAM_ENABLE_JASPER = utils::getConfigurationParameterBool("OPENCV_IO_ENABLE_JASPER",
|
||||
#ifdef OPENCV_IMGCODECS_FORCE_JASPER
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
return PARAM_ENABLE_JASPER;
|
||||
}
|
||||
static JasperInitializer& initJasper()
|
||||
{
|
||||
if (isJasperEnabled())
|
||||
{
|
||||
return _initJasper();
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* message = "imgcodecs: Jasper (JPEG-2000) codec is disabled. You can enable it via 'OPENCV_IO_ENABLE_JASPER' option. Refer for details and cautions here: https://github.com/opencv/opencv/issues/14058";
|
||||
CV_LOG_WARNING(NULL, message);
|
||||
CV_Error(Error::StsNotImplemented, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// Jpeg2KDecoder ///////////////////
|
||||
|
||||
Jpeg2KDecoder::Jpeg2KDecoder()
|
||||
{
|
||||
static const unsigned char signature_[12] = { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 13, 10, 0x87, 10};
|
||||
m_signature = String((const char*)signature_, (const char*)signature_ + sizeof(signature_));
|
||||
m_stream = 0;
|
||||
m_image = 0;
|
||||
}
|
||||
|
||||
|
||||
Jpeg2KDecoder::~Jpeg2KDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KDecoder::newDecoder() const
|
||||
{
|
||||
initJasper();
|
||||
return makePtr<Jpeg2KDecoder>();
|
||||
}
|
||||
|
||||
void Jpeg2KDecoder::close()
|
||||
{
|
||||
if( m_stream )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
jas_stream_close( (jas_stream_t*)m_stream );
|
||||
m_stream = 0;
|
||||
}
|
||||
|
||||
if( m_image )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
jas_image_destroy( (jas_image_t*)m_image );
|
||||
m_image = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readHeader()
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
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 ) {
|
||||
CV_Assert(0 == (jas_image_tlx(image)) && "not supported");
|
||||
CV_Assert(0 == (jas_image_tly(image)) && "not supported");
|
||||
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 );
|
||||
CV_Assert(depth == 0 || depth == depth_i); // component data type mismatch
|
||||
depth = MAX(depth, depth_i);
|
||||
if( jas_image_cmpttype( image, i ) > 2 )
|
||||
continue;
|
||||
int sgnd = jas_image_cmptsgnd(image, i);
|
||||
int xstart = jas_image_cmpttlx(image, i);
|
||||
int xend = jas_image_cmptbrx(image, i);
|
||||
int xstep = jas_image_cmpthstep(image, i);
|
||||
int ystart = jas_image_cmpttly(image, i);
|
||||
int yend = jas_image_cmptbry(image, i);
|
||||
int ystep = jas_image_cmptvstep(image, i);
|
||||
CV_Assert(sgnd == 0 && "not supported");
|
||||
CV_Assert(xstart == 0 && "not supported");
|
||||
CV_Assert(ystart == 0 && "not supported");
|
||||
CV_Assert(xstep == 1 && "not supported");
|
||||
CV_Assert(ystep == 1 && "not supported");
|
||||
CV_Assert(xend == m_width);
|
||||
CV_Assert(yend == m_height);
|
||||
cntcmpts++;
|
||||
}
|
||||
|
||||
if( cntcmpts )
|
||||
{
|
||||
CV_Assert(depth == 8 || depth == 16);
|
||||
CV_Assert(cntcmpts == 1 || cntcmpts == 3);
|
||||
m_type = CV_MAKETYPE(depth <= 8 ? CV_8U : CV_16U, cntcmpts > 1 ? 3 : 1);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Jpeg2KDecoder_close(Jpeg2KDecoder* ptr)
|
||||
{
|
||||
ptr->close();
|
||||
}
|
||||
|
||||
bool Jpeg2KDecoder::readData( Mat& img )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
|
||||
Ptr<Jpeg2KDecoder> close_this(this, Jpeg2KDecoder_close);
|
||||
bool result = false;
|
||||
bool color = img.channels() > 1;
|
||||
uchar* data = img.ptr();
|
||||
size_t step = img.step;
|
||||
jas_stream_t* stream = (jas_stream_t*)m_stream;
|
||||
jas_image_t* image = (jas_image_t*)m_image;
|
||||
|
||||
#ifndef _WIN32
|
||||
// At least on some Linux instances the
|
||||
// system libjasper segfaults when
|
||||
// converting color to grey.
|
||||
// We do this conversion manually at the end.
|
||||
Mat clr;
|
||||
if (CV_MAT_CN(img.type()) < CV_MAT_CN(this->type()))
|
||||
{
|
||||
clr.create(img.size().height, img.size().width, this->type());
|
||||
color = true;
|
||||
data = clr.ptr();
|
||||
step = (int)clr.step;
|
||||
}
|
||||
#endif
|
||||
|
||||
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? (GENGRAY fails on Win.)
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
jas_cmprof_destroy(clrprof);
|
||||
CV_Error(Error::StsError, "JPEG 2000 LOADER ERROR: cannot convert colorspace");
|
||||
}
|
||||
jas_cmprof_destroy( clrprof );
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsError, "JPEG 2000 LOADER ERROR: unable to create colorspace");
|
||||
}
|
||||
}
|
||||
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, validateToInt(step), cmptlut[i], maxval, offset, ncmpts );
|
||||
else
|
||||
result = readComponent16u( ((unsigned short *)data) + i, buffer, validateToInt(step / 2), cmptlut[i], maxval, offset, ncmpts );
|
||||
if( !result )
|
||||
{
|
||||
jas_matrix_destroy( buffer );
|
||||
CV_Error(Error::StsError, "JPEG2000 LOADER ERROR: failed to read component");
|
||||
}
|
||||
}
|
||||
jas_matrix_destroy( buffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsError, "JPEG2000 LOADER ERROR: colorspace conversion failed");
|
||||
}
|
||||
}
|
||||
|
||||
CV_Assert(result == true);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (!clr.empty())
|
||||
{
|
||||
cv::cvtColor(clr, img, COLOR_BGR2GRAY);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KDecoder::readComponent8u( uchar *data, void *_buffer,
|
||||
int step, int cmpt,
|
||||
int maxval, int offset, int ncmpts )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
|
||||
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_getref( 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 )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
|
||||
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_getref( 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
|
||||
{
|
||||
initJasper();
|
||||
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>& params )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
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;
|
||||
|
||||
CV_Assert(params.size() % 2 == 0);
|
||||
double target_compression_rate = 1.0;
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
switch(params[i])
|
||||
{
|
||||
case cv::IMWRITE_JPEG2000_COMPRESSION_X1000:
|
||||
target_compression_rate = std::min(std::max(params[i+1], 0), 1000) / 1000.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
std::stringstream options;
|
||||
options << "rate=" << target_compression_rate;
|
||||
|
||||
result = !jas_image_encode( img, stream, jas_image_strtofmt( (char*)"jp2" ), (char*)options.str().c_str() );
|
||||
|
||||
jas_stream_close( stream );
|
||||
}
|
||||
|
||||
}
|
||||
jas_image_destroy( img );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KEncoder::writeComponent8u( void *__img, const Mat& _img )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
|
||||
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++ )
|
||||
{
|
||||
const uchar* data = _img.ptr(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 )
|
||||
{
|
||||
CV_Assert(isJasperEnabled());
|
||||
|
||||
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++ )
|
||||
{
|
||||
const ushort* data = _img.ptr<ushort>(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. */
|
95
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000.hpp
vendored
Normal file
95
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000.hpp
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*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 CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
Jpeg2KDecoder();
|
||||
virtual ~Jpeg2KDecoder();
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
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 CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
Jpeg2KEncoder();
|
||||
virtual ~Jpeg2KEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
bool writeComponent8u( void *img, const Mat& _img );
|
||||
bool writeComponent16u( void *img, const Mat& _img );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_JASPER_H_*/
|
810
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000_openjpeg.cpp
vendored
Normal file
810
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000_openjpeg.cpp
vendored
Normal file
@ -0,0 +1,810 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2020, Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#ifdef HAVE_OPENJPEG
|
||||
#include "grfmt_jpeg2000_openjpeg.hpp"
|
||||
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
|
||||
namespace cv {
|
||||
|
||||
namespace {
|
||||
|
||||
String colorspaceName(COLOR_SPACE colorspace)
|
||||
{
|
||||
switch (colorspace)
|
||||
{
|
||||
case OPJ_CLRSPC_CMYK:
|
||||
return "CMYK";
|
||||
case OPJ_CLRSPC_SRGB:
|
||||
return "sRGB";
|
||||
case OPJ_CLRSPC_EYCC:
|
||||
return "e-YCC";
|
||||
case OPJ_CLRSPC_GRAY:
|
||||
return "grayscale";
|
||||
case OPJ_CLRSPC_SYCC:
|
||||
return "YUV";
|
||||
case OPJ_CLRSPC_UNKNOWN:
|
||||
return "unknown";
|
||||
case OPJ_CLRSPC_UNSPECIFIED:
|
||||
return "unspecified";
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "Invalid colorspace");
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct ConstItTraits {
|
||||
using value_type = T;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = const T*;
|
||||
using reference = const T&;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct NonConstItTraits {
|
||||
using value_type = T;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator over the channel in continuous chunk of the memory e.g. in the one row of a Mat
|
||||
* No bounds checks are preformed due to keeping this class as simple as possible while
|
||||
* fulfilling RandomAccessIterator naming requirements.
|
||||
*
|
||||
* @tparam Traits holds information about value type and constness of the defined types
|
||||
*/
|
||||
template <class Traits>
|
||||
class ChannelsIterator
|
||||
{
|
||||
public:
|
||||
using difference_type = typename Traits::difference_type;
|
||||
using value_type = typename Traits::value_type;
|
||||
using pointer = typename Traits::pointer;
|
||||
using reference = typename Traits::reference;
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
|
||||
ChannelsIterator(pointer ptr, std::size_t channel, std::size_t channels_count)
|
||||
: ptr_ { ptr + channel }, step_ { channels_count }
|
||||
{
|
||||
}
|
||||
|
||||
/* Element Access */
|
||||
reference operator*() const
|
||||
{
|
||||
return *ptr_;
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return &(operator*());
|
||||
}
|
||||
|
||||
reference operator[](difference_type n) const
|
||||
{
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
/* Iterator movement */
|
||||
ChannelsIterator<Traits>& operator++()
|
||||
{
|
||||
ptr_ += step_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits> operator++(int)
|
||||
{
|
||||
ChannelsIterator ret(*this);
|
||||
++(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits>& operator--()
|
||||
{
|
||||
ptr_ -= step_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits> operator--(int)
|
||||
{
|
||||
ChannelsIterator ret(*this);
|
||||
--(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits>& operator-=(difference_type n)
|
||||
{
|
||||
ptr_ -= n * step_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits>& operator+=(difference_type n)
|
||||
{
|
||||
ptr_ += n * step_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits> operator-(difference_type n) const
|
||||
{
|
||||
return ChannelsIterator<Traits>(*this) -= n;
|
||||
}
|
||||
|
||||
ChannelsIterator<Traits> operator+(difference_type n) const
|
||||
{
|
||||
return ChannelsIterator<Traits>(*this) += n;
|
||||
}
|
||||
|
||||
difference_type operator-(const ChannelsIterator<Traits>& other) const
|
||||
{
|
||||
return (ptr_ - other.ptr_) / step_;
|
||||
}
|
||||
|
||||
/* Comparision */
|
||||
bool operator==(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return ptr_ == other.ptr_;
|
||||
}
|
||||
|
||||
bool operator!=(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool operator<(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return ptr_ < other.ptr_;
|
||||
}
|
||||
|
||||
bool operator>(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return other < *this;
|
||||
}
|
||||
|
||||
bool operator>=(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return !(*this < other);
|
||||
}
|
||||
|
||||
bool operator<=(const ChannelsIterator<Traits>& other) const CV_NOEXCEPT
|
||||
{
|
||||
return !(other < *this);
|
||||
}
|
||||
|
||||
private:
|
||||
pointer ptr_{nullptr};
|
||||
std::size_t step_{1};
|
||||
};
|
||||
|
||||
template <class Traits>
|
||||
inline ChannelsIterator<Traits> operator+(typename Traits::difference_type n, const ChannelsIterator<Traits>& it)
|
||||
{
|
||||
return it + n;
|
||||
}
|
||||
|
||||
template<typename OutT, typename InT>
|
||||
void copyToMatImpl(std::vector<InT*>&& in, Mat& out, uint8_t shift)
|
||||
{
|
||||
using ChannelsIt = ChannelsIterator<NonConstItTraits<OutT>>;
|
||||
|
||||
Size size = out.size();
|
||||
if (out.isContinuous())
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
const bool isShiftRequired = shift != 0;
|
||||
|
||||
const std::size_t channelsCount = in.size();
|
||||
|
||||
if (isShiftRequired)
|
||||
{
|
||||
for (int i = 0; i < size.height; ++i)
|
||||
{
|
||||
auto rowPtr = out.ptr<OutT>(i);
|
||||
for (std::size_t c = 0; c < channelsCount; ++c)
|
||||
{
|
||||
const auto first = in[c];
|
||||
const auto last = first + size.width;
|
||||
auto dOut = ChannelsIt(rowPtr, c, channelsCount);
|
||||
std::transform(first, last, dOut, [shift](InT val) -> OutT { return static_cast<OutT>(val >> shift); });
|
||||
in[c] += size.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < size.height; ++i)
|
||||
{
|
||||
auto rowPtr = out.ptr<OutT>(i);
|
||||
for (std::size_t c = 0; c < channelsCount; ++c)
|
||||
{
|
||||
const auto first = in[c];
|
||||
const auto last = first + size.width;
|
||||
auto dOut = ChannelsIt(rowPtr, c, channelsCount);
|
||||
std::transform(first, last, dOut, [](InT val) -> OutT { return static_cast<OutT>(val); });
|
||||
in[c] += size.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InT>
|
||||
void copyToMat(std::vector<const InT*>&& in, Mat& out, uint8_t shift)
|
||||
{
|
||||
switch (out.depth())
|
||||
{
|
||||
case CV_8U:
|
||||
copyToMatImpl<uint8_t>(std::move(in), out, shift);
|
||||
break;
|
||||
case CV_16U:
|
||||
copyToMatImpl<uint16_t>(std::move(in), out, shift);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "only depth CV_8U and CV16_U are supported");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InT, typename OutT>
|
||||
void copyFromMatImpl(const Mat& in, std::vector<OutT*>&& out)
|
||||
{
|
||||
using ChannelsIt = ChannelsIterator<ConstItTraits<InT>>;
|
||||
|
||||
Size size = in.size();
|
||||
if (in.isContinuous())
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
const std::size_t outChannelsCount = out.size();
|
||||
|
||||
for (int i = 0; i < size.height; ++i)
|
||||
{
|
||||
const InT* row = in.ptr<InT>(i);
|
||||
for (std::size_t c = 0; c < outChannelsCount; ++c)
|
||||
{
|
||||
auto first = ChannelsIt(row, c, outChannelsCount);
|
||||
auto last = first + size.width;
|
||||
out[c] = std::copy(first, last, out[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OutT>
|
||||
void copyFromMat(const Mat& in, std::vector<OutT*>&& out)
|
||||
{
|
||||
switch (in.depth())
|
||||
{
|
||||
case CV_8U:
|
||||
copyFromMatImpl<uint8_t>(in, std::move(out));
|
||||
break;
|
||||
case CV_16U:
|
||||
copyFromMatImpl<uint16_t>(in, std::move(out));
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "only depth CV_8U and CV16_U are supported");
|
||||
}
|
||||
}
|
||||
|
||||
void errorLogCallback(const char* msg, void* /* userData */)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, cv::format("OpenJPEG2000: %s", msg));
|
||||
}
|
||||
|
||||
void warningLogCallback(const char* msg, void* /* userData */)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, cv::format("OpenJPEG2000: %s", msg));
|
||||
}
|
||||
|
||||
void setupLogCallbacks(opj_codec_t* codec)
|
||||
{
|
||||
if (!opj_set_error_handler(codec, errorLogCallback, nullptr))
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000: can not set error log handler");
|
||||
}
|
||||
if (!opj_set_warning_handler(codec, warningLogCallback, nullptr))
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000: can not set warning log handler");
|
||||
}
|
||||
}
|
||||
|
||||
opj_dparameters setupDecoderParameters()
|
||||
{
|
||||
opj_dparameters parameters;
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
opj_cparameters setupEncoderParameters(const std::vector<int>& params)
|
||||
{
|
||||
opj_cparameters parameters;
|
||||
opj_set_default_encoder_parameters(¶meters);
|
||||
bool rate_is_specified = false;
|
||||
for (size_t i = 0; i < params.size(); i += 2)
|
||||
{
|
||||
switch (params[i])
|
||||
{
|
||||
case cv::IMWRITE_JPEG2000_COMPRESSION_X1000:
|
||||
parameters.tcp_rates[0] = 1000.f / std::min(std::max(params[i + 1], 1), 1000);
|
||||
rate_is_specified = true;
|
||||
break;
|
||||
default:
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000(encoder): skip unsupported parameter: " << params[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
parameters.tcp_numlayers = 1;
|
||||
parameters.cp_disto_alloc = 1;
|
||||
if (!rate_is_specified)
|
||||
{
|
||||
parameters.tcp_rates[0] = 4;
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
bool decodeSRGBData(const opj_image_t& inImg, cv::Mat& outImg, uint8_t shift)
|
||||
{
|
||||
using ImageComponents = std::vector<const OPJ_INT32*>;
|
||||
|
||||
const int inChannels = inImg.numcomps;
|
||||
const int outChannels = outImg.channels();
|
||||
|
||||
if (outChannels == 1)
|
||||
{
|
||||
// Assume gray (+ alpha) for 1 channels -> gray
|
||||
if (inChannels <= 2)
|
||||
{
|
||||
copyToMat(ImageComponents { inImg.comps[0].data }, outImg, shift);
|
||||
}
|
||||
// Assume RGB for >= 3 channels -> gray
|
||||
else
|
||||
{
|
||||
Mat tmp(outImg.size(), CV_MAKETYPE(outImg.depth(), 3));
|
||||
copyToMat(ImageComponents { inImg.comps[2].data, inImg.comps[1].data, inImg.comps[0].data },
|
||||
tmp, shift);
|
||||
cvtColor(tmp, outImg, COLOR_BGR2GRAY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inChannels >= 3)
|
||||
{
|
||||
// Assume RGB (+ alpha) for 3 channels -> BGR
|
||||
ImageComponents incomps { inImg.comps[2].data, inImg.comps[1].data, inImg.comps[0].data };
|
||||
// Assume RGBA for 4 channels -> BGRA
|
||||
if (outChannels > 3)
|
||||
{
|
||||
incomps.push_back(inImg.comps[3].data);
|
||||
}
|
||||
copyToMat(std::move(incomps), outImg, shift);
|
||||
return true;
|
||||
}
|
||||
CV_LOG_ERROR(NULL,
|
||||
cv::format("OpenJPEG2000: unsupported conversion from %d components to %d for SRGB image decoding",
|
||||
inChannels, outChannels));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool decodeGrayscaleData(const opj_image_t& inImg, cv::Mat& outImg, uint8_t shift)
|
||||
{
|
||||
using ImageComponents = std::vector<const OPJ_INT32*>;
|
||||
|
||||
const int inChannels = inImg.numcomps;
|
||||
const int outChannels = outImg.channels();
|
||||
|
||||
if (outChannels == 1 || outChannels == 3)
|
||||
{
|
||||
copyToMat(ImageComponents(outChannels, inImg.comps[0].data), outImg, shift);
|
||||
return true;
|
||||
}
|
||||
CV_LOG_ERROR(NULL,
|
||||
cv::format("OpenJPEG2000: unsupported conversion from %d components to %d for Grayscale image decoding",
|
||||
inChannels, outChannels));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool decodeSYCCData(const opj_image_t& inImg, cv::Mat& outImg, uint8_t shift)
|
||||
{
|
||||
using ImageComponents = std::vector<const OPJ_INT32*>;
|
||||
|
||||
const int inChannels = inImg.numcomps;
|
||||
const int outChannels = outImg.channels();
|
||||
|
||||
if (outChannels == 1) {
|
||||
copyToMat(ImageComponents { inImg.comps[0].data }, outImg, shift);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (outChannels == 3 && inChannels >= 3) {
|
||||
copyToMat(ImageComponents { inImg.comps[0].data, inImg.comps[1].data, inImg.comps[2].data },
|
||||
outImg, shift);
|
||||
cvtColor(outImg, outImg, COLOR_YUV2BGR);
|
||||
return true;
|
||||
}
|
||||
|
||||
CV_LOG_ERROR(NULL,
|
||||
cv::format("OpenJPEG2000: unsupported conversion from %d components to %d for YUV image decoding",
|
||||
inChannels, outChannels));
|
||||
return false;
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opjReadFromBuffer(void* dist, OPJ_SIZE_T count, detail::OpjMemoryBuffer* buffer)
|
||||
{
|
||||
const OPJ_SIZE_T bytesToRead = std::min(buffer->availableBytes(), count);
|
||||
if (bytesToRead > 0)
|
||||
{
|
||||
memcpy(dist, buffer->pos, bytesToRead);
|
||||
buffer->pos += bytesToRead;
|
||||
return bytesToRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<OPJ_SIZE_T>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opjSkipFromBuffer(OPJ_SIZE_T count, detail::OpjMemoryBuffer* buffer) {
|
||||
const OPJ_SIZE_T bytesToSkip = std::min(buffer->availableBytes(), count);
|
||||
if (bytesToSkip > 0)
|
||||
{
|
||||
buffer->pos += bytesToSkip;
|
||||
return bytesToSkip;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<OPJ_SIZE_T>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
OPJ_BOOL opjSeekFromBuffer(OPJ_OFF_T count, detail::OpjMemoryBuffer* buffer)
|
||||
{
|
||||
// Count should stay positive to prevent unsigned overflow
|
||||
CV_DbgAssert(count > 0);
|
||||
// To provide proper comparison between OPJ_OFF_T and OPJ_SIZE_T, both should be
|
||||
// casted to uint64_t (On 32-bit systems sizeof(size_t) might be 4)
|
||||
CV_DbgAssert(static_cast<uint64_t>(count) < static_cast<uint64_t>(std::numeric_limits<OPJ_SIZE_T>::max()));
|
||||
const OPJ_SIZE_T pos = std::min(buffer->length, static_cast<OPJ_SIZE_T>(count));
|
||||
buffer->pos = buffer->begin + pos;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
detail::StreamPtr opjCreateBufferInputStream(detail::OpjMemoryBuffer* buf)
|
||||
{
|
||||
detail::StreamPtr stream{ opj_stream_default_create(/* isInput */ true) };
|
||||
if (stream)
|
||||
{
|
||||
opj_stream_set_user_data(stream.get(), static_cast<void*>(buf), nullptr);
|
||||
opj_stream_set_user_data_length(stream.get(), buf->length);
|
||||
|
||||
opj_stream_set_read_function(stream.get(), (opj_stream_read_fn)(opjReadFromBuffer));
|
||||
opj_stream_set_skip_function(stream.get(), (opj_stream_skip_fn)(opjSkipFromBuffer));
|
||||
opj_stream_set_seek_function(stream.get(), (opj_stream_seek_fn)(opjSeekFromBuffer));
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
/////////////////////// Jpeg2KOpjDecoder ///////////////////
|
||||
|
||||
namespace detail {
|
||||
|
||||
Jpeg2KOpjDecoderBase::Jpeg2KOpjDecoderBase(OPJ_CODEC_FORMAT format)
|
||||
: format_(format)
|
||||
{
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
bool Jpeg2KOpjDecoderBase::readHeader()
|
||||
{
|
||||
if (!m_buf.empty()) {
|
||||
opjBuf_ = detail::OpjMemoryBuffer(m_buf);
|
||||
stream_ = opjCreateBufferInputStream(&opjBuf_);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_.reset(opj_stream_create_default_file_stream(m_filename.c_str(), OPJ_STREAM_READ));
|
||||
}
|
||||
if (!stream_)
|
||||
return false;
|
||||
|
||||
codec_.reset(opj_create_decompress(format_));
|
||||
if (!codec_)
|
||||
return false;
|
||||
|
||||
// Callbacks are cleared, when opj_destroy_codec is called,
|
||||
// They can provide some additional information for the user, about what goes wrong
|
||||
setupLogCallbacks(codec_.get());
|
||||
|
||||
opj_dparameters parameters = setupDecoderParameters();
|
||||
if (!opj_setup_decoder(codec_.get(), ¶meters))
|
||||
return false;
|
||||
|
||||
{
|
||||
opj_image_t* rawImage;
|
||||
if (!opj_read_header(stream_.get(), codec_.get(), &rawImage))
|
||||
return false;
|
||||
|
||||
image_.reset(rawImage);
|
||||
}
|
||||
|
||||
m_width = image_->x1 - image_->x0;
|
||||
m_height = image_->y1 - image_->y0;
|
||||
|
||||
/* Different components may have different precision,
|
||||
* so check all.
|
||||
*/
|
||||
bool hasAlpha = false;
|
||||
const int numcomps = image_->numcomps;
|
||||
CV_Assert(numcomps >= 1);
|
||||
for (int i = 0; i < numcomps; i++)
|
||||
{
|
||||
const opj_image_comp_t& comp = image_->comps[i];
|
||||
|
||||
if (comp.sgnd)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, cv::format("OpenJPEG2000: Component %d/%d is signed", i, numcomps));
|
||||
}
|
||||
|
||||
if (hasAlpha && comp.alpha)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, cv::format("OpenJPEG2000: Component %d/%d is duplicate alpha channel", i, numcomps));
|
||||
}
|
||||
|
||||
hasAlpha |= comp.alpha != 0;
|
||||
|
||||
if (comp.prec > 64)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: precision > 64 is not supported");
|
||||
}
|
||||
m_maxPrec = std::max(m_maxPrec, comp.prec);
|
||||
}
|
||||
|
||||
if (m_maxPrec < 8) {
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Precision < 8 not supported");
|
||||
} else if (m_maxPrec == 8) {
|
||||
m_type = CV_MAKETYPE(CV_8U, numcomps);
|
||||
} else if (m_maxPrec <= 16) {
|
||||
m_type = CV_MAKETYPE(CV_16U, numcomps);
|
||||
} else if (m_maxPrec <= 23) {
|
||||
m_type = CV_MAKETYPE(CV_32F, numcomps);
|
||||
} else {
|
||||
m_type = CV_MAKETYPE(CV_64F, numcomps);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Jpeg2KOpjDecoderBase::readData( Mat& img )
|
||||
{
|
||||
using DecodeFunc = bool(*)(const opj_image_t&, cv::Mat&, uint8_t shift);
|
||||
|
||||
if (!opj_decode(codec_.get(), stream_.get(), image_.get()))
|
||||
{
|
||||
CV_Error(Error::StsError, "OpenJPEG2000: Decoding is failed");
|
||||
}
|
||||
|
||||
if (img.channels() == 2)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
cv::format("OpenJPEG2000: Unsupported number of output channels. IN: %d OUT: 2", image_->numcomps));
|
||||
}
|
||||
|
||||
DecodeFunc decode = nullptr;
|
||||
switch (image_->color_space)
|
||||
{
|
||||
case OPJ_CLRSPC_UNKNOWN:
|
||||
/* FALLTHRU */
|
||||
case OPJ_CLRSPC_UNSPECIFIED:
|
||||
CV_LOG_WARNING(NULL, "OpenJPEG2000: Image has unknown or unspecified color space, SRGB is assumed");
|
||||
/* FALLTHRU */
|
||||
case OPJ_CLRSPC_SRGB:
|
||||
decode = decodeSRGBData;
|
||||
break;
|
||||
case OPJ_CLRSPC_GRAY:
|
||||
decode = decodeGrayscaleData;
|
||||
break;
|
||||
case OPJ_CLRSPC_SYCC:
|
||||
decode = decodeSYCCData;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
cv::format("OpenJPEG2000: Unsupported color space conversion: %s -> %s",
|
||||
colorspaceName(image_->color_space).c_str(),
|
||||
(img.channels() == 1) ? "gray" : "BGR"));
|
||||
}
|
||||
|
||||
const int depth = img.depth();
|
||||
const OPJ_UINT32 outPrec = [depth]() {
|
||||
if (depth == CV_8U) return 8;
|
||||
if (depth == CV_16U) return 16;
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
cv::format("OpenJPEG2000: output precision > 16 not supported: target depth %d", depth));
|
||||
}();
|
||||
const uint8_t shift = outPrec > m_maxPrec ? 0 : (uint8_t)(m_maxPrec - outPrec); // prec <= 64
|
||||
|
||||
const int inChannels = image_->numcomps;
|
||||
|
||||
CV_Assert(inChannels > 0);
|
||||
CV_Assert(image_->comps);
|
||||
for (int c = 0; c < inChannels; c++)
|
||||
{
|
||||
const opj_image_comp_t& comp = image_->comps[c];
|
||||
CV_CheckEQ((int)comp.dx, 1, "OpenJPEG2000: tiles are not supported");
|
||||
CV_CheckEQ((int)comp.dy, 1, "OpenJPEG2000: tiles are not supported");
|
||||
CV_CheckEQ((int)comp.x0, 0, "OpenJPEG2000: tiles are not supported");
|
||||
CV_CheckEQ((int)comp.y0, 0, "OpenJPEG2000: tiles are not supported");
|
||||
CV_CheckEQ((int)comp.w, img.cols, "OpenJPEG2000: tiles are not supported");
|
||||
CV_CheckEQ((int)comp.h, img.rows, "OpenJPEG2000: tiles are not supported");
|
||||
CV_Assert(comp.data && "OpenJPEG2000: missing component data (unsupported / broken input)");
|
||||
}
|
||||
|
||||
return decode(*image_, img, shift);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
Jpeg2KJP2OpjDecoder::Jpeg2KJP2OpjDecoder()
|
||||
: Jpeg2KOpjDecoderBase(OPJ_CODEC_JP2)
|
||||
{
|
||||
static const unsigned char JP2Signature[] = { 0, 0, 0, 0x0c, 'j', 'P', ' ', ' ', 13, 10, 0x87, 10 };
|
||||
m_signature = String((const char*) JP2Signature, sizeof(JP2Signature));
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KJP2OpjDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KJP2OpjDecoder>();
|
||||
}
|
||||
|
||||
Jpeg2KJ2KOpjDecoder::Jpeg2KJ2KOpjDecoder()
|
||||
: Jpeg2KOpjDecoderBase(OPJ_CODEC_J2K)
|
||||
{
|
||||
static const unsigned char J2KSignature[] = { 0xff, 0x4f, 0xff, 0x51 };
|
||||
m_signature = String((const char*) J2KSignature, sizeof(J2KSignature));
|
||||
}
|
||||
|
||||
ImageDecoder Jpeg2KJ2KOpjDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KJ2KOpjDecoder>();
|
||||
}
|
||||
|
||||
/////////////////////// Jpeg2KOpjEncoder ///////////////////
|
||||
|
||||
Jpeg2KOpjEncoder::Jpeg2KOpjEncoder()
|
||||
{
|
||||
m_description = "JPEG-2000 files (*.jp2)";
|
||||
}
|
||||
|
||||
ImageEncoder Jpeg2KOpjEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<Jpeg2KOpjEncoder>();
|
||||
}
|
||||
|
||||
bool Jpeg2KOpjEncoder::isFormatSupported(int depth) const
|
||||
{
|
||||
return depth == CV_8U || depth == CV_16U;
|
||||
}
|
||||
|
||||
bool Jpeg2KOpjEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
CV_Assert(params.size() % 2 == 0);
|
||||
|
||||
const int channels = img.channels();
|
||||
CV_DbgAssert(channels > 0); // passed matrix is not empty
|
||||
if (channels > 4)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: only BGR(a) and gray (+ alpha) images supported");
|
||||
}
|
||||
|
||||
const int depth = img.depth();
|
||||
|
||||
const OPJ_UINT32 outPrec = [depth]() {
|
||||
if (depth == CV_8U) return 8;
|
||||
if (depth == CV_16U) return 16;
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
cv::format("OpenJPEG2000: image precision > 16 not supported. Got: %d", depth));
|
||||
}();
|
||||
|
||||
opj_cparameters parameters = setupEncoderParameters(params);
|
||||
|
||||
std::vector<opj_image_cmptparm_t> compparams(channels);
|
||||
for (int i = 0; i < channels; i++) {
|
||||
compparams[i].prec = outPrec;
|
||||
compparams[i].bpp = outPrec;
|
||||
compparams[i].sgnd = 0; // unsigned for now
|
||||
compparams[i].dx = parameters.subsampling_dx;
|
||||
compparams[i].dy = parameters.subsampling_dy;
|
||||
compparams[i].w = img.size().width;
|
||||
compparams[i].h = img.size().height;
|
||||
}
|
||||
|
||||
|
||||
auto colorspace = (channels > 2) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY;
|
||||
detail::ImagePtr image(opj_image_create(channels, compparams.data(), colorspace));
|
||||
if (!image)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: can not create image");
|
||||
}
|
||||
|
||||
if (channels == 2 || channels == 4)
|
||||
{
|
||||
image->comps[channels - 1].alpha = 1;
|
||||
}
|
||||
// we want the full image
|
||||
image->x0 = 0;
|
||||
image->y0 = 0;
|
||||
image->x1 = compparams[0].dx * compparams[0].w;
|
||||
image->y1 = compparams[0].dy * compparams[0].h;
|
||||
|
||||
// fill the component data arrays
|
||||
std::vector<OPJ_INT32*> outcomps(channels, nullptr);
|
||||
if (channels == 1)
|
||||
{
|
||||
outcomps.assign({ image->comps[0].data });
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
outcomps.assign({ image->comps[0].data, image->comps[1].data });
|
||||
}
|
||||
// Reversed order for BGR -> RGB conversion
|
||||
else if (channels == 3)
|
||||
{
|
||||
outcomps.assign({ image->comps[2].data, image->comps[1].data, image->comps[0].data });
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
outcomps.assign({ image->comps[2].data, image->comps[1].data, image->comps[0].data,
|
||||
image->comps[3].data });
|
||||
}
|
||||
// outcomps holds pointers to the data, so the actual data will be modified but won't be freed
|
||||
// The container is not needed after data was copied
|
||||
copyFromMat(img, std::move(outcomps));
|
||||
|
||||
detail::CodecPtr codec(opj_create_compress(OPJ_CODEC_JP2));
|
||||
if (!codec) {
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: can not create compression codec");
|
||||
}
|
||||
|
||||
setupLogCallbacks(codec.get());
|
||||
|
||||
if (!opj_setup_encoder(codec.get(), ¶meters, image.get()))
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Can not setup encoder");
|
||||
}
|
||||
|
||||
detail::StreamPtr stream(opj_stream_create_default_file_stream(m_filename.c_str(), OPJ_STREAM_WRITE));
|
||||
if (!stream)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Can not create stream");
|
||||
}
|
||||
|
||||
if (!opj_start_compress(codec.get(), image.get(), stream.get()))
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Can not start compression");
|
||||
}
|
||||
|
||||
if (!opj_encode(codec.get(), stream.get()))
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Encoding failed");
|
||||
}
|
||||
|
||||
if (!opj_end_compress(codec.get(), stream.get()))
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "OpenJPEG2000: Can not end compression");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif
|
112
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000_openjpeg.hpp
vendored
Normal file
112
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_jpeg2000_openjpeg.hpp
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2020, Stefan Brüns <stefan.bruens@rwth-aachen.de>
|
||||
|
||||
#ifndef _GRFMT_OPENJPEG_H_
|
||||
#define _GRFMT_OPENJPEG_H_
|
||||
|
||||
#ifdef HAVE_OPENJPEG
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include <openjpeg.h>
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
struct OpjStreamDeleter
|
||||
{
|
||||
void operator()(opj_stream_t* stream) const
|
||||
{
|
||||
opj_stream_destroy(stream);
|
||||
}
|
||||
};
|
||||
|
||||
struct OpjCodecDeleter
|
||||
{
|
||||
void operator()(opj_codec_t* codec) const
|
||||
{
|
||||
opj_destroy_codec(codec);
|
||||
}
|
||||
};
|
||||
|
||||
struct OpjImageDeleter
|
||||
{
|
||||
void operator()(opj_image_t* image) const
|
||||
{
|
||||
opj_image_destroy(image);
|
||||
}
|
||||
};
|
||||
|
||||
struct OpjMemoryBuffer {
|
||||
OPJ_BYTE* pos{nullptr};
|
||||
OPJ_BYTE* begin{nullptr};
|
||||
OPJ_SIZE_T length{0};
|
||||
|
||||
OpjMemoryBuffer() = default;
|
||||
|
||||
explicit OpjMemoryBuffer(cv::Mat& mat)
|
||||
: pos{ mat.ptr() }, begin{ mat.ptr() }, length{ mat.rows * mat.cols * mat.elemSize() }
|
||||
{
|
||||
}
|
||||
|
||||
OPJ_SIZE_T availableBytes() const CV_NOEXCEPT {
|
||||
return begin + length - pos;
|
||||
}
|
||||
};
|
||||
|
||||
using StreamPtr = std::unique_ptr<opj_stream_t, detail::OpjStreamDeleter>;
|
||||
using CodecPtr = std::unique_ptr<opj_codec_t, detail::OpjCodecDeleter>;
|
||||
using ImagePtr = std::unique_ptr<opj_image_t, detail::OpjImageDeleter>;
|
||||
|
||||
class Jpeg2KOpjDecoderBase : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
Jpeg2KOpjDecoderBase(OPJ_CODEC_FORMAT format);
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
|
||||
private:
|
||||
detail::StreamPtr stream_{nullptr};
|
||||
detail::CodecPtr codec_{nullptr};
|
||||
detail::ImagePtr image_{nullptr};
|
||||
|
||||
detail::OpjMemoryBuffer opjBuf_;
|
||||
|
||||
OPJ_UINT32 m_maxPrec = 0;
|
||||
OPJ_CODEC_FORMAT format_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Jpeg2KJP2OpjDecoder CV_FINAL : public detail::Jpeg2KOpjDecoderBase {
|
||||
public:
|
||||
Jpeg2KJP2OpjDecoder();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
class Jpeg2KJ2KOpjDecoder CV_FINAL : public detail::Jpeg2KOpjDecoderBase {
|
||||
public:
|
||||
Jpeg2KJ2KOpjDecoder();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
class Jpeg2KOpjEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
Jpeg2KOpjEncoder();
|
||||
~Jpeg2KOpjEncoder() CV_OVERRIDE = default;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
} //namespace cv
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_OPENJPEG_H_*/
|
727
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pam.cpp
vendored
Normal file
727
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pam.cpp
vendored
Normal file
@ -0,0 +1,727 @@
|
||||
/*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
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
|
||||
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
|
||||
// Copyright (C) 2015-2016, Itseez 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:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions 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.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may 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 copyright holders 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_IMGCODEC_PXM
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "grfmt_pam.hpp"
|
||||
|
||||
namespace cv {
|
||||
|
||||
/* the PAM related fields */
|
||||
#define MAX_PAM_HEADER_IDENITFIER_LENGTH 8
|
||||
#define MAX_PAM_HEADER_VALUE_LENGTH 255
|
||||
|
||||
/* PAM header fields */
|
||||
typedef enum {
|
||||
PAM_HEADER_NONE,
|
||||
PAM_HEADER_COMMENT,
|
||||
PAM_HEADER_ENDHDR,
|
||||
PAM_HEADER_HEIGHT,
|
||||
PAM_HEADER_WIDTH,
|
||||
PAM_HEADER_DEPTH,
|
||||
PAM_HEADER_MAXVAL,
|
||||
PAM_HEADER_TUPLTYPE,
|
||||
} PamHeaderFieldType;
|
||||
|
||||
struct pam_header_field {
|
||||
PamHeaderFieldType type;
|
||||
char identifier[MAX_PAM_HEADER_IDENITFIER_LENGTH+1];
|
||||
};
|
||||
|
||||
const static struct pam_header_field fields[] = {
|
||||
{PAM_HEADER_ENDHDR, "ENDHDR"},
|
||||
{PAM_HEADER_HEIGHT, "HEIGHT"},
|
||||
{PAM_HEADER_WIDTH, "WIDTH"},
|
||||
{PAM_HEADER_DEPTH, "DEPTH"},
|
||||
{PAM_HEADER_MAXVAL, "MAXVAL"},
|
||||
{PAM_HEADER_TUPLTYPE, "TUPLTYPE"},
|
||||
};
|
||||
#define PAM_FIELDS_NO (sizeof (fields) / sizeof ((fields)[0]))
|
||||
|
||||
typedef bool (*cvtFunc) (void *src, void *target, int width, int target_channels,
|
||||
int target_depth);
|
||||
|
||||
struct channel_layout {
|
||||
uint rchan, gchan, bchan, graychan;
|
||||
};
|
||||
|
||||
struct pam_format {
|
||||
uint fmt;
|
||||
char name[MAX_PAM_HEADER_VALUE_LENGTH+1];
|
||||
cvtFunc cvt_func;
|
||||
/* the channel layout that should be used when
|
||||
* imread_ creates a 3 channel or 1 channel image
|
||||
* used when no conversion function is available
|
||||
*/
|
||||
struct channel_layout layout;
|
||||
};
|
||||
|
||||
static bool rgb_convert (void *src, void *target, int width, int target_channels,
|
||||
int target_depth);
|
||||
|
||||
const static struct pam_format formats[] = {
|
||||
{CV_IMWRITE_PAM_FORMAT_NULL, "", NULL, {0, 0, 0, 0} },
|
||||
{CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE, "BLACKANDWHITE", NULL, {0, 0, 0, 0} },
|
||||
{CV_IMWRITE_PAM_FORMAT_GRAYSCALE, "GRAYSCALE", NULL, {0, 0, 0, 0} },
|
||||
{CV_IMWRITE_PAM_FORMAT_GRAYSCALE_ALPHA, "GRAYSCALE_ALPHA", NULL, {0, 0, 0, 0} },
|
||||
{CV_IMWRITE_PAM_FORMAT_RGB, "RGB", rgb_convert, {0, 1, 2, 0} },
|
||||
{CV_IMWRITE_PAM_FORMAT_RGB_ALPHA, "RGB_ALPHA", NULL, {0, 1, 2, 0} },
|
||||
};
|
||||
#define PAM_FORMATS_NO (sizeof (fields) / sizeof ((fields)[0]))
|
||||
|
||||
/*
|
||||
* conversion functions
|
||||
*/
|
||||
|
||||
static bool
|
||||
rgb_convert (void *src, void *target, int width, int target_channels, int target_depth)
|
||||
{
|
||||
bool ret = false;
|
||||
if (target_channels == 3) {
|
||||
switch (target_depth) {
|
||||
case CV_8U:
|
||||
icvCvt_RGB2BGR_8u_C3R( (uchar*) src, 0, (uchar*) target, 0,
|
||||
Size(width,1) );
|
||||
ret = true;
|
||||
break;
|
||||
case CV_16U:
|
||||
icvCvt_RGB2BGR_16u_C3R( (ushort *)src, 0, (ushort *)target, 0,
|
||||
Size(width,1) );
|
||||
ret = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (target_channels == 1) {
|
||||
switch (target_depth) {
|
||||
case CV_8U:
|
||||
icvCvt_BGR2Gray_8u_C3C1R( (uchar*) src, 0, (uchar*) target, 0,
|
||||
Size(width,1), 2 );
|
||||
ret = true;
|
||||
break;
|
||||
case CV_16U:
|
||||
icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)target, 0,
|
||||
Size(width,1), 3, 2 );
|
||||
ret = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy functions used as a fall back for undefined formats
|
||||
* or simpler conversion options
|
||||
*/
|
||||
|
||||
static void
|
||||
basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_size,
|
||||
int src_width, void *target, int target_channels, int target_depth)
|
||||
{
|
||||
switch (target_depth) {
|
||||
case CV_8U:
|
||||
{
|
||||
uchar *d = (uchar *)target, *s = (uchar *)src,
|
||||
*end = ((uchar *)src) + src_width;
|
||||
switch (target_channels) {
|
||||
case 1:
|
||||
for( ; s < end; d += 3, s += src_sampe_size )
|
||||
d[0] = d[1] = d[2] = s[layout->graychan];
|
||||
break;
|
||||
case 3:
|
||||
for( ; s < end; d += 3, s += src_sampe_size ) {
|
||||
d[0] = s[layout->bchan];
|
||||
d[1] = s[layout->gchan];
|
||||
d[2] = s[layout->rchan];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CV_16U:
|
||||
{
|
||||
ushort *d = (ushort *)target, *s = (ushort *)src,
|
||||
*end = ((ushort *)src) + src_width;
|
||||
switch (target_channels) {
|
||||
case 1:
|
||||
for( ; s < end; d += 3, s += src_sampe_size )
|
||||
d[0] = d[1] = d[2] = s[layout->graychan];
|
||||
break;
|
||||
case 3:
|
||||
for( ; s < end; d += 3, s += src_sampe_size ) {
|
||||
d[0] = s[layout->bchan];
|
||||
d[1] = s[layout->gchan];
|
||||
d[2] = s[layout->rchan];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool ReadPAMHeaderLine(
|
||||
cv::RLByteStream& strm,
|
||||
CV_OUT PamHeaderFieldType &fieldtype,
|
||||
CV_OUT char value[MAX_PAM_HEADER_VALUE_LENGTH+1])
|
||||
{
|
||||
int code;
|
||||
char ident[MAX_PAM_HEADER_IDENITFIER_LENGTH+1] = {};
|
||||
|
||||
do {
|
||||
code = strm.getByte();
|
||||
} while ( isspace(code) );
|
||||
|
||||
if (code == '#') {
|
||||
/* we are in a comment, eat characters until linebreak */
|
||||
do
|
||||
{
|
||||
code = strm.getByte();
|
||||
} while( code != '\n' && code != '\r' );
|
||||
fieldtype = PAM_HEADER_COMMENT;
|
||||
return true;
|
||||
} else if (code == '\n' || code == '\r' ) {
|
||||
fieldtype = PAM_HEADER_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
int ident_sz = 0;
|
||||
for (; ident_sz < MAX_PAM_HEADER_IDENITFIER_LENGTH; ident_sz++)
|
||||
{
|
||||
if (isspace(code))
|
||||
break;
|
||||
ident[ident_sz] = (char)code;
|
||||
code = strm.getByte();
|
||||
}
|
||||
CV_DbgAssert(ident_sz <= MAX_PAM_HEADER_IDENITFIER_LENGTH);
|
||||
ident[ident_sz] = 0;
|
||||
|
||||
/* we may have filled the buffer and still have data */
|
||||
if (!isspace(code))
|
||||
return false;
|
||||
|
||||
bool ident_found = false;
|
||||
for (uint i = 0; i < PAM_FIELDS_NO; i++)
|
||||
{
|
||||
if (0 == strncmp(fields[i].identifier, ident, std::min(ident_sz, MAX_PAM_HEADER_IDENITFIER_LENGTH) + 1))
|
||||
{
|
||||
fieldtype = fields[i].type;
|
||||
ident_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ident_found)
|
||||
return false;
|
||||
|
||||
memset(value, 0, sizeof(char) * (MAX_PAM_HEADER_VALUE_LENGTH + 1));
|
||||
/* we may have an identifier that has no value */
|
||||
if (code == '\n' || code == '\r')
|
||||
return true;
|
||||
|
||||
do {
|
||||
code = strm.getByte();
|
||||
} while (isspace(code));
|
||||
|
||||
/* read identifier value */
|
||||
int value_sz = 0;
|
||||
for (; value_sz < MAX_PAM_HEADER_VALUE_LENGTH; value_sz++)
|
||||
{
|
||||
if (code == '\n' || code == '\r')
|
||||
break;
|
||||
value[value_sz] = (char)code;
|
||||
code = strm.getByte();
|
||||
}
|
||||
CV_DbgAssert(value_sz <= MAX_PAM_HEADER_VALUE_LENGTH);
|
||||
value[value_sz] = 0;
|
||||
|
||||
int pos = value_sz;
|
||||
|
||||
/* should be terminated */
|
||||
if (code != '\n' && code != '\r')
|
||||
return false;
|
||||
|
||||
/* remove trailing white spaces */
|
||||
while (--pos >= 0 && isspace(value[pos]))
|
||||
value[pos] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ParseInt(const char *str, int len)
|
||||
{
|
||||
CV_Assert(len > 0);
|
||||
|
||||
int pos = 0;
|
||||
bool is_negative = false;
|
||||
if (str[0] == '-')
|
||||
{
|
||||
is_negative = true;
|
||||
pos++;
|
||||
CV_Assert(isdigit(str[pos]));
|
||||
}
|
||||
uint64_t number = 0;
|
||||
while (pos < len && isdigit(str[pos]))
|
||||
{
|
||||
char ch = str[pos];
|
||||
number = (number * 10) + (uint64_t)((int)ch - (int)'0');
|
||||
CV_Assert(number < INT_MAX);
|
||||
pos++;
|
||||
}
|
||||
if (pos < len)
|
||||
CV_Assert(str[pos] == 0);
|
||||
return (is_negative) ? -(int)number : (int)number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PAMDecoder::PAMDecoder()
|
||||
{
|
||||
m_offset = -1;
|
||||
m_buf_supported = true;
|
||||
bit_mode = false;
|
||||
selected_fmt = CV_IMWRITE_PAM_FORMAT_NULL;
|
||||
m_maxval = 0;
|
||||
m_channels = 0;
|
||||
m_sampledepth = 0;
|
||||
}
|
||||
|
||||
|
||||
PAMDecoder::~PAMDecoder()
|
||||
{
|
||||
m_strm.close();
|
||||
}
|
||||
|
||||
size_t PAMDecoder::signatureLength() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool PAMDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
return signature.size() >= 3 && signature[0] == 'P' &&
|
||||
signature[1] == '7' &&
|
||||
isspace(signature[2]);
|
||||
}
|
||||
|
||||
ImageDecoder PAMDecoder::newDecoder() const
|
||||
{
|
||||
return makePtr<PAMDecoder>();
|
||||
}
|
||||
|
||||
bool PAMDecoder::readHeader()
|
||||
{
|
||||
PamHeaderFieldType fieldtype = PAM_HEADER_NONE;
|
||||
char value[MAX_PAM_HEADER_VALUE_LENGTH+1];
|
||||
int byte;
|
||||
|
||||
if( !m_buf.empty() )
|
||||
{
|
||||
if( !m_strm.open(m_buf) )
|
||||
return false;
|
||||
}
|
||||
else if( !m_strm.open( m_filename ))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
byte = m_strm.getByte();
|
||||
if( byte != 'P' )
|
||||
throw RBS_BAD_HEADER;
|
||||
|
||||
byte = m_strm.getByte();
|
||||
if (byte != '7')
|
||||
throw RBS_BAD_HEADER;
|
||||
|
||||
byte = m_strm.getByte();
|
||||
if (byte != '\n' && byte != '\r')
|
||||
throw RBS_BAD_HEADER;
|
||||
|
||||
bool flds_endhdr = false, flds_height = false, flds_width = false, flds_depth = false, flds_maxval = false;
|
||||
|
||||
do {
|
||||
if (!ReadPAMHeaderLine(m_strm, fieldtype, value))
|
||||
throw RBS_BAD_HEADER;
|
||||
switch (fieldtype)
|
||||
{
|
||||
case PAM_HEADER_NONE:
|
||||
case PAM_HEADER_COMMENT:
|
||||
continue;
|
||||
case PAM_HEADER_ENDHDR:
|
||||
flds_endhdr = true;
|
||||
break;
|
||||
case PAM_HEADER_HEIGHT:
|
||||
if (flds_height)
|
||||
throw RBS_BAD_HEADER;
|
||||
m_height = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH);
|
||||
flds_height = true;
|
||||
break;
|
||||
case PAM_HEADER_WIDTH:
|
||||
if (flds_width)
|
||||
throw RBS_BAD_HEADER;
|
||||
m_width = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH);
|
||||
flds_width = true;
|
||||
break;
|
||||
case PAM_HEADER_DEPTH:
|
||||
if (flds_depth)
|
||||
throw RBS_BAD_HEADER;
|
||||
m_channels = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH);
|
||||
flds_depth = true;
|
||||
break;
|
||||
case PAM_HEADER_MAXVAL:
|
||||
if (flds_maxval)
|
||||
throw RBS_BAD_HEADER;
|
||||
m_maxval = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH);
|
||||
if ( m_maxval > 65535 )
|
||||
throw RBS_BAD_HEADER;
|
||||
m_sampledepth = (m_maxval > 255) ? CV_16U : CV_8U;
|
||||
if (m_maxval == 1)
|
||||
bit_mode = true;
|
||||
flds_maxval = true;
|
||||
break;
|
||||
case PAM_HEADER_TUPLTYPE:
|
||||
{
|
||||
bool format_found = false;
|
||||
for (uint i=0; i<PAM_FORMATS_NO; i++)
|
||||
{
|
||||
if (0 == strncmp(formats[i].name, value, MAX_PAM_HEADER_VALUE_LENGTH+1))
|
||||
{
|
||||
selected_fmt = formats[i].fmt;
|
||||
format_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CV_Assert(format_found);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw RBS_BAD_HEADER;
|
||||
}
|
||||
} while (fieldtype != PAM_HEADER_ENDHDR);
|
||||
|
||||
if (flds_endhdr && flds_height && flds_width && flds_depth && flds_maxval)
|
||||
{
|
||||
if (selected_fmt == CV_IMWRITE_PAM_FORMAT_NULL)
|
||||
{
|
||||
if (m_channels == 1 && m_maxval == 1)
|
||||
selected_fmt = CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE;
|
||||
else if (m_channels == 1 && m_maxval < 256)
|
||||
selected_fmt = CV_IMWRITE_PAM_FORMAT_GRAYSCALE;
|
||||
else if (m_channels == 3 && m_maxval < 256)
|
||||
selected_fmt = CV_IMWRITE_PAM_FORMAT_RGB;
|
||||
}
|
||||
m_type = CV_MAKETYPE(m_sampledepth, m_channels);
|
||||
m_offset = m_strm.getPos();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// failed
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PAMDecoder::readData(Mat& img)
|
||||
{
|
||||
uchar* data = img.ptr();
|
||||
const int target_channels = img.channels();
|
||||
size_t imp_stride = img.step;
|
||||
const int sample_depth = CV_ELEM_SIZE1(m_type);
|
||||
const int src_elems_per_row = m_width*m_channels;
|
||||
const int src_stride = src_elems_per_row*sample_depth;
|
||||
PaletteEntry palette[256] = {};
|
||||
const struct pam_format *fmt = NULL;
|
||||
struct channel_layout layout = { 0, 0, 0, 0 }; // normalized to 1-channel grey format
|
||||
|
||||
/* setting buffer to max data size so scaling up is possible */
|
||||
AutoBuffer<uchar> _src(src_elems_per_row * 2);
|
||||
uchar* src = _src.data();
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
if (selected_fmt != CV_IMWRITE_PAM_FORMAT_NULL)
|
||||
fmt = &formats[selected_fmt];
|
||||
else {
|
||||
/* default layout handling */
|
||||
if (m_channels >= 3) {
|
||||
layout.bchan = 0;
|
||||
layout.gchan = 1;
|
||||
layout.rchan = 2;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
m_strm.setPos( m_offset );
|
||||
|
||||
/* the case where data fits the opencv matrix */
|
||||
if (m_sampledepth == img.depth() && target_channels == m_channels && !bit_mode) {
|
||||
/* special case for 16bit images with wrong endianness */
|
||||
if (m_sampledepth == CV_16U && !isBigEndian())
|
||||
{
|
||||
for (int y = 0; y < m_height; y++, data += imp_stride)
|
||||
{
|
||||
m_strm.getBytes( src, src_stride );
|
||||
for (int x = 0; x < src_elems_per_row; x++)
|
||||
{
|
||||
uchar v = src[x * 2];
|
||||
data[x * 2] = src[x * 2 + 1];
|
||||
data[x * 2 + 1] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_strm.getBytes( data, src_stride * m_height );
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* black and white mode */
|
||||
if (bit_mode) {
|
||||
if( target_channels == 1 )
|
||||
{
|
||||
uchar gray_palette[2] = {0, 255};
|
||||
for (int y = 0; y < m_height; y++, data += imp_stride)
|
||||
{
|
||||
m_strm.getBytes( src, src_stride );
|
||||
FillGrayRow1( data, src, m_width, gray_palette );
|
||||
}
|
||||
} else if ( target_channels == 3 )
|
||||
{
|
||||
FillGrayPalette( palette, 1 , false );
|
||||
for (int y = 0; y < m_height; y++, data += imp_stride)
|
||||
{
|
||||
m_strm.getBytes( src, src_stride );
|
||||
FillColorRow1( data, src, m_width, palette );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < m_height; y++, data += imp_stride)
|
||||
{
|
||||
m_strm.getBytes( src, src_stride );
|
||||
|
||||
/* endianness correction */
|
||||
if( m_sampledepth == CV_16U && !isBigEndian() )
|
||||
{
|
||||
for (int x = 0; x < src_elems_per_row; x++)
|
||||
{
|
||||
uchar v = src[x * 2];
|
||||
src[x * 2] = src[x * 2 + 1];
|
||||
src[x * 2 + 1] = v;
|
||||
}
|
||||
}
|
||||
|
||||
/* scale down */
|
||||
if( img.depth() == CV_8U && m_sampledepth == CV_16U )
|
||||
{
|
||||
for (int x = 0; x < src_elems_per_row; x++)
|
||||
{
|
||||
int v = ((ushort *)src)[x];
|
||||
src[x] = (uchar)(v >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we are only scaling up/down then we can then copy the data */
|
||||
if (target_channels == m_channels) {
|
||||
memcpy (data, src, imp_stride);
|
||||
}
|
||||
/* perform correct conversion based on format */
|
||||
else if (fmt) {
|
||||
bool funcout = false;
|
||||
if (fmt->cvt_func)
|
||||
funcout = fmt->cvt_func (src, data, m_width, target_channels,
|
||||
img.depth());
|
||||
/* fall back to default if there is no conversion function or it
|
||||
* can't handle the specified characteristics
|
||||
*/
|
||||
if (!funcout)
|
||||
basic_conversion (src, &fmt->layout, m_channels,
|
||||
m_width, data, target_channels, img.depth());
|
||||
|
||||
/* default to selecting the first available channels */
|
||||
} else {
|
||||
basic_conversion (src, &layout, m_channels,
|
||||
m_width, data, target_channels, img.depth());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PAMEncoder::PAMEncoder()
|
||||
{
|
||||
m_description = "Portable arbitrary format (*.pam)";
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
|
||||
PAMEncoder::~PAMEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ImageEncoder PAMEncoder::newEncoder() const
|
||||
{
|
||||
return makePtr<PAMEncoder>();
|
||||
}
|
||||
|
||||
|
||||
bool PAMEncoder::isFormatSupported( int depth ) const
|
||||
{
|
||||
return depth == CV_8U || depth == CV_16U;
|
||||
}
|
||||
|
||||
|
||||
bool PAMEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
{
|
||||
|
||||
WLByteStream strm;
|
||||
|
||||
int width = img.cols, height = img.rows;
|
||||
int stride = width*(int)img.elemSize();
|
||||
const uchar* data = img.ptr();
|
||||
const struct pam_format *fmt = NULL;
|
||||
int x, y, tmp, bufsize = 256;
|
||||
|
||||
/* parse save file type */
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
if( params[i] == CV_IMWRITE_PAM_TUPLETYPE ) {
|
||||
if ( params[i+1] > CV_IMWRITE_PAM_FORMAT_NULL &&
|
||||
params[i+1] < (int) PAM_FORMATS_NO)
|
||||
fmt = &formats[params[i+1]];
|
||||
}
|
||||
|
||||
if( m_buf )
|
||||
{
|
||||
if( !strm.open(*m_buf) )
|
||||
return false;
|
||||
m_buf->reserve( alignSize(256 + stride*height, 256));
|
||||
}
|
||||
else if( !strm.open(m_filename) )
|
||||
return false;
|
||||
|
||||
tmp = width * (int)img.elemSize();
|
||||
|
||||
if (bufsize < tmp)
|
||||
bufsize = tmp;
|
||||
|
||||
AutoBuffer<char> _buffer(bufsize);
|
||||
char* buffer = _buffer.data();
|
||||
|
||||
/* write header */
|
||||
tmp = 0;
|
||||
tmp += sprintf( buffer, "P7\n");
|
||||
tmp += sprintf( buffer + tmp, "WIDTH %d\n", width);
|
||||
tmp += sprintf( buffer + tmp, "HEIGHT %d\n", height);
|
||||
tmp += sprintf( buffer + tmp, "DEPTH %d\n", img.channels());
|
||||
tmp += sprintf( buffer + tmp, "MAXVAL %d\n", (1 << img.elemSize1()*8) - 1);
|
||||
if (fmt)
|
||||
tmp += sprintf( buffer + tmp, "TUPLTYPE %s\n", fmt->name );
|
||||
sprintf( buffer + tmp, "ENDHDR\n" );
|
||||
|
||||
strm.putBytes( buffer, (int)strlen(buffer) );
|
||||
/* write data */
|
||||
if (img.depth() == CV_8U)
|
||||
strm.putBytes( data, stride*height );
|
||||
else if (img.depth() == CV_16U) {
|
||||
/* fix endianness */
|
||||
if (!isBigEndian()) {
|
||||
for( y = 0; y < height; y++ ) {
|
||||
memcpy( buffer, img.ptr(y), stride );
|
||||
for( x = 0; x < stride; x += 2 )
|
||||
{
|
||||
uchar v = buffer[x];
|
||||
buffer[x] = buffer[x + 1];
|
||||
buffer[x + 1] = v;
|
||||
}
|
||||
strm.putBytes( buffer, stride );
|
||||
}
|
||||
} else
|
||||
strm.putBytes( data, stride*height );
|
||||
} else
|
||||
CV_Error(Error::StsInternal, "");
|
||||
|
||||
strm.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
103
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pam.hpp
vendored
Normal file
103
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pam.hpp
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/*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
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2000-2016, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
|
||||
// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
|
||||
// Copyright (C) 2015-2016, Itseez 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:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions 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.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may 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 copyright holders 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*/
|
||||
|
||||
//Based on "imgcodecs/src/grfmt_pxm.hpp"
|
||||
//Written by Dimitrios Katsaros <patcherwork@gmail.com>
|
||||
|
||||
#ifndef _OPENCV_PAM_HPP_
|
||||
#define _OPENCV_PAM_HPP_
|
||||
|
||||
#ifdef HAVE_IMGCODEC_PXM
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class PAMDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
PAMDecoder();
|
||||
virtual ~PAMDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
RLByteStream m_strm;
|
||||
int m_maxval, m_channels, m_sampledepth, m_offset,
|
||||
selected_fmt;
|
||||
bool bit_mode;
|
||||
};
|
||||
|
||||
|
||||
class PAMEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PAMEncoder();
|
||||
virtual ~PAMEncoder() CV_OVERRIDE;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _OPENCV_PAM_HPP_ */
|
264
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pfm.cpp
vendored
Normal file
264
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pfm.cpp
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "grfmt_pfm.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_IMGCODEC_PFM
|
||||
|
||||
namespace {
|
||||
|
||||
static_assert(sizeof(float) == 4, "float must be 32 bit.");
|
||||
|
||||
|
||||
bool is_byte_order_swapped(double scale)
|
||||
{
|
||||
// ".pfm" format file specifies that:
|
||||
// positive scale means big endianness;
|
||||
// negative scale means little endianness.
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
return scale < 0.0;
|
||||
#else
|
||||
return scale >= 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void swap_endianess(uint32_t& ui)
|
||||
{
|
||||
static const uint32_t A(0x000000ffU);
|
||||
static const uint32_t B(0x0000ff00U);
|
||||
static const uint32_t C(0x00ff0000U);
|
||||
static const uint32_t D(0xff000000U);
|
||||
|
||||
ui = ( (ui & A) << 24 )
|
||||
| ( (ui & B) << 8 )
|
||||
| ( (ui & C) >> 8 )
|
||||
| ( (ui & D) >> 24 );
|
||||
}
|
||||
|
||||
template<typename T> T atoT(const std::string& s);
|
||||
template<> int atoT<int>(const std::string& s) { return std::atoi(s.c_str()); }
|
||||
template<> double atoT<double>(const std::string& s) { return std::atof(s.c_str()); }
|
||||
|
||||
template<typename T>
|
||||
T read_number(cv::RLByteStream& strm)
|
||||
{
|
||||
// should be enough to take string representation of any number
|
||||
const size_t buffer_size = 2048;
|
||||
|
||||
std::vector<char> buffer(buffer_size, 0);
|
||||
for (size_t i = 0; i < buffer_size; ++i) {
|
||||
const int intc = strm.getByte();
|
||||
CV_Assert(intc >= -128 && intc < 128);
|
||||
char c = static_cast<char>(intc);
|
||||
if (std::isspace(c)) {
|
||||
break;
|
||||
}
|
||||
buffer[i] = c;
|
||||
}
|
||||
const std::string str(buffer.begin(), buffer.end());
|
||||
return atoT<T>(str);
|
||||
}
|
||||
|
||||
template<typename T> void write_anything(cv::WLByteStream& strm, const T& t)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << t;
|
||||
strm.putBytes(ss.str().c_str(), static_cast<int>(ss.str().size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace cv {
|
||||
|
||||
PFMDecoder::~PFMDecoder()
|
||||
{
|
||||
}
|
||||
|
||||
PFMDecoder::PFMDecoder() : m_scale_factor(0), m_swap_byte_order(false)
|
||||
{
|
||||
m_strm.close();
|
||||
}
|
||||
|
||||
bool PFMDecoder::readHeader()
|
||||
{
|
||||
if (m_buf.empty()) {
|
||||
if (!m_strm.open(m_filename)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!m_strm.open(m_buf)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_strm.getByte() != 'P') {
|
||||
CV_Error(Error::StsError, "Unexpected file type (expected P)");
|
||||
}
|
||||
|
||||
switch (m_strm.getByte()) {
|
||||
case 'f':
|
||||
m_type = CV_32FC1;
|
||||
break;
|
||||
case 'F':
|
||||
m_type = CV_32FC3;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsError, "Unexpected file type (expected `f` or `F`)");
|
||||
}
|
||||
|
||||
if ('\n' != m_strm.getByte()) {
|
||||
CV_Error(Error::StsError, "Unexpected header format (expected line break)");
|
||||
}
|
||||
|
||||
|
||||
m_width = read_number<int>(m_strm);
|
||||
m_height = read_number<int>(m_strm);
|
||||
m_scale_factor = read_number<double>(m_strm);
|
||||
m_swap_byte_order = is_byte_order_swapped(m_scale_factor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PFMDecoder::readData(Mat& mat)
|
||||
{
|
||||
if (!m_strm.isOpened()) {
|
||||
CV_Error(Error::StsError, "Unexpected status in data stream");
|
||||
}
|
||||
|
||||
Mat buffer(mat.size(), m_type);
|
||||
for (int y = m_height - 1; y >= 0; --y) {
|
||||
m_strm.getBytes(buffer.ptr(y), static_cast<int>(m_width * buffer.elemSize()));
|
||||
if (is_byte_order_swapped(m_scale_factor)) {
|
||||
for (int i = 0; i < m_width * buffer.channels(); ++i) {
|
||||
static_assert( sizeof(uint32_t) == sizeof(float),
|
||||
"uint32_t and float must have same size." );
|
||||
swap_endianess(buffer.ptr<uint32_t>(y)[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.channels() == 3) {
|
||||
cv::cvtColor(buffer, buffer, cv::COLOR_BGR2RGB);
|
||||
}
|
||||
|
||||
CV_Assert(fabs(m_scale_factor) > 0.0f);
|
||||
buffer *= 1.f / fabs(m_scale_factor);
|
||||
|
||||
buffer.convertTo(mat, mat.type());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t PFMDecoder::signatureLength() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool PFMDecoder::checkSignature( const String& signature ) const
|
||||
{
|
||||
return signature.size() >= 3
|
||||
&& signature[0] == 'P'
|
||||
&& ( signature[1] == 'f' || signature[1] == 'F' )
|
||||
&& isspace(signature[2]);
|
||||
}
|
||||
|
||||
void PFMDecoder::close()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PFMEncoder::PFMEncoder()
|
||||
{
|
||||
m_description = "Portable image format - float (*.pfm)";
|
||||
}
|
||||
|
||||
PFMEncoder::~PFMEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
bool PFMEncoder::isFormatSupported(int depth) const
|
||||
{
|
||||
// any depth will be converted into 32-bit float.
|
||||
CV_UNUSED(depth);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PFMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
CV_UNUSED(params);
|
||||
|
||||
WLByteStream strm;
|
||||
if (m_buf) {
|
||||
if (!strm.open(*m_buf)) {
|
||||
return false;
|
||||
} else {
|
||||
m_buf->reserve(alignSize(256 + sizeof(float) * img.channels() * img.total(), 256));
|
||||
}
|
||||
} else if (!strm.open(m_filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mat float_img;
|
||||
strm.putByte('P');
|
||||
switch (img.channels()) {
|
||||
case 1:
|
||||
strm.putByte('f');
|
||||
img.convertTo(float_img, CV_32FC1);
|
||||
break;
|
||||
case 3:
|
||||
strm.putByte('F');
|
||||
img.convertTo(float_img, CV_32FC3);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "Expected 1 or 3 channel image.");
|
||||
}
|
||||
strm.putByte('\n');
|
||||
|
||||
|
||||
write_anything(strm, float_img.cols);
|
||||
strm.putByte(' ');
|
||||
write_anything(strm, float_img.rows);
|
||||
strm.putByte('\n');
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
write_anything(strm, 1.0);
|
||||
#else
|
||||
write_anything(strm, -1.0);
|
||||
#endif
|
||||
|
||||
strm.putByte('\n');
|
||||
|
||||
// Comments are not officially supported in this file format.
|
||||
// write_anything(strm, "# Generated by OpenCV " CV_VERSION "\n");
|
||||
|
||||
for (int y = float_img.rows - 1; y >= 0; --y)
|
||||
{
|
||||
if (float_img.channels() == 3) {
|
||||
const float* bgr_row = float_img.ptr<float>(y);
|
||||
size_t row_size = float_img.cols * float_img.channels();
|
||||
std::vector<float> rgb_row(row_size);
|
||||
for (int x = 0; x < float_img.cols; ++x) {
|
||||
rgb_row[x*3+0] = bgr_row[x*3+2];
|
||||
rgb_row[x*3+1] = bgr_row[x*3+1];
|
||||
rgb_row[x*3+2] = bgr_row[x*3+0];
|
||||
}
|
||||
strm.putBytes( reinterpret_cast<const uchar*>(rgb_row.data()),
|
||||
static_cast<int>(sizeof(float) * row_size) );
|
||||
} else if (float_img.channels() == 1) {
|
||||
strm.putBytes(float_img.ptr(y), sizeof(float) * float_img.cols);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_IMGCODEC_PFM
|
57
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pfm.hpp
vendored
Normal file
57
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pfm.hpp
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef _GRFMT_PFM_H_
|
||||
#define _GRFMT_PFM_H_
|
||||
|
||||
#include "grfmt_base.hpp"
|
||||
#include "bitstrm.hpp"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_PFM
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class PFMDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
PFMDecoder();
|
||||
virtual ~PFMDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE
|
||||
{
|
||||
return makePtr<PFMDecoder>();
|
||||
}
|
||||
|
||||
private:
|
||||
RLByteStream m_strm;
|
||||
double m_scale_factor;
|
||||
bool m_swap_byte_order;
|
||||
};
|
||||
|
||||
class PFMEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PFMEncoder();
|
||||
virtual ~PFMEncoder() CV_OVERRIDE;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE
|
||||
{
|
||||
return makePtr<PFMEncoder>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_PXM
|
||||
|
||||
#endif/*_GRFMT_PFM_H_*/
|
464
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_png.cpp
vendored
Normal file
464
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_png.cpp
vendored
Normal file
@ -0,0 +1,464 @@
|
||||
/*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 pointer 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;
|
||||
m_bit_depth = 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.ptr() + decoder->m_buf_pos, size );
|
||||
decoder->m_buf_pos += size;
|
||||
}
|
||||
|
||||
bool PngDecoder::readHeader()
|
||||
{
|
||||
volatile 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:
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values);
|
||||
if( num_trans > 0 )
|
||||
m_type = CV_8UC4;
|
||||
else
|
||||
m_type = CV_8UC3;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
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 )
|
||||
{
|
||||
volatile bool result = false;
|
||||
AutoBuffer<uchar*> _buffer(m_height);
|
||||
uchar** buffer = _buffer.data();
|
||||
bool color = img.channels() > 1;
|
||||
|
||||
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( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height )
|
||||
{
|
||||
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 );
|
||||
} else
|
||||
png_set_tRNS_to_alpha( png_ptr );
|
||||
|
||||
if( m_color_type == PNG_COLOR_TYPE_PALETTE )
|
||||
png_set_palette_to_rgb( png_ptr );
|
||||
|
||||
if( (m_color_type & PNG_COLOR_MASK_COLOR) == 0 && 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( (m_color_type & PNG_COLOR_MASK_COLOR) && 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] = img.data + y*img.step;
|
||||
|
||||
png_read_image( png_ptr, buffer );
|
||||
png_read_end( png_ptr, end_info );
|
||||
|
||||
#ifdef PNG_eXIf_SUPPORTED
|
||||
png_uint_32 num_exif = 0;
|
||||
png_bytep exif = 0;
|
||||
|
||||
// Exif info could be in info_ptr (intro_info) or end_info per specification
|
||||
if( png_get_valid(png_ptr, info_ptr, PNG_INFO_eXIf) )
|
||||
png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif);
|
||||
else if( png_get_valid(png_ptr, end_info, PNG_INFO_eXIf) )
|
||||
png_get_eXIf_1(png_ptr, end_info, &num_exif, &exif);
|
||||
|
||||
if( exif && num_exif > 0 )
|
||||
{
|
||||
m_exif.parseExif(exif, num_exif);
|
||||
}
|
||||
#endif
|
||||
|
||||
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 * volatile f = 0;
|
||||
int y, width = img.cols, height = img.rows;
|
||||
int depth = img.depth(), channels = img.channels();
|
||||
volatile 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, (png_FILE_p)f );
|
||||
}
|
||||
|
||||
int compression_level = -1; // Invalid value to allow setting 0-9 as valid
|
||||
int compression_strategy = IMWRITE_PNG_STRATEGY_RLE; // Default strategy
|
||||
bool isBilevel = false;
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
if( params[i] == IMWRITE_PNG_COMPRESSION )
|
||||
{
|
||||
compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy
|
||||
compression_level = params[i+1];
|
||||
compression_level = MIN(MAX(compression_level, 0), Z_BEST_COMPRESSION);
|
||||
}
|
||||
if( params[i] == IMWRITE_PNG_STRATEGY )
|
||||
{
|
||||
compression_strategy = params[i+1];
|
||||
compression_strategy = MIN(MAX(compression_strategy, 0), Z_FIXED);
|
||||
}
|
||||
if( params[i] == 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.data() );
|
||||
png_write_end( png_ptr, info_ptr );
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
png_destroy_write_struct( &png_ptr, &info_ptr );
|
||||
if(f) fclose( (FILE*)f );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
101
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_png.hpp
vendored
Normal file
101
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_png.hpp
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/*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 CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
PngDecoder();
|
||||
virtual ~PngDecoder();
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
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 CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PngEncoder();
|
||||
virtual ~PngEncoder();
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
static void writeDataToBuf(void* png_ptr, uchar* src, size_t size);
|
||||
static void flushBuf(void* png_ptr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*_GRFMT_PNG_H_*/
|
621
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pxm.cpp
vendored
Normal file
621
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pxm.cpp
vendored
Normal file
@ -0,0 +1,621 @@
|
||||
/*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"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_IMGCODEC_PXM
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
///////////////////////// P?M reader //////////////////////////////
|
||||
|
||||
static int ReadNumber(RLByteStream& strm, int maxdigits = 0)
|
||||
{
|
||||
int code;
|
||||
int64 val = 0;
|
||||
int digits = 0;
|
||||
|
||||
code = strm.getByte();
|
||||
|
||||
while (!isdigit(code))
|
||||
{
|
||||
if (code == '#' )
|
||||
{
|
||||
do
|
||||
{
|
||||
code = strm.getByte();
|
||||
}
|
||||
while (code != '\n' && code != '\r');
|
||||
code = strm.getByte();
|
||||
}
|
||||
else if (isspace(code))
|
||||
{
|
||||
while (isspace(code))
|
||||
code = strm.getByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
CV_Error_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code));
|
||||
#else
|
||||
code = strm.getByte();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
val = val*10 + (code - '0');
|
||||
CV_Assert(val <= INT_MAX && "PXM: ReadNumber(): result is too large");
|
||||
digits++;
|
||||
if (maxdigits != 0 && digits >= maxdigits) break;
|
||||
code = strm.getByte();
|
||||
}
|
||||
while (isdigit(code));
|
||||
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
|
||||
PxMDecoder::PxMDecoder()
|
||||
{
|
||||
m_offset = -1;
|
||||
m_buf_supported = true;
|
||||
m_bpp = 0;
|
||||
m_binary = false;
|
||||
m_maxval = 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
m_height = ReadNumber(m_strm);
|
||||
|
||||
m_maxval = m_bpp == 1 ? 1 : ReadNumber(m_strm);
|
||||
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 (const cv::Exception&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "PXM::readHeader(): unknown C++ exception" << std::endl << std::flush;
|
||||
throw;
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
m_offset = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool PxMDecoder::readData( Mat& img )
|
||||
{
|
||||
bool color = img.channels() > 1;
|
||||
uchar* data = img.ptr();
|
||||
PaletteEntry palette[256];
|
||||
bool result = false;
|
||||
const int bit_depth = CV_ELEM_SIZE1(m_type)*8;
|
||||
const int src_pitch = divUp(m_width*m_bpp*(bit_depth/8), 8);
|
||||
int nch = CV_MAT_CN(m_type);
|
||||
int width3 = m_width*nch;
|
||||
|
||||
if( m_offset < 0 || !m_strm.isOpened())
|
||||
return false;
|
||||
|
||||
uchar gray_palette[256] = {0};
|
||||
|
||||
// create LUT for converting colors
|
||||
if( bit_depth == 8 )
|
||||
{
|
||||
CV_Assert(m_maxval < 256 && m_maxval > 0);
|
||||
|
||||
for (int 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:
|
||||
CV_Assert(CV_MAT_DEPTH(m_type) == CV_8U);
|
||||
if( !m_binary )
|
||||
{
|
||||
AutoBuffer<uchar> _src(m_width);
|
||||
uchar* src = _src.data();
|
||||
|
||||
for (int y = 0; y < m_height; y++, data += img.step)
|
||||
{
|
||||
for (int 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
|
||||
{
|
||||
AutoBuffer<uchar> _src(src_pitch);
|
||||
uchar* src = _src.data();
|
||||
|
||||
for (int y = 0; y < m_height; y++, data += img.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:
|
||||
{
|
||||
AutoBuffer<uchar> _src(std::max<size_t>(width3*2, src_pitch));
|
||||
uchar* src = _src.data();
|
||||
|
||||
for (int y = 0; y < m_height; y++, data += img.step)
|
||||
{
|
||||
if( !m_binary )
|
||||
{
|
||||
for (int x = 0; x < width3; x++)
|
||||
{
|
||||
int code = ReadNumber(m_strm);
|
||||
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 (int 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 (int 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, img.elemSize1()*m_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( color )
|
||||
{
|
||||
if( img.depth() == CV_8U )
|
||||
icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, Size(m_width,1) );
|
||||
else
|
||||
icvCvt_RGB2BGR_16u_C3R( (ushort *)src, 0, (ushort *)data, 0, Size(m_width,1) );
|
||||
}
|
||||
else if( img.depth() == CV_8U )
|
||||
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, Size(m_width,1), 2 );
|
||||
else
|
||||
icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)data, 0, Size(m_width,1), 3, 2 );
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CV_Error(Error::StsError, "m_bpp is not supported");
|
||||
}
|
||||
}
|
||||
catch (const cv::Exception&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "PXM::readData(): unknown exception" << std::endl << std::flush;
|
||||
throw;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PxMEncoder::PxMEncoder(PxMMode mode) :
|
||||
mode_(mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case PXM_TYPE_AUTO: m_description = "Portable image format - auto (*.pnm)"; break;
|
||||
case PXM_TYPE_PBM: m_description = "Portable image format - monochrome (*.pbm)"; break;
|
||||
case PXM_TYPE_PGM: m_description = "Portable image format - gray (*.pgm)"; break;
|
||||
case PXM_TYPE_PPM: m_description = "Portable image format - color (*.ppm)"; break;
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
m_buf_supported = true;
|
||||
}
|
||||
|
||||
PxMEncoder::~PxMEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
bool PxMEncoder::isFormatSupported(int depth) const
|
||||
{
|
||||
if (mode_ == PXM_TYPE_PBM)
|
||||
return depth == CV_8U;
|
||||
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] == IMWRITE_PXM_BINARY )
|
||||
isBinary = params[i+1] != 0;
|
||||
}
|
||||
|
||||
int mode = mode_;
|
||||
if (mode == PXM_TYPE_AUTO)
|
||||
{
|
||||
mode = img.channels() == 1 ? PXM_TYPE_PGM : PXM_TYPE_PPM;
|
||||
}
|
||||
|
||||
if (mode == PXM_TYPE_PGM && img.channels() > 1)
|
||||
{
|
||||
CV_Error(Error::StsBadArg, "Portable bitmap(.pgm) expects gray image");
|
||||
}
|
||||
if (mode == PXM_TYPE_PPM && img.channels() != 3)
|
||||
{
|
||||
CV_Error(Error::StsBadArg, "Portable bitmap(.ppm) expects BGR image");
|
||||
}
|
||||
if (mode == PXM_TYPE_PBM && img.type() != CV_8UC1)
|
||||
{
|
||||
CV_Error(Error::StsBadArg, "For portable bitmap(.pbm) type must be CV_8UC1");
|
||||
}
|
||||
|
||||
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.data();
|
||||
|
||||
// write header;
|
||||
const int code = ((mode == PXM_TYPE_PBM) ? 1 : (mode == PXM_TYPE_PGM) ? 2 : 3)
|
||||
+ (isBinary ? 3 : 0);
|
||||
|
||||
int header_sz = sprintf(buffer, "P%c\n%d %d\n",
|
||||
(char)('0' + code), width, height);
|
||||
CV_Assert(header_sz > 0);
|
||||
if (mode != PXM_TYPE_PBM)
|
||||
{
|
||||
int sz = sprintf(&buffer[header_sz], "%d\n", (1 << depth) - 1);
|
||||
CV_Assert(sz > 0);
|
||||
header_sz += sz;
|
||||
}
|
||||
|
||||
strm.putBytes(buffer, header_sz);
|
||||
|
||||
for( y = 0; y < height; y++ )
|
||||
{
|
||||
const uchar* const data = img.ptr(y);
|
||||
if( isBinary )
|
||||
{
|
||||
if (mode == PXM_TYPE_PBM)
|
||||
{
|
||||
char* ptr = buffer;
|
||||
int bcount = 7;
|
||||
char byte = 0;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
if (bcount == 0)
|
||||
{
|
||||
if (data[x] == 0)
|
||||
byte = (byte) | 1;
|
||||
*ptr++ = byte;
|
||||
bcount = 7;
|
||||
byte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data[x] == 0)
|
||||
byte = (byte) | (1 << bcount);
|
||||
bcount--;
|
||||
}
|
||||
}
|
||||
if (bcount != 7)
|
||||
{
|
||||
*ptr++ = byte;
|
||||
}
|
||||
strm.putBytes(buffer, (int)(ptr - buffer));
|
||||
continue;
|
||||
}
|
||||
|
||||
if( _channels == 3 )
|
||||
{
|
||||
if( depth == 8 )
|
||||
icvCvt_BGR2RGB_8u_C3R( (const uchar*)data, 0,
|
||||
(uchar*)buffer, 0, Size(width,1) );
|
||||
else
|
||||
icvCvt_BGR2RGB_16u_C3R( (const ushort*)data, 0,
|
||||
(ushort*)buffer, 0, Size(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 : (const char*)data, fileStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* ptr = buffer;
|
||||
if (mode == PXM_TYPE_PBM)
|
||||
{
|
||||
CV_Assert(channels == 1);
|
||||
CV_Assert(depth == 8);
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
ptr[0] = data[x] ? '0' : '1';
|
||||
ptr += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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", ((const ushort *)data)[x + 2] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((const ushort *)data)[x + 1] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((const 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", ((const ushort *)data)[x] );
|
||||
ptr += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++ = '\n';
|
||||
|
||||
strm.putBytes( buffer, (int)(ptr - buffer) );
|
||||
}
|
||||
}
|
||||
|
||||
strm.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_PXM
|
108
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pxm.hpp
vendored
Normal file
108
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_pxm.hpp
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_PXM
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
enum PxMMode
|
||||
{
|
||||
PXM_TYPE_AUTO = 0, // "auto"
|
||||
PXM_TYPE_PBM = 1, // monochrome format (single channel)
|
||||
PXM_TYPE_PGM = 2, // gray format (single channel)
|
||||
PXM_TYPE_PPM = 3 // color format
|
||||
};
|
||||
|
||||
class PxMDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
PxMDecoder();
|
||||
virtual ~PxMDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
RLByteStream m_strm;
|
||||
PaletteEntry m_palette[256];
|
||||
int m_bpp;
|
||||
int m_offset;
|
||||
bool m_binary;
|
||||
int m_maxval;
|
||||
};
|
||||
|
||||
class PxMEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
PxMEncoder(PxMMode mode);
|
||||
virtual ~PxMEncoder() CV_OVERRIDE;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE
|
||||
{
|
||||
return makePtr<PxMEncoder>(mode_);
|
||||
}
|
||||
|
||||
const PxMMode mode_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_PXM
|
||||
|
||||
#endif/*_GRFMT_PxM_H_*/
|
433
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_sunras.cpp
vendored
Normal file
433
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_sunras.cpp
vendored
Normal file
@ -0,0 +1,433 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_SUNRASTER
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
static const char* fmtSignSunRas = "\x59\xA6\x6A\x95";
|
||||
|
||||
/************************ Sun Raster reader *****************************/
|
||||
|
||||
SunRasterDecoder::SunRasterDecoder()
|
||||
{
|
||||
m_offset = -1;
|
||||
m_signature = fmtSignSunRas;
|
||||
m_bpp = 0;
|
||||
m_encoding = RAS_STANDARD;
|
||||
m_maptype = RMT_NONE;
|
||||
m_maplength = 0;
|
||||
}
|
||||
|
||||
|
||||
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 = (m_bpp > 0 && m_bpp <= 8) ? (3*(1 << m_bpp)) : 0;
|
||||
|
||||
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_maplength > 0 && 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();
|
||||
|
||||
CV_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();
|
||||
|
||||
CV_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 )
|
||||
{
|
||||
bool color = img.channels() > 1;
|
||||
uchar* data = img.ptr();
|
||||
size_t step = img.step;
|
||||
uchar gray_palette[256] = {0};
|
||||
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.data();
|
||||
|
||||
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 )
|
||||
{
|
||||
CV_Error(Error::StsInternal, "");
|
||||
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, validateToInt(step), width3,
|
||||
y, m_height, len,
|
||||
m_palette[code] );
|
||||
else
|
||||
data = FillUniGray( data, line_end, validateToInt(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(src, src_pitch );
|
||||
|
||||
if( color )
|
||||
{
|
||||
if( m_type == RAS_FORMAT_RGB )
|
||||
icvCvt_RGB2BGR_8u_C3R(src, 0, data, 0, Size(m_width,1) );
|
||||
else
|
||||
memcpy(data, src, std::min(step, (size_t)src_pitch));
|
||||
}
|
||||
else
|
||||
{
|
||||
icvCvt_BGR2Gray_8u_C3C1R(src, 0, data, 0, Size(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, Size(m_width,1),
|
||||
m_type == RAS_FORMAT_RGB ? 2 : 0 );
|
||||
else
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( src + 4, 0, data, 0, Size(m_width,1),
|
||||
m_type == RAS_FORMAT_RGB ? 2 : 0 );
|
||||
}
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
}
|
||||
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.ptr(y), fileStep );
|
||||
|
||||
strm.close();
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_SUNRASTER
|
109
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_sunras.hpp
vendored
Normal file
109
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_sunras.hpp
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_IMGCODEC_SUNRASTER
|
||||
|
||||
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 CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
SunRasterDecoder();
|
||||
virtual ~SunRasterDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
void close();
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
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 CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
SunRasterEncoder();
|
||||
virtual ~SunRasterEncoder() CV_OVERRIDE;
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_IMGCODEC_SUNRASTER
|
||||
|
||||
#endif/*_GRFMT_SUNRAS_H_*/
|
1018
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_tiff.cpp
vendored
Normal file
1018
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_tiff.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
151
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_tiff.hpp
vendored
Normal file
151
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_tiff.hpp
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
/*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"
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
// libtiff based TIFF codec
|
||||
class TiffDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
TiffDecoder();
|
||||
virtual ~TiffDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
void close();
|
||||
bool nextPage() CV_OVERRIDE;
|
||||
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature ) const CV_OVERRIDE;
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
cv::Ptr<void> m_tif;
|
||||
int normalizeChannelsNumber(int channels) const;
|
||||
bool m_hdr;
|
||||
size_t m_buf_pos;
|
||||
|
||||
private:
|
||||
TiffDecoder(const TiffDecoder &); // copy disabled
|
||||
TiffDecoder& operator=(const TiffDecoder &); // assign disabled
|
||||
};
|
||||
|
||||
// ... and writer
|
||||
class TiffEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
TiffEncoder();
|
||||
virtual ~TiffEncoder() CV_OVERRIDE;
|
||||
|
||||
bool isFormatSupported( int depth ) const CV_OVERRIDE;
|
||||
|
||||
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
|
||||
|
||||
bool writemulti(const std::vector<Mat>& img_vec, const std::vector<int>& params) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
void writeTag( WLByteStream& strm, TiffTag tag,
|
||||
TiffFieldType fieldType,
|
||||
int count, int value );
|
||||
|
||||
bool writeLibTiff( const std::vector<Mat>& img_vec, const std::vector<int>& params );
|
||||
bool write_32FC3_SGILOG(const Mat& img, void* tif);
|
||||
|
||||
private:
|
||||
TiffEncoder(const TiffEncoder &); // copy disabled
|
||||
TiffEncoder& operator=(const TiffEncoder &); // assign disabled
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAVE_TIFF
|
||||
|
||||
#endif/*_GRFMT_TIFF_H_*/
|
326
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_webp.cpp
vendored
Normal file
326
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_webp.cpp
vendored
Normal file
@ -0,0 +1,326 @@
|
||||
/*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"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// 64Mb limit to avoid memory DDOS
|
||||
static size_t param_maxFileSize = utils::getConfigurationParameterSizeT("OPENCV_IMGCODECS_WEBP_MAX_FILE_SIZE", 64*1024*1024);
|
||||
|
||||
static const size_t WEBP_HEADER_SIZE = 32;
|
||||
|
||||
WebPDecoder::WebPDecoder()
|
||||
{
|
||||
m_buf_supported = true;
|
||||
channels = 0;
|
||||
fs_size = 0;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
uint8_t header[WEBP_HEADER_SIZE] = { 0 };
|
||||
if (m_buf.empty())
|
||||
{
|
||||
fs.open(m_filename.c_str(), std::ios::binary);
|
||||
fs.seekg(0, std::ios::end);
|
||||
fs_size = safeCastToSizeT(fs.tellg(), "File is too large");
|
||||
fs.seekg(0, std::ios::beg);
|
||||
CV_Assert(fs && "File stream error");
|
||||
CV_CheckGE(fs_size, WEBP_HEADER_SIZE, "File is too small");
|
||||
CV_CheckLE(fs_size, param_maxFileSize, "File is too large. Increase OPENCV_IMGCODECS_WEBP_MAX_FILE_SIZE parameter if you want to process large files");
|
||||
|
||||
fs.read((char*)header, sizeof(header));
|
||||
CV_Assert(fs && "Can't read WEBP_HEADER_SIZE bytes");
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_CheckGE(m_buf.total(), WEBP_HEADER_SIZE, "Buffer is too small");
|
||||
memcpy(header, m_buf.ptr(), sizeof(header));
|
||||
data = m_buf;
|
||||
}
|
||||
|
||||
WebPBitstreamFeatures features;
|
||||
if (VP8_STATUS_OK == WebPGetFeatures(header, sizeof(header), &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)
|
||||
{
|
||||
CV_CheckGE(m_width, 0, ""); CV_CheckGE(m_height, 0, "");
|
||||
|
||||
CV_CheckEQ(img.cols, m_width, "");
|
||||
CV_CheckEQ(img.rows, m_height, "");
|
||||
|
||||
if (m_buf.empty())
|
||||
{
|
||||
fs.seekg(0, std::ios::beg); CV_Assert(fs && "File stream error");
|
||||
data.create(1, validateToInt(fs_size), CV_8UC1);
|
||||
fs.read((char*)data.ptr(), fs_size);
|
||||
CV_Assert(fs && "Can't read file data");
|
||||
fs.close();
|
||||
}
|
||||
CV_Assert(data.type() == CV_8UC1); CV_Assert(data.rows == 1);
|
||||
|
||||
{
|
||||
Mat read_img;
|
||||
CV_CheckType(img.type(), img.type() == CV_8UC1 || img.type() == CV_8UC3 || img.type() == CV_8UC4, "");
|
||||
if (img.type() != m_type)
|
||||
{
|
||||
read_img.create(m_height, m_width, m_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
read_img = img; // copy header
|
||||
}
|
||||
|
||||
uchar* out_data = read_img.ptr();
|
||||
size_t out_data_size = read_img.dataend - out_data;
|
||||
|
||||
uchar *res_ptr = NULL;
|
||||
if (channels == 3)
|
||||
{
|
||||
CV_CheckTypeEQ(read_img.type(), CV_8UC3, "");
|
||||
res_ptr = WebPDecodeBGRInto(data.ptr(), data.total(), out_data,
|
||||
(int)out_data_size, (int)read_img.step);
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
CV_CheckTypeEQ(read_img.type(), CV_8UC4, "");
|
||||
res_ptr = WebPDecodeBGRAInto(data.ptr(), data.total(), out_data,
|
||||
(int)out_data_size, (int)read_img.step);
|
||||
}
|
||||
|
||||
if (res_ptr != out_data)
|
||||
return false;
|
||||
|
||||
if (read_img.data == img.data && img.type() == m_type)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
else if (img.type() == CV_8UC1)
|
||||
{
|
||||
cvtColor(read_img, img, COLOR_BGR2GRAY);
|
||||
}
|
||||
else if (img.type() == CV_8UC3 && m_type == CV_8UC4)
|
||||
{
|
||||
cvtColor(read_img, img, COLOR_BGRA2BGR);
|
||||
}
|
||||
else if (img.type() == CV_8UC4 && m_type == CV_8UC3)
|
||||
{
|
||||
cvtColor(read_img, img, COLOR_BGR2BGRA);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsInternal, "");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
CV_CheckDepthEQ(img.depth(), CV_8U, "WebP codec supports 8U images only");
|
||||
|
||||
const int width = img.cols, height = img.rows;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int channels = img.channels();
|
||||
CV_Check(channels, channels == 1 || channels == 3 || channels == 4, "");
|
||||
|
||||
const Mat *image = &img;
|
||||
Mat temp;
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
cvtColor(*image, temp, COLOR_GRAY2BGR);
|
||||
image = &temp;
|
||||
channels = 3;
|
||||
}
|
||||
|
||||
uint8_t *out = NULL;
|
||||
size_t size = 0;
|
||||
if (comp_lossless)
|
||||
{
|
||||
if (channels == 3)
|
||||
{
|
||||
size = WebPEncodeLosslessBGR(image->ptr(), width, height, (int)image->step, &out);
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
size = WebPEncodeLosslessBGRA(image->ptr(), width, height, (int)image->step, &out);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channels == 3)
|
||||
{
|
||||
size = WebPEncodeBGR(image->ptr(), width, height, (int)image->step, quality, &out);
|
||||
}
|
||||
else if (channels == 4)
|
||||
{
|
||||
size = WebPEncodeBGRA(image->ptr(), width, height, (int)image->step, quality, &out);
|
||||
}
|
||||
}
|
||||
#if WEBP_DECODER_ABI_VERSION >= 0x0206
|
||||
Ptr<uint8_t> out_cleaner(out, WebPFree);
|
||||
#else
|
||||
Ptr<uint8_t> out_cleaner(out, free);
|
||||
#endif
|
||||
|
||||
CV_Assert(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;
|
||||
}
|
||||
}
|
||||
|
||||
return size > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
92
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_webp.hpp
vendored
Normal file
92
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmt_webp.hpp
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*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
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class WebPDecoder CV_FINAL : public BaseImageDecoder
|
||||
{
|
||||
public:
|
||||
|
||||
WebPDecoder();
|
||||
~WebPDecoder() CV_OVERRIDE;
|
||||
|
||||
bool readData( Mat& img ) CV_OVERRIDE;
|
||||
bool readHeader() CV_OVERRIDE;
|
||||
|
||||
size_t signatureLength() const CV_OVERRIDE;
|
||||
bool checkSignature( const String& signature) const CV_OVERRIDE;
|
||||
|
||||
ImageDecoder newDecoder() const CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
std::ifstream fs;
|
||||
size_t fs_size;
|
||||
Mat data;
|
||||
int channels;
|
||||
};
|
||||
|
||||
class WebPEncoder CV_FINAL : public BaseImageEncoder
|
||||
{
|
||||
public:
|
||||
WebPEncoder();
|
||||
~WebPEncoder() CV_OVERRIDE;
|
||||
|
||||
bool write(const Mat& img, const std::vector<int>& params) CV_OVERRIDE;
|
||||
|
||||
ImageEncoder newEncoder() const CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GRFMT_WEBP_H_ */
|
62
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmts.hpp
vendored
Normal file
62
3rdparty/opencv-4.5.4/modules/imgcodecs/src/grfmts.hpp
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/*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_pfm.hpp"
|
||||
#include "grfmt_tiff.hpp"
|
||||
#include "grfmt_png.hpp"
|
||||
#include "grfmt_jpeg2000.hpp"
|
||||
#include "grfmt_jpeg2000_openjpeg.hpp"
|
||||
#include "grfmt_exr.hpp"
|
||||
#include "grfmt_webp.hpp"
|
||||
#include "grfmt_hdr.hpp"
|
||||
#include "grfmt_gdal.hpp"
|
||||
#include "grfmt_gdcm.hpp"
|
||||
#include "grfmt_pam.hpp"
|
||||
|
||||
#endif/*_GRFMTS_H_*/
|
63
3rdparty/opencv-4.5.4/modules/imgcodecs/src/ios_conversions.mm
vendored
Normal file
63
3rdparty/opencv-4.5.4/modules/imgcodecs/src/ios_conversions.mm
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/*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 <UIKit/UIKit.h>
|
||||
#include "apple_conversions.h"
|
||||
|
||||
CV_EXPORTS UIImage* MatToUIImage(const cv::Mat& image);
|
||||
CV_EXPORTS void UIImageToMat(const UIImage* image, cv::Mat& m, bool alphaExist);
|
||||
|
||||
UIImage* MatToUIImage(const cv::Mat& image) {
|
||||
// Creating CGImage from cv::Mat
|
||||
CGImageRef imageRef = MatToCGImage(image);
|
||||
|
||||
// Getting UIImage from CGImage
|
||||
UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
return uiImage;
|
||||
}
|
||||
|
||||
void UIImageToMat(const UIImage* image, cv::Mat& m, bool alphaExist) {
|
||||
CGImageRef imageRef = image.CGImage;
|
||||
CGImageToMat(imageRef, m, alphaExist);
|
||||
}
|
1035
3rdparty/opencv-4.5.4/modules/imgcodecs/src/loadsave.cpp
vendored
Normal file
1035
3rdparty/opencv-4.5.4/modules/imgcodecs/src/loadsave.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
25
3rdparty/opencv-4.5.4/modules/imgcodecs/src/macosx_conversions.mm
vendored
Normal file
25
3rdparty/opencv-4.5.4/modules/imgcodecs/src/macosx_conversions.mm
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "apple_conversions.h"
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
CV_EXPORTS NSImage* MatToNSImage(const cv::Mat& image);
|
||||
CV_EXPORTS void NSImageToMat(const NSImage* image, cv::Mat& m, bool alphaExist);
|
||||
|
||||
NSImage* MatToNSImage(const cv::Mat& image) {
|
||||
// Creating CGImage from cv::Mat
|
||||
CGImageRef imageRef = MatToCGImage(image);
|
||||
|
||||
// Getting NSImage from CGImage
|
||||
NSImage *nsImage = [[NSImage alloc] initWithCGImage:imageRef size:CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef))];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
return nsImage;
|
||||
}
|
||||
|
||||
void NSImageToMat(const NSImage* image, cv::Mat& m, bool alphaExist) {
|
||||
CGImageRef imageRef = [image CGImageForProposedRect:NULL context:NULL hints:NULL];
|
||||
CGImageToMat(imageRef, m, alphaExist);
|
||||
}
|
71
3rdparty/opencv-4.5.4/modules/imgcodecs/src/precomp.hpp
vendored
Normal file
71
3rdparty/opencv-4.5.4/modules/imgcodecs/src/precomp.hpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*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 __IMGCODECS_H_
|
||||
#define __IMGCODECS_H_
|
||||
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/imgcodecs/legacy/constants_c.h"
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/private.hpp"
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined _WIN32 || defined WINCE
|
||||
#include <windows.h>
|
||||
#undef small
|
||||
#undef min
|
||||
#undef max
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
#define __BEGIN__ __CV_BEGIN__
|
||||
#define __END__ __CV_END__
|
||||
#define EXIT __CV_EXIT__
|
||||
|
||||
#endif /* __IMGCODECS_H_ */
|
454
3rdparty/opencv-4.5.4/modules/imgcodecs/src/rgbe.cpp
vendored
Normal file
454
3rdparty/opencv-4.5.4/modules/imgcodecs/src/rgbe.cpp
vendored
Normal file
@ -0,0 +1,454 @@
|
||||
/*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>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// This file contains code to read and write four byte rgbe file format
|
||||
// developed by Greg Ward. It handles the conversions between rgbe and
|
||||
// pixels consisting of floats. The data is assumed to be an array of floats.
|
||||
// By default there are three floats per pixel in the order red, green, blue.
|
||||
// (RGBE_DATA_??? values control this.) Only the minimal 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));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 = "RADIANCE";
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 1. read first line
|
||||
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;
|
||||
}
|
||||
|
||||
// 2. reading other header lines
|
||||
bool hasFormat = false;
|
||||
for(;;) {
|
||||
if (fgets(buf,sizeof(buf)/sizeof(buf[0]),fp) == 0)
|
||||
return rgbe_error(rgbe_read_error,NULL);
|
||||
if (buf[0] == '\n') // end of the header
|
||||
break;
|
||||
else if (buf[0] == '#') // comment
|
||||
continue;
|
||||
else if (strcmp(buf,"FORMAT=32-bit_rle_rgbe\n") == 0)
|
||||
hasFormat = true;
|
||||
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 (strcmp(buf,"\n") != 0)
|
||||
return rgbe_error(rgbe_format_error,
|
||||
"missing blank line after FORMAT specifier");
|
||||
if (!hasFormat)
|
||||
return rgbe_error(rgbe_format_error, "missing FORMAT specifier");
|
||||
|
||||
// 3. reading resolution string
|
||||
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;
|
||||
}
|
89
3rdparty/opencv-4.5.4/modules/imgcodecs/src/rgbe.hpp
vendored
Normal file
89
3rdparty/opencv-4.5.4/modules/imgcodecs/src/rgbe.hpp
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*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_*/
|
609
3rdparty/opencv-4.5.4/modules/imgcodecs/src/utils.cpp
vendored
Normal file
609
3rdparty/opencv-4.5.4/modules/imgcodecs/src/utils.cpp
vendored
Normal file
@ -0,0 +1,609 @@
|
||||
/*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"
|
||||
|
||||
namespace cv {
|
||||
|
||||
int validateToInt(size_t sz)
|
||||
{
|
||||
int valueInt = (int)sz;
|
||||
CV_Assert((size_t)valueInt == sz);
|
||||
return valueInt;
|
||||
}
|
||||
|
||||
#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* bgr, int bgr_step,
|
||||
uchar* gray, int gray_step,
|
||||
Size size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
short cBGR0 = cB;
|
||||
short cBGR2 = cR;
|
||||
if (_swap_rb) std::swap(cBGR0, cBGR2);
|
||||
for( i = 0; i < size.width; i++, bgr += 3 )
|
||||
{
|
||||
int t = descale( bgr[0]*cBGR0 + bgr[1]*cG + bgr[2]*cBGR2, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
|
||||
bgr += bgr_step - size.width*3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgr, int bgr_step,
|
||||
ushort* gray, int gray_step,
|
||||
Size size, int ncn, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
short cBGR0 = cB;
|
||||
short cBGR2 = cR;
|
||||
if (_swap_rb) std::swap(cBGR0, cBGR2);
|
||||
for( i = 0; i < size.width; i++, bgr += ncn )
|
||||
{
|
||||
int t = descale( bgr[0]*cBGR0 + bgr[1]*cG + bgr[2]*cBGR2, SCALE );
|
||||
gray[i] = (ushort)t;
|
||||
}
|
||||
|
||||
bgr += bgr_step - size.width*ncn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int rgba_step,
|
||||
uchar* gray, int gray_step,
|
||||
Size size, int _swap_rb )
|
||||
{
|
||||
int i;
|
||||
for( ; size.height--; gray += gray_step )
|
||||
{
|
||||
short cBGR0 = cB;
|
||||
short cBGR2 = cR;
|
||||
if (_swap_rb) std::swap(cBGR0, cBGR2);
|
||||
for( i = 0; i < size.width; i++, bgra += 4 )
|
||||
{
|
||||
int t = descale( bgra[0]*cBGR0 + bgra[1]*cG + bgra[2]*cBGR2, SCALE );
|
||||
gray[i] = (uchar)t;
|
||||
}
|
||||
|
||||
bgra += rgba_step - size.width*4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
|
||||
uchar* bgr, int bgr_step, Size 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, Size 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,
|
||||
Size 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,
|
||||
Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size 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, Size(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;
|
||||
|
||||
const PaletteEntry p0 = palette[0], p1 = palette[1];
|
||||
|
||||
while( (data += 24) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
*((PaletteEntry*)(data - 24)) = (idx & 128) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 21)) = (idx & 64) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 18)) = (idx & 32) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 15)) = (idx & 16) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 12)) = (idx & 8) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 9)) = (idx & 4) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 6)) = (idx & 2) ? p1 : p0;
|
||||
*((PaletteEntry*)(data - 3)) = (idx & 1) ? p1 : p0;
|
||||
}
|
||||
|
||||
int idx = indices[0];
|
||||
for( data -= 24; data < end; data += 3, idx += idx )
|
||||
{
|
||||
const PaletteEntry clr = (idx & 128) ? p1 : p0;
|
||||
WRITE_PIX( data, clr );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
|
||||
{
|
||||
uchar* end = data + len;
|
||||
|
||||
const uchar p0 = palette[0], p1 = palette[1];
|
||||
|
||||
while( (data += 8) < end )
|
||||
{
|
||||
int idx = *indices++;
|
||||
*((uchar*)(data - 8)) = (idx & 128) ? p1 : p0;
|
||||
*((uchar*)(data - 7)) = (idx & 64) ? p1 : p0;
|
||||
*((uchar*)(data - 6)) = (idx & 32) ? p1 : p0;
|
||||
*((uchar*)(data - 5)) = (idx & 16) ? p1 : p0;
|
||||
*((uchar*)(data - 4)) = (idx & 8) ? p1 : p0;
|
||||
*((uchar*)(data - 3)) = (idx & 4) ? p1 : p0;
|
||||
*((uchar*)(data - 2)) = (idx & 2) ? p1 : p0;
|
||||
*((uchar*)(data - 1)) = (idx & 1) ? p1 : p0;
|
||||
}
|
||||
|
||||
int idx = indices[0];
|
||||
for( data -= 8; data < end; data++, idx += idx )
|
||||
{
|
||||
data[0] = (idx & 128) ? p1 : p0;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace
|
143
3rdparty/opencv-4.5.4/modules/imgcodecs/src/utils.hpp
vendored
Normal file
143
3rdparty/opencv-4.5.4/modules/imgcodecs/src/utils.hpp
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
/*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_
|
||||
|
||||
namespace cv {
|
||||
|
||||
int validateToInt(size_t step);
|
||||
|
||||
template <typename _Tp> static inline
|
||||
size_t safeCastToSizeT(const _Tp v_origin, const char* msg)
|
||||
{
|
||||
const size_t value_cast = (size_t)v_origin;
|
||||
if ((_Tp)value_cast != v_origin)
|
||||
CV_Error(cv::Error::StsError, msg ? msg : "Can't cast value into size_t");
|
||||
return value_cast;
|
||||
}
|
||||
|
||||
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,
|
||||
Size size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int bgra_step,
|
||||
uchar* gray, int gray_step,
|
||||
Size size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgra, int bgra_step,
|
||||
ushort* gray, int gray_step,
|
||||
Size size, int ncn, int swap_rb=0 );
|
||||
|
||||
void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
|
||||
uchar* bgr, int bgr_step, Size size );
|
||||
void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
|
||||
ushort* bgr, int bgr_step, Size size );
|
||||
|
||||
void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
|
||||
uchar* bgr, int bgr_step,
|
||||
Size size, int swap_rb=0 );
|
||||
void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
|
||||
ushort* bgr, int bgr_step,
|
||||
Size size, int _swap_rb );
|
||||
|
||||
void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
|
||||
uchar* rgb, int rgb_step, Size 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, Size 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, Size 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, Size 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, Size size );
|
||||
void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* gray, int gray_step, Size size );
|
||||
void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
|
||||
uchar* bgr, int bgr_step, Size size );
|
||||
void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
|
||||
uchar* bgr, int bgr_step, Size size );
|
||||
void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
|
||||
uchar* bgr, int bgr_step, Size size );
|
||||
void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* ycck, int ycck_step,
|
||||
uchar* gray, int gray_step, Size 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;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif/*_UTILS_H_*/
|
Reference in New Issue
Block a user