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)(const vidl_frame& in_frame, vidl_frame& out_frame);
00036
00037
00038
00039 bool default_conversion(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& ,
00070 vidl_frame& )
00071 {
00072 return false;
00073 }
00074 };
00075
00076
00077
00078
00079
00080
00081 bool convert_generic(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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(const vidl_frame& 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 table_init<Fmt_Code-1>::populate(table);
00408 }
00409 };
00410
00411
00412
00413 VCL_DEFINE_SPECIALIZATION
00414 struct table_init<0>
00415 {
00416 static inline void populate(converter_func table[VIDL_PIXEL_FORMAT_ENUM_END][VIDL_PIXEL_FORMAT_ENUM_END])
00417 {
00418 const vidl_pixel_format in_fmt = vidl_pixel_format(0);
00419 const vidl_pixel_format out_fmt = vidl_pixel_format(0);
00420 table_entry_init<in_fmt,out_fmt>::set_entry(table[in_fmt][out_fmt]);
00421 }
00422 };
00423
00424
00425
00426 class converter
00427 {
00428 public:
00429
00430 converter()
00431 {
00432
00433 table_init<VIDL_PIXEL_FORMAT_ENUM_END*VIDL_PIXEL_FORMAT_ENUM_END-1>::populate(table);
00434 }
00435
00436
00437 bool operator()(const vidl_frame& in_frame, vidl_frame& out_frame) const
00438 {
00439 return (*table[in_frame.pixel_format()][out_frame.pixel_format()])(in_frame, out_frame);
00440 }
00441 private:
00442
00443 converter_func table[VIDL_PIXEL_FORMAT_ENUM_END][VIDL_PIXEL_FORMAT_ENUM_END];
00444 };
00445
00446
00447 converter conversion_table;
00448
00449
00450
00451 bool intermediate_rgb24_conversion(const vidl_frame& in_frame, vidl_frame& out_frame)
00452 {
00453 unsigned int ni = in_frame.ni(), nj = in_frame.nj();
00454 vil_memory_chunk_sptr memory = new vil_memory_chunk(ni*nj*3, VIL_PIXEL_FORMAT_BYTE);
00455 vidl_memory_chunk_frame temp_frame(ni,nj,VIDL_PIXEL_FORMAT_RGB_24,memory);
00456 return conversion_table(in_frame, temp_frame) &&
00457 conversion_table(temp_frame, out_frame);
00458 }
00459
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469 bool vidl_convert_frame(const vidl_frame& in_frame,
00470 vidl_frame& out_frame)
00471 {
00472 vidl_pixel_format in_fmt = in_frame.pixel_format();
00473 vidl_pixel_format out_fmt = out_frame.pixel_format();
00474
00475 if (in_fmt == VIDL_PIXEL_FORMAT_UNKNOWN ||
00476 out_fmt == VIDL_PIXEL_FORMAT_UNKNOWN)
00477 return false;
00478
00479 unsigned ni = in_frame.ni();
00480 unsigned nj = in_frame.nj();
00481 unsigned out_size = vidl_pixel_format_buffer_size(ni,nj,out_fmt);
00482
00483 if (out_frame.size() != out_size ||
00484 out_frame.ni() != ni ||
00485 out_frame.nj() != nj ||
00486 !out_frame.data() )
00487 return false;
00488
00489
00490 return conversion_table(in_frame, out_frame);
00491 }
00492
00493
00494
00495
00496
00497
00498 vidl_frame_sptr vidl_convert_frame(const vidl_frame_sptr& in_frame,
00499 vidl_pixel_format format)
00500 {
00501 if (format == VIDL_PIXEL_FORMAT_UNKNOWN)
00502 return NULL;
00503
00504 unsigned ni = in_frame->ni();
00505 unsigned nj = in_frame->nj();
00506 unsigned size = vidl_pixel_format_buffer_size(ni,nj,format);
00507 vil_memory_chunk_sptr memory = new vil_memory_chunk(size, VIL_PIXEL_FORMAT_BYTE);
00508 vidl_frame_sptr out_frame = new vidl_memory_chunk_frame(ni, nj, format, memory);
00509
00510 if (vidl_convert_frame(*in_frame, *out_frame))
00511 return out_frame;
00512
00513 return NULL;
00514 }
00515
00516
00517
00518
00519
00520 vidl_frame_sptr vidl_convert_to_frame(const vil_image_view_base_sptr& image)
00521 {
00522 if (!image)
00523 return NULL;
00524 return vidl_convert_to_frame(*image);
00525 }
00526
00527
00528
00529
00530
00531 vidl_frame_sptr vidl_convert_to_frame(const vil_image_view_base& image)
00532 {
00533
00534 vidl_frame_sptr frame = new vidl_memory_chunk_frame(image);
00535 if (frame->pixel_format() != VIDL_PIXEL_FORMAT_UNKNOWN)
00536 return frame;
00537
00538
00539 unsigned ni = image.ni(), nj = image.nj(), np = image.nplanes();
00540
00541
00542
00543 vil_pixel_format cmp_format =
00544 vil_pixel_format_component_format(image.pixel_format());
00545 unsigned int num_cmp = vil_pixel_format_num_components(image.pixel_format());
00546 unsigned int num_channels = np * num_cmp;
00547
00548
00549 if (cmp_format == VIL_PIXEL_FORMAT_UINT_16)
00550 {
00551 if (num_channels == 1)
00552 {
00553 vil_image_view<vxl_uint_16> img(ni,nj);
00554 img.deep_copy(vil_image_view<vxl_uint_16>(image));
00555 return new vidl_memory_chunk_frame(ni, nj, VIDL_PIXEL_FORMAT_MONO_16,
00556 img.memory_chunk());
00557 }
00558 }
00559
00560 else if (cmp_format == VIL_PIXEL_FORMAT_FLOAT)
00561 {
00562 if (num_channels == 1 || num_channels == 3)
00563 {
00564 vidl_pixel_format format = VIDL_PIXEL_FORMAT_UNKNOWN;
00565 if (num_channels == 1)
00566 format = VIDL_PIXEL_FORMAT_MONO_F32;
00567 else
00568 format = VIDL_PIXEL_FORMAT_RGB_F32P;
00569
00570 vil_image_view<vxl_ieee_32> img(ni,nj,num_channels);
00571 img.deep_copy(vil_image_view<vxl_ieee_32>(image));
00572 return new vidl_memory_chunk_frame(ni, nj, format,
00573 img.memory_chunk());
00574 }
00575 }
00576
00577 vidl_pixel_format format = VIDL_PIXEL_FORMAT_UNKNOWN;
00578 if (num_channels == 1)
00579 format = VIDL_PIXEL_FORMAT_MONO_8;
00580 else if (num_channels == 3)
00581 format = VIDL_PIXEL_FORMAT_RGB_24P;
00582 else if (num_channels == 4)
00583 format = VIDL_PIXEL_FORMAT_RGBA_32P;
00584 else
00585 return NULL;
00586
00587 vil_image_view<vxl_byte> img;
00588 if (image.pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00589 img.deep_copy(vil_image_view<vxl_byte>(image));
00590 else
00591 {
00592 vil_image_resource_sptr resrc = vil_new_image_resource_of_view(image);
00593 vil_image_view_base_sptr bimage = vil_convert_cast(vxl_byte(),resrc->get_view());
00594 if (!bimage)
00595 return NULL;
00596 img = *bimage;
00597 }
00598 return new vidl_memory_chunk_frame(ni, nj, format,
00599 img.memory_chunk());
00600 }
00601
00602
00603
00604
00605
00606 bool vidl_convert_to_view(const vidl_frame& frame,
00607 vil_image_view_base& image,
00608 vidl_pixel_color require_color)
00609 {
00610 if (frame.pixel_format() == VIDL_PIXEL_FORMAT_UNKNOWN ||
00611 frame.data() == NULL)
00612 return false;
00613
00614 vidl_pixel_color in_color = vidl_pixel_format_color(frame.pixel_format());
00615 if (require_color == VIDL_PIXEL_COLOR_UNKNOWN)
00616 require_color = in_color;
00617
00618 unsigned ni = frame.ni(), nj = frame.nj();
00619 unsigned np = vidl_pixel_color_num_channels(require_color);
00620
00621
00622 image.set_size(ni,nj,np);
00623
00624
00625 if (frame.pixel_format() == VIDL_PIXEL_FORMAT_MONO_16) {
00626 vil_image_view<vxl_uint_16> wrapper(static_cast<const vxl_uint_16*>(frame.data()),
00627 ni,nj,1,1,ni,ni*nj);
00628 if (image.pixel_format() == VIL_PIXEL_FORMAT_UINT_16) {
00629 vil_image_view<vxl_uint_16>& img = static_cast<vil_image_view<vxl_uint_16>&>(image);
00630 img.deep_copy(vil_image_view<vxl_uint_16>(wrapper));
00631 return true;
00632 }
00633
00634 switch ( vil_pixel_format_component_format(image.pixel_format()) ) {
00635 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00636 #define macro(F , T) \
00637 case F: {\
00638 vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00639 vil_convert_cast( wrapper, dest_ref); break;}
00640
00641 #if VXL_HAS_INT_64
00642 macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00643 macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00644 #endif
00645 macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00646 macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00647 macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00648 macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00649 macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00650 macro( VIL_PIXEL_FORMAT_FLOAT, float );
00651 macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00652 macro( VIL_PIXEL_FORMAT_BOOL, bool );
00653 #undef macro
00654 #endif // DOXYGEN_SHOULD_SKIP_THIS
00655 default:
00656 return false;
00657 }
00658 return true;
00659 }
00660
00661 vidl_pixel_format default_format = VIDL_PIXEL_FORMAT_UNKNOWN;
00662 if (image.pixel_format() == VIL_PIXEL_FORMAT_BYTE)
00663 {
00664 vil_image_view<vxl_byte>& img = static_cast<vil_image_view<vxl_byte>&>(image);
00665 bool interleaved = (img.planestep() == 1);
00666
00667 switch (require_color) {
00668 case VIDL_PIXEL_COLOR_MONO:
00669 default_format = VIDL_PIXEL_FORMAT_MONO_8; break;
00670 case VIDL_PIXEL_COLOR_RGB:
00671 default_format = interleaved?VIDL_PIXEL_FORMAT_RGB_24
00672 :VIDL_PIXEL_FORMAT_RGB_24P; break;
00673 case VIDL_PIXEL_COLOR_RGBA:
00674 default_format = interleaved?VIDL_PIXEL_FORMAT_RGBA_32
00675 :VIDL_PIXEL_FORMAT_RGBA_32P; break;
00676 case VIDL_PIXEL_COLOR_YUV:
00677 default_format = interleaved?VIDL_PIXEL_FORMAT_UYV_444
00678 :VIDL_PIXEL_FORMAT_YUV_444P; break;
00679 default:
00680 break;
00681 }
00682 }
00683
00684 vidl_frame_sptr out_frame = new vidl_memory_chunk_frame(image,default_format);
00685
00686 if (out_frame->pixel_format() != VIDL_PIXEL_FORMAT_UNKNOWN) {
00687 vidl_convert_frame(frame, *out_frame);
00688 return true;
00689 }
00690
00691
00692 vidl_pixel_format out_fmt;
00693 switch (in_color) {
00694 case VIDL_PIXEL_COLOR_MONO:
00695 out_fmt = VIDL_PIXEL_FORMAT_MONO_8; break;
00696 case VIDL_PIXEL_COLOR_RGB:
00697 out_fmt = VIDL_PIXEL_FORMAT_RGB_24P; break;
00698 case VIDL_PIXEL_COLOR_RGBA:
00699 out_fmt = VIDL_PIXEL_FORMAT_RGBA_32P; break;
00700 case VIDL_PIXEL_COLOR_YUV:
00701 out_fmt = VIDL_PIXEL_FORMAT_YUV_444P; break;
00702 default:
00703 return false;
00704 }
00705
00706 vil_image_view<vxl_byte> temp(ni,nj,np);
00707 out_frame = new vidl_memory_chunk_frame(ni,nj,out_fmt,temp.memory_chunk());
00708 vidl_convert_frame(frame, *out_frame);
00709
00710 switch ( vil_pixel_format_component_format(image.pixel_format()) ) {
00711 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00712 #define macro(F , T) \
00713 case F: {\
00714 vil_image_view<T> & dest_ref = static_cast<vil_image_view<T> &>(image); \
00715 vil_convert_cast( temp, dest_ref); break;}
00716
00717 #if VXL_HAS_INT_64
00718 macro( VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64 );
00719 macro( VIL_PIXEL_FORMAT_INT_64, vxl_int_64 );
00720 #endif
00721 macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 );
00722 macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 );
00723 macro( VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16 );
00724 macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 );
00725 macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte );
00726 macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte );
00727 macro( VIL_PIXEL_FORMAT_FLOAT, float );
00728 macro( VIL_PIXEL_FORMAT_DOUBLE, double );
00729 macro( VIL_PIXEL_FORMAT_BOOL, bool );
00730 #undef macro
00731 #endif // DOXYGEN_SHOULD_SKIP_THIS
00732 default:
00733 return false;
00734 }
00735 return true;
00736 }
00737
00738
00739
00740
00741 vil_image_view_base_sptr
00742 vidl_convert_wrap_in_view(const vidl_frame& frame)
00743 {
00744 vidl_pixel_format format = frame.pixel_format();
00745 vidl_pixel_traits pt = vidl_pixel_format_traits(format);
00746 if ( pt.chroma_shift_x != 0 || pt.chroma_shift_y != 0 ||
00747 pt.bits_per_pixel % pt.num_channels != 0)
00748 return NULL;
00749
00750 unsigned ni = frame.ni(), nj = frame.nj();
00751 unsigned np = pt.num_channels;
00752 vcl_ptrdiff_t i_step, j_step, p_step;
00753 switch (pt.arrangement) {
00754 case VIDL_PIXEL_ARRANGE_SINGLE:
00755 i_step = np;
00756 j_step = np*ni;
00757 p_step = 1;
00758 break;
00759 case VIDL_PIXEL_ARRANGE_PLANAR:
00760 i_step = 1;
00761 j_step = ni;
00762 p_step = ni*nj;
00763 break;
00764 default:
00765
00766 return NULL;
00767 }
00768 vcl_ptrdiff_t top_left_offset = 0;
00769
00770 if (format == VIDL_PIXEL_FORMAT_BGR_24) {
00771 top_left_offset = 3;
00772 p_step = -1;
00773 }
00774
00775
00776 if ( const vidl_memory_chunk_frame* cf =
00777 dynamic_cast<const vidl_memory_chunk_frame*>(&frame) )
00778 {
00779 vil_memory_chunk_sptr chunk = cf->memory_chunk();
00780 if (format == VIDL_PIXEL_FORMAT_MONO_16) {
00781 const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(cf->data()) + top_left_offset;
00782 return new vil_image_view<vxl_uint_16>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00783 }
00784 else if (format == VIDL_PIXEL_FORMAT_MONO_1) {
00785 const bool* top_left = static_cast<const bool*>(cf->data()) + top_left_offset;
00786 return new vil_image_view<bool>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00787 }else if (format == VIDL_PIXEL_FORMAT_MONO_F32 ||
00788 format == VIDL_PIXEL_FORMAT_RGB_F32 ||
00789 format == VIDL_PIXEL_FORMAT_RGB_F32P) {
00790 const vxl_ieee_32* top_left = static_cast<const vxl_ieee_32*>(cf->data()) + top_left_offset;
00791 return new vil_image_view<float>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00792 } else {
00793 const vxl_byte* top_left = static_cast<const vxl_byte*>(cf->data()) + top_left_offset;
00794 return new vil_image_view<vxl_byte>(chunk,top_left, ni,nj,np, i_step,j_step,p_step);
00795 }
00796 }
00797
00798
00799 if (format == VIDL_PIXEL_FORMAT_MONO_16) {
00800 const vxl_uint_16* top_left = static_cast<const vxl_uint_16*>(frame.data()) + top_left_offset;
00801 return new vil_image_view<vxl_uint_16>(top_left, ni,nj,np, i_step,j_step,p_step);
00802 }
00803 else if (format == VIDL_PIXEL_FORMAT_MONO_1) {
00804 const bool* top_left = static_cast<const bool*>(frame.data()) + top_left_offset;
00805 return new vil_image_view<bool>(top_left, ni,nj,np, i_step,j_step,p_step);
00806 }
00807 const vxl_byte* top_left = static_cast<const vxl_byte*>(frame.data()) + top_left_offset;
00808 return new vil_image_view<vxl_byte>(top_left, ni,nj,np, i_step,j_step,p_step);
00809 }