9#ifndef BOOST_GIL_IO_DEVICE_HPP
10#define BOOST_GIL_IO_DEVICE_HPP
12#include <boost/gil/detail/mp11.hpp>
13#include <boost/gil/io/base.hpp>
19namespace boost {
namespace gil {
21#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
23#pragma warning(disable:4512)
28template <
typename T >
struct buff_item
30 static const unsigned int size =
sizeof( T );
33template <>
struct buff_item< void >
35 static const unsigned int size = 1;
48template<
typename FormatTag >
53 using format_tag_t = FormatTag;
79 io_error_if( ( file = fopen( file_name,
"rb" )) ==
nullptr
80 ,
"file_stream_device: 打开文件以供读取失败" )
83 _file = file_ptr_t( file
104 FILE* file =
nullptr;
106 io_error_if( ( file = fopen( file_name,
"wb" )) ==
nullptr
107 ,
"file_stream_device: 打开文件以供写入失败" )
110 _file = file_ptr_t( file
124 auto get() -> FILE* {
return _file.get(); }
125 auto get() const -> FILE const* {
return _file.get(); }
129 {
return std::getc( get() ); }
136 io_error_if( ( ch = std::getc( get() )) == EOF
137 ,
"file_stream_device: 意外的 EOF" )
140 {
return (
char ) ch; }
144 auto read(byte_t* data, std::size_t count) -> std::size_t
146 { std::size_t num_elements = fread( data
148 ,
static_cast<int>(
sizeof( byte_t ) )
153 io_error_if( ferror( get() )
154 ,
"file_stream_device: 文件读取错误" )
160 return num_elements; }
164 template<
typename T,
int N>
167 { io_error_if(
read( buf, N ) < N
168 ,
"file_stream_device: 文件读取错误" ); }
187 return (m[1] << 8) | m[0]; }
196 return (m[3] << 24) | (m[2] << 16) | (m[1] << 8) | m[0]; }
200 template <
typename T >
201 auto write(T
const* buf, std::size_t count) -> std::size_t
203 { std::size_t num_elements = fwrite( buf
211 return num_elements; }
215 template <
typename T
220 { io_error_if(
write( buf, N ) < N
221 ,
"file_stream_device: 文件写入错误" ); }
229 { byte_t m[1] = { x };
238 m[0] = byte_t( x >> 0 );
239 m[1] = byte_t( x >> 8 );
249 m[0] = byte_t( x >> 0 );
250 m[1] = byte_t( x >> 8 );
251 m[2] = byte_t( x >> 16 );
252 m[3] = byte_t( x >> 24 );
257 void seek(
long count,
int whence = SEEK_SET )
259 { io_error_if( fseek( get()
263 ,
"file_stream_device: 文件查找错误" ); }
269 {
long int pos = ftell( get() );
271 io_error_if( pos == -1L
272 ,
"file_stream_device: 文件定位错误" );
286 { std::size_t num_elements = fwrite( line.c_str()
292 io_error_if( num_elements < line.size()
293 ,
"file_stream_device: 行打印错误" ); }
299 {
return ferror( get() ); }
304 static void file_deleter( FILE* file )
314 using file_ptr_t = std::shared_ptr<FILE> ;
321template<
typename FormatTag >
330 ,
"istream_device: 流无效。" )
336 {
return _in.get(); }
343 io_error_if( ( ch = _in.get() ) == EOF
344 ,
"istream_device: 意外的 EOF" )
347 {
return (
char ) ch; }
350 std::size_t read( byte_t* data
351 , std::size_t count )
353 { std::streamsize cr = 0;
358 std::streamsize c = _in.readsome(
reinterpret_cast< char*
>( data )
359 ,
static_cast< std::streamsize
>( count ));
361 count -=
static_cast< std::size_t
>( c );
365 }
while( count && _in );
367 return static_cast< std::size_t
>( cr ); }
371 template<
typename T,
int N>
392 return (m[1] << 8) | m[0]; }
401 return (m[3] << 24) | (m[2] << 16) | (m[1] << 8) | m[0]; }
404 void seek(
long count,
int whence = SEEK_SET )
407 , whence == SEEK_SET ? std::ios::beg
408 :( whence == SEEK_CUR ? std::ios::cur
409 : std::ios::end ) ); }
415 {
auto pos = _in.tellg();
417 io_error_if( pos == std::istream::pos_type(-1)
418 ,
"istream_device: 文件定位错误" );
421 return static_cast<long int>(pos); }
424 void write(
const byte_t*, std::size_t)
426 { io_error(
"istream_device: 错误的 IO 错误。" ); }
433 {
return _in.fail(); }
444template<
typename FormatTag >
453 std::size_t read(byte_t *, std::size_t)
455 { io_error(
"ostream_device: 错误的 IO 错误。" );
459 void seek(
long count,
int whence )
464 : ( whence == SEEK_CUR
466 :std::ios::end ) ); }
472 {
auto pos = _out.tellp();
474 io_error_if( pos == std::ostream::pos_type(-1)
475 ,
"ostream_device: 文件定位错误" );
478 return static_cast<long int>(pos); }
481 void write(
const byte_t* data
482 , std::size_t count )
484 { _out.write(
reinterpret_cast<char const*
>( data )
485 ,
static_cast<std::streamsize
>( count ) ); }
490 template <
typename T
501 { byte_t m[1] = { x };
510 m[0] = byte_t( x >> 0 );
511 m[1] = byte_t( x >> 8 );
521 m[0] = byte_t( x >> 0 );
522 m[1] = byte_t( x >> 8 );
523 m[2] = byte_t( x >> 16 );
524 m[3] = byte_t( x >> 24 );
531 { _out << std::flush; }
557template<
typename FormatTag >
struct is_input_device< istream_device< FormatTag > > : std::true_type{};
559template<
typename FormatTag
563struct is_adaptable_input_device : std::false_type{};
565template <
typename FormatTag,
typename T>
566struct is_adaptable_input_device
570 typename std::enable_if
574 std::is_base_of<std::istream, T>,
575 std::is_same<std::istream, T>
580 using device_type = istream_device<FormatTag>;
583template<
typename FormatTag >
584struct is_adaptable_input_device< FormatTag
590 using device_type = file_stream_device<FormatTag>;
596template<
typename FormatTag
603template <
typename FormatTag,
typename T>
608 typename std::enable_if
612 is_input_device<FormatTag>,
613 is_adaptable_input_device<FormatTag, T>
628template<
typename FormatTag >
struct is_output_device< ostream_device < FormatTag > > : std::true_type{};
630template<
typename FormatTag
634struct is_adaptable_output_device : std::false_type {};
636template <
typename FormatTag,
typename T>
637struct is_adaptable_output_device
641 typename std::enable_if
645 std::is_base_of<std::ostream, T>,
646 std::is_same<std::ostream, T>
651 using device_type = ostream_device<FormatTag>;
654template<
typename FormatTag>
struct is_adaptable_output_device<FormatTag,FILE*,
void>
657 using device_type = file_stream_device<FormatTag>;
664template<
typename FormatTag
671template <
typename FormatTag,
typename T>
676 typename std::enable_if
680 is_output_device<FormatTag>,
681 is_adaptable_output_device<FormatTag, T>
690template<
typename Device,
typename FormatTag >
class scanline_reader;
691template<
typename Device,
typename FormatTag,
typename ConversionPolicy >
class reader;
693template<
typename Device,
typename FormatTag,
typename Log = no_log >
class writer;
695template<
typename Device,
typename FormatTag >
class dynamic_image_reader;
696template<
typename Device,
typename FormatTag,
typename Log = no_log >
class dynamic_image_writer;
701template<
typename T >
702struct is_reader : std::false_type
705template<
typename Device
707 ,
typename ConversionPolicy
709struct is_reader< reader< Device
716template<
typename T >
717struct is_dynamic_image_reader : std::false_type
720template<
typename Device
723struct is_dynamic_image_reader< dynamic_image_reader< Device
729template<
typename T >
730struct is_writer : std::false_type
733template<
typename Device
736struct is_writer< writer< Device
742template<
typename T >
743struct is_dynamic_image_writer : std::false_type
746template<
typename Device
749struct is_dynamic_image_writer< dynamic_image_writer< Device
757#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
file_stream_device(const std::string &file_name, read_tag tag=read_tag())
定义 device.hpp:64
void write_uint32(uint32_t x)
写入 32 位小端整数。
定义 device.hpp:245
void print_line(const std::string &line)
打印格式化的 ASCII 文本。
定义 device.hpp:284
void write_uint8(uint8_t x)
写入字节。
定义 device.hpp:227
void read(T(&buf)[N])
读取数组。
定义 device.hpp:165
file_stream_device(FILE *file)
定义 device.hpp:118
uint16_t read_uint16()
读取 16 位小端整数。
定义 device.hpp:182
uint8_t read_uint8()
读取字节。
定义 device.hpp:173
file_stream_device(const char *file_name, write_tag)
定义 device.hpp:100
auto read(byte_t *data, std::size_t count) -> std::size_t
定义 device.hpp:144
file_stream_device(const std::string &file_name, write_tag tag)
定义 device.hpp:91
void write(const T(&buf)[N])
写入数组。
定义 device.hpp:218
file_stream_device(const char *file_name, read_tag=read_tag())
定义 device.hpp:73
uint32_t read_uint32()
读取 32 位小端整数。
定义 device.hpp:191
void write_uint16(uint16_t x)
写入 16 位小端整数。
定义 device.hpp:234
auto write(T const *buf, std::size_t count) -> std::size_t
从缓冲区写入多个元素。
定义 device.hpp:201
void read(T(&buf)[N])
读取数组。
定义 device.hpp:372
uint16_t read_uint16()
读取 16 位小端整数。
定义 device.hpp:387
uint8_t read_uint8()
读取字节。
定义 device.hpp:378
uint32_t read_uint32()
读取 32 位小端整数。
定义 device.hpp:396
void write_uint32(uint32_t x)
写入 32 位小端整数。
定义 device.hpp:517
void print_line(const std::string &line)
打印格式化的 ASCII 文本。
定义 device.hpp:535
void write_uint8(uint8_t x)
写入字节。
定义 device.hpp:499
void write(const T(&buf)[N])
写入数组。
定义 device.hpp:493
void write_uint16(uint16_t x)
写入 16 位小端整数。
定义 device.hpp:506
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
定义 algorithm.hpp:36
用于重载构造函数。
定义 device.hpp:58