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
, rescaler_group
& rescalers
)
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 rescalers(newf
->get_pixels(), nwidth
, nheight
, get_pixels(), width
, height
);