8 #ifndef BOOST_GIL_IO_DEVICE_HPP
9 #define BOOST_GIL_IO_DEVICE_HPP
11 #include <boost/gil/detail/mp11.hpp>
12 #include <boost/gil/io/base.hpp>
16 #include <type_traits>
18 namespace boost {
namespace gil {
20 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
22 #pragma warning(disable:4512) //assignment operator could not be generated
27 template <
typename T >
struct buff_item
29 static const unsigned int size =
sizeof( T );
32 template <>
struct buff_item< void >
34 static const unsigned int size = 1;
47 template<
typename FormatTag >
52 using format_tag_t = FormatTag;
78 io_error_if( ( file = fopen( file_name,
"rb" )) ==
nullptr
79 ,
"file_stream_device: failed to open file for reading"
82 _file = file_ptr_t( file
103 FILE* file =
nullptr;
105 io_error_if( ( file = fopen( file_name,
"wb" )) ==
nullptr
106 ,
"file_stream_device: failed to open file for writing"
109 _file = file_ptr_t( file
123 FILE* get() {
return _file.get(); }
124 const FILE* get()
const {
return _file.get(); }
128 return std::getc( get() );
135 io_error_if( ( ch = std::getc( get() )) == EOF
136 ,
"file_stream_device: unexpected EOF"
147 std::size_t num_elements = fread( data
149 ,
static_cast<int>( count )
154 io_error_if( ferror( get() )
155 ,
"file_stream_device: file read error"
170 io_error_if(
read( buf, N ) < N
171 ,
"file_stream_device: file read error"
190 return (m[1] << 8) | m[0];
199 return (m[3] << 24) | (m[2] << 16) | (m[1] << 8) | m[0];
203 template <
typename T >
208 std::size_t num_elements = fwrite( buf
220 template <
typename T
225 io_error_if(
write( buf, N ) < N
226 ,
"file_stream_device: file write error"
243 m[0] = byte_t( x >> 0 );
244 m[1] = byte_t( x >> 8 );
254 m[0] = byte_t( x >> 0 );
255 m[1] = byte_t( x >> 8 );
256 m[2] = byte_t( x >> 16 );
257 m[3] = byte_t( x >> 24 );
262 void seek(
long count,
int whence = SEEK_SET )
264 io_error_if( fseek( get()
268 ,
"file_stream_device: file seek error"
274 long int pos = ftell( get() );
276 io_error_if( pos == -1L
277 ,
"file_stream_device: file position error"
291 std::size_t num_elements = fwrite( line.c_str()
297 io_error_if( num_elements < line.size()
298 ,
"file_stream_device: line print error"
304 return ferror( get() );
309 static void file_deleter( FILE* file )
319 using file_ptr_t = std::shared_ptr<FILE> ;
326 template<
typename FormatTag >
335 ,
"istream_device: Stream is not valid."
348 io_error_if( ( ch = _in.get() ) == EOF
349 ,
"istream_device: unexpected EOF"
355 std::size_t read( byte_t* data
356 , std::size_t count )
358 std::streamsize cr = 0;
363 std::streamsize c = _in.readsome(
reinterpret_cast< char*
>( data )
364 ,
static_cast< std::streamsize
>( count ));
366 count -=
static_cast< std::size_t
>( c );
370 }
while( count && _in );
372 return static_cast< std::size_t
>( cr );
376 template<
typename T,
int N>
397 return (m[1] << 8) | m[0];
406 return (m[3] << 24) | (m[2] << 16) | (m[1] << 8) | m[0];
409 void seek(
long count,
int whence = SEEK_SET )
412 , whence == SEEK_SET ? std::ios::beg
413 :( whence == SEEK_CUR ? std::ios::cur
418 void write(
const byte_t*, std::size_t)
420 io_error(
"istream_device: Bad io error." );
433 template<
typename FormatTag >
442 std::size_t read(byte_t *, std::size_t)
444 io_error(
"ostream_device: Bad io error." );
448 void seek(
long count,
int whence )
453 : ( whence == SEEK_CUR
459 void write(
const byte_t* data
460 , std::size_t count )
462 _out.write(
reinterpret_cast<char const*
>( data )
463 ,
static_cast<std::streamsize
>( count )
468 template <
typename T
488 m[0] = byte_t( x >> 0 );
489 m[1] = byte_t( x >> 8 );
499 m[0] = byte_t( x >> 0 );
500 m[1] = byte_t( x >> 8 );
501 m[2] = byte_t( x >> 16 );
502 m[3] = byte_t( x >> 24 );
532 template<
typename FormatTag >
struct is_input_device< istream_device< FormatTag > > : std::true_type{};
534 template<
typename FormatTag
538 struct is_adaptable_input_device : std::false_type{};
540 template <
typename FormatTag,
typename T>
541 struct is_adaptable_input_device
545 typename std::enable_if
549 std::is_base_of<std::istream, T>,
550 std::is_same<std::istream, T>
555 using device_type = istream_device<FormatTag>;
558 template<
typename FormatTag >
559 struct is_adaptable_input_device< FormatTag
565 using device_type = file_stream_device<FormatTag>;
571 template<
typename FormatTag
578 template <
typename FormatTag,
typename T>
583 typename std::enable_if
587 is_input_device<FormatTag>,
588 is_adaptable_input_device<FormatTag, T>
603 template<
typename FormatTag >
struct is_output_device< ostream_device < FormatTag > > : std::true_type{};
605 template<
typename FormatTag
609 struct is_adaptable_output_device : std::false_type {};
611 template <
typename FormatTag,
typename T>
612 struct is_adaptable_output_device
616 typename std::enable_if
620 std::is_base_of<std::ostream, T>,
621 std::is_same<std::ostream, T>
626 using device_type = ostream_device<FormatTag>;
629 template<
typename FormatTag>
struct is_adaptable_output_device<FormatTag,FILE*,
void>
632 using device_type = file_stream_device<FormatTag>;
639 template<
typename FormatTag
646 template <
typename FormatTag,
typename T>
651 typename std::enable_if
655 is_output_device<FormatTag>,
656 is_adaptable_output_device<FormatTag, T>
665 template<
typename Device,
typename FormatTag >
class scanline_reader;
666 template<
typename Device,
typename FormatTag,
typename ConversionPolicy >
class reader;
668 template<
typename Device,
typename FormatTag,
typename Log = no_log >
class writer;
670 template<
typename Device,
typename FormatTag >
class dynamic_image_reader;
671 template<
typename Device,
typename FormatTag,
typename Log = no_log >
class dynamic_image_writer;
676 template<
typename T >
677 struct is_reader : std::false_type
680 template<
typename Device
682 ,
typename ConversionPolicy
684 struct is_reader< reader< Device
691 template<
typename T >
692 struct is_dynamic_image_reader : std::false_type
695 template<
typename Device
698 struct is_dynamic_image_reader< dynamic_image_reader< Device
704 template<
typename T >
705 struct is_writer : std::false_type
708 template<
typename Device
711 struct is_writer< writer< Device
717 template<
typename T >
718 struct is_dynamic_image_writer : std::false_type
721 template<
typename Device
724 struct is_dynamic_image_writer< dynamic_image_writer< Device
732 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)