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
;
128 this->imagedata
= new unsigned char[4 * width
* height
];
130 this->imagedata
= NULL
;
133 image_frame_rgbx::image_frame_rgbx(const image_frame_rgbx
& x
)
135 this->width
= x
.width
;
136 this->height
= x
.height
;
137 if(width
&& height
) {
138 this->imagedata
= new unsigned char[4 * width
* height
];
139 memcpy(imagedata
, x
.imagedata
, 4 * width
* height
);
141 this->imagedata
= NULL
;
144 image_frame_rgbx
& image_frame_rgbx::operator=(const image_frame_rgbx
& x
)
148 unsigned char* old_imagedata
= imagedata
;
149 if(x
.width
&& x
.height
)
150 this->imagedata
= new unsigned char[4 * x
.width
* x
.height
];
152 this->imagedata
= NULL
;
153 this->width
= x
.width
;
154 this->height
= x
.height
;
155 if(x
.width
&& x
.height
)
156 memcpy(imagedata
, x
.imagedata
, 4 * width
* height
);
157 delete[] old_imagedata
;
161 image_frame_rgbx::image_frame_rgbx(struct packet
& p
)
163 if(p
.rp_major
!= 0) {
164 std::stringstream str
;
165 str
<< "frame_from_packet: Incorrect major type (" << p
.rp_major
<< ", should be 0)";
166 throw std::runtime_error(str
.str());
168 if(p
.rp_minor
!= 0 && p
.rp_minor
!= 1) {
169 std::stringstream str
;
170 str
<< "frame_from_packet: Unknown minor type (" << p
.rp_minor
<< ", should be 0 or 1)";
171 throw std::runtime_error(str
.str());
173 if(p
.rp_payload
.size() < 4)
174 throw std::runtime_error("frame_from_packet: Malformed payload (image parameters missing)");
176 uint32_t ihdr
= decode32(&p
.rp_payload
[0]);
177 width
= ihdr
/ 65536;
178 height
= ihdr
% 65536;
179 imagedata
= new unsigned char[4 * width
* height
];
182 memcpy(imagedata
, &p
.rp_payload
[4], 4 * width
* height
);
183 else if(p
.rp_minor
== 1)
185 decode_zlib(imagedata
, &p
.rp_payload
[4], p
.rp_payload
.size() - 4, width
* height
);
193 size_t image_frame_rgbx::get_data_size() const
195 return 4 * width
* height
;
198 image_frame_rgbx
& image_frame_rgbx::resize(uint32_t nwidth
, uint32_t nheight
, resizer
& using_resizer
)
200 if(width
== nwidth
&& height
== nheight
)
202 image_frame_rgbx
* newf
= new image_frame_rgbx(nwidth
, nheight
);
203 if(width
== 0 && height
== 0) {
205 memset(newf
->get_pixels(), 0, newf
->get_data_size());
208 using_resizer(newf
->get_pixels(), nwidth
, nheight
, get_pixels(), width
, height
);
216 std::map
<std::string
, resizer_factory
*>* resizer_factory::factories
;
218 resizer_factory::~resizer_factory()
222 resizer_factory::resizer_factory(const std::string
& type
)
225 factories
= new std::map
<std::string
, resizer_factory
*>();
226 (*factories
)[type
] = this;
229 resizer
& resizer_factory::make_by_type(const std::string
& type
)
231 if(!factories
|| !factories
->count(type
))
232 throw std::runtime_error("Unknown output driver type");
233 return (*factories
)[type
]->make(type
);
236 std::string
get_resizer_list()
239 if(!resizer_factory::factories
)
242 std::map
<std::string
, resizer_factory
*>& f
= *resizer_factory::factories
;
243 for(std::map
<std::string
, resizer_factory
*>::iterator i
= f
.begin(); i
!= f
.end(); ++i
) {
247 c
= c
+ " " + i
->first
;
255 class simple_resizer_c
: public resizer
258 simple_resizer_c(void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
259 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
))
261 resize_fn
= _resize_fn
;
264 void operator()(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
265 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
)
267 resize_fn(target
, twidth
, theight
, source
, swidth
, sheight
);
271 void(*resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
272 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
);
275 class simple_resizer_c2
: public resizer
278 simple_resizer_c2(void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
279 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
), int _algo
)
281 resize_fn
= _resize_fn
;
285 void operator()(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
286 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
)
288 resize_fn(target
, twidth
, theight
, source
, swidth
, sheight
, algo
);
292 void(*resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
293 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
);
298 simple_resizer::simple_resizer(const std::string
& type
, void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
299 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
))
300 : resizer_factory(type
)
302 resize_fn
= _resize_fn
;
307 simple_resizer::simple_resizer(const std::string
& type
, void(*_resize_fn
)(uint8_t* target
, uint32_t twidth
, uint32_t theight
,
308 const uint8_t* source
, uint32_t swidth
, uint32_t sheight
, int algo
), int _algo
)
309 : resizer_factory(type
)
312 resize_fn2
= _resize_fn
;
316 resizer
& simple_resizer::make(const std::string
& type
)
319 return *new simple_resizer_c(resize_fn
);
321 return *new simple_resizer_c2(resize_fn2
, algo
);