00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "vidl2_convert.h"
00018 #include "vidl2_frame.h"
00019 #include "vidl2_pixel_format.h"
00020 #include "vidl2_pixel_iterator.txx"
00021 #include "vidl2_color.h"
00022 #include <vil/vil_convert.h>
00023 #include <vil/vil_memory_chunk.h>
00024 #include <vcl_cstring.h>
00025 #include <vcl_cassert.h>
00026 #include <vcl_memory.h>
00027
00028
00029
00030
00031 namespace {
00032
00033
00034 typedef bool (*converter_func)(const vidl2_frame& in_frame, vidl2_frame& out_frame);
00035
00036
00037
00038 bool default_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00039 {
00040 vcl_cerr << "No routine to convert " << in_frame.pixel_format()
00041 << " to " << out_frame.pixel_format() << vcl_endl;
00042 return false;
00043 }
00044
00045
00046
00047 bool copy_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00048 {
00049 assert(in_frame.pixel_format() == out_frame.pixel_format());
00050 assert(in_frame.size() == out_frame.size());
00051 vcl_memcpy(out_frame.data(), in_frame.data(), in_frame.size());
00052 return true;
00053 }
00054
00055
00056
00057
00058
00059
00060 bool intermediate_rgb24_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame);
00061
00062
00063
00064 template <vidl2_pixel_format in_Fmt, vidl2_pixel_format out_Fmt>
00065 struct convert
00066 {
00067 enum { defined = false };
00068 static inline bool apply(const vidl2_frame& ,
00069 vidl2_frame& )
00070 {
00071 return false;
00072 }
00073 };
00074
00075
00076
00077
00078
00079
00080 bool convert_generic(const vidl2_frame& in_frame,
00081 vidl2_frame& out_frame)
00082 {
00083
00084 vcl_auto_ptr<vidl2_pixel_iterator> in_pitr(vidl2_make_pixel_iterator(in_frame));
00085 if (!in_pitr.get())
00086 return false;
00087 vcl_auto_ptr<vidl2_pixel_iterator> out_pitr(vidl2_make_pixel_iterator(out_frame));
00088 if (!out_pitr.get())
00089 return false;
00090
00091 vidl2_pixel_iterator& in_itr = *in_pitr;
00092 vidl2_pixel_iterator& out_itr = *out_pitr;
00093
00094 vidl2_pixel_traits in_t = vidl2_pixel_format_traits(in_frame.pixel_format());
00095 vidl2_pixel_traits out_t = vidl2_pixel_format_traits(out_frame.pixel_format());
00096
00097
00098 vidl2_color_conv_fptr color_conv =
00099 vidl2_color_converter_func( in_t.color, in_t.bits_per_pixel,
00100 out_t.color, out_t.bits_per_pixel);
00101 if (!color_conv)
00102 return false;
00103
00104 const unsigned int num_pix = in_frame.ni() * in_frame.nj();
00105 vxl_byte in_pixel[4], out_pixel[4];
00106 for (unsigned int c=0; c<num_pix; ++c, ++in_itr, ++out_itr){
00107 in_itr.get_data(in_pixel);
00108 color_conv(in_pixel, out_pixel);
00109 out_itr.set_data(out_pixel);
00110 }
00111 return true;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 VCL_DEFINE_SPECIALIZATION
00121 struct convert<VIDL2_PIXEL_FORMAT_RGB_24, VIDL2_PIXEL_FORMAT_UYVY_422>
00122 {
00123 enum { defined = true };
00124 static inline bool apply(const vidl2_frame& in_frame,
00125 vidl2_frame& out_frame)
00126 {
00127 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00128 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00129 const vxl_byte* rgb = reinterpret_cast<const vxl_byte*>(in_frame.data());
00130 vxl_byte* uyvy = reinterpret_cast<vxl_byte*>(out_frame.data());
00131 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00132 for (unsigned int c=0; c<num_half_pix; ++c){
00133 const vxl_byte& r1 = *(rgb++);
00134 const vxl_byte& g1 = *(rgb++);
00135 const vxl_byte& b1 = *(rgb++);
00136 const vxl_byte& r2 = *(rgb++);
00137 const vxl_byte& g2 = *(rgb++);
00138 const vxl_byte& b2 = *(rgb++);
00139 vxl_byte y1,u1,v1,y2,u2,v2;
00140 vidl2_color_convert_rgb2yuv(r1,g1,b1,y1,u1,v1);
00141 vidl2_color_convert_rgb2yuv(r2,g2,b2,y2,u2,v2);
00142 *(uyvy++) = (u1+u2)/2;
00143 *(uyvy++) = y1;
00144 *(uyvy++) = (v1+v2)/2;
00145 *(uyvy++) = y2;
00146 }
00147 return true;
00148 }
00149 };
00150
00151
00152
00153 VCL_DEFINE_SPECIALIZATION
00154 struct convert<VIDL2_PIXEL_FORMAT_UYVY_422, VIDL2_PIXEL_FORMAT_RGB_24>
00155 {
00156 enum { defined = true };
00157 static inline bool apply(const vidl2_frame& in_frame,
00158 vidl2_frame& out_frame)
00159 {
00160 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00161 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00162 const vxl_byte* uyvy = reinterpret_cast<const vxl_byte*>(in_frame.data());
00163 vxl_byte* rgb = reinterpret_cast<vxl_byte*>(out_frame.data());
00164 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00165 for (unsigned int c=0; c<num_half_pix; ++c){
00166 const vxl_byte& u1 = *(uyvy++);
00167 const vxl_byte& y1 = *(uyvy++);
00168 const vxl_byte& v1 = *(uyvy++);
00169 const vxl_byte& y2 = *(uyvy++);
00170 vxl_byte r,g,b;
00171 vidl2_color_convert_yuv2rgb(y1,u1,v1,r,g,b);
00172 *(rgb++) = r;
00173 *(rgb++) = g;
00174 *(rgb++) = b;
00175 vidl2_color_convert_yuv2rgb(y2,u1,v1,r,g,b);
00176 *(rgb++) = r;
00177 *(rgb++) = g;
00178 *(rgb++) = b;
00179 }
00180 return true;
00181 }
00182 };
00183
00184
00185
00186 VCL_DEFINE_SPECIALIZATION
00187 struct convert<VIDL2_PIXEL_FORMAT_UYVY_422, VIDL2_PIXEL_FORMAT_MONO_8>
00188 {
00189 enum { defined = true };
00190 static inline bool apply(const vidl2_frame& in_frame,
00191 vidl2_frame& out_frame)
00192 {
00193 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_UYVY_422);
00194 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_MONO_8);
00195 const vxl_byte* uyvy = reinterpret_cast<const vxl_byte*>(in_frame.data());
00196 vxl_byte* mono = reinterpret_cast<vxl_byte*>(out_frame.data());
00197 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00198 for (unsigned int c=0; c<num_half_pix; ++c){
00199 ++uyvy;
00200 const vxl_byte& y1 = *(uyvy++);
00201 ++uyvy;
00202 const vxl_byte& y2 = *(uyvy++);
00203 *(mono++) = y1;
00204 *(mono++) = y2;
00205 }
00206 return true;
00207 }
00208 };
00209
00210
00211
00212 VCL_DEFINE_SPECIALIZATION
00213 struct convert<VIDL2_PIXEL_FORMAT_RGB_24, VIDL2_PIXEL_FORMAT_YUYV_422>
00214 {
00215 enum { defined = true };
00216 static inline bool apply(const vidl2_frame& in_frame,
00217 vidl2_frame& out_frame)
00218 {
00219 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00220 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_YUYV_422);
00221 const vxl_byte* rgb = reinterpret_cast<const vxl_byte*>(in_frame.data());
00222 vxl_byte* yuyv = reinterpret_cast<vxl_byte*>(out_frame.data());
00223 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00224 for (unsigned int c=0; c<num_half_pix; ++c){
00225 const vxl_byte& r1 = *(rgb++);
00226 const vxl_byte& g1 = *(rgb++);
00227 const vxl_byte& b1 = *(rgb++);
00228 const vxl_byte& r2 = *(rgb++);
00229 const vxl_byte& g2 = *(rgb++);
00230 const vxl_byte& b2 = *(rgb++);
00231 vxl_byte y1,u1,v1,y2,u2,v2;
00232 vidl2_color_convert_rgb2yuv(r1,g1,b1,y1,u1,v1);
00233 vidl2_color_convert_rgb2yuv(r2,g2,b2,y2,u2,v2);
00234 *(yuyv++) = y1;
00235 *(yuyv++) = (u1+u2)/2;
00236 *(yuyv++) = y2;
00237 *(yuyv++) = (v1+v2)/2;
00238 }
00239 return true;
00240 }
00241 };
00242
00243
00244
00245 VCL_DEFINE_SPECIALIZATION
00246 struct convert<VIDL2_PIXEL_FORMAT_YUYV_422, VIDL2_PIXEL_FORMAT_RGB_24>
00247 {
00248 enum { defined = true };
00249 static inline bool apply(const vidl2_frame& in_frame,
00250 vidl2_frame& out_frame)
00251 {
00252 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_YUYV_422);
00253 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24);
00254 const vxl_byte* yuyv = reinterpret_cast<const vxl_byte*>(in_frame.data());
00255 vxl_byte* rgb = reinterpret_cast<vxl_byte*>(out_frame.data());
00256 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00257 for (unsigned int c=0; c<num_half_pix; ++c){
00258 const vxl_byte& y1 = *(yuyv++);
00259 const vxl_byte& u1 = *(yuyv++);
00260 const vxl_byte& y2 = *(yuyv++);
00261 const vxl_byte& v1 = *(yuyv++);
00262 vxl_byte r,g,b;
00263 vidl2_color_convert_yuv2rgb(y1,u1,v1,r,g,b);
00264 *(rgb++) = r;
00265 *(rgb++) = g;
00266 *(rgb++) = b;
00267 vidl2_color_convert_yuv2rgb(y2,u1,v1,r,g,b);
00268 *(rgb++) = r;
00269 *(rgb++) = g;
00270 *(rgb++) = b;
00271 }
00272 return true;
00273 }
00274 };
00275
00276
00277
00278 VCL_DEFINE_SPECIALIZATION
00279 struct convert<VIDL2_PIXEL_FORMAT_RGB_24P, VIDL2_PIXEL_FORMAT_YUYV_422>
00280 {
00281 enum { defined = true };
00282 static inline bool apply(const vidl2_frame& in_frame,
00283 vidl2_frame& out_frame)
00284 {
00285 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24P);
00286 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_YUYV_422);
00287 const vxl_byte* red = reinterpret_cast<const vxl_byte*>(in_frame.data());
00288 const vxl_byte* green= red+in_frame.ni() * in_frame.nj();
00289 const vxl_byte* blue= green+in_frame.ni() * in_frame.nj();
00290 vxl_byte* yuyv = reinterpret_cast<vxl_byte*>(out_frame.data());
00291 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00292 for (unsigned int c=0; c<num_half_pix; ++c){
00293 const vxl_byte& r1 = *(red++);
00294 const vxl_byte& g1 = *(green++);
00295 const vxl_byte& b1 = *(blue++);
00296 const vxl_byte& r2 = *(red++);
00297 const vxl_byte& g2 = *(green++);
00298 const vxl_byte& b2 = *(blue++);
00299 vxl_byte y1,u1,v1,y2,u2,v2;
00300 vidl2_color_convert_rgb2yuv(r1,g1,b1,y1,u1,v1);
00301 vidl2_color_convert_rgb2yuv(r2,g2,b2,y2,u2,v2);
00302 *(yuyv++) = y1;
00303 *(yuyv++) = (u1+u2)/2;
00304 *(yuyv++) = y2;
00305 *(yuyv++) = (v1+v2)/2;
00306 }
00307 return true;
00308 }
00309 };
00310
00311
00312 VCL_DEFINE_SPECIALIZATION
00313 struct convert<VIDL2_PIXEL_FORMAT_YUYV_422, VIDL2_PIXEL_FORMAT_RGB_24P>
00314 {
00315 enum { defined = true };
00316 static inline bool apply(const vidl2_frame& in_frame,
00317 vidl2_frame& out_frame)
00318 {
00319 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_YUYV_422);
00320 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_RGB_24P);
00321 const vxl_byte* yuyv = reinterpret_cast<const vxl_byte*>(in_frame.data());
00322 vxl_byte* red = reinterpret_cast<vxl_byte*>(out_frame.data());
00323 vxl_byte* green = red+out_frame.ni()*out_frame.nj();
00324 vxl_byte* blue = green+out_frame.ni()*out_frame.nj();
00325 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00326 for (unsigned int c=0; c<num_half_pix; ++c){
00327 const vxl_byte& y1 = *(yuyv++);
00328 const vxl_byte& u1 = *(yuyv++);
00329 const vxl_byte& y2 = *(yuyv++);
00330 const vxl_byte& v1 = *(yuyv++);
00331 vxl_byte r,g,b;
00332 vidl2_color_convert_yuv2rgb(y1,u1,v1,r,g,b);
00333 *(red++) = r;
00334 *(green++) = g;
00335 *(blue++) = b;
00336 vidl2_color_convert_yuv2rgb(y2,u1,v1,r,g,b);
00337 *(red++) = r;
00338 *(green++) = g;
00339 *(blue++) = b;
00340 }
00341 return true;
00342 }
00343 };
00344
00345
00346 VCL_DEFINE_SPECIALIZATION
00347 struct convert<VIDL2_PIXEL_FORMAT_YUYV_422, VIDL2_PIXEL_FORMAT_MONO_8>
00348 {
00349 enum { defined = true };
00350 static inline bool apply(const vidl2_frame& in_frame,
00351 vidl2_frame& out_frame)
00352 {
00353 assert(in_frame.pixel_format()==VIDL2_PIXEL_FORMAT_YUYV_422);
00354 assert(out_frame.pixel_format()==VIDL2_PIXEL_FORMAT_MONO_8);
00355 const vxl_byte* yuyv = reinterpret_cast<const vxl_byte*>(in_frame.data());
00356 vxl_byte* mono = reinterpret_cast<vxl_byte*>(out_frame.data());
00357 unsigned int num_half_pix = (in_frame.ni() * in_frame.nj() + 1)/2;
00358 for (unsigned int c=0; c<num_half_pix; ++c){
00359 const vxl_byte& y1 = *(yuyv++);
00360 ++yuyv;
00361 const vxl_byte& y2 = *(yuyv++);
00362 ++yuyv;
00363 *(mono++) = y1;
00364 *(mono++) = y2;
00365 }
00366 return true;
00367 }
00368 };
00369
00370
00371
00372
00373
00374
00375
00376
00377 template <vidl2_pixel_format in_Fmt, vidl2_pixel_format out_Fmt>
00378 struct table_entry_init
00379 {
00380 static inline void set_entry(converter_func& table_entry)
00381 {
00382
00383
00384 if (in_Fmt == out_Fmt)
00385 table_entry = ©_conversion;
00386 else if (convert<in_Fmt,out_Fmt>::defined)
00387 table_entry = &convert<in_Fmt,out_Fmt>::apply;
00388 else if (vidl2_pixel_iterator_valid<in_Fmt>::value &&
00389 vidl2_pixel_iterator_valid<out_Fmt>::value)
00390 table_entry = &convert_generic;
00391 else
00392 table_entry = &default_conversion;
00393 }
00394 };
00395
00396
00397 template <int Fmt_Code>
00398 struct table_init
00399 {
00400 static inline void populate(converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END])
00401 {
00402 const vidl2_pixel_format in_fmt = vidl2_pixel_format(Fmt_Code/VIDL2_PIXEL_FORMAT_ENUM_END);
00403 const vidl2_pixel_format out_fmt = vidl2_pixel_format(Fmt_Code%VIDL2_PIXEL_FORMAT_ENUM_END);
00404 table_entry_init<in_fmt,out_fmt>::set_entry(table[in_fmt][out_fmt]);
00405 table_init<Fmt_Code-1>::populate(table);
00406 }
00407 };
00408
00409
00410
00411 VCL_DEFINE_SPECIALIZATION
00412 struct table_init<0>
00413 {
00414 static inline void populate(converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END])
00415 {
00416 const vidl2_pixel_format in_fmt = vidl2_pixel_format(0);
00417 const vidl2_pixel_format out_fmt = vidl2_pixel_format(0);
00418 table_entry_init<in_fmt,out_fmt>::set_entry(table[in_fmt][out_fmt]);
00419 }
00420 };
00421
00422
00423
00424 class converter
00425 {
00426 public:
00427
00428 converter()
00429 {
00430
00431 table_init<VIDL2_PIXEL_FORMAT_ENUM_END*VIDL2_PIXEL_FORMAT_ENUM_END-1>::populate(table);
00432 }
00433
00434
00435 bool operator()(const vidl2_frame& in_frame, vidl2_frame& out_frame) const
00436 {
00437 return (*table[in_frame.pixel_format()][out_frame.pixel_format()])(in_frame, out_frame);
00438 }
00439 private:
00440
00441 converter_func table[VIDL2_PIXEL_FORMAT_ENUM_END][VIDL2_PIXEL_FORMAT_ENUM_END];
00442 };
00443
00444
00445 converter conversion_table;
00446
00447
00448
00449 bool intermediate_rgb24_conversion(const vidl2_frame& in_frame, vidl2_frame& out_frame)
00450 {
00451 unsigned int ni = in_frame.ni(), nj = in_frame.nj();
00452 vil_memory_chunk_sptr memory = new vil_memory_chunk(ni*nj*3, VIL_PIXEL_FORMAT_BYTE);
00453 vidl2_memory_chunk_frame temp_frame(ni,nj,VIDL2_PIXEL_FORMAT_RGB_24,memory);
00454 return conversion_table(in_frame, temp_frame) &&
00455 conversion_table(temp_frame, out_frame);
00456 }
00457
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467 bool vidl2_convert_frame(const vidl2_frame& in_frame,
00468 vidl2_frame& out_frame)
00469 {
00470 vidl2_pixel_format in_fmt = in_frame.pixel_format();
00471 vidl2_pixel_format out_fmt = out_frame.pixel_format();
00472
00473 if (in_fmt == VIDL2_PIXEL_FORMAT_UNKNOWN ||
00474 out_fmt == VIDL2_PIXEL_FORMAT_UNKNOWN)
00475 return false;
00476
00477 unsigned ni = in_frame.ni();
00478 unsigned nj = in_frame.nj();
00479 unsigned out_size = vidl2_pixel_format_buffer_size(ni,nj,out_fmt);
00480
00481 if (out_frame.size() != out_size ||
00482 out_frame.ni() != ni ||
00483 out_frame.nj() != nj ||
00484 !out_frame.data() )
00485 return false;
00486
00487
00488 return conversion_table(in_frame, out_frame);
00489 }
00490
00491
00492
00493
00494
00495
00496 vidl2_frame_sptr vidl2_convert_frame(const vidl2_frame_sptr& in_frame,
00497 vidl2_pixel_format format)
00498 {
00499 if (format == VIDL2_PIXEL_FORMAT_UNKNOWN)
00500 return NULL;
00501
00502 unsigned ni = in_frame->ni();
00503 unsigned nj = in_frame->nj();
00504 unsigned size = vidl2_pixel_format_buffer_size(ni,nj,format);
00505 vil_memory_chunk_sptr memory = new vil_memory_chunk(size, VIL_PIXEL_FORMAT_BYTE);
00506 vidl2_frame_sptr out_frame = new vidl2_memory_chunk_frame(ni, nj, format, memory);
00507
00508 if (vidl2_convert_frame(*in_frame, *out_frame))
00509 return out_frame;
00510
00511 return NULL;
00512 }
00513
00514
00515
00516
00517
00518 vidl2_frame_sptr vidl2_convert_to_frame(const vil_image_view_base_sptr& image)
00519 {
00520 if (!image)
00521 return NULL;
00522
00523
00524 vidl2_frame_sptr frame = new vidl2_memory_chunk_frame(*image);
00525 if (frame->pixel_format() != VIDL2_PIXEL_FORMAT_UNKNOWN)
00526 return frame;
00527
00528
00529 unsigned ni = image->ni(), nj = image->nj(), np = image->nplanes();
00530
00531
00532 if (image->pixel_format() == VIL_PIXEL_FORMAT_UINT_16)
00533 {
00534 if (np != 1)
00535 return NULL;
00536 vil_image_view<vxl_uint_16> img(ni,nj);
00537 img.deep_copy(vil_image_view<vxl_uint_16>(*image));
00538 return new vidl2_memory_chunk_frame(ni, nj, VIDL2_PIXEL_FORMAT_MONO_16,
00539 img.memory_chunk());
00540 }
00541
00542 vidl2_pixel_format format = VIDL2_PIXEL_FORMAT_UNKNOWN;
00543 if (np == 1)
00544 format = VIDL2_PIXEL_FORMAT_MONO_8;
00545 else if (np == 3)
00546 format = VIDL2_PIXEL_FORMAT_RGB_24P;
00547 else if (np == 4)
00548 format = VIDL2_PIXEL_FORMAT_RGBA_32P;
00549 else
00550 return NULL;
00551
00552 vil_image_view<vxl_byte> img;
00553 if (image->pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00554 img.deep_copy(vil_image_view<vxl_byte>(*image));
00555 else
00556 {
00557 vil_image_view_base_sptr bimage = vil_convert_cast(vxl_byte(),image);
00558 if (!bimage)
00559 return NULL;
00560 img = *bimage;
00561 }
00562 return new vidl2_memory_chunk_frame(ni, nj, format,
00563 img.memory_chunk());
00564 }
00565
00566
00567
00568
00569
00570 bool vidl2_convert_to_view(const vidl2_frame& frame,
00571 vil_image_view_base& image,
00572 vidl2_pixel_color require_color)
00573 {
00574 if (frame.pixel_format() == VIDL2_PIXEL_FORMAT_UNKNOWN ||
00575 frame.data() == NULL)
00576 return false;
00577
00578 vidl2_pixel_color in_color = vidl2_pixel_format_color(frame.pixel_format());
00579 if (require_color == VIDL2_PIXEL_COLOR_UNKNOWN)
00580 require_color = in_color;
00581
00582 unsigned ni = frame.ni(), nj = frame.nj();
00583 unsigned np = vidl2_pixel_color_num_channels(require_color);
00584
00585
00586 image.set_size(ni,nj,np);
00587
00588
00589 if (frame.pixel_format() == VIDL2_PIXEL_FORMAT_MONO_16){
00590 vil_image_view<vxl_uint_16> wrapper(static_cast<const vxl_uint_16*>(frame.data()),
00591 ni,nj,1,1,ni,ni*nj);
00592 if (image.pixel_format() == VIL_PIXEL_FORMAT_UINT_16){
00593 vil_image_view<vxl_uint_16>& img = static_cast<vil_image_view<vxl_uint_16>&>(image);
00594 img.deep_copy(vil_image_view<vxl_uint_16>(wrapper));
00595 return true;
00596 }
00597
00598 switch ( vil_pixel_format_component_format(image.pixel_format()) ){
00599 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00600 #define macro(F , T) \
00601 case F: {\
00602 vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00603 vil_convert_cast( wrapper, dest_ref); break;}
00604
00605 #if VXL_HAS_INT_64
00606 macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00607 macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00608 #endif
00609 macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00610 macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00611 macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00612 macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00613 macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00614 macro( VIL_PIXEL_FORMAT_FLOAT, float );
00615 macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00616 macro( VIL_PIXEL_FORMAT_BOOL, bool );
00617 #undef macro
00618 #endif // DOXYGEN_SHOULD_SKIP_THIS
00619 default:
00620 return false;
00621 }
00622 return true;
00623 }
00624
00625 vidl2_pixel_format default_format = VIDL2_PIXEL_FORMAT_UNKNOWN;
00626 if (image.pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00627 {
00628 vil_image_view<vxl_byte>& img = static_cast<vil_image_view<vxl_byte>&>(image);
00629 bool interleaved = (img.planestep() == 1);
00630
00631 switch (require_color) {
00632 case VIDL2_PIXEL_COLOR_MONO:
00633 default_format = VIDL2_PIXEL_FORMAT_MONO_8; break;
00634 case VIDL2_PIXEL_COLOR_RGB:
00635 default_format = interleaved?VIDL2_PIXEL_FORMAT_RGB_24
00636 :VIDL2_PIXEL_FORMAT_RGB_24P; break;
00637 case VIDL2_PIXEL_COLOR_RGBA:
00638 default_format = interleaved?VIDL2_PIXEL_FORMAT_RGBA_32
00639 :VIDL2_PIXEL_FORMAT_RGBA_32P; break;
00640 case VIDL2_PIXEL_COLOR_YUV:
00641 default_format = interleaved?VIDL2_PIXEL_FORMAT_UYV_444
00642 :VIDL2_PIXEL_FORMAT_YUV_444P; break;
00643 default:
00644 break;
00645 }
00646 }
00647
00648 vidl2_frame_sptr out_frame = new vidl2_memory_chunk_frame(image,default_format);
00649
00650 if (out_frame->pixel_format() != VIDL2_PIXEL_FORMAT_UNKNOWN){
00651 vidl2_convert_frame(frame, *out_frame);
00652 return true;
00653 }
00654
00655
00656 vidl2_pixel_format out_fmt;
00657 switch (in_color) {
00658 case VIDL2_PIXEL_COLOR_MONO:
00659 out_fmt = VIDL2_PIXEL_FORMAT_MONO_8; break;
00660 case VIDL2_PIXEL_COLOR_RGB:
00661 out_fmt = VIDL2_PIXEL_FORMAT_RGB_24P; break;
00662 case VIDL2_PIXEL_COLOR_RGBA:
00663 out_fmt = VIDL2_PIXEL_FORMAT_RGBA_32P; break;
00664 case VIDL2_PIXEL_COLOR_YUV:
00665 out_fmt = VIDL2_PIXEL_FORMAT_YUV_444P; break;
00666 default:
00667 return false;
00668 }
00669
00670 vil_image_view<vxl_byte> temp(ni,nj,np);
00671 out_frame = new vidl2_memory_chunk_frame(ni,nj,out_fmt,temp.memory_chunk());
00672 vidl2_convert_frame(frame, *out_frame);
00673
00674 switch ( vil_pixel_format_component_format(image.pixel_format()) ){
00675 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00676 #define macro(F , T) \
00677 case F: {\
00678 vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00679 vil_convert_cast( temp, dest_ref); break;}
00680
00681 #if VXL_HAS_INT_64
00682 macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00683 macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00684 #endif
00685 macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00686 macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00687 macro( VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16 );
00688 macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00689 macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00690 macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00691 macro( VIL_PIXEL_FORMAT_FLOAT, float );
00692 macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00693 macro( VIL_PIXEL_FORMAT_BOOL, bool );
00694 #undef macro
00695 #endif // DOXYGEN_SHOULD_SKIP_THIS
00696 default:
00697 return false;
00698 }
00699 return true;
00700 }
00701
00702
00703
00704
00705 vil_image_view_base_sptr
00706 vidl2_convert_wrap_in_view(const vidl2_frame& frame)
00707 {
00708 vidl2_pixel_format format = frame.pixel_format();
00709 vidl2_pixel_traits pt = vidl2_pixel_format_traits(format);
00710 if ( pt.chroma_shift_x != 0 || pt.chroma_shift_y != 0 ||
00711 pt.bits_per_pixel % pt.num_channels != 0)
00712 return NULL;
00713
00714 unsigned ni = frame.ni(), nj = frame.nj();
00715 unsigned np = pt.num_channels;
00716 vcl_ptrdiff_t i_step, j_step, p_step;
00717 switch (pt.arrangement) {
00718 case VIDL2_PIXEL_ARRANGE_SINGLE:
00719 i_step = np;
00720 j_step = np*ni;
00721 p_step = 1;
00722 break;
00723 case VIDL2_PIXEL_ARRANGE_PLANAR:
00724 i_step = 1;
00725 j_step = ni;
00726 p_step = ni*nj;
00727 break;
00728 default:
00729
00730 return NULL;
00731 }
00732 vcl_ptrdiff_t top_left_offset = 0;
00733
00734 if (format == VIDL2_PIXEL_FORMAT_BGR_24){
00735 top_left_offset = 3;
00736 p_step = -1;
00737 }
00738
00739
00740 if ( const vidl2_memory_chunk_frame* cf =
00741 dynamic_cast<const vidl2_memory_chunk_frame*>(&frame) )
00742 {
00743 vil_memory_chunk_sptr chunk = cf->memory_chunk();
00744 if (format == VIDL2_PIXEL_FORMAT_MONO_16){
00745 const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(cf->data()) + top_left_offset;
00746 return new vil_image_view<vxl_uint_16>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00747 }
00748 else if (format == VIDL2_PIXEL_FORMAT_MONO_1){
00749 const bool* top_left = static_cast<const bool*>(cf->data()) + top_left_offset;
00750 return new vil_image_view<bool>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00751 }
00752 const vxl_byte* top_left = static_cast<const vxl_byte*>(cf->data()) + top_left_offset;
00753 return new vil_image_view<vxl_byte>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00754 }
00755
00756
00757 if (format == VIDL2_PIXEL_FORMAT_MONO_16){
00758 const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(frame.data()) + top_left_offset;
00759 return new vil_image_view<vxl_uint_16>(top_left, ni,nj,np, i_step,j_step,p_step);
00760 }
00761 else if (format == VIDL2_PIXEL_FORMAT_MONO_1){
00762 const bool* top_left = static_cast<const bool*>(frame.data()) + top_left_offset;
00763 return new vil_image_view<bool>(top_left, ni,nj,np, i_step,j_step,p_step);
00764 }
00765 const vxl_byte* top_left = static_cast<const vxl_byte*>(frame.data()) + top_left_offset;
00766 return new vil_image_view<vxl_byte>(top_left, ni,nj,np, i_step,j_step,p_step);
00767 }