Skip to content

Commit 5a94610

Browse files
committed
Merge pull request opencv#9706 from alalek:imgcodecs_tiff_drop_legacy_code
2 parents 39e7427 + 08b5dc6 commit 5a94610

File tree

3 files changed

+46
-229
lines changed

3 files changed

+46
-229
lines changed

modules/imgcodecs/src/grfmt_tiff.cpp

Lines changed: 37 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,25 @@
4646
\****************************************************************************************/
4747

4848
#include "precomp.hpp"
49+
50+
#ifdef HAVE_TIFF
4951
#include "grfmt_tiff.hpp"
50-
#include <opencv2/imgproc.hpp>
5152
#include <limits>
5253

54+
// TODO FIXIT Conflict declarations for common types like int64/uint64
55+
namespace tiff_dummy_namespace {
56+
#include "tiff.h"
57+
#include "tiffio.h"
58+
}
59+
using namespace tiff_dummy_namespace;
60+
5361
namespace cv
5462
{
55-
static const char fmtSignTiffII[] = "II\x2a\x00";
5663

57-
#ifdef HAVE_TIFF
5864

65+
static const char fmtSignTiffII[] = "II\x2a\x00";
5966
static const char fmtSignTiffMM[] = "MM\x00\x2a";
6067

61-
#include "tiff.h"
62-
#include "tiffio.h"
63-
6468
static int grfmt_tiff_err_handler_init = 0;
6569
static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {}
6670

@@ -119,19 +123,24 @@ ImageDecoder TiffDecoder::newDecoder() const
119123

120124
class TiffDecoderBufHelper
121125
{
126+
Mat& m_buf;
127+
size_t& m_buf_pos;
122128
public:
129+
TiffDecoderBufHelper(Mat& buf, size_t& buf_pos) :
130+
m_buf(buf), m_buf_pos(buf_pos)
131+
{}
123132
static tmsize_t read( thandle_t handle, void* buffer, tmsize_t n )
124133
{
125-
TiffDecoder *decoder = reinterpret_cast<TiffDecoder*>(handle);
126-
const Mat& buf = decoder->m_buf;
134+
TiffDecoderBufHelper *helper = reinterpret_cast<TiffDecoderBufHelper*>(handle);
135+
const Mat& buf = helper->m_buf;
127136
const tmsize_t size = buf.cols*buf.rows*buf.elemSize();
128-
tmsize_t pos = decoder->m_buf_pos;
137+
tmsize_t pos = helper->m_buf_pos;
129138
if ( n > (size - pos) )
130139
{
131140
n = size - pos;
132141
}
133142
memcpy(buffer, buf.ptr() + pos, n);
134-
decoder->m_buf_pos += n;
143+
helper->m_buf_pos += n;
135144
return n;
136145
}
137146

@@ -143,10 +152,10 @@ class TiffDecoderBufHelper
143152

144153
static toff_t seek( thandle_t handle, toff_t offset, int whence )
145154
{
146-
TiffDecoder *decoder = reinterpret_cast<TiffDecoder*>(handle);
147-
const Mat& buf = decoder->m_buf;
155+
TiffDecoderBufHelper *helper = reinterpret_cast<TiffDecoderBufHelper*>(handle);
156+
const Mat& buf = helper->m_buf;
148157
const toff_t size = buf.cols*buf.rows*buf.elemSize();
149-
toff_t new_pos = decoder->m_buf_pos;
158+
toff_t new_pos = helper->m_buf_pos;
150159
switch (whence)
151160
{
152161
case SEEK_SET:
@@ -160,29 +169,30 @@ class TiffDecoderBufHelper
160169
break;
161170
}
162171
new_pos = std::min(new_pos, size);
163-
decoder->m_buf_pos = (size_t)new_pos;
172+
helper->m_buf_pos = (size_t)new_pos;
164173
return new_pos;
165174
}
166175

167176
static int map( thandle_t handle, void** base, toff_t* size )
168177
{
169-
TiffDecoder *decoder = reinterpret_cast<TiffDecoder*>(handle);
170-
Mat& buf = decoder->m_buf;
178+
TiffDecoderBufHelper *helper = reinterpret_cast<TiffDecoderBufHelper*>(handle);
179+
Mat& buf = helper->m_buf;
171180
*base = buf.ptr();
172181
*size = buf.cols*buf.rows*buf.elemSize();
173182
return 0;
174183
}
175184

176185
static toff_t size( thandle_t handle )
177186
{
178-
TiffDecoder *decoder = reinterpret_cast<TiffDecoder*>(handle);
179-
const Mat& buf = decoder->m_buf;
187+
TiffDecoderBufHelper *helper = reinterpret_cast<TiffDecoderBufHelper*>(handle);
188+
const Mat& buf = helper->m_buf;
180189
return buf.cols*buf.rows*buf.elemSize();
181190
}
182191

183-
static int close( thandle_t /*handle*/ )
192+
static int close( thandle_t handle )
184193
{
185-
// Do nothing.
194+
TiffDecoderBufHelper *helper = reinterpret_cast<TiffDecoderBufHelper*>(handle);
195+
delete helper;
186196
return 0;
187197
}
188198
};
@@ -199,7 +209,8 @@ bool TiffDecoder::readHeader()
199209
if ( !m_buf.empty() )
200210
{
201211
m_buf_pos = 0;
202-
tif = TIFFClientOpen( "", "r", reinterpret_cast<thandle_t>(this), &TiffDecoderBufHelper::read,
212+
TiffDecoderBufHelper* buf_helper = new TiffDecoderBufHelper(this->m_buf, this->m_buf_pos);
213+
tif = TIFFClientOpen( "", "r", reinterpret_cast<thandle_t>(buf_helper), &TiffDecoderBufHelper::read,
203214
&TiffDecoderBufHelper::write, &TiffDecoderBufHelper::seek,
204215
&TiffDecoderBufHelper::close, &TiffDecoderBufHelper::size,
205216
&TiffDecoderBufHelper::map, /*unmap=*/0 );
@@ -548,8 +559,6 @@ bool TiffDecoder::readHdrData(Mat& img)
548559
return true;
549560
}
550561

551-
#endif
552-
553562
//////////////////////////////////////////////////////////////////////////////////////////
554563

555564
TiffEncoder::TiffEncoder()
@@ -569,11 +578,7 @@ ImageEncoder TiffEncoder::newEncoder() const
569578

570579
bool TiffEncoder::isFormatSupported( int depth ) const
571580
{
572-
#ifdef HAVE_TIFF
573581
return depth == CV_8U || depth == CV_16U || depth == CV_32F;
574-
#else
575-
return depth == CV_8U || depth == CV_16U;
576-
#endif
577582
}
578583

579584
void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
@@ -586,8 +591,6 @@ void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
586591
strm.putDWord( value );
587592
}
588593

589-
#ifdef HAVE_TIFF
590-
591594
class TiffEncoderBufHelper
592595
{
593596
public:
@@ -854,204 +857,20 @@ bool TiffEncoder::writeHdr(const Mat& _img)
854857
return true;
855858
}
856859

857-
#endif
858-
859-
#ifdef HAVE_TIFF
860860
bool TiffEncoder::write( const Mat& img, const std::vector<int>& params)
861-
#else
862-
bool TiffEncoder::write( const Mat& img, const std::vector<int>& /*params*/)
863-
#endif
864861
{
865862
int depth = img.depth();
866-
#ifdef HAVE_TIFF
863+
867864
if(img.type() == CV_32FC3)
868865
{
869-
return writeHdr(img);
866+
return writeHdr(img); // TODO Rename
870867
}
871-
#endif
872868

873-
if (depth != CV_8U && depth != CV_16U)
874-
return false;
869+
CV_Assert(depth == CV_8U || depth == CV_16U);
875870

876-
#ifdef HAVE_TIFF
877871
return writeLibTiff(img, params);
878-
#else
879-
int channels = img.channels();
880-
int width = img.cols, height = img.rows;
881-
int bytesPerChannel = depth == CV_8U ? 1 : 2;
882-
int fileStep = width * channels * bytesPerChannel;
883-
884-
WLByteStream strm;
885-
886-
if( m_buf )
887-
{
888-
if( !strm.open(*m_buf) )
889-
return false;
890-
}
891-
else
892-
{
893-
if( !strm.open(m_filename) )
894-
return false;
895-
}
896-
897-
int rowsPerStrip = (1 << 13)/fileStep;
898-
899-
if( rowsPerStrip < 1 )
900-
rowsPerStrip = 1;
901-
902-
if( rowsPerStrip > height )
903-
rowsPerStrip = height;
904-
905-
int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
906-
907-
if( m_buf )
908-
m_buf->reserve( alignSize(stripCount*8 + fileStep*height + 256, 256) );
909-
910-
/*#if defined _DEBUG || !defined _WIN32
911-
int uncompressedRowSize = rowsPerStrip * fileStep;
912-
#endif*/
913-
int directoryOffset = 0;
914-
915-
AutoBuffer<int> stripOffsets(stripCount);
916-
AutoBuffer<short> stripCounts(stripCount);
917-
AutoBuffer<uchar> _buffer(fileStep+32);
918-
uchar* buffer = _buffer;
919-
int stripOffsetsOffset = 0;
920-
int stripCountsOffset = 0;
921-
int bitsPerSample = 8 * bytesPerChannel;
922-
int y = 0;
923-
924-
strm.putBytes( fmtSignTiffII, 4 );
925-
strm.putDWord( directoryOffset );
926-
927-
// write an image data first (the most reasonable way
928-
// for compressed images)
929-
for( i = 0; i < stripCount; i++ )
930-
{
931-
int limit = y + rowsPerStrip;
932-
933-
if( limit > height )
934-
limit = height;
935-
936-
stripOffsets[i] = strm.getPos();
937-
938-
for( ; y < limit; y++ )
939-
{
940-
if( channels == 3 )
941-
{
942-
if (depth == CV_8U)
943-
icvCvt_BGR2RGB_8u_C3R( img.ptr(y), 0, buffer, 0, cvSize(width,1) );
944-
else
945-
icvCvt_BGR2RGB_16u_C3R( img.ptr<ushort>(y), 0, (ushort*)buffer, 0, cvSize(width,1) );
946-
}
947-
else
948-
{
949-
if( channels == 4 )
950-
{
951-
if (depth == CV_8U)
952-
icvCvt_BGRA2RGBA_8u_C4R( img.ptr(y), 0, buffer, 0, cvSize(width,1) );
953-
else
954-
icvCvt_BGRA2RGBA_16u_C4R( img.ptr<ushort>(y), 0, (ushort*)buffer, 0, cvSize(width,1) );
955-
}
956-
}
957-
958-
strm.putBytes( channels > 1 ? buffer : img.ptr(y), fileStep );
959-
}
960-
961-
stripCounts[i] = (short)(strm.getPos() - stripOffsets[i]);
962-
/*assert( stripCounts[i] == uncompressedRowSize ||
963-
stripCounts[i] < uncompressedRowSize &&
964-
i == stripCount - 1);*/
965-
}
966-
967-
if( stripCount > 2 )
968-
{
969-
stripOffsetsOffset = strm.getPos();
970-
for( i = 0; i < stripCount; i++ )
971-
strm.putDWord( stripOffsets[i] );
972-
973-
stripCountsOffset = strm.getPos();
974-
for( i = 0; i < stripCount; i++ )
975-
strm.putWord( stripCounts[i] );
976-
}
977-
else if(stripCount == 2)
978-
{
979-
stripOffsetsOffset = strm.getPos();
980-
for (i = 0; i < stripCount; i++)
981-
{
982-
strm.putDWord (stripOffsets [i]);
983-
}
984-
stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16);
985-
}
986-
else
987-
{
988-
stripOffsetsOffset = stripOffsets[0];
989-
stripCountsOffset = stripCounts[0];
990-
}
991-
992-
if( channels > 1 )
993-
{
994-
int bitsPerSamplePos = strm.getPos();
995-
strm.putWord(bitsPerSample);
996-
strm.putWord(bitsPerSample);
997-
strm.putWord(bitsPerSample);
998-
if( channels == 4 )
999-
strm.putWord(bitsPerSample);
1000-
bitsPerSample = bitsPerSamplePos;
1001-
}
1002-
1003-
directoryOffset = strm.getPos();
1004-
1005-
// write header
1006-
strm.putWord( 9 );
1007-
1008-
/* warning: specification 5.0 of Tiff want to have tags in
1009-
ascending order. This is a non-fatal error, but this cause
1010-
warning with some tools. So, keep this in ascending order */
1011-
1012-
writeTag( strm, TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width );
1013-
writeTag( strm, TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height );
1014-
writeTag( strm, TIFF_TAG_BITS_PER_SAMPLE,
1015-
TIFF_TYPE_SHORT, channels, bitsPerSample );
1016-
writeTag( strm, TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
1017-
writeTag( strm, TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 );
1018-
1019-
writeTag( strm, TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
1020-
stripCount, stripOffsetsOffset );
1021-
1022-
writeTag( strm, TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels );
1023-
writeTag( strm, TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
1024-
1025-
writeTag( strm, TIFF_TAG_STRIP_COUNTS,
1026-
stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG,
1027-
stripCount, stripCountsOffset );
872+
}
1028873

1029-
strm.putDWord(0);
1030-
strm.close();
874+
} // namespace
1031875

1032-
if( m_buf )
1033-
{
1034-
(*m_buf)[4] = (uchar)directoryOffset;
1035-
(*m_buf)[5] = (uchar)(directoryOffset >> 8);
1036-
(*m_buf)[6] = (uchar)(directoryOffset >> 16);
1037-
(*m_buf)[7] = (uchar)(directoryOffset >> 24);
1038-
}
1039-
else
1040-
{
1041-
// write directory offset
1042-
FILE* f = fopen( m_filename.c_str(), "r+b" );
1043-
buffer[0] = (uchar)directoryOffset;
1044-
buffer[1] = (uchar)(directoryOffset >> 8);
1045-
buffer[2] = (uchar)(directoryOffset >> 16);
1046-
buffer[3] = (uchar)(directoryOffset >> 24);
1047-
1048-
fseek( f, 4, SEEK_SET );
1049-
fwrite( buffer, 1, 4, f );
1050-
fclose(f);
1051-
}
1052-
1053-
return true;
1054876
#endif
1055-
}
1056-
1057-
}

0 commit comments

Comments
 (0)