7 #include <boost/iostreams/categories.hpp>
8 #include <boost/iostreams/copy.hpp>
9 #include <boost/iostreams/stream.hpp>
10 #include <boost/iostreams/stream_buffer.hpp>
11 #include <boost/iostreams/filter/symmetric.hpp>
12 #include <boost/iostreams/filter/zlib.hpp>
13 #include <boost/iostreams/filtering_stream.hpp>
14 #include <boost/iostreams/device/back_inserter.hpp>
18 void encode32(char* _buf
, uint32_t val
) throw()
20 unsigned char* buf
= reinterpret_cast<unsigned char*>(_buf
);
21 buf
[0] = ((val
>> 24) & 0xFF);
22 buf
[1] = ((val
>> 16) & 0xFF);
23 buf
[2] = ((val
>> 8) & 0xFF);
24 buf
[3] = (val
& 0xFF);
30 typedef char char_type
;
31 struct category
: boost::iostreams::closable_tag
, boost::iostreams::sink_tag
{};
32 png_hunk_output(std::ostream
& _os
, uint32_t _type
)
33 : os(_os
), type(_type
)
39 uint32_t crc
= crc32(0, NULL
, 0);
41 encode32(fixed
, stream
.size());
42 encode32(fixed
+ 4, type
);
43 crc
= crc32(crc
, reinterpret_cast<Bytef
*>(fixed
+ 4), 4);
45 crc
= crc32(crc
, reinterpret_cast<Bytef
*>(&stream
[0]), stream
.size());
46 encode32(fixed
+ 8, crc
);
48 os
.write(&stream
[0], stream
.size());
49 os
.write(fixed
+ 8, 4);
52 std::streamsize
write(const char* s
, std::streamsize n
)
54 size_t oldsize
= stream
.size();
55 stream
.resize(oldsize
+ n
);
56 memcpy(&stream
[oldsize
], s
, n
);
60 std::vector
<char> stream
;
66 void save_png_data(const std::string
& file
, uint8_t* data24
, uint32_t width
, uint32_t height
) throw(std::bad_alloc
,
69 char* data
= reinterpret_cast<char*>(data24
);
70 std::ofstream
filp(file
.c_str());
72 throw std::runtime_error("Can't open target PNG file");
73 char png_magic
[] = {-119, 80, 78, 71, 13, 10, 26, 10};
74 filp
.write(png_magic
, sizeof(png_magic
));
75 char ihdr
[] = {25, 25, 25, 25, 25, 25, 25, 25, 8, 2, 0, 0, 0};
76 boost::iostreams::stream
<png_hunk_output
> ihdr_h(filp
, 0x49484452);
77 encode32(ihdr
, width
);
78 encode32(ihdr
+ 4, height
);
79 ihdr_h
.write(ihdr
, sizeof(ihdr
));
82 boost::iostreams::filtering_ostream idat_h
;
83 boost::iostreams::zlib_params params
;
84 params
.noheader
= false;
85 idat_h
.push(boost::iostreams::zlib_compressor(params
));
86 idat_h
.push(png_hunk_output(filp
, 0x49444154));
87 for(uint32_t i
= 0; i
< height
; i
++) {
88 char identity_filter
= 0;
89 idat_h
.write(&identity_filter
, 1);
90 idat_h
.write(data
+ i
* 3 * width
, 3 * width
);
95 boost::iostreams::stream
<png_hunk_output
> iend_h(filp
, 0x49454E44);
98 throw std::runtime_error("Can't write target PNG file");