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