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