13 uint32_t decode32(const unsigned char* buf
)
16 v
|= ((uint32_t)buf
[0] << 24);
17 v
|= ((uint32_t)buf
[1] << 16);
18 v
|= ((uint32_t)buf
[2] << 8);
19 v
|= ((uint32_t)buf
[3]);
23 #define INBUF_SIZE 16384
24 #define OUTBUF_SIZE 16384
26 void decode_zlib(unsigned char* target
, const unsigned char* src
, uint32_t insize
, uint32_t pixels
)
28 unsigned char out
[INBUF_SIZE
];
29 unsigned char in
[OUTBUF_SIZE
];
33 memset(&s
, 0, sizeof(s
));
34 int r
= inflateInit(&s
);
36 std::stringstream str
;
37 str
<< "inflateInit: zlib error: " << s
.msg
;
38 throw std::runtime_error(str
.str());
44 s
.avail_out
= INBUF_SIZE
;
47 uint32_t old_avail_out
= s
.avail_out
;
50 if(insize
> OUTBUF_SIZE
) {
52 s
.avail_in
= OUTBUF_SIZE
;
53 memcpy(s
.next_in
, src
, OUTBUF_SIZE
);
55 insize
-= OUTBUF_SIZE
;
59 memcpy(s
.next_in
, src
, insize
);
65 r
= inflate(&s
, Z_NO_FLUSH
);
68 std::stringstream str
;
69 str
<< "inflate: zlib error: " << s
.msg
;
70 throw std::runtime_error(str
.str());
72 dptr
+= (old_avail_out
- s
.avail_out
);
73 if(s
.avail_out
== 0) {
74 memcpy(target
, out
, INBUF_SIZE
);
76 s
.avail_out
= INBUF_SIZE
;
79 if(dptr
== 4 * pixels
) {
80 memcpy(target
, out
, INBUF_SIZE
- s
.avail_out
);
81 target
+= (INBUF_SIZE
- s
.avail_out
);
82 s
.avail_out
= INBUF_SIZE
;
86 if(r
== Z_STREAM_END
) {
88 std::stringstream str
;
89 str
<< "Uncompressed stream truncated";
90 throw std::runtime_error(str
.str());
98 const unsigned char* image_frame_rgbx::get_pixels() const
103 unsigned char* image_frame_rgbx::get_pixels()
108 uint32_t image_frame_rgbx::get_height() const
113 uint32_t image_frame_rgbx::get_width() const
118 image_frame_rgbx::~image_frame_rgbx()
123 image_frame_rgbx::image_frame_rgbx(uint32_t width
, uint32_t height
)
126 this->height
= height
;
127 if(width
&& height
) {
128 this->imagedata
= new unsigned char[4 * width
* height
];
129 memset(this->imagedata
, 0, 4 * width
* height
);
131 this->imagedata
= NULL
;
134 image_frame_rgbx::image_frame_rgbx(const image_frame_rgbx
& x
)
136 this->width
= x
.width
;
137 this->height
= x
.height
;
138 if(width
&& height
) {
139 this->imagedata
= new unsigned char[4 * width
* height
];
140 memcpy(imagedata
, x
.imagedata
, 4 * width
* height
);
142 this->imagedata
= NULL
;
145 image_frame_rgbx
& image_frame_rgbx::operator=(const image_frame_rgbx
& x
)
149 unsigned char* old_imagedata
= imagedata
;
150 if(x
.width
&& x
.height
)
151 this->imagedata
= new unsigned char[4 * x
.width
* x
.height
];
153 this->imagedata
= NULL
;
154 this->width
= x
.width
;
155 this->height
= x
.height
;
156 if(x
.width
&& x
.height
)
157 memcpy(imagedata
, x
.imagedata
, 4 * width
* height
);
158 delete[] old_imagedata
;
162 image_frame_rgbx::image_frame_rgbx(struct packet
& p
)
164 if(p
.rp_major
!= 0) {
165 std::stringstream str
;
166 str
<< "frame_from_packet: Incorrect major type (" << p
.rp_major
<< ", should be 0)";
167 throw std::runtime_error(str
.str());
169 if(p
.rp_minor
!= 0 && p
.rp_minor
!= 1) {
170 std::stringstream str
;
171 str
<< "frame_from_packet: Unknown minor type (" << p
.rp_minor
<< ", should be 0 or 1)";
172 throw std::runtime_error(str
.str());
174 if(p
.rp_payload
.size() < 4)
175 throw std::runtime_error("frame_from_packet: Malformed payload (image parameters missing)");
177 uint32_t ihdr
= decode32(&p
.rp_payload
[0]);
178 width
= ihdr
/ 65536;
179 height
= ihdr
% 65536;
180 imagedata
= new unsigned char[4 * width
* height
];
183 memcpy(imagedata
, &p
.rp_payload
[4], 4 * width
* height
);
184 else if(p
.rp_minor
== 1)
186 decode_zlib(imagedata
, &p
.rp_payload
[4], p
.rp_payload
.size() - 4, width
* height
);
194 size_t image_frame_rgbx::get_data_size() const
196 return 4 * width
* height
;
199 image_frame_rgbx
& image_frame_rgbx::resize(uint32_t nwidth
, uint32_t nheight
, resizer
& using_resizer
)
201 if(width
== nwidth
&& height
== nheight
)
203 image_frame_rgbx
* newf
= new image_frame_rgbx(nwidth
, nheight
);
204 if(width
== 0 && height
== 0) {
206 memset(newf
->get_pixels(), 0, newf
->get_data_size());
209 using_resizer(newf
->get_pixels(), nwidth
, nheight
, get_pixels(), width
, height
);
217 std::map
<std::string
, resizer_factory
*>* resizer_factory::factories
;
219 resizer_factory::~resizer_factory()
223 resizer_factory::resizer_factory(const std::string
& type
)
226 factories
= new std::map
<std::string
, resizer_factory
*>();
227 (*factories
)[type
] = this;
230 resizer
& resizer_factory::make_by_type(const std::string
& type
)
232 if(!factories
|| !factories
->count(type
))
233 throw std::runtime_error("Unknown output driver type");
234 return (*factories
)[type
]->make(type
);
237 std::string
get_resizer_list()
240 if(!resizer_factory::factories
)
243 std::map
<std::string
, resizer_factory
*>& f
= *resizer_factory::factories
;
244 for(std::map
<std::string
, resizer_factory
*>::iterator i
= f
.begin(); i
!= f
.end(); ++i
) {
248 c
= c
+ " " + i
->first
;
256 class simple_resizer_c
: public resizer
259 simple_resizer_c(void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
260 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
))
262 resize_fn
= _resize_fn
;
265 void operator()(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
266 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
)
268 resize_fn(target
, twidth
, theight
, source
, swidth
, sheight
);
272 void(*resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
273 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
);
276 class simple_resizer_c2
: public resizer
279 simple_resizer_c2(void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
280 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
), int _algo
)
282 resize_fn
= _resize_fn
;
286 void operator()(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
287 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
)
289 resize_fn(target
, twidth
, theight
, source
, swidth
, sheight
, algo
);
293 void(*resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
294 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
);
299 simple_resizer::simple_resizer(const std::string
& type
, void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
300 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
))
301 : resizer_factory(type
)
303 resize_fn
= _resize_fn
;
308 simple_resizer::simple_resizer(const std::string
& type
, void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
309 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
), int _algo
)
310 : resizer_factory(type
)
313 resize_fn2
= _resize_fn
;
317 resizer
& simple_resizer::make(const std::string
& type
)
320 return *new simple_resizer_c(resize_fn
);
322 return *new simple_resizer_c2(resize_fn2
, algo
);