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
cc5da834
Commit
cc5da834
authored
7 years ago
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9252 from jbms:fix/tiff-in-memory
parents
9c14a2f0
c515e878
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
194 additions
and
12 deletions
+194
-12
grfmt_tiff.cpp
modules/imgcodecs/src/grfmt_tiff.cpp
+188
-12
grfmt_tiff.hpp
modules/imgcodecs/src/grfmt_tiff.hpp
+6
-0
No files found.
modules/imgcodecs/src/grfmt_tiff.cpp
View file @
cc5da834
...
...
@@ -75,6 +75,8 @@ TiffDecoder::TiffDecoder()
TIFFSetWarningHandler
(
GrFmtSilentTIFFErrorHandler
);
}
m_hdr
=
false
;
m_buf_supported
=
true
;
m_buf_pos
=
0
;
}
...
...
@@ -115,6 +117,76 @@ ImageDecoder TiffDecoder::newDecoder() const
return
makePtr
<
TiffDecoder
>
();
}
class
TiffDecoderBufHelper
{
public
:
static
tmsize_t
read
(
thandle_t
handle
,
void
*
buffer
,
tmsize_t
n
)
{
TiffDecoder
*
decoder
=
reinterpret_cast
<
TiffDecoder
*>
(
handle
);
const
Mat
&
buf
=
decoder
->
m_buf
;
const
tmsize_t
size
=
buf
.
cols
*
buf
.
rows
*
buf
.
elemSize
();
tmsize_t
pos
=
decoder
->
m_buf_pos
;
if
(
n
>
(
size
-
pos
)
)
{
n
=
size
-
pos
;
}
memcpy
(
buffer
,
buf
.
ptr
()
+
pos
,
n
);
decoder
->
m_buf_pos
+=
n
;
return
n
;
}
static
tmsize_t
write
(
thandle_t
/*handle*/
,
void
*
/*buffer*/
,
tmsize_t
/*n*/
)
{
// Not used for decoding.
return
0
;
}
static
toff_t
seek
(
thandle_t
handle
,
toff_t
offset
,
int
whence
)
{
TiffDecoder
*
decoder
=
reinterpret_cast
<
TiffDecoder
*>
(
handle
);
const
Mat
&
buf
=
decoder
->
m_buf
;
const
toff_t
size
=
buf
.
cols
*
buf
.
rows
*
buf
.
elemSize
();
toff_t
new_pos
=
decoder
->
m_buf_pos
;
switch
(
whence
)
{
case
SEEK_SET
:
new_pos
=
offset
;
break
;
case
SEEK_CUR
:
new_pos
+=
offset
;
break
;
case
SEEK_END
:
new_pos
=
size
+
offset
;
break
;
}
new_pos
=
std
::
min
(
new_pos
,
size
);
decoder
->
m_buf_pos
=
(
size_t
)
new_pos
;
return
new_pos
;
}
static
int
map
(
thandle_t
handle
,
void
**
base
,
toff_t
*
size
)
{
TiffDecoder
*
decoder
=
reinterpret_cast
<
TiffDecoder
*>
(
handle
);
Mat
&
buf
=
decoder
->
m_buf
;
*
base
=
buf
.
ptr
();
*
size
=
buf
.
cols
*
buf
.
rows
*
buf
.
elemSize
();
return
0
;
}
static
toff_t
size
(
thandle_t
handle
)
{
TiffDecoder
*
decoder
=
reinterpret_cast
<
TiffDecoder
*>
(
handle
);
const
Mat
&
buf
=
decoder
->
m_buf
;
return
buf
.
cols
*
buf
.
rows
*
buf
.
elemSize
();
}
static
int
close
(
thandle_t
/*handle*/
)
{
// Do nothing.
return
0
;
}
};
bool
TiffDecoder
::
readHeader
()
{
bool
result
=
false
;
...
...
@@ -124,8 +196,19 @@ bool TiffDecoder::readHeader()
{
// 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
if
(
!
m_buf
.
empty
()
)
{
m_buf_pos
=
0
;
tif
=
TIFFClientOpen
(
""
,
"r"
,
reinterpret_cast
<
thandle_t
>
(
this
),
&
TiffDecoderBufHelper
::
read
,
&
TiffDecoderBufHelper
::
write
,
&
TiffDecoderBufHelper
::
seek
,
&
TiffDecoderBufHelper
::
close
,
&
TiffDecoderBufHelper
::
size
,
&
TiffDecoderBufHelper
::
map
,
/*unmap=*/
0
);
}
else
{
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"r"
);
}
}
if
(
tif
)
{
...
...
@@ -472,11 +555,7 @@ bool TiffDecoder::readHdrData(Mat& img)
TiffEncoder
::
TiffEncoder
()
{
m_description
=
"TIFF Files (*.tiff;*.tif)"
;
#ifdef HAVE_TIFF
m_buf_supported
=
false
;
#else
m_buf_supported
=
true
;
#endif
}
TiffEncoder
::~
TiffEncoder
()
...
...
@@ -509,6 +588,81 @@ void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
#ifdef HAVE_TIFF
class
TiffEncoderBufHelper
{
public
:
TiffEncoderBufHelper
(
std
::
vector
<
uchar
>
*
buf
)
:
m_buf
(
buf
),
m_buf_pos
(
0
)
{}
TIFF
*
open
()
{
return
TIFFClientOpen
(
""
,
"w"
,
reinterpret_cast
<
thandle_t
>
(
this
),
&
TiffEncoderBufHelper
::
read
,
&
TiffEncoderBufHelper
::
write
,
&
TiffEncoderBufHelper
::
seek
,
&
TiffEncoderBufHelper
::
close
,
&
TiffEncoderBufHelper
::
size
,
/*map=*/
0
,
/*unmap=*/
0
);
}
static
tmsize_t
read
(
thandle_t
/*handle*/
,
void
*
/*buffer*/
,
tmsize_t
/*n*/
)
{
// Not used for encoding.
return
0
;
}
static
tmsize_t
write
(
thandle_t
handle
,
void
*
buffer
,
tmsize_t
n
)
{
TiffEncoderBufHelper
*
helper
=
reinterpret_cast
<
TiffEncoderBufHelper
*>
(
handle
);
size_t
begin
=
(
size_t
)
helper
->
m_buf_pos
;
size_t
end
=
begin
+
n
;
if
(
helper
->
m_buf
->
size
()
<
end
)
{
helper
->
m_buf
->
resize
(
end
);
}
memcpy
(
&
(
*
helper
->
m_buf
)[
begin
],
buffer
,
n
);
helper
->
m_buf_pos
=
end
;
return
n
;
}
static
toff_t
seek
(
thandle_t
handle
,
toff_t
offset
,
int
whence
)
{
TiffEncoderBufHelper
*
helper
=
reinterpret_cast
<
TiffEncoderBufHelper
*>
(
handle
);
const
toff_t
size
=
helper
->
m_buf
->
size
();
toff_t
new_pos
=
helper
->
m_buf_pos
;
switch
(
whence
)
{
case
SEEK_SET
:
new_pos
=
offset
;
break
;
case
SEEK_CUR
:
new_pos
+=
offset
;
break
;
case
SEEK_END
:
new_pos
=
size
+
offset
;
break
;
}
helper
->
m_buf_pos
=
new_pos
;
return
new_pos
;
}
static
toff_t
size
(
thandle_t
handle
)
{
TiffEncoderBufHelper
*
helper
=
reinterpret_cast
<
TiffEncoderBufHelper
*>
(
handle
);
return
helper
->
m_buf
->
size
();
}
static
int
close
(
thandle_t
/*handle*/
)
{
// Do nothing.
return
0
;
}
private
:
std
::
vector
<
uchar
>*
m_buf
;
toff_t
m_buf_pos
;
};
static
void
readParam
(
const
std
::
vector
<
int
>&
params
,
int
key
,
int
&
value
)
{
for
(
size_t
i
=
0
;
i
+
1
<
params
.
size
();
i
+=
2
)
...
...
@@ -559,7 +713,17 @@ bool TiffEncoder::writeLibTiff( const Mat& img, const std::vector<int>& params)
// do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
TIFF
*
pTiffHandle
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
TIFF
*
pTiffHandle
;
TiffEncoderBufHelper
buf_helper
(
m_buf
);
if
(
m_buf
)
{
pTiffHandle
=
buf_helper
.
open
();
}
else
{
pTiffHandle
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
}
if
(
!
pTiffHandle
)
{
return
false
;
...
...
@@ -655,7 +819,19 @@ bool TiffEncoder::writeHdr(const Mat& _img)
{
Mat
img
;
cvtColor
(
_img
,
img
,
COLOR_BGR2XYZ
);
TIFF
*
tif
=
TIFFOpen
(
m_filename
.
c_str
(),
"w"
);
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
;
...
...
@@ -686,8 +862,6 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& params)
bool
TiffEncoder
::
write
(
const
Mat
&
img
,
const
std
::
vector
<
int
>&
/*params*/
)
#endif
{
int
channels
=
img
.
channels
();
int
width
=
img
.
cols
,
height
=
img
.
rows
;
int
depth
=
img
.
depth
();
#ifdef HAVE_TIFF
if
(
img
.
type
()
==
CV_32FC3
)
...
...
@@ -699,6 +873,11 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
if
(
depth
!=
CV_8U
&&
depth
!=
CV_16U
)
return
false
;
#ifdef HAVE_TIFF
return
writeLibTiff
(
img
,
params
);
#else
int
channels
=
img
.
channels
();
int
width
=
img
.
cols
,
height
=
img
.
rows
;
int
bytesPerChannel
=
depth
==
CV_8U
?
1
:
2
;
int
fileStep
=
width
*
channels
*
bytesPerChannel
;
...
...
@@ -711,12 +890,8 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
}
else
{
#ifdef HAVE_TIFF
return
writeLibTiff
(
img
,
params
);
#else
if
(
!
strm
.
open
(
m_filename
)
)
return
false
;
#endif
}
int
rowsPerStrip
=
(
1
<<
13
)
/
fileStep
;
...
...
@@ -876,6 +1051,7 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
}
return
true
;
#endif
}
}
This diff is collapsed.
Click to expand it.
modules/imgcodecs/src/grfmt_tiff.hpp
View file @
cc5da834
...
...
@@ -91,6 +91,8 @@ enum TiffFieldType
// libtiff based TIFF codec
class
TiffDecoderBufHelper
;
class
TiffDecoder
:
public
BaseImageDecoder
{
public
:
...
...
@@ -107,10 +109,14 @@ public:
ImageDecoder
newDecoder
()
const
;
protected
:
friend
class
TiffDecoderBufHelper
;
void
*
m_tif
;
int
normalizeChannelsNumber
(
int
channels
)
const
;
bool
readHdrData
(
Mat
&
img
);
bool
m_hdr
;
size_t
m_buf_pos
;
};
#endif
...
...
This diff is collapsed.
Click to expand it.
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