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