46
46
\****************************************************************************************/
47
47
48
48
#include " precomp.hpp"
49
+
50
+ #ifdef HAVE_TIFF
49
51
#include " grfmt_tiff.hpp"
50
- #include < opencv2/imgproc.hpp>
51
52
#include < limits>
52
53
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
+
53
61
namespace cv
54
62
{
55
- static const char fmtSignTiffII[] = " II\x2a\x00 " ;
56
63
57
- #ifdef HAVE_TIFF
58
64
65
+ static const char fmtSignTiffII[] = " II\x2a\x00 " ;
59
66
static const char fmtSignTiffMM[] = " MM\x00\x2a " ;
60
67
61
- #include " tiff.h"
62
- #include " tiffio.h"
63
-
64
68
static int grfmt_tiff_err_handler_init = 0 ;
65
69
static void GrFmtSilentTIFFErrorHandler ( const char *, const char *, va_list ) {}
66
70
@@ -119,19 +123,24 @@ ImageDecoder TiffDecoder::newDecoder() const
119
123
120
124
class TiffDecoderBufHelper
121
125
{
126
+ Mat& m_buf;
127
+ size_t & m_buf_pos;
122
128
public:
129
+ TiffDecoderBufHelper (Mat& buf, size_t & buf_pos) :
130
+ m_buf (buf), m_buf_pos(buf_pos)
131
+ {}
123
132
static tmsize_t read ( thandle_t handle, void * buffer, tmsize_t n )
124
133
{
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 ;
127
136
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 ;
129
138
if ( n > (size - pos) )
130
139
{
131
140
n = size - pos;
132
141
}
133
142
memcpy (buffer, buf.ptr () + pos, n);
134
- decoder ->m_buf_pos += n;
143
+ helper ->m_buf_pos += n;
135
144
return n;
136
145
}
137
146
@@ -143,10 +152,10 @@ class TiffDecoderBufHelper
143
152
144
153
static toff_t seek ( thandle_t handle, toff_t offset, int whence )
145
154
{
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 ;
148
157
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 ;
150
159
switch (whence)
151
160
{
152
161
case SEEK_SET:
@@ -160,29 +169,30 @@ class TiffDecoderBufHelper
160
169
break ;
161
170
}
162
171
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;
164
173
return new_pos;
165
174
}
166
175
167
176
static int map ( thandle_t handle, void ** base, toff_t * size )
168
177
{
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 ;
171
180
*base = buf.ptr ();
172
181
*size = buf.cols *buf.rows *buf.elemSize ();
173
182
return 0 ;
174
183
}
175
184
176
185
static toff_t size ( thandle_t handle )
177
186
{
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 ;
180
189
return buf.cols *buf.rows *buf.elemSize ();
181
190
}
182
191
183
- static int close ( thandle_t /* handle*/ )
192
+ static int close ( thandle_t handle )
184
193
{
185
- // Do nothing.
194
+ TiffDecoderBufHelper *helper = reinterpret_cast <TiffDecoderBufHelper*>(handle);
195
+ delete helper;
186
196
return 0 ;
187
197
}
188
198
};
@@ -199,7 +209,8 @@ bool TiffDecoder::readHeader()
199
209
if ( !m_buf.empty () )
200
210
{
201
211
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,
203
214
&TiffDecoderBufHelper::write, &TiffDecoderBufHelper::seek,
204
215
&TiffDecoderBufHelper::close, &TiffDecoderBufHelper::size,
205
216
&TiffDecoderBufHelper::map, /* unmap=*/ 0 );
@@ -548,8 +559,6 @@ bool TiffDecoder::readHdrData(Mat& img)
548
559
return true ;
549
560
}
550
561
551
- #endif
552
-
553
562
// ////////////////////////////////////////////////////////////////////////////////////////
554
563
555
564
TiffEncoder::TiffEncoder ()
@@ -569,11 +578,7 @@ ImageEncoder TiffEncoder::newEncoder() const
569
578
570
579
bool TiffEncoder::isFormatSupported ( int depth ) const
571
580
{
572
- #ifdef HAVE_TIFF
573
581
return depth == CV_8U || depth == CV_16U || depth == CV_32F;
574
- #else
575
- return depth == CV_8U || depth == CV_16U;
576
- #endif
577
582
}
578
583
579
584
void TiffEncoder::writeTag ( WLByteStream& strm, TiffTag tag,
@@ -586,8 +591,6 @@ void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
586
591
strm.putDWord ( value );
587
592
}
588
593
589
- #ifdef HAVE_TIFF
590
-
591
594
class TiffEncoderBufHelper
592
595
{
593
596
public:
@@ -854,204 +857,20 @@ bool TiffEncoder::writeHdr(const Mat& _img)
854
857
return true ;
855
858
}
856
859
857
- #endif
858
-
859
- #ifdef HAVE_TIFF
860
860
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
864
861
{
865
862
int depth = img.depth ();
866
- # ifdef HAVE_TIFF
863
+
867
864
if (img.type () == CV_32FC3)
868
865
{
869
- return writeHdr (img);
866
+ return writeHdr (img); // TODO Rename
870
867
}
871
- #endif
872
868
873
- if (depth != CV_8U && depth != CV_16U)
874
- return false ;
869
+ CV_Assert (depth == CV_8U || depth == CV_16U);
875
870
876
- #ifdef HAVE_TIFF
877
871
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
+ }
1028
873
1029
- strm.putDWord (0 );
1030
- strm.close ();
874
+ } // namespace
1031
875
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 ;
1054
876
#endif
1055
- }
1056
-
1057
- }
0 commit comments