fuse_image_content.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <fvutils/net/fuse_image_content.h>
00025 #include <fvutils/ipc/shm_image.h>
00026 #include <fvutils/color/conversions.h>
00027 #include <fvutils/compression/jpeg_decompressor.h>
00028
00029 #include <core/exceptions/system.h>
00030 #include <core/exceptions/software.h>
00031
00032 #include <cstdlib>
00033 #include <netinet/in.h>
00034 #include <cstring>
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 FuseImageContent::FuseImageContent(uint32_t type,
00049 void *payload, size_t payload_size)
00050 {
00051 if ( type != FUSE_MT_IMAGE ) {
00052 throw fawkes::TypeMismatchException("Type %u != FUSE_MT_IMAGE (%u)", type, FUSE_MT_IMAGE);
00053 }
00054
00055 _payload_size = payload_size;
00056 _payload = payload;
00057
00058 __header = (FUSE_image_message_header_t *)_payload;
00059 __buffer = (unsigned char *)_payload + sizeof(FUSE_image_message_header_t);
00060 __capture_time = new fawkes::Time(ntohl(__header->capture_time_sec),
00061 ntohl(__header->capture_time_usec));
00062
00063 __buffer_size = ntohl(__header->buffer_size);
00064 }
00065
00066
00067
00068
00069
00070
00071 FuseImageContent::FuseImageContent(SharedMemoryImageBuffer *b)
00072 {
00073 __buffer_size = colorspace_buffer_size(b->colorspace(), b->width(), b->height());
00074 _payload_size = __buffer_size + sizeof(FUSE_image_message_header_t);
00075 _payload = malloc(_payload_size);
00076
00077 if ( _payload == NULL ) {
00078 throw fawkes::OutOfMemoryException("Cannot allocate FuseImageContent buffer");
00079 }
00080
00081 __header = (FUSE_image_message_header_t *)_payload;
00082 __buffer = (unsigned char *)_payload + sizeof(FUSE_image_message_header_t);
00083
00084 strncpy(__header->image_id, b->image_id(), IMAGE_ID_MAX_LENGTH);
00085 __header->format = FUSE_IF_RAW;
00086 __header->colorspace = htons(b->colorspace());
00087 __header->reserved = 0;
00088 __header->width = htonl(b->width());
00089 __header->height = htonl(b->height());
00090 __header->buffer_size = htonl(__buffer_size);
00091
00092 long int cts = 0, ctus = 0;
00093 b->capture_time(&cts, &ctus);
00094 __header->capture_time_sec = htonl(cts);
00095 __header->capture_time_usec = htonl(ctus);
00096
00097 __capture_time = NULL;
00098
00099 b->lock_for_read();
00100 memcpy(__buffer, b->buffer(), __buffer_size);
00101 b->unlock();
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 FuseImageContent::FuseImageContent(FUSE_image_format_t image_format, const char *image_id,
00118 unsigned char *buffer, size_t buffer_size,
00119 colorspace_t colorspace,
00120 unsigned int width, unsigned int height,
00121 long int capture_time_sec,
00122 long int capture_time_usec)
00123 {
00124 __buffer_size = buffer_size;
00125 _payload_size = __buffer_size + sizeof(FUSE_image_message_header_t);
00126 _payload = malloc(_payload_size);
00127
00128 if ( _payload == NULL ) {
00129 throw fawkes::OutOfMemoryException("Cannot allocate FuseImageContent buffer");
00130 }
00131
00132 __header = (FUSE_image_message_header_t *)_payload;
00133 __buffer = (unsigned char *)_payload + sizeof(FUSE_image_message_header_t);
00134
00135 strncpy(__header->image_id, image_id, IMAGE_ID_MAX_LENGTH);
00136 __header->format = image_format;
00137 __header->colorspace = htons(colorspace);
00138 __header->reserved = 0;
00139 __header->width = htonl(width);
00140 __header->height = htonl(height);
00141 __header->buffer_size = htonl(__buffer_size);
00142 __header->capture_time_sec = htonl(capture_time_sec);
00143 __header->capture_time_usec = htonl(capture_time_usec);
00144
00145 __capture_time = NULL;
00146
00147 memcpy(__buffer, buffer, __buffer_size);
00148 }
00149
00150
00151
00152 FuseImageContent::~FuseImageContent()
00153 {
00154 delete __capture_time;
00155 }
00156
00157
00158
00159
00160 unsigned char *
00161 FuseImageContent::buffer() const
00162 {
00163 return __buffer;
00164 }
00165
00166
00167
00168
00169
00170 size_t
00171 FuseImageContent::buffer_size() const
00172 {
00173 return __buffer_size;
00174 }
00175
00176
00177
00178
00179
00180 unsigned int
00181 FuseImageContent::pixel_width() const
00182 {
00183 return ntohl(__header->width);
00184 }
00185
00186
00187
00188
00189
00190 unsigned int
00191 FuseImageContent::pixel_height() const
00192 {
00193 return ntohl(__header->height);
00194 }
00195
00196
00197
00198
00199
00200 unsigned int
00201 FuseImageContent::colorspace() const
00202 {
00203 return ntohs(__header->colorspace);
00204 }
00205
00206
00207
00208
00209
00210 unsigned int
00211 FuseImageContent::format() const
00212 {
00213 return __header->format;
00214 }
00215
00216
00217
00218
00219
00220 fawkes::Time *
00221 FuseImageContent::capture_time() const
00222 {
00223 if ( ! __capture_time ) {
00224 __capture_time = new fawkes::Time(ntohl(__header->capture_time_sec),
00225 ntohl(__header->capture_time_usec));
00226 }
00227 return __capture_time;
00228 }
00229
00230 void
00231 FuseImageContent::serialize()
00232 {
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 void
00248 FuseImageContent::decompress(unsigned char *yuv422_planar_buffer, size_t buffer_size)
00249 {
00250 if ( buffer_size < colorspace_buffer_size(YUV422_PLANAR, ntohs(__header->width),
00251 ntohs(__header->height)) ) {
00252 throw fawkes::IllegalArgumentException("Supplied buffer is too small\n");
00253 }
00254 if ( __header->format != FUSE_IF_JPEG ) {
00255 JpegImageDecompressor *decompressor = new JpegImageDecompressor();
00256 decompressor->set_compressed_buffer(__buffer, __buffer_size);
00257 decompressor->set_decompressed_buffer(yuv422_planar_buffer, buffer_size);
00258 decompressor->decompress();
00259 delete decompressor;
00260 } else {
00261 convert((colorspace_t)ntohs(__header->colorspace), YUV422_PLANAR,
00262 __buffer, yuv422_planar_buffer,
00263 ntohs(__header->width), ntohs(__header->height));
00264 }
00265 }