Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
1fb93b62
Commit
1fb93b62
authored
Apr 04, 2019
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14249 from alalek:imgcodecs_tiff_update_3.4
parents
ab21dc6d
ba5ddd64
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
398 additions
and
422 deletions
+398
-422
grfmt_tiff.cpp
modules/imgcodecs/src/grfmt_tiff.cpp
+292
-378
grfmt_tiff.hpp
modules/imgcodecs/src/grfmt_tiff.hpp
+2
-5
utils.cpp
modules/imgcodecs/src/utils.cpp
+24
-19
utils.hpp
modules/imgcodecs/src/utils.hpp
+21
-17
test_tiff.cpp
modules/imgcodecs/test/test_tiff.cpp
+59
-3
No files found.
modules/imgcodecs/src/grfmt_tiff.cpp
View file @
1fb93b62
...
@@ -48,6 +48,8 @@
...
@@ -48,6 +48,8 @@
#include "precomp.hpp"
#include "precomp.hpp"
#ifdef HAVE_TIFF
#ifdef HAVE_TIFF
#include <opencv2/core/utils/logger.hpp>
#include "grfmt_tiff.hpp"
#include "grfmt_tiff.hpp"
#include <limits>
#include <limits>
...
@@ -61,23 +63,58 @@ using namespace tiff_dummy_namespace;
...
@@ -61,23 +63,58 @@ using namespace tiff_dummy_namespace;
namespace
cv
namespace
cv
{
{
#define CV_TIFF_CHECK_CALL(call) \
if (0 == (call)) { \
CV_LOG_WARNING(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed " #call); \
CV_Error(Error::StsError, "OpenCV TIFF: failed " #call); \
}
#define CV_TIFF_CHECK_CALL_INFO(call) \
if (0 == (call)) { \
CV_LOG_INFO(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed optional call: " #call ", ignoring"); \
}
#define CV_TIFF_CHECK_CALL_DEBUG(call) \
if (0 == (call)) { \
CV_LOG_DEBUG(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed optional call: " #call ", ignoring"); \
}
static
void
cv_tiffCloseHandle
(
void
*
handle
)
{
TIFFClose
((
TIFF
*
)
handle
);
}
static
void
cv_tiffErrorHandler
(
const
char
*
module
,
const
char
*
fmt
,
va_list
ap
)
{
if
(
cv
::
utils
::
logging
::
getLogLevel
()
<
cv
::
utils
::
logging
::
LOG_LEVEL_DEBUG
)
return
;
// TODO cv::vformat() with va_list parameter
fprintf
(
stderr
,
"OpenCV TIFF: "
);
if
(
module
!=
NULL
)
fprintf
(
stderr
,
"%s: "
,
module
);
fprintf
(
stderr
,
"Warning, "
);
vfprintf
(
stderr
,
fmt
,
ap
);
fprintf
(
stderr
,
".
\n
"
);
}
static
bool
cv_tiffSetErrorHandler_
()
{
TIFFSetErrorHandler
(
cv_tiffErrorHandler
);
TIFFSetWarningHandler
(
cv_tiffErrorHandler
);
return
true
;
}
static
bool
cv_tiffSetErrorHandler
()
{
static
bool
v
=
cv_tiffSetErrorHandler_
();
return
v
;
}
static
const
char
fmtSignTiffII
[]
=
"II
\x2a\x00
"
;
static
const
char
fmtSignTiffII
[]
=
"II
\x2a\x00
"
;
static
const
char
fmtSignTiffMM
[]
=
"MM
\x00\x2a
"
;
static
const
char
fmtSignTiffMM
[]
=
"MM
\x00\x2a
"
;
static
int
grfmt_tiff_err_handler_init
=
0
;
static
void
GrFmtSilentTIFFErrorHandler
(
const
char
*
,
const
char
*
,
va_list
)
{}
TiffDecoder
::
TiffDecoder
()
TiffDecoder
::
TiffDecoder
()
{
{
m_tif
=
0
;
if
(
!
grfmt_tiff_err_handler_init
)
{
grfmt_tiff_err_handler_init
=
1
;
TIFFSetErrorHandler
(
GrFmtSilentTIFFErrorHandler
);
TIFFSetWarningHandler
(
GrFmtSilentTIFFErrorHandler
);
}
m_hdr
=
false
;
m_hdr
=
false
;
m_buf_supported
=
true
;
m_buf_supported
=
true
;
m_buf_pos
=
0
;
m_buf_pos
=
0
;
...
@@ -86,12 +123,7 @@ TiffDecoder::TiffDecoder()
...
@@ -86,12 +123,7 @@ TiffDecoder::TiffDecoder()
void
TiffDecoder
::
close
()
void
TiffDecoder
::
close
()
{
{
if
(
m_tif
)
m_tif
.
release
();
{
TIFF
*
tif
=
(
TIFF
*
)
m_tif
;
TIFFClose
(
tif
);
m_tif
=
0
;
}
}
}
TiffDecoder
::~
TiffDecoder
()
TiffDecoder
::~
TiffDecoder
()
...
@@ -113,11 +145,13 @@ bool TiffDecoder::checkSignature( const String& signature ) const
...
@@ -113,11 +145,13 @@ bool TiffDecoder::checkSignature( const String& signature ) const
int
TiffDecoder
::
normalizeChannelsNumber
(
int
channels
)
const
int
TiffDecoder
::
normalizeChannelsNumber
(
int
channels
)
const
{
{
CV_Assert
(
channels
<=
4
);
return
channels
>
4
?
4
:
channels
;
return
channels
>
4
?
4
:
channels
;
}
}
ImageDecoder
TiffDecoder
::
newDecoder
()
const
ImageDecoder
TiffDecoder
::
newDecoder
()
const
{
{
cv_tiffSetErrorHandler
();
return
makePtr
<
TiffDecoder
>
();
return
makePtr
<
TiffDecoder
>
();
}
}
...
@@ -201,8 +235,8 @@ bool TiffDecoder::readHeader()
...
@@ -201,8 +235,8 @@ bool TiffDecoder::readHeader()
{
{
bool
result
=
false
;
bool
result
=
false
;
TIFF
*
tif
=
static_cast
<
TIFF
*>
(
m_tif
);
TIFF
*
tif
=
static_cast
<
TIFF
*>
(
m_tif
.
get
()
);
if
(
!
m_
tif
)
if
(
!
tif
)
{
{
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
...
@@ -221,25 +255,30 @@ bool TiffDecoder::readHeader()
...
@@ -221,25 +255,30 @@ bool TiffDecoder::readHeader()
{
{
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"r"
);
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"r"
);
}
}
if
(
tif
)
m_tif
.
reset
(
tif
,
cv_tiffCloseHandle
);
else
m_tif
.
release
();
}
}
if
(
tif
)
if
(
tif
)
{
{
uint32
wdth
=
0
,
hght
=
0
;
uint32
wdth
=
0
,
hght
=
0
;
uint16
photometric
=
0
;
uint16
photometric
=
0
;
m_tif
=
tif
;
if
(
TIFFGetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
&
wdth
)
&&
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
&
wdth
));
TIFFGetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
&
hght
)
&&
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
&
hght
));
TIFFGetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
&
photometric
))
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
&
photometric
));
{
{
uint16
bpp
=
8
,
ncn
=
photometric
>
1
?
3
:
1
;
bool
isGrayScale
=
photometric
==
PHOTOMETRIC_MINISWHITE
||
photometric
==
PHOTOMETRIC_MINISBLACK
;
TIFFGetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
&
bpp
);
uint16
bpp
=
8
,
ncn
=
isGrayScale
?
1
:
3
;
TIFFGetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
&
ncn
);
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
&
bpp
));
CV_TIFF_CHECK_CALL_DEBUG
(
TIFFGetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
&
ncn
));
m_width
=
wdth
;
m_width
=
wdth
;
m_height
=
hght
;
m_height
=
hght
;
if
((
bpp
==
32
&&
ncn
==
3
)
||
photometric
==
PHOTOMETRIC_LOGLUV
)
if
(
ncn
==
3
&&
photometric
==
PHOTOMETRIC_LOGLUV
)
{
{
m_type
=
CV_32FC3
;
m_type
=
CV_32FC3
;
m_hdr
=
true
;
m_hdr
=
true
;
...
@@ -256,23 +295,23 @@ bool TiffDecoder::readHeader()
...
@@ -256,23 +295,23 @@ bool TiffDecoder::readHeader()
switch
(
bpp
)
switch
(
bpp
)
{
{
case
1
:
case
1
:
m_type
=
CV_MAKETYPE
(
CV_8U
,
photometric
>
1
?
wanted_channels
:
1
);
m_type
=
CV_MAKETYPE
(
CV_8U
,
!
isGrayScale
?
wanted_channels
:
1
);
result
=
true
;
result
=
true
;
break
;
break
;
case
8
:
case
8
:
m_type
=
CV_MAKETYPE
(
CV_8U
,
photometric
>
1
?
wanted_channels
:
1
);
m_type
=
CV_MAKETYPE
(
CV_8U
,
!
isGrayScale
?
wanted_channels
:
1
);
result
=
true
;
result
=
true
;
break
;
break
;
case
16
:
case
16
:
m_type
=
CV_MAKETYPE
(
CV_16U
,
photometric
>
1
?
wanted_channels
:
1
);
m_type
=
CV_MAKETYPE
(
CV_16U
,
!
isGrayScale
?
wanted_channels
:
1
);
result
=
true
;
result
=
true
;
break
;
break
;
case
32
:
case
32
:
m_type
=
CV_MAKETYPE
(
CV_32F
,
photometric
>
1
?
3
:
1
);
m_type
=
CV_MAKETYPE
(
CV_32F
,
wanted_channels
);
result
=
true
;
result
=
true
;
break
;
break
;
case
64
:
case
64
:
m_type
=
CV_MAKETYPE
(
CV_64F
,
photometric
>
1
?
3
:
1
);
m_type
=
CV_MAKETYPE
(
CV_64F
,
wanted_channels
);
result
=
true
;
result
=
true
;
break
;
break
;
default
:
default
:
...
@@ -290,206 +329,210 @@ bool TiffDecoder::readHeader()
...
@@ -290,206 +329,210 @@ bool TiffDecoder::readHeader()
bool
TiffDecoder
::
nextPage
()
bool
TiffDecoder
::
nextPage
()
{
{
// Prepare the next page, if any.
// Prepare the next page, if any.
return
m_tif
&&
return
!
m_tif
.
empty
()
&&
TIFFReadDirectory
(
static_cast
<
TIFF
*>
(
m_tif
))
&&
TIFFReadDirectory
(
static_cast
<
TIFF
*>
(
m_tif
.
get
()
))
&&
readHeader
();
readHeader
();
}
}
bool
TiffDecoder
::
readData
(
Mat
&
img
)
bool
TiffDecoder
::
readData
(
Mat
&
img
)
{
{
if
(
m_hdr
&&
img
.
type
()
==
CV_32FC3
)
int
type_
=
img
.
type
();
{
int
depth
=
CV_MAT_DEPTH
(
type_
);
return
readData_32FC3
(
img
);
}
CV_Assert
(
!
m_tif
.
empty
());
if
(
img
.
type
()
==
CV_32FC1
)
TIFF
*
tif
=
(
TIFF
*
)
m_tif
.
get
();
uint16
photometric
=
(
uint16
)
-
1
;
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
&
photometric
));
if
(
m_hdr
&&
depth
>=
CV_32F
)
{
{
return
readData_32FC1
(
img
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SGILOGDATAFMT
,
SGILOGDATAFMT_FLOAT
)
);
}
}
bool
result
=
false
;
bool
color
=
img
.
channels
()
>
1
;
bool
color
=
img
.
channels
()
>
1
;
if
(
img
.
depth
()
!=
CV_8U
&&
img
.
depth
()
!=
CV_16U
&&
img
.
depth
()
!=
CV_32F
&&
img
.
depth
()
!=
CV_64F
)
CV_CheckType
(
type_
,
depth
==
CV_8U
||
depth
==
CV_16U
||
depth
==
CV_32F
||
depth
==
CV_64F
,
""
);
return
false
;
if
(
m_tif
&&
m_width
&&
m_height
)
if
(
m_width
&&
m_height
)
{
{
TIFF
*
tif
=
(
TIFF
*
)
m_tif
;
int
is_tiled
=
TIFFIsTiled
(
tif
)
!=
0
;
uint32
tile_width0
=
m_width
,
tile_height0
=
0
;
bool
isGrayScale
=
photometric
==
PHOTOMETRIC_MINISWHITE
||
photometric
==
PHOTOMETRIC_MINISBLACK
;
int
x
,
y
,
i
;
uint16
bpp
=
8
,
ncn
=
isGrayScale
?
1
:
3
;
int
is_tiled
=
TIFFIsTiled
(
tif
);
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
&
bpp
));
uint16
photometric
;
CV_TIFF_CHECK_CALL_DEBUG
(
TIFFGetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
&
ncn
));
TIFFGetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
&
photometric
);
uint16
bpp
=
8
,
ncn
=
photometric
>
1
?
3
:
1
;
TIFFGetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
&
bpp
);
TIFFGetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
&
ncn
);
uint16
img_orientation
=
ORIENTATION_TOPLEFT
;
uint16
img_orientation
=
ORIENTATION_TOPLEFT
;
TIFFGetField
(
tif
,
TIFFTAG_ORIENTATION
,
&
img_orientation
);
CV_TIFF_CHECK_CALL_DEBUG
(
TIFFGetField
(
tif
,
TIFFTAG_ORIENTATION
,
&
img_orientation
)
);
bool
vert_flip
=
(
img_orientation
==
ORIENTATION_BOTRIGHT
)
||
(
img_orientation
==
ORIENTATION_RIGHTBOT
)
||
bool
vert_flip
=
(
img_orientation
==
ORIENTATION_BOTRIGHT
)
||
(
img_orientation
==
ORIENTATION_RIGHTBOT
)
||
(
img_orientation
==
ORIENTATION_BOTLEFT
)
||
(
img_orientation
==
ORIENTATION_LEFTBOT
);
(
img_orientation
==
ORIENTATION_BOTLEFT
)
||
(
img_orientation
==
ORIENTATION_LEFTBOT
);
const
int
bitsPerByte
=
8
;
const
int
bitsPerByte
=
8
;
int
dst_bpp
=
(
int
)(
img
.
elemSize1
()
*
bitsPerByte
);
int
dst_bpp
=
(
int
)(
img
.
elemSize1
()
*
bitsPerByte
);
int
wanted_channels
=
normalizeChannelsNumber
(
img
.
channels
());
int
wanted_channels
=
normalizeChannelsNumber
(
img
.
channels
());
if
(
dst_bpp
==
8
)
if
(
dst_bpp
==
8
)
{
{
char
errmsg
[
1024
];
char
errmsg
[
1024
];
if
(
!
TIFFRGBAImageOK
(
tif
,
errmsg
))
if
(
!
TIFFRGBAImageOK
(
tif
,
errmsg
))
{
{
CV_LOG_WARNING
(
NULL
,
"OpenCV TIFF: TIFFRGBAImageOK: "
<<
errmsg
);
close
();
close
();
return
false
;
return
false
;
}
}
}
}
if
(
(
!
is_tiled
)
||
uint32
tile_width0
=
m_width
,
tile_height0
=
0
;
(
is_tiled
&&
TIFFGetField
(
tif
,
TIFFTAG_TILEWIDTH
,
&
tile_width0
)
&&
if
(
is_tiled
)
TIFFGetField
(
tif
,
TIFFTAG_TILELENGTH
,
&
tile_height0
)))
{
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_TILEWIDTH
,
&
tile_width0
));
CV_TIFF_CHECK_CALL
(
TIFFGetField
(
tif
,
TIFFTAG_TILELENGTH
,
&
tile_height0
));
}
else
{
{
if
(
!
is_tiled
)
// optional
TIFFGetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
&
tile_height0
);
CV_TIFF_CHECK_CALL_DEBUG
(
TIFFGetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
&
tile_height0
));
}
if
(
tile_width0
<=
0
)
{
if
(
tile_width0
==
0
)
tile_width0
=
m_width
;
tile_width0
=
m_width
;
if
(
tile_height0
<
=
0
||
if
(
tile_height0
=
=
0
||
(
!
is_tiled
&&
tile_height0
==
std
::
numeric_limits
<
uint32
>::
max
())
)
(
!
is_tiled
&&
tile_height0
==
std
::
numeric_limits
<
uint32
>::
max
())
)
tile_height0
=
m_height
;
tile_height0
=
m_height
;
if
(
dst_bpp
==
8
)
{
if
(
dst_bpp
==
8
)
{
// we will use TIFFReadRGBA* functions, so allocate temporary buffer for 32bit RGBA
// we will use TIFFReadRGBA* functions, so allocate temporary buffer for 32bit RGBA
bpp
=
8
;
bpp
=
8
;
ncn
=
4
;
ncn
=
4
;
}
}
const
size_t
buffer_size
=
(
bpp
/
bitsPerByte
)
*
ncn
*
tile_height0
*
tile_width0
;
else
if
(
dst_bpp
==
32
||
dst_bpp
==
64
)
AutoBuffer
<
uchar
>
_buffer
(
buffer_size
);
{
CV_Assert
(
ncn
==
img
.
channels
());
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SAMPLEFORMAT
,
SAMPLEFORMAT_IEEEFP
));
}
const
size_t
buffer_size
=
(
bpp
/
bitsPerByte
)
*
ncn
*
tile_height0
*
tile_width0
;
AutoBuffer
<
uchar
>
_buffer
(
buffer_size
);
uchar
*
buffer
=
_buffer
.
data
();
uchar
*
buffer
=
_buffer
.
data
();
ushort
*
buffer16
=
(
ushort
*
)
buffer
;
ushort
*
buffer16
=
(
ushort
*
)
buffer
;
float
*
buffer32
=
(
float
*
)
buffer
;
double
*
buffer64
=
(
double
*
)
buffer
;
int
tileidx
=
0
;
int
tileidx
=
0
;
for
(
y
=
0
;
y
<
m_height
;
y
+=
tile_height0
)
for
(
int
y
=
0
;
y
<
m_height
;
y
+=
(
int
)
tile_height0
)
{
{
int
tile_height
=
tile_height0
;
int
tile_height
=
std
::
min
((
int
)
tile_height0
,
m_height
-
y
);
if
(
y
+
tile_height
>
m_height
)
tile_height
=
m_height
-
y
;
uchar
*
data
=
img
.
ptr
(
vert_flip
?
m_height
-
y
-
tile_height
:
y
)
;
const
int
img_y
=
vert_flip
?
m_height
-
y
-
tile_height
:
y
;
for
(
x
=
0
;
x
<
m_width
;
x
+=
tile_width0
,
tileidx
++
)
for
(
int
x
=
0
;
x
<
m_width
;
x
+=
(
int
)
tile_width0
,
tileidx
++
)
{
{
int
tile_width
=
tile_width0
,
ok
;
int
tile_width
=
std
::
min
((
int
)
tile_width0
,
m_width
-
x
)
;
if
(
x
+
tile_width
>
m_width
)
switch
(
dst_bpp
)
tile_width
=
m_width
-
x
;
switch
(
dst_bpp
)
{
{
case
8
:
case
8
:
{
{
uchar
*
bstart
=
buffer
;
uchar
*
bstart
=
buffer
;
if
(
!
is_tiled
)
if
(
!
is_tiled
)
ok
=
TIFFReadRGBAStrip
(
tif
,
y
,
(
uint32
*
)
buffer
);
else
{
{
ok
=
TIFFReadRGBATile
(
tif
,
x
,
y
,
(
uint32
*
)
buffer
);
CV_TIFF_CHECK_CALL
(
TIFFReadRGBAStrip
(
tif
,
y
,
(
uint32
*
)
buffer
));
//Tiles fill the buffer from the bottom up
bstart
+=
(
tile_height0
-
tile_height
)
*
tile_width0
*
4
;
}
}
if
(
!
ok
)
else
{
{
close
();
CV_TIFF_CHECK_CALL
(
TIFFReadRGBATile
(
tif
,
x
,
y
,
(
uint32
*
)
buffer
));
return
false
;
// Tiles fill the buffer from the bottom up
bstart
+=
(
tile_height0
-
tile_height
)
*
tile_width0
*
4
;
}
}
for
(
i
=
0
;
i
<
tile_height
;
i
++
)
for
(
int
i
=
0
;
i
<
tile_height
;
i
++
)
if
(
color
)
{
if
(
color
)
{
{
if
(
wanted_channels
==
4
)
if
(
wanted_channels
==
4
)
{
{
icvCvt_BGRA2RGBA_8u_C4R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
icvCvt_BGRA2RGBA_8u_C4R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
data
+
x
*
4
+
img
.
step
*
(
tile_height
-
i
-
1
),
0
,
img
.
ptr
(
img_y
+
tile_height
-
i
-
1
,
x
),
0
,
cvSize
(
tile_width
,
1
)
);
Size
(
tile_width
,
1
)
);
}
}
else
else
{
{
icvCvt_BGRA2BGR_8u_C4C3R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
icvCvt_BGRA2BGR_8u_C4C3R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
data
+
x
*
3
+
img
.
step
*
(
tile_height
-
i
-
1
),
0
,
img
.
ptr
(
img_y
+
tile_height
-
i
-
1
,
x
),
0
,
cvSize
(
tile_width
,
1
),
2
);
Size
(
tile_width
,
1
),
2
);
}
}
}
}
else
else
{
icvCvt_BGRA2Gray_8u_C4C1R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
icvCvt_BGRA2Gray_8u_C4C1R
(
bstart
+
i
*
tile_width0
*
4
,
0
,
data
+
x
+
img
.
step
*
(
tile_height
-
i
-
1
),
0
,
img
.
ptr
(
img_y
+
tile_height
-
i
-
1
,
x
),
0
,
cvSize
(
tile_width
,
1
),
2
);
Size
(
tile_width
,
1
),
2
);
}
}
break
;
break
;
}
}
case
16
:
case
16
:
{
{
if
(
!
is_tiled
)
if
(
!
is_tiled
)
ok
=
(
int
)
TIFFReadEncodedStrip
(
tif
,
tileidx
,
(
uint32
*
)
buffer
,
buffer_size
)
>=
0
;
{
CV_TIFF_CHECK_CALL
((
int
)
TIFFReadEncodedStrip
(
tif
,
tileidx
,
(
uint32
*
)
buffer
,
buffer_size
)
>=
0
);
}
else
else
ok
=
(
int
)
TIFFReadEncodedTile
(
tif
,
tileidx
,
(
uint32
*
)
buffer
,
buffer_size
)
>=
0
;
if
(
!
ok
)
{
{
close
();
CV_TIFF_CHECK_CALL
((
int
)
TIFFReadEncodedTile
(
tif
,
tileidx
,
(
uint32
*
)
buffer
,
buffer_size
)
>=
0
);
return
false
;
}
}
for
(
i
=
0
;
i
<
tile_height
;
i
++
)
for
(
int
i
=
0
;
i
<
tile_height
;
i
++
)
{
{
if
(
color
)
if
(
color
)
{
{
if
(
ncn
==
1
)
if
(
ncn
==
1
)
{
{
icvCvt_Gray2BGR_16u_C1C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_Gray2BGR_16u_C1C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
*
3
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cvSize
(
tile_width
,
1
)
);
Size
(
tile_width
,
1
)
);
}
}
else
if
(
ncn
==
3
)
else
if
(
ncn
==
3
)
{
{
icvCvt_RGB2BGR_16u_C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_RGB2BGR_16u_C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
*
3
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cvSize
(
tile_width
,
1
)
);
Size
(
tile_width
,
1
)
);
}
}
else
if
(
ncn
==
4
)
else
if
(
ncn
==
4
)
{
{
if
(
wanted_channels
==
4
)
if
(
wanted_channels
==
4
)
{
{
icvCvt_BGRA2RGBA_16u_C4R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_BGRA2RGBA_16u_C4R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
*
4
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cv
Size
(
tile_width
,
1
));
Size
(
tile_width
,
1
));
}
}
else
else
{
{
icvCvt_BGRA2BGR_16u_C4C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_BGRA2BGR_16u_C4C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
*
3
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cv
Size
(
tile_width
,
1
),
2
);
Size
(
tile_width
,
1
),
2
);
}
}
}
}
else
else
{
{
icvCvt_BGRA2BGR_16u_C4C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_BGRA2BGR_16u_C4C3R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
*
3
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cvSize
(
tile_width
,
1
),
2
);
Size
(
tile_width
,
1
),
2
);
}
}
}
}
else
else
{
{
if
(
ncn
==
1
)
if
(
ncn
==
1
)
{
{
memcpy
(
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
,
memcpy
(
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
buffer16
+
i
*
tile_width0
*
ncn
,
buffer16
+
i
*
tile_width0
*
ncn
,
tile_width
*
sizeof
(
buffer16
[
0
]
));
tile_width
*
sizeof
(
ushort
));
}
}
else
else
{
{
icvCvt_BGRA2Gray_16u_CnC1R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
icvCvt_BGRA2Gray_16u_CnC1R
(
buffer16
+
i
*
tile_width0
*
ncn
,
0
,
(
ushort
*
)(
data
+
img
.
step
*
i
)
+
x
,
0
,
img
.
ptr
<
ushort
>
(
img_y
+
i
,
x
)
,
0
,
cvSize
(
tile_width
,
1
),
ncn
,
2
);
Size
(
tile_width
,
1
),
ncn
,
2
);
}
}
}
}
}
}
...
@@ -500,120 +543,43 @@ bool TiffDecoder::readData( Mat& img )
...
@@ -500,120 +543,43 @@ bool TiffDecoder::readData( Mat& img )
case
64
:
case
64
:
{
{
if
(
!
is_tiled
)
if
(
!
is_tiled
)
ok
=
(
int
)
TIFFReadEncodedStrip
(
tif
,
tileidx
,
buffer
,
buffer_size
)
>=
0
;
else
ok
=
(
int
)
TIFFReadEncodedTile
(
tif
,
tileidx
,
buffer
,
buffer_size
)
>=
0
;
if
(
!
ok
||
ncn
!=
1
)
{
{
close
();
CV_TIFF_CHECK_CALL
((
int
)
TIFFReadEncodedStrip
(
tif
,
tileidx
,
buffer
,
buffer_size
)
>=
0
);
return
false
;
}
}
else
for
(
i
=
0
;
i
<
tile_height
;
i
++
)
{
{
if
(
dst_bpp
==
32
)
CV_TIFF_CHECK_CALL
((
int
)
TIFFReadEncodedTile
(
tif
,
tileidx
,
buffer
,
buffer_size
)
>=
0
);
{
memcpy
((
float
*
)(
data
+
img
.
step
*
i
)
+
x
,
buffer32
+
i
*
tile_width0
*
ncn
,
tile_width
*
sizeof
(
buffer32
[
0
]));
}
else
{
memcpy
((
double
*
)(
data
+
img
.
step
*
i
)
+
x
,
buffer64
+
i
*
tile_width0
*
ncn
,
tile_width
*
sizeof
(
buffer64
[
0
]));
}
}
}
Mat
m_tile
(
Size
(
tile_width0
,
tile_height0
),
CV_MAKETYPE
((
dst_bpp
==
32
)
?
CV_32F
:
CV_64F
,
ncn
),
buffer
);
Rect
roi_tile
(
0
,
0
,
tile_width
,
tile_height
);
Rect
roi_img
(
x
,
img_y
,
tile_width
,
tile_height
);
if
(
!
m_hdr
&&
ncn
==
3
)
cvtColor
(
m_tile
(
roi_tile
),
img
(
roi_img
),
COLOR_RGB2BGR
);
else
if
(
!
m_hdr
&&
ncn
==
4
)
cvtColor
(
m_tile
(
roi_tile
),
img
(
roi_img
),
COLOR_RGBA2BGRA
);
else
m_tile
(
roi_tile
).
copyTo
(
img
(
roi_img
));
break
;
break
;
}
}
default
:
default
:
{
{
close
();
CV_Assert
(
0
&&
"OpenCV TIFF: unsupported depth"
);
return
false
;
}
}
}
}
// switch (dst_bpp)
}
}
// for x
}
}
// for y
result
=
true
;
}
}
}
}
return
result
;
if
(
m_hdr
&&
depth
>=
CV_32F
)
}
bool
TiffDecoder
::
readData_32FC3
(
Mat
&
img
)
{
int
rows_per_strip
=
0
,
photometric
=
0
;
if
(
!
m_tif
)
{
return
false
;
}
TIFF
*
tif
=
static_cast
<
TIFF
*>
(
m_tif
);
TIFFGetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
&
rows_per_strip
);
TIFFGetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
&
photometric
);
TIFFSetField
(
tif
,
TIFFTAG_SGILOGDATAFMT
,
SGILOGDATAFMT_FLOAT
);
int
size
=
3
*
m_width
*
m_height
*
sizeof
(
float
);
tstrip_t
strip_size
=
3
*
m_width
*
rows_per_strip
;
float
*
ptr
=
img
.
ptr
<
float
>
();
for
(
tstrip_t
i
=
0
;
i
<
TIFFNumberOfStrips
(
tif
);
i
++
,
ptr
+=
strip_size
)
{
TIFFReadEncodedStrip
(
tif
,
i
,
ptr
,
size
);
size
-=
strip_size
*
sizeof
(
float
);
}
close
();
if
(
photometric
==
PHOTOMETRIC_LOGLUV
)
{
{
CV_Assert
(
photometric
==
PHOTOMETRIC_LOGLUV
);
cvtColor
(
img
,
img
,
COLOR_XYZ2BGR
);
cvtColor
(
img
,
img
,
COLOR_XYZ2BGR
);
}
}
else
{
cvtColor
(
img
,
img
,
COLOR_RGB2BGR
);
}
return
true
;
return
true
;
}
}
bool
TiffDecoder
::
readData_32FC1
(
Mat
&
img
)
{
if
(
!
m_tif
)
{
return
false
;
}
TIFF
*
tif
=
static_cast
<
TIFF
*>
(
m_tif
);
uint32
img_width
,
img_height
;
TIFFGetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
&
img_width
);
TIFFGetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
&
img_height
);
if
(
img
.
size
()
!=
Size
(
img_width
,
img_height
))
{
close
();
return
false
;
}
tsize_t
scanlength
=
TIFFScanlineSize
(
tif
);
tdata_t
buf
=
_TIFFmalloc
(
scanlength
);
float
*
data
;
bool
result
=
true
;
for
(
uint32
row
=
0
;
row
<
img_height
;
row
++
)
{
if
(
TIFFReadScanline
(
tif
,
buf
,
row
)
!=
1
)
{
result
=
false
;
break
;
}
data
=
(
float
*
)
buf
;
for
(
uint32
i
=
0
;
i
<
img_width
;
i
++
)
{
img
.
at
<
float
>
(
row
,
i
)
=
data
[
i
];
}
}
_TIFFfree
(
buf
);
close
();
return
result
;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
TiffEncoder
::
TiffEncoder
()
TiffEncoder
::
TiffEncoder
()
...
@@ -633,7 +599,7 @@ ImageEncoder TiffEncoder::newEncoder() const
...
@@ -633,7 +599,7 @@ ImageEncoder TiffEncoder::newEncoder() const
bool
TiffEncoder
::
isFormatSupported
(
int
depth
)
const
bool
TiffEncoder
::
isFormatSupported
(
int
depth
)
const
{
{
return
depth
==
CV_8U
||
depth
==
CV_16U
||
depth
==
CV_32F
;
return
depth
==
CV_8U
||
depth
==
CV_16U
||
depth
==
CV_32F
||
depth
==
CV_64F
;
}
}
void
TiffEncoder
::
writeTag
(
WLByteStream
&
strm
,
TiffTag
tag
,
void
TiffEncoder
::
writeTag
(
WLByteStream
&
strm
,
TiffTag
tag
,
...
@@ -656,6 +622,8 @@ public:
...
@@ -656,6 +622,8 @@ public:
TIFF
*
open
()
TIFF
*
open
()
{
{
// do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
return
TIFFClientOpen
(
""
,
"w"
,
reinterpret_cast
<
thandle_t
>
(
this
),
&
TiffEncoderBufHelper
::
read
,
return
TIFFClientOpen
(
""
,
"w"
,
reinterpret_cast
<
thandle_t
>
(
this
),
&
TiffEncoderBufHelper
::
read
,
&
TiffEncoderBufHelper
::
write
,
&
TiffEncoderBufHelper
::
seek
,
&
TiffEncoderBufHelper
::
write
,
&
TiffEncoderBufHelper
::
seek
,
&
TiffEncoderBufHelper
::
close
,
&
TiffEncoderBufHelper
::
size
,
&
TiffEncoderBufHelper
::
close
,
&
TiffEncoderBufHelper
::
size
,
...
@@ -721,35 +689,39 @@ private:
...
@@ -721,35 +689,39 @@ private:
toff_t
m_buf_pos
;
toff_t
m_buf_pos
;
};
};
static
void
readParam
(
const
std
::
vector
<
int
>&
params
,
int
key
,
int
&
value
)
static
bool
readParam
(
const
std
::
vector
<
int
>&
params
,
int
key
,
int
&
value
)
{
{
for
(
size_t
i
=
0
;
i
+
1
<
params
.
size
();
i
+=
2
)
for
(
size_t
i
=
0
;
i
+
1
<
params
.
size
();
i
+=
2
)
if
(
params
[
i
]
==
key
)
{
if
(
params
[
i
]
==
key
)
{
{
value
=
params
[
i
+
1
];
value
=
params
[
i
+
1
];
break
;
return
true
;
}
}
}
return
false
;
}
}
bool
TiffEncoder
::
writeLibTiff
(
const
std
::
vector
<
Mat
>&
img_vec
,
const
std
::
vector
<
int
>&
params
)
bool
TiffEncoder
::
writeLibTiff
(
const
std
::
vector
<
Mat
>&
img_vec
,
const
std
::
vector
<
int
>&
params
)
{
{
// do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
// do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
TIFF
*
pTiffHandle
;
TIFF
*
tif
=
NULL
;
TiffEncoderBufHelper
buf_helper
(
m_buf
);
TiffEncoderBufHelper
buf_helper
(
m_buf
);
if
(
m_buf
)
if
(
m_buf
)
{
{
pTiffHandle
=
buf_helper
.
open
();
tif
=
buf_helper
.
open
();
}
}
else
else
{
{
pTiffHandle
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
}
}
if
(
!
pTiffHandle
)
if
(
!
tif
)
{
{
return
false
;
return
false
;
}
}
cv
::
Ptr
<
void
>
tif_cleanup
(
tif
,
cv_tiffCloseHandle
);
//Settings that matter to all images
//Settings that matter to all images
int
compression
=
COMPRESSION_LZW
;
int
compression
=
COMPRESSION_LZW
;
...
@@ -768,7 +740,29 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
...
@@ -768,7 +740,29 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
const
Mat
&
img
=
img_vec
[
page
];
const
Mat
&
img
=
img_vec
[
page
];
int
channels
=
img
.
channels
();
int
channels
=
img
.
channels
();
int
width
=
img
.
cols
,
height
=
img
.
rows
;
int
width
=
img
.
cols
,
height
=
img
.
rows
;
int
depth
=
img
.
depth
();
int
type
=
img
.
type
();
int
depth
=
CV_MAT_DEPTH
(
type
);
CV_CheckType
(
type
,
depth
==
CV_8U
||
depth
==
CV_16U
||
depth
==
CV_32F
||
depth
==
CV_64F
,
""
);
CV_CheckType
(
type
,
channels
>=
1
&&
channels
<=
4
,
""
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
width
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
height
));
if
(
img_vec
.
size
()
>
1
)
{
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SUBFILETYPE
,
FILETYPE_PAGE
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PAGENUMBER
,
page
,
img_vec
.
size
()));
}
int
compression_param
=
-
1
;
// OPENCV_FUTURE
if
(
type
==
CV_32FC3
&&
(
!
readParam
(
params
,
IMWRITE_TIFF_COMPRESSION
,
compression_param
)
||
compression_param
==
COMPRESSION_SGILOG
))
{
if
(
!
write_32FC3_SGILOG
(
img
,
tif
))
return
false
;
continue
;
}
int
page_compression
=
compression
;
int
bitsPerChannel
=
-
1
;
int
bitsPerChannel
=
-
1
;
switch
(
depth
)
switch
(
depth
)
...
@@ -783,9 +777,20 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
...
@@ -783,9 +777,20 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
bitsPerChannel
=
16
;
bitsPerChannel
=
16
;
break
;
break
;
}
}
case
CV_32F
:
{
bitsPerChannel
=
32
;
page_compression
=
COMPRESSION_NONE
;
break
;
}
case
CV_64F
:
{
bitsPerChannel
=
64
;
page_compression
=
COMPRESSION_NONE
;
break
;
}
default
:
default
:
{
{
TIFFClose
(
pTiffHandle
);
return
false
;
return
false
;
}
}
}
}
...
@@ -795,57 +800,42 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
...
@@ -795,57 +800,42 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
int
rowsPerStrip
=
(
int
)((
1
<<
13
)
/
fileStep
);
int
rowsPerStrip
=
(
int
)((
1
<<
13
)
/
fileStep
);
readParam
(
params
,
TIFFTAG_ROWSPERSTRIP
,
rowsPerStrip
);
readParam
(
params
,
TIFFTAG_ROWSPERSTRIP
,
rowsPerStrip
);
rowsPerStrip
=
std
::
max
(
1
,
std
::
min
(
height
,
rowsPerStrip
));
int
colorspace
=
channels
>
1
?
PHOTOMETRIC_RGB
:
PHOTOMETRIC_MINISBLACK
;
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
bitsPerChannel
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_COMPRESSION
,
page_compression
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
colorspace
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
channels
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PLANARCONFIG
,
PLANARCONFIG_CONTIG
));
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
rowsPerStrip
));
if
(
rowsPerStrip
<
1
)
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SAMPLEFORMAT
,
depth
>=
CV_32F
?
SAMPLEFORMAT_IEEEFP
:
SAMPLEFORMAT_UINT
));
rowsPerStrip
=
1
;
if
(
page_compression
!=
COMPRESSION_NONE
)
if
(
rowsPerStrip
>
height
)
rowsPerStrip
=
height
;
int
colorspace
=
channels
>
1
?
PHOTOMETRIC_RGB
:
PHOTOMETRIC_MINISBLACK
;
if
(
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_IMAGEWIDTH
,
width
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_IMAGELENGTH
,
height
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_BITSPERSAMPLE
,
bitsPerChannel
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_COMPRESSION
,
compression
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_PHOTOMETRIC
,
colorspace
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_SAMPLESPERPIXEL
,
channels
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_PLANARCONFIG
,
PLANARCONFIG_CONTIG
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_ROWSPERSTRIP
,
rowsPerStrip
)
||
(
img_vec
.
size
()
>
1
&&
(
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_SUBFILETYPE
,
FILETYPE_PAGE
)
||
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_PAGENUMBER
,
page
,
img_vec
.
size
()
)))
)
{
{
TIFFClose
(
pTiffHandle
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PREDICTOR
,
predictor
));
return
false
;
}
}
if
(
compression
!=
COMPRESSION_NONE
&&
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_PREDICTOR
,
predictor
)
)
if
(
resUnit
>=
RESUNIT_NONE
&&
resUnit
<=
RESUNIT_CENTIMETER
)
{
{
TIFFClose
(
pTiffHandle
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_RESOLUTIONUNIT
,
resUnit
));
return
false
;
}
}
if
(
dpiX
>=
0
)
if
(((
resUnit
>=
RESUNIT_NONE
&&
resUnit
<=
RESUNIT_CENTIMETER
)
&&
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_RESOLUTIONUNIT
,
resUnit
))
||
(
dpiX
>=
0
&&
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_XRESOLUTION
,
(
float
)
dpiX
))
||
(
dpiY
>=
0
&&
!
TIFFSetField
(
pTiffHandle
,
TIFFTAG_YRESOLUTION
,
(
float
)
dpiY
))
)
{
{
TIFFClose
(
pTiffHandle
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_XRESOLUTION
,
(
float
)
dpiX
));
return
false
;
}
if
(
dpiY
>=
0
)
{
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_YRESOLUTION
,
(
float
)
dpiY
));
}
}
// row buffer, because TIFFWriteScanline modifies the original data!
// row buffer, because TIFFWriteScanline modifies the original data!
size_t
scanlineSize
=
TIFFScanlineSize
(
pTiffHandle
);
size_t
scanlineSize
=
TIFFScanlineSize
(
tif
);
AutoBuffer
<
uchar
>
_buffer
(
scanlineSize
+
32
);
AutoBuffer
<
uchar
>
_buffer
(
scanlineSize
+
32
);
uchar
*
buffer
=
_buffer
.
data
();
uchar
*
buffer
=
_buffer
.
data
();
CV_DbgAssert
(
buffer
);
if
(
!
buffer
)
Mat
m_buffer
(
Size
(
width
,
1
),
CV_MAKETYPE
(
depth
,
channels
),
buffer
,
(
size_t
)
scanlineSize
);
{
TIFFClose
(
pTiffHandle
);
return
false
;
}
for
(
int
y
=
0
;
y
<
height
;
++
y
)
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
{
...
@@ -859,122 +849,54 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
...
@@ -859,122 +849,54 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
case
3
:
case
3
:
{
{
if
(
depth
==
CV_8U
)
cvtColor
(
img
(
Rect
(
0
,
y
,
width
,
1
)),
(
const
Mat
&
)
m_buffer
,
COLOR_BGR2RGB
);
icvCvt_BGR2RGB_8u_C3R
(
img
.
ptr
(
y
),
0
,
buffer
,
0
,
cvSize
(
width
,
1
));
else
icvCvt_BGR2RGB_16u_C3R
(
img
.
ptr
<
ushort
>
(
y
),
0
,
(
ushort
*
)
buffer
,
0
,
cvSize
(
width
,
1
));
break
;
break
;
}
}
case
4
:
case
4
:
{
{
if
(
depth
==
CV_8U
)
cvtColor
(
img
(
Rect
(
0
,
y
,
width
,
1
)),
(
const
Mat
&
)
m_buffer
,
COLOR_BGRA2RGBA
);
icvCvt_BGRA2RGBA_8u_C4R
(
img
.
ptr
(
y
),
0
,
buffer
,
0
,
cvSize
(
width
,
1
));
else
icvCvt_BGRA2RGBA_16u_C4R
(
img
.
ptr
<
ushort
>
(
y
),
0
,
(
ushort
*
)
buffer
,
0
,
cvSize
(
width
,
1
));
break
;
break
;
}
}
default
:
default
:
{
{
TIFFClose
(
pTiffHandle
);
CV_Assert
(
0
);
return
false
;
}
}
}
}
int
writeResult
=
TIFFWriteScanline
(
pTiffHandle
,
buffer
,
y
,
0
);
CV_TIFF_CHECK_CALL
(
TIFFWriteScanline
(
tif
,
buffer
,
y
,
0
)
==
1
);
if
(
writeResult
!=
1
)
{
TIFFClose
(
pTiffHandle
);
return
false
;
}
}
}
TIFFWriteDirectory
(
pTiffHandle
);
CV_TIFF_CHECK_CALL
(
TIFFWriteDirectory
(
tif
));
}
}
TIFFClose
(
pTiffHandle
);
return
true
;
return
true
;
}
}
bool
TiffEncoder
::
write_32FC3
(
const
Mat
&
_img
)
bool
TiffEncoder
::
write_32FC3
_SGILOG
(
const
Mat
&
_img
,
void
*
tif_
)
{
{
TIFF
*
tif
=
(
TIFF
*
)
tif_
;
CV_Assert
(
tif
);
Mat
img
;
Mat
img
;
cvtColor
(
_img
,
img
,
COLOR_BGR2XYZ
);
cvtColor
(
_img
,
img
,
COLOR_BGR2XYZ
);
TIFF
*
tif
;
//done by caller: CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.cols));
//done by caller: CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.rows));
TiffEncoderBufHelper
buf_helper
(
m_buf
);
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
3
));
if
(
m_buf
)
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
32
));
{
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_COMPRESSION
,
COMPRESSION_SGILOG
));
tif
=
buf_helper
.
open
();
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
PHOTOMETRIC_LOGLUV
));
}
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_PLANARCONFIG
,
PLANARCONFIG_CONTIG
));
else
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_SGILOGDATAFMT
,
SGILOGDATAFMT_FLOAT
));
{
CV_TIFF_CHECK_CALL
(
TIFFSetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
1
));
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
const
int
strip_size
=
3
*
img
.
cols
;
}
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
)
{
if
(
!
tif
)
CV_TIFF_CHECK_CALL
(
TIFFWriteEncodedStrip
(
tif
,
i
,
(
tdata_t
)
img
.
ptr
<
float
>
(
i
),
strip_size
*
sizeof
(
float
))
!=
(
tsize_t
)
-
1
);
{
}
return
false
;
CV_TIFF_CHECK_CALL
(
TIFFWriteDirectory
(
tif
));
}
TIFFSetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
img
.
cols
);
TIFFSetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
img
.
rows
);
TIFFSetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
3
);
TIFFSetField
(
tif
,
TIFFTAG_COMPRESSION
,
COMPRESSION_SGILOG
);
TIFFSetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
PHOTOMETRIC_LOGLUV
);
TIFFSetField
(
tif
,
TIFFTAG_PLANARCONFIG
,
PLANARCONFIG_CONTIG
);
TIFFSetField
(
tif
,
TIFFTAG_SGILOGDATAFMT
,
SGILOGDATAFMT_FLOAT
);
TIFFSetField
(
tif
,
TIFFTAG_ROWSPERSTRIP
,
1
);
int
strip_size
=
3
*
img
.
cols
;
float
*
ptr
=
const_cast
<
float
*>
(
img
.
ptr
<
float
>
());
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
,
ptr
+=
strip_size
)
{
TIFFWriteEncodedStrip
(
tif
,
i
,
ptr
,
strip_size
*
sizeof
(
float
));
}
TIFFClose
(
tif
);
return
true
;
}
bool
TiffEncoder
::
write_32FC1
(
const
Mat
&
_img
)
{
TIFF
*
tif
;
TiffEncoderBufHelper
buf_helper
(
m_buf
);
if
(
m_buf
)
{
tif
=
buf_helper
.
open
();
}
else
{
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
}
if
(
!
tif
)
{
return
false
;
}
TIFFSetField
(
tif
,
TIFFTAG_IMAGEWIDTH
,
_img
.
cols
);
TIFFSetField
(
tif
,
TIFFTAG_IMAGELENGTH
,
_img
.
rows
);
TIFFSetField
(
tif
,
TIFFTAG_SAMPLESPERPIXEL
,
1
);
TIFFSetField
(
tif
,
TIFFTAG_BITSPERSAMPLE
,
32
);
TIFFSetField
(
tif
,
TIFFTAG_PHOTOMETRIC
,
PHOTOMETRIC_MINISBLACK
);
TIFFSetField
(
tif
,
TIFFTAG_SAMPLEFORMAT
,
SAMPLEFORMAT_IEEEFP
);
TIFFSetField
(
tif
,
TIFFTAG_COMPRESSION
,
COMPRESSION_NONE
);
for
(
uint32
row
=
0
;
row
<
(
uint32
)
_img
.
rows
;
row
++
)
{
if
(
TIFFWriteScanline
(
tif
,
(
tdata_t
)
_img
.
ptr
<
float
>
(
row
),
row
,
1
)
!=
1
)
{
TIFFClose
(
tif
);
return
false
;
}
}
TIFFWriteDirectory
(
tif
);
TIFFClose
(
tif
);
return
true
;
return
true
;
}
}
...
@@ -985,18 +907,10 @@ bool TiffEncoder::writemulti(const std::vector<Mat>& img_vec, const std::vector<
...
@@ -985,18 +907,10 @@ bool TiffEncoder::writemulti(const std::vector<Mat>& img_vec, const std::vector<
bool
TiffEncoder
::
write
(
const
Mat
&
img
,
const
std
::
vector
<
int
>&
params
)
bool
TiffEncoder
::
write
(
const
Mat
&
img
,
const
std
::
vector
<
int
>&
params
)
{
{
int
depth
=
img
.
depth
();
int
type
=
img
.
type
();
int
depth
=
CV_MAT_DEPTH
(
type
);
if
(
img
.
type
()
==
CV_32FC3
)
{
return
write_32FC3
(
img
);
}
if
(
img
.
type
()
==
CV_32FC1
)
{
return
write_32FC1
(
img
);
}
CV_
Assert
(
depth
==
CV_8U
||
depth
==
CV_16U
);
CV_
CheckType
(
type
,
depth
==
CV_8U
||
depth
==
CV_16U
||
depth
==
CV_32F
||
depth
==
CV_64F
,
""
);
std
::
vector
<
Mat
>
img_vec
;
std
::
vector
<
Mat
>
img_vec
;
img_vec
.
push_back
(
img
);
img_vec
.
push_back
(
img
);
...
...
modules/imgcodecs/src/grfmt_tiff.hpp
View file @
1fb93b62
...
@@ -106,10 +106,8 @@ public:
...
@@ -106,10 +106,8 @@ public:
ImageDecoder
newDecoder
()
const
CV_OVERRIDE
;
ImageDecoder
newDecoder
()
const
CV_OVERRIDE
;
protected
:
protected
:
void
*
m_tif
;
cv
::
Ptr
<
void
>
m_tif
;
int
normalizeChannelsNumber
(
int
channels
)
const
;
int
normalizeChannelsNumber
(
int
channels
)
const
;
bool
readData_32FC3
(
Mat
&
img
);
bool
readData_32FC1
(
Mat
&
img
);
bool
m_hdr
;
bool
m_hdr
;
size_t
m_buf_pos
;
size_t
m_buf_pos
;
...
@@ -139,8 +137,7 @@ protected:
...
@@ -139,8 +137,7 @@ protected:
int
count
,
int
value
);
int
count
,
int
value
);
bool
writeLibTiff
(
const
std
::
vector
<
Mat
>&
img_vec
,
const
std
::
vector
<
int
>&
params
);
bool
writeLibTiff
(
const
std
::
vector
<
Mat
>&
img_vec
,
const
std
::
vector
<
int
>&
params
);
bool
write_32FC3
(
const
Mat
&
img
);
bool
write_32FC3_SGILOG
(
const
Mat
&
img
,
void
*
tif
);
bool
write_32FC1
(
const
Mat
&
img
);
private
:
private
:
TiffEncoder
(
const
TiffEncoder
&
);
// copy disabled
TiffEncoder
(
const
TiffEncoder
&
);
// copy disabled
...
...
modules/imgcodecs/src/utils.cpp
View file @
1fb93b62
...
@@ -42,6 +42,8 @@
...
@@ -42,6 +42,8 @@
#include "precomp.hpp"
#include "precomp.hpp"
#include "utils.hpp"
#include "utils.hpp"
namespace
cv
{
int
validateToInt
(
size_t
sz
)
int
validateToInt
(
size_t
sz
)
{
{
int
valueInt
=
(
int
)
sz
;
int
valueInt
=
(
int
)
sz
;
...
@@ -56,7 +58,7 @@ int validateToInt(size_t sz)
...
@@ -56,7 +58,7 @@ int validateToInt(size_t sz)
void
icvCvt_BGR2Gray_8u_C3C1R
(
const
uchar
*
rgb
,
int
rgb_step
,
void
icvCvt_BGR2Gray_8u_C3C1R
(
const
uchar
*
rgb
,
int
rgb_step
,
uchar
*
gray
,
int
gray_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
_swap_rb
)
Size
size
,
int
_swap_rb
)
{
{
int
i
;
int
i
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
...
@@ -75,7 +77,7 @@ void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step,
...
@@ -75,7 +77,7 @@ void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step,
void
icvCvt_BGRA2Gray_16u_CnC1R
(
const
ushort
*
rgb
,
int
rgb_step
,
void
icvCvt_BGRA2Gray_16u_CnC1R
(
const
ushort
*
rgb
,
int
rgb_step
,
ushort
*
gray
,
int
gray_step
,
ushort
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
ncn
,
int
_swap_rb
)
Size
size
,
int
ncn
,
int
_swap_rb
)
{
{
int
i
;
int
i
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
...
@@ -94,7 +96,7 @@ void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step,
...
@@ -94,7 +96,7 @@ void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step,
void
icvCvt_BGRA2Gray_8u_C4C1R
(
const
uchar
*
rgba
,
int
rgba_step
,
void
icvCvt_BGRA2Gray_8u_C4C1R
(
const
uchar
*
rgba
,
int
rgba_step
,
uchar
*
gray
,
int
gray_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
_swap_rb
)
Size
size
,
int
_swap_rb
)
{
{
int
i
;
int
i
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
...
@@ -112,7 +114,7 @@ void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step,
...
@@ -112,7 +114,7 @@ void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step,
void
icvCvt_Gray2BGR_8u_C1C3R
(
const
uchar
*
gray
,
int
gray_step
,
void
icvCvt_Gray2BGR_8u_C1C3R
(
const
uchar
*
gray
,
int
gray_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
)
uchar
*
bgr
,
int
bgr_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
gray
+=
gray_step
)
for
(
;
size
.
height
--
;
gray
+=
gray_step
)
...
@@ -127,7 +129,7 @@ void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
...
@@ -127,7 +129,7 @@ void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
void
icvCvt_Gray2BGR_16u_C1C3R
(
const
ushort
*
gray
,
int
gray_step
,
void
icvCvt_Gray2BGR_16u_C1C3R
(
const
ushort
*
gray
,
int
gray_step
,
ushort
*
bgr
,
int
bgr_step
,
Cv
Size
size
)
ushort
*
bgr
,
int
bgr_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
gray
+=
gray_step
/
sizeof
(
gray
[
0
])
)
for
(
;
size
.
height
--
;
gray
+=
gray_step
/
sizeof
(
gray
[
0
])
)
...
@@ -143,7 +145,7 @@ void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
...
@@ -143,7 +145,7 @@ void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
void
icvCvt_BGRA2BGR_8u_C4C3R
(
const
uchar
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2BGR_8u_C4C3R
(
const
uchar
*
bgra
,
int
bgra_step
,
uchar
*
bgr
,
int
bgr_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
,
int
_swap_rb
)
Size
size
,
int
_swap_rb
)
{
{
int
i
;
int
i
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
...
@@ -163,7 +165,7 @@ void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
...
@@ -163,7 +165,7 @@ void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
void
icvCvt_BGRA2BGR_16u_C4C3R
(
const
ushort
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2BGR_16u_C4C3R
(
const
ushort
*
bgra
,
int
bgra_step
,
ushort
*
bgr
,
int
bgr_step
,
ushort
*
bgr
,
int
bgr_step
,
Cv
Size
size
,
int
_swap_rb
)
Size
size
,
int
_swap_rb
)
{
{
int
i
;
int
i
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
int
swap_rb
=
_swap_rb
?
2
:
0
;
...
@@ -182,7 +184,7 @@ void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
...
@@ -182,7 +184,7 @@ void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
void
icvCvt_BGRA2RGBA_8u_C4R
(
const
uchar
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2RGBA_8u_C4R
(
const
uchar
*
bgra
,
int
bgra_step
,
uchar
*
rgba
,
int
rgba_step
,
Cv
Size
size
)
uchar
*
rgba
,
int
rgba_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -200,7 +202,7 @@ void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
...
@@ -200,7 +202,7 @@ void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
}
}
void
icvCvt_BGRA2RGBA_16u_C4R
(
const
ushort
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2RGBA_16u_C4R
(
const
ushort
*
bgra
,
int
bgra_step
,
ushort
*
rgba
,
int
rgba_step
,
Cv
Size
size
)
ushort
*
rgba
,
int
rgba_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -220,7 +222,7 @@ void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step,
...
@@ -220,7 +222,7 @@ void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step,
void
icvCvt_BGR2RGB_8u_C3R
(
const
uchar
*
bgr
,
int
bgr_step
,
void
icvCvt_BGR2RGB_8u_C3R
(
const
uchar
*
bgr
,
int
bgr_step
,
uchar
*
rgb
,
int
rgb_step
,
Cv
Size
size
)
uchar
*
rgb
,
int
rgb_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -237,7 +239,7 @@ void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
...
@@ -237,7 +239,7 @@ void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
void
icvCvt_BGR2RGB_16u_C3R
(
const
ushort
*
bgr
,
int
bgr_step
,
void
icvCvt_BGR2RGB_16u_C3R
(
const
ushort
*
bgr
,
int
bgr_step
,
ushort
*
rgb
,
int
rgb_step
,
Cv
Size
size
)
ushort
*
rgb
,
int
rgb_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -256,7 +258,7 @@ void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step,
...
@@ -256,7 +258,7 @@ void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step,
typedef
unsigned
short
ushort
;
typedef
unsigned
short
ushort
;
void
icvCvt_BGR5552Gray_8u_C2C1R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
void
icvCvt_BGR5552Gray_8u_C2C1R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
)
uchar
*
gray
,
int
gray_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
gray
+=
gray_step
,
bgr555
+=
bgr555_step
)
for
(
;
size
.
height
--
;
gray
+=
gray_step
,
bgr555
+=
bgr555_step
)
...
@@ -273,7 +275,7 @@ void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
...
@@ -273,7 +275,7 @@ void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
void
icvCvt_BGR5652Gray_8u_C2C1R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
void
icvCvt_BGR5652Gray_8u_C2C1R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
)
uchar
*
gray
,
int
gray_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
gray
+=
gray_step
,
bgr565
+=
bgr565_step
)
for
(
;
size
.
height
--
;
gray
+=
gray_step
,
bgr565
+=
bgr565_step
)
...
@@ -290,7 +292,7 @@ void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
...
@@ -290,7 +292,7 @@ void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
void
icvCvt_BGR5552BGR_8u_C2C3R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
void
icvCvt_BGR5552BGR_8u_C2C3R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
)
uchar
*
bgr
,
int
bgr_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
bgr555
+=
bgr555_step
)
for
(
;
size
.
height
--
;
bgr555
+=
bgr555_step
)
...
@@ -308,7 +310,7 @@ void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
...
@@ -308,7 +310,7 @@ void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
void
icvCvt_BGR5652BGR_8u_C2C3R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
void
icvCvt_BGR5652BGR_8u_C2C3R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
)
uchar
*
bgr
,
int
bgr_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
bgr565
+=
bgr565_step
)
for
(
;
size
.
height
--
;
bgr565
+=
bgr565_step
)
...
@@ -326,7 +328,7 @@ void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
...
@@ -326,7 +328,7 @@ void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
void
icvCvt_CMYK2BGR_8u_C4C3R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
void
icvCvt_CMYK2BGR_8u_C4C3R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
)
uchar
*
bgr
,
int
bgr_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -346,7 +348,7 @@ void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
...
@@ -346,7 +348,7 @@ void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
void
icvCvt_CMYK2Gray_8u_C4C1R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
void
icvCvt_CMYK2Gray_8u_C4C1R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
)
uchar
*
gray
,
int
gray_step
,
Size
size
)
{
{
int
i
;
int
i
;
for
(
;
size
.
height
--
;
)
for
(
;
size
.
height
--
;
)
...
@@ -371,7 +373,7 @@ void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entr
...
@@ -371,7 +373,7 @@ void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entr
int
i
;
int
i
;
for
(
i
=
0
;
i
<
entries
;
i
++
)
for
(
i
=
0
;
i
<
entries
;
i
++
)
{
{
icvCvt_BGR2Gray_8u_C3C1R
(
(
uchar
*
)(
palette
+
i
),
0
,
grayPalette
+
i
,
0
,
cv
Size
(
1
,
1
)
);
icvCvt_BGR2Gray_8u_C3C1R
(
(
uchar
*
)(
palette
+
i
),
0
,
grayPalette
+
i
,
0
,
Size
(
1
,
1
)
);
}
}
}
}
...
@@ -598,6 +600,9 @@ uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
...
@@ -598,6 +600,9 @@ uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
return
data
;
return
data
;
}
}
}
// namespace
using
namespace
cv
;
CV_IMPL
void
CV_IMPL
void
cvConvertImage
(
const
CvArr
*
srcarr
,
CvArr
*
dstarr
,
int
flags
)
cvConvertImage
(
const
CvArr
*
srcarr
,
CvArr
*
dstarr
,
int
flags
)
...
@@ -652,7 +657,7 @@ cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags )
...
@@ -652,7 +657,7 @@ cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags )
uchar
*
s
=
src
->
data
.
ptr
,
*
d
=
dst
->
data
.
ptr
;
uchar
*
s
=
src
->
data
.
ptr
,
*
d
=
dst
->
data
.
ptr
;
int
s_step
=
src
->
step
,
d_step
=
dst
->
step
;
int
s_step
=
src
->
step
,
d_step
=
dst
->
step
;
int
code
=
src_cn
*
10
+
dst_cn
;
int
code
=
src_cn
*
10
+
dst_cn
;
CvSize
size
=
{
src
->
cols
,
src
->
rows
}
;
Size
size
(
src
->
cols
,
src
->
rows
)
;
if
(
CV_IS_MAT_CONT
(
src
->
type
&
dst
->
type
)
)
if
(
CV_IS_MAT_CONT
(
src
->
type
&
dst
->
type
)
)
{
{
...
...
modules/imgcodecs/src/utils.hpp
View file @
1fb93b62
...
@@ -42,6 +42,8 @@
...
@@ -42,6 +42,8 @@
#ifndef _UTILS_H_
#ifndef _UTILS_H_
#define _UTILS_H_
#define _UTILS_H_
namespace
cv
{
int
validateToInt
(
size_t
step
);
int
validateToInt
(
size_t
step
);
template
<
typename
_Tp
>
static
inline
template
<
typename
_Tp
>
static
inline
...
@@ -68,53 +70,53 @@ struct PaletteEntry
...
@@ -68,53 +70,53 @@ struct PaletteEntry
void
icvCvt_BGR2Gray_8u_C3C1R
(
const
uchar
*
bgr
,
int
bgr_step
,
void
icvCvt_BGR2Gray_8u_C3C1R
(
const
uchar
*
bgr
,
int
bgr_step
,
uchar
*
gray
,
int
gray_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
swap_rb
=
0
);
Size
size
,
int
swap_rb
=
0
);
void
icvCvt_BGRA2Gray_8u_C4C1R
(
const
uchar
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2Gray_8u_C4C1R
(
const
uchar
*
bgra
,
int
bgra_step
,
uchar
*
gray
,
int
gray_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
swap_rb
=
0
);
Size
size
,
int
swap_rb
=
0
);
void
icvCvt_BGRA2Gray_16u_CnC1R
(
const
ushort
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2Gray_16u_CnC1R
(
const
ushort
*
bgra
,
int
bgra_step
,
ushort
*
gray
,
int
gray_step
,
ushort
*
gray
,
int
gray_step
,
Cv
Size
size
,
int
ncn
,
int
swap_rb
=
0
);
Size
size
,
int
ncn
,
int
swap_rb
=
0
);
void
icvCvt_Gray2BGR_8u_C1C3R
(
const
uchar
*
gray
,
int
gray_step
,
void
icvCvt_Gray2BGR_8u_C1C3R
(
const
uchar
*
gray
,
int
gray_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
);
uchar
*
bgr
,
int
bgr_step
,
Size
size
);
void
icvCvt_Gray2BGR_16u_C1C3R
(
const
ushort
*
gray
,
int
gray_step
,
void
icvCvt_Gray2BGR_16u_C1C3R
(
const
ushort
*
gray
,
int
gray_step
,
ushort
*
bgr
,
int
bgr_step
,
Cv
Size
size
);
ushort
*
bgr
,
int
bgr_step
,
Size
size
);
void
icvCvt_BGRA2BGR_8u_C4C3R
(
const
uchar
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2BGR_8u_C4C3R
(
const
uchar
*
bgra
,
int
bgra_step
,
uchar
*
bgr
,
int
bgr_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
,
int
swap_rb
=
0
);
Size
size
,
int
swap_rb
=
0
);
void
icvCvt_BGRA2BGR_16u_C4C3R
(
const
ushort
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2BGR_16u_C4C3R
(
const
ushort
*
bgra
,
int
bgra_step
,
ushort
*
bgr
,
int
bgr_step
,
ushort
*
bgr
,
int
bgr_step
,
Cv
Size
size
,
int
_swap_rb
);
Size
size
,
int
_swap_rb
);
void
icvCvt_BGR2RGB_8u_C3R
(
const
uchar
*
bgr
,
int
bgr_step
,
void
icvCvt_BGR2RGB_8u_C3R
(
const
uchar
*
bgr
,
int
bgr_step
,
uchar
*
rgb
,
int
rgb_step
,
Cv
Size
size
);
uchar
*
rgb
,
int
rgb_step
,
Size
size
);
#define icvCvt_RGB2BGR_8u_C3R icvCvt_BGR2RGB_8u_C3R
#define icvCvt_RGB2BGR_8u_C3R icvCvt_BGR2RGB_8u_C3R
void
icvCvt_BGR2RGB_16u_C3R
(
const
ushort
*
bgr
,
int
bgr_step
,
void
icvCvt_BGR2RGB_16u_C3R
(
const
ushort
*
bgr
,
int
bgr_step
,
ushort
*
rgb
,
int
rgb_step
,
Cv
Size
size
);
ushort
*
rgb
,
int
rgb_step
,
Size
size
);
#define icvCvt_RGB2BGR_16u_C3R icvCvt_BGR2RGB_16u_C3R
#define icvCvt_RGB2BGR_16u_C3R icvCvt_BGR2RGB_16u_C3R
void
icvCvt_BGRA2RGBA_8u_C4R
(
const
uchar
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2RGBA_8u_C4R
(
const
uchar
*
bgra
,
int
bgra_step
,
uchar
*
rgba
,
int
rgba_step
,
Cv
Size
size
);
uchar
*
rgba
,
int
rgba_step
,
Size
size
);
#define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R
#define icvCvt_RGBA2BGRA_8u_C4R icvCvt_BGRA2RGBA_8u_C4R
void
icvCvt_BGRA2RGBA_16u_C4R
(
const
ushort
*
bgra
,
int
bgra_step
,
void
icvCvt_BGRA2RGBA_16u_C4R
(
const
ushort
*
bgra
,
int
bgra_step
,
ushort
*
rgba
,
int
rgba_step
,
Cv
Size
size
);
ushort
*
rgba
,
int
rgba_step
,
Size
size
);
#define icvCvt_RGBA2BGRA_16u_C4R icvCvt_BGRA2RGBA_16u_C4R
#define icvCvt_RGBA2BGRA_16u_C4R icvCvt_BGRA2RGBA_16u_C4R
void
icvCvt_BGR5552Gray_8u_C2C1R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
void
icvCvt_BGR5552Gray_8u_C2C1R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
);
uchar
*
gray
,
int
gray_step
,
Size
size
);
void
icvCvt_BGR5652Gray_8u_C2C1R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
void
icvCvt_BGR5652Gray_8u_C2C1R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
);
uchar
*
gray
,
int
gray_step
,
Size
size
);
void
icvCvt_BGR5552BGR_8u_C2C3R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
void
icvCvt_BGR5552BGR_8u_C2C3R
(
const
uchar
*
bgr555
,
int
bgr555_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
);
uchar
*
bgr
,
int
bgr_step
,
Size
size
);
void
icvCvt_BGR5652BGR_8u_C2C3R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
void
icvCvt_BGR5652BGR_8u_C2C3R
(
const
uchar
*
bgr565
,
int
bgr565_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
);
uchar
*
bgr
,
int
bgr_step
,
Size
size
);
void
icvCvt_CMYK2BGR_8u_C4C3R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
void
icvCvt_CMYK2BGR_8u_C4C3R
(
const
uchar
*
cmyk
,
int
cmyk_step
,
uchar
*
bgr
,
int
bgr_step
,
Cv
Size
size
);
uchar
*
bgr
,
int
bgr_step
,
Size
size
);
void
icvCvt_CMYK2Gray_8u_C4C1R
(
const
uchar
*
ycck
,
int
ycck_step
,
void
icvCvt_CMYK2Gray_8u_C4C1R
(
const
uchar
*
ycck
,
int
ycck_step
,
uchar
*
gray
,
int
gray_step
,
Cv
Size
size
);
uchar
*
gray
,
int
gray_step
,
Size
size
);
void
FillGrayPalette
(
PaletteEntry
*
palette
,
int
bpp
,
bool
negative
=
false
);
void
FillGrayPalette
(
PaletteEntry
*
palette
,
int
bpp
,
bool
negative
=
false
);
bool
IsColorPalette
(
PaletteEntry
*
palette
,
int
bpp
);
bool
IsColorPalette
(
PaletteEntry
*
palette
,
int
bpp
);
...
@@ -136,4 +138,6 @@ CV_INLINE bool isBigEndian( void )
...
@@ -136,4 +138,6 @@ CV_INLINE bool isBigEndian( void )
return
(((
const
int
*
)
"
\0
\x1\x2\x3\x4\x5\x6\x7"
)[
0
]
&
255
)
!=
0
;
return
(((
const
int
*
)
"
\0
\x1\x2\x3\x4\x5\x6\x7"
)[
0
]
&
255
)
!=
0
;
}
}
}
// namespace
#endif
/*_UTILS_H_*/
#endif
/*_UTILS_H_*/
modules/imgcodecs/test/test_tiff.cpp
View file @
1fb93b62
...
@@ -158,12 +158,68 @@ TEST(Imgcodecs_Tiff, readWrite_32FC1)
...
@@ -158,12 +158,68 @@ TEST(Imgcodecs_Tiff, readWrite_32FC1)
ASSERT_TRUE
(
cv
::
imwrite
(
filenameOutput
,
img
));
ASSERT_TRUE
(
cv
::
imwrite
(
filenameOutput
,
img
));
const
Mat
img2
=
cv
::
imread
(
filenameOutput
,
IMREAD_UNCHANGED
);
const
Mat
img2
=
cv
::
imread
(
filenameOutput
,
IMREAD_UNCHANGED
);
ASSERT_EQ
(
img2
.
type
(),
img
.
type
());
ASSERT_EQ
(
img2
.
type
(),
img
.
type
());
ASSERT_EQ
(
img2
.
size
(),
img
.
size
());
ASSERT_EQ
(
img2
.
size
(),
img
.
size
());
EXPECT_
GE
(
1e-3
,
cvtest
::
norm
(
img
,
img2
,
NORM_INF
|
NORM_RELATIVE
)
);
EXPECT_
LE
(
cvtest
::
norm
(
img
,
img2
,
NORM_INF
|
NORM_RELATIVE
),
1e-3
);
EXPECT_EQ
(
0
,
remove
(
filenameOutput
.
c_str
()));
EXPECT_EQ
(
0
,
remove
(
filenameOutput
.
c_str
()));
}
}
TEST
(
Imgcodecs_Tiff
,
readWrite_64FC1
)
{
const
string
root
=
cvtest
::
TS
::
ptr
()
->
get_data_path
();
const
string
filenameInput
=
root
+
"readwrite/test64FC1.tiff"
;
const
string
filenameOutput
=
cv
::
tempfile
(
".tiff"
);
const
Mat
img
=
cv
::
imread
(
filenameInput
,
IMREAD_UNCHANGED
);
ASSERT_FALSE
(
img
.
empty
());
ASSERT_EQ
(
CV_64FC1
,
img
.
type
());
ASSERT_TRUE
(
cv
::
imwrite
(
filenameOutput
,
img
));
const
Mat
img2
=
cv
::
imread
(
filenameOutput
,
IMREAD_UNCHANGED
);
ASSERT_EQ
(
img2
.
type
(),
img
.
type
());
ASSERT_EQ
(
img2
.
size
(),
img
.
size
());
EXPECT_LE
(
cvtest
::
norm
(
img
,
img2
,
NORM_INF
|
NORM_RELATIVE
),
1e-3
);
EXPECT_EQ
(
0
,
remove
(
filenameOutput
.
c_str
()));
}
TEST
(
Imgcodecs_Tiff
,
readWrite_32FC3_SGILOG
)
{
const
string
root
=
cvtest
::
TS
::
ptr
()
->
get_data_path
();
const
string
filenameInput
=
root
+
"readwrite/test32FC3_sgilog.tiff"
;
const
string
filenameOutput
=
cv
::
tempfile
(
".tiff"
);
const
Mat
img
=
cv
::
imread
(
filenameInput
,
IMREAD_UNCHANGED
);
ASSERT_FALSE
(
img
.
empty
());
ASSERT_EQ
(
CV_32FC3
,
img
.
type
());
ASSERT_TRUE
(
cv
::
imwrite
(
filenameOutput
,
img
));
const
Mat
img2
=
cv
::
imread
(
filenameOutput
,
IMREAD_UNCHANGED
);
ASSERT_EQ
(
img2
.
type
(),
img
.
type
());
ASSERT_EQ
(
img2
.
size
(),
img
.
size
());
EXPECT_LE
(
cvtest
::
norm
(
img
,
img2
,
NORM_INF
|
NORM_RELATIVE
),
0.01
);
EXPECT_EQ
(
0
,
remove
(
filenameOutput
.
c_str
()));
}
TEST
(
Imgcodecs_Tiff
,
readWrite_32FC3_RAW
)
{
const
string
root
=
cvtest
::
TS
::
ptr
()
->
get_data_path
();
const
string
filenameInput
=
root
+
"readwrite/test32FC3_raw.tiff"
;
const
string
filenameOutput
=
cv
::
tempfile
(
".tiff"
);
const
Mat
img
=
cv
::
imread
(
filenameInput
,
IMREAD_UNCHANGED
);
ASSERT_FALSE
(
img
.
empty
());
ASSERT_EQ
(
CV_32FC3
,
img
.
type
());
std
::
vector
<
int
>
params
;
params
.
push_back
(
IMWRITE_TIFF_COMPRESSION
);
params
.
push_back
(
1
/*COMPRESSION_NONE*/
);
ASSERT_TRUE
(
cv
::
imwrite
(
filenameOutput
,
img
,
params
));
const
Mat
img2
=
cv
::
imread
(
filenameOutput
,
IMREAD_UNCHANGED
);
ASSERT_EQ
(
img2
.
type
(),
img
.
type
());
ASSERT_EQ
(
img2
.
size
(),
img
.
size
());
EXPECT_LE
(
cvtest
::
norm
(
img
,
img2
,
NORM_INF
|
NORM_RELATIVE
),
1e-3
);
EXPECT_EQ
(
0
,
remove
(
filenameOutput
.
c_str
()));
}
//==================================================================================================
//==================================================================================================
typedef
testing
::
TestWithParam
<
int
>
Imgcodecs_Tiff_Modes
;
typedef
testing
::
TestWithParam
<
int
>
Imgcodecs_Tiff_Modes
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment