00001
00002 #ifndef vidl2_color_h_
00003 #define vidl2_color_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "vidl2_pixel_format.h"
00016 #include <vcl_cstring.h>
00017
00018
00019
00020
00021
00022
00023
00024 template <class outT>
00025 inline void vidl2_color_convert_yuv2rgb( vxl_byte y, vxl_byte u, vxl_byte v,
00026 outT& r, outT& g, outT& b )
00027 {
00028 double dy = y/255.0;
00029 double du = (u-128)/255.0;
00030 double dv = (v-128)/255.0;
00031 r = dy + 1.1402 * dv;
00032 g = dy - 0.34413628620102 * du - 0.71413628620102 * dv;
00033 b = dy + 1.772 * du;
00034 }
00035
00036
00037
00038
00039 VCL_DEFINE_SPECIALIZATION
00040 inline void vidl2_color_convert_yuv2rgb( vxl_byte y, vxl_byte u, vxl_byte v,
00041 vxl_byte& r, vxl_byte& g, vxl_byte& b )
00042 {
00043 register int iy = y, iu = u-128, iv = v-128, ir, ib, ig;
00044 r = ir = iy + ((iv*1436) >> 10);
00045 g = ig = iy - ((iu*352 + iv*731) >> 10);
00046 b = ib = iy + ((iu*1814) >> 10);
00047 r = ir < 0 ? 0 : r;
00048 g = ig < 0 ? 0 : g;
00049 b = ib < 0 ? 0 : b;
00050 r = ir > 255 ? 255 : r;
00051 g = ig > 255 ? 255 : g;
00052 b = ib > 255 ? 255 : b;
00053 }
00054
00055
00056
00057 template <class outT>
00058 inline void vidl2_color_convert_rgb2yuv( vxl_byte r, vxl_byte g, vxl_byte b,
00059 outT& y, outT& u, outT& v )
00060 {
00061 double dr = r/255.0;
00062 double dg = g/255.0;
00063 double db = b/255.0;
00064 y = 0.299*dr + 0.587*dg + 0.114*db;
00065 u = (db-y)/1.772;
00066 v = (dr-y)/1.402;
00067 }
00068
00069
00070
00071
00072 VCL_DEFINE_SPECIALIZATION
00073 inline void vidl2_color_convert_rgb2yuv( vxl_byte r, vxl_byte g, vxl_byte b,
00074 vxl_byte& y, vxl_byte& u, vxl_byte& v )
00075 {
00076 register int ir = r, ib = b, ig = g, iy, iu, iv;
00077 y = iy = (306*ir + 601*ig + 117*ib) >> 10;
00078 u = iu = ((-172*ir - 340*ig + 512*ib) >> 10) + 128;
00079 v = iv = ((512*ir - 429*ig - 83*ib) >> 10) + 128;
00080 y = iy < 0 ? 0 : y;
00081 u = iu < 0 ? 0 : u;
00082 v = iv < 0 ? 0 : v;
00083 y = iy > 255 ? 255 : y;
00084 u = iu > 255 ? 255 : u;
00085 v = iv > 255 ? 255 : v;
00086 }
00087
00088
00089
00090
00091
00092
00093 typedef void (*vidl2_color_conv_fptr)(const vxl_byte* in, vxl_byte* out);
00094
00095
00096
00097
00098
00099
00100 vidl2_color_conv_fptr
00101 vidl2_color_converter_func( vidl2_pixel_color in_C, unsigned in_bpp,
00102 vidl2_pixel_color out_C, unsigned out_bpp);
00103
00104
00105 template <vidl2_pixel_color in_C, vidl2_pixel_color out_C>
00106 struct vidl2_color_converter;
00107
00108 VCL_DEFINE_SPECIALIZATION
00109 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_RGB>
00110 {
00111 static inline void convert(const vxl_byte in[3], vxl_byte out[3])
00112 {
00113 out[0] = in[0];
00114 out[1] = in[1];
00115 out[2] = in[2];
00116 }
00117 };
00118
00119
00120 VCL_DEFINE_SPECIALIZATION
00121 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_RGBA>
00122 {
00123 static inline void convert(const vxl_byte in[4], vxl_byte out[4])
00124 {
00125 out[0] = in[0];
00126 out[1] = in[1];
00127 out[2] = in[2];
00128 out[3] = in[3];
00129 }
00130 };
00131
00132
00133 VCL_DEFINE_SPECIALIZATION
00134 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_RGB>
00135 {
00136 static inline void convert(const vxl_byte in[4], vxl_byte out[3])
00137 {
00138 out[0] = in[0];
00139 out[1] = in[1];
00140 out[2] = in[2];
00141 }
00142 };
00143
00144
00145 VCL_DEFINE_SPECIALIZATION
00146 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_RGBA>
00147 {
00148 static inline void convert(const vxl_byte in[3], vxl_byte out[4])
00149 {
00150 out[0] = in[0];
00151 out[1] = in[1];
00152 out[2] = in[2];
00153 out[3] = 0xFF;
00154 }
00155 };
00156
00157 VCL_DEFINE_SPECIALIZATION
00158 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_YUV>
00159 {
00160 static inline void convert(const vxl_byte in[3], vxl_byte out[3])
00161 {
00162 out[0] = in[0];
00163 out[1] = in[1];
00164 out[2] = in[2];
00165 }
00166 };
00167
00168
00169 VCL_DEFINE_SPECIALIZATION
00170 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>
00171 {
00172 template <class T>
00173 static inline void convert(const T in[1], T out[1])
00174 {
00175 out[0] = in[0];
00176 }
00177
00178 static inline void convert(const vxl_byte in[1], bool out[1])
00179 {
00180 out[0] = (in[0]&0x80) > 0;
00181 }
00182
00183 static inline void convert(const vxl_uint_16 in[1], bool out[1])
00184 {
00185 out[0] = (in[0]&0x8000) > 0;
00186 }
00187
00188 static inline void convert(const bool in[1], vxl_byte out[1])
00189 {
00190 out[0] = in[0]?0xFF:0x00;
00191 }
00192
00193 static inline void convert(const bool in[1], vxl_uint_16 out[1])
00194 {
00195 out[0] = in[0]?0xFFFF:0x0000;
00196 }
00197
00198 static inline void convert(const vxl_byte in[1], vxl_uint_16 out[1])
00199 {
00200 out[0] = in[0]<<8;
00201 }
00202
00203 static inline void convert(const vxl_uint_16 in[1], vxl_byte out[1])
00204 {
00205 out[0] = in[0]>>8;
00206 }
00207 };
00208
00209
00210 VCL_DEFINE_SPECIALIZATION
00211 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_YUV>
00212 {
00213 template <class outT>
00214 static inline void convert(const vxl_byte in[3], outT out[3])
00215 {
00216 vidl2_color_convert_rgb2yuv(in[0],in[1],in[2],
00217 out[0],out[1],out[2]);
00218 }
00219 };
00220
00221
00222 VCL_DEFINE_SPECIALIZATION
00223 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_YUV>
00224 {
00225 template <class outT>
00226 static inline void convert(const vxl_byte in[4], outT out[3])
00227 {
00228 vidl2_color_convert_rgb2yuv(in[0],in[1],in[2],
00229 out[0],out[1],out[2]);
00230 }
00231 };
00232
00233
00234 VCL_DEFINE_SPECIALIZATION
00235 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_RGB>
00236 {
00237 template <class outT>
00238 static inline void convert(const vxl_byte in[3], outT out[3])
00239 {
00240 vidl2_color_convert_yuv2rgb(in[0],in[1],in[2],
00241 out[0],out[1],out[2]);
00242 }
00243 };
00244
00245
00246 VCL_DEFINE_SPECIALIZATION
00247 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_RGBA>
00248 {
00249 template <class outT>
00250 static inline void convert(const vxl_byte in[3], outT out[4])
00251 {
00252 vidl2_color_convert_yuv2rgb(in[0],in[1],in[2],
00253 out[0],out[1],out[2]);
00254 out[3] = vidl2_pixel_limits<outT>::max();
00255 }
00256 };
00257
00258
00259 VCL_DEFINE_SPECIALIZATION
00260 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_YUV,VIDL2_PIXEL_COLOR_MONO>
00261 {
00262 template <class T>
00263 static inline void convert(const vxl_byte in[3], T out[1])
00264 {
00265
00266 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00267 }
00268 };
00269
00270
00271 VCL_DEFINE_SPECIALIZATION
00272 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_YUV>
00273 {
00274 template <class T>
00275 static inline void convert(const T in[1], vxl_byte out[3])
00276 {
00277
00278 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00279 out[1] = 128;
00280 out[2] = 128;
00281 }
00282 };
00283
00284 VCL_DEFINE_SPECIALIZATION
00285 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGB,VIDL2_PIXEL_COLOR_MONO>
00286 {
00287 template <class T>
00288 static inline void convert(const vxl_byte in[3], T out[1])
00289 {
00290
00291 vxl_byte grey = (306*in[0] + 601*in[1] + 117*in[2]) >> 10;
00292 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(&grey,out);
00293 }
00294 };
00295
00296 VCL_DEFINE_SPECIALIZATION
00297 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_RGBA,VIDL2_PIXEL_COLOR_MONO>
00298 {
00299 template <class T>
00300 static inline void convert(const vxl_byte in[4], T out[1])
00301 {
00302
00303 vxl_byte grey = (306*in[0] + 601*in[1] + 117*in[2]) >> 10;
00304 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(&grey,out);
00305 }
00306 };
00307
00308 VCL_DEFINE_SPECIALIZATION
00309 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_RGB>
00310 {
00311 template <class T>
00312 static inline void convert(const T in[1], vxl_byte out[3])
00313 {
00314
00315 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00316 out[2] = out[1] = out[0];
00317 }
00318 };
00319
00320 VCL_DEFINE_SPECIALIZATION
00321 struct vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_RGBA>
00322 {
00323 template <class T>
00324 static inline void convert(const T in[1], vxl_byte out[4])
00325 {
00326
00327 vidl2_color_converter<VIDL2_PIXEL_COLOR_MONO,VIDL2_PIXEL_COLOR_MONO>::convert(in,out);
00328 out[2] = out[1] = out[0];
00329 out[3] = 0xFF;
00330 }
00331 };
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 template <vidl2_pixel_format FMT>
00344 struct vidl2_color_component
00345 {
00346 typedef typename vidl2_pixel_traits_of<FMT>::type cmp_type;
00347 static inline
00348 cmp_type get(const cmp_type * ptr, unsigned int i)
00349 {
00350 return ptr[i];
00351 }
00352
00353
00354 static inline
00355 void get_all(const cmp_type * ptr, cmp_type * data)
00356 {
00357 vcl_memcpy(data, ptr, sizeof(cmp_type)*vidl2_pixel_traits_of<FMT>::num_channels);
00358 }
00359
00360 static inline
00361 void set(cmp_type * ptr, unsigned int i, cmp_type val)
00362 {
00363 ptr[i] = val;
00364 }
00365
00366
00367 static inline
00368 void set_all(cmp_type * ptr, const cmp_type * data)
00369 {
00370 vcl_memcpy(ptr, data, sizeof(cmp_type)*vidl2_pixel_traits_of<FMT>::num_channels);
00371 }
00372 };
00373
00374
00375 VCL_DEFINE_SPECIALIZATION
00376 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_BGR_24>
00377 {
00378
00379
00380
00381 static inline
00382 vxl_byte get(const vxl_byte * ptr, unsigned int i)
00383 {
00384 return ptr[2-i];
00385 }
00386
00387 static inline
00388 void get_all(const vxl_byte * ptr, vxl_byte * data)
00389 {
00390 data[0] = ptr[2];
00391 data[1] = ptr[1];
00392 data[2] = ptr[0];
00393 }
00394
00395 static inline
00396 void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00397 {
00398 ptr[2-i] = val;
00399 }
00400
00401 static inline
00402 void set_all(vxl_byte * ptr, const vxl_byte * data)
00403 {
00404 ptr[2] = data[0];
00405 ptr[1] = data[1];
00406 ptr[0] = data[2];
00407 }
00408 };
00409
00410
00411 VCL_DEFINE_SPECIALIZATION
00412 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_RGB_555>
00413 {
00414 static inline
00415 vxl_byte get(const vxl_byte * ptr, unsigned int i)
00416 {
00417 const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00418 return static_cast<vxl_byte>(*p >> (2-i)*5)<<3;
00419 }
00420
00421 static inline
00422 void get_all(const vxl_byte * ptr, vxl_byte * data)
00423 {
00424 const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00425 data[0] = static_cast<vxl_byte>(*p >>10)<<3;
00426 data[1] = static_cast<vxl_byte>(*p >>5)<<3;
00427 data[2] = static_cast<vxl_byte>(*p)<<3;
00428 }
00429
00430 static inline
00431 void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00432 {
00433 vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00434 vxl_uint_16 v = static_cast<vxl_uint_16>(val>>3)<<(2-i)*5;
00435 vxl_uint_16 mask = ~(31<<(2-i)*5);
00436 *p = (*p & mask) | v;
00437 }
00438
00439 static inline
00440 void set_all(vxl_byte * ptr, const vxl_byte * data)
00441 {
00442 vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00443 *p = ((data[0]>>3) << 10) | ((data[1]>>3) << 5) | (data[2]>>3);
00444 }
00445 };
00446
00447
00448 VCL_DEFINE_SPECIALIZATION
00449 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_RGB_565>
00450 {
00451 static inline
00452 vxl_byte get(const vxl_byte * ptr, unsigned int i)
00453 {
00454 const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00455 switch (i) {
00456 case 0: return vxl_byte((*p & 0xF800) >> 8);
00457 case 1: return vxl_byte((*p & 0x07E0) >> 3);
00458 case 2: return vxl_byte((*p & 0x001F) << 3);
00459 }
00460 return 0;
00461 }
00462
00463 static inline
00464 void get_all(const vxl_byte * ptr, vxl_byte * data)
00465 {
00466 const vxl_uint_16* p = reinterpret_cast<const vxl_uint_16*>(ptr);
00467 data[0] = static_cast<vxl_byte>(*p >>11)<<3;
00468 data[1] = static_cast<vxl_byte>(*p >>5)<<2;
00469 data[2] = static_cast<vxl_byte>(*p)<<3;
00470 }
00471
00472 static inline
00473 void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00474 {
00475 vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00476 vxl_uint_16 v = static_cast<vxl_uint_16>(val>>3);
00477 switch (i) {
00478 case 0: *p &= 0x07FF; *p |= (v<<11); break;
00479 case 1: *p &= 0xF81F; *p |= (v<<5); break;
00480 case 2: *p &= 0xFFE0; *p |= v; break;
00481 }
00482 }
00483
00484 static inline
00485 void set_all(vxl_byte * ptr, const vxl_byte * data)
00486 {
00487 vxl_uint_16* p = reinterpret_cast<vxl_uint_16*>(ptr);
00488 *p = ((data[0]>>3) << 11) | ((data[1]>>2) << 5) | (data[2]>>3);
00489 }
00490 };
00491
00492
00493 VCL_DEFINE_SPECIALIZATION
00494 struct vidl2_color_component<VIDL2_PIXEL_FORMAT_UYV_444>
00495 {
00496
00497
00498
00499 static inline
00500 vxl_byte get(const vxl_byte * ptr, unsigned int i)
00501 {
00502 return ptr[i^((i>>1)^1)];
00503 }
00504
00505 static inline
00506 void get_all(const vxl_byte * ptr, vxl_byte * data)
00507 {
00508 data[0] = ptr[1];
00509 data[1] = ptr[0];
00510 data[2] = ptr[2];
00511 }
00512
00513 static inline
00514 void set(vxl_byte * ptr, unsigned int i, vxl_byte val)
00515 {
00516 ptr[i^((i>>1)^1)] = val;
00517 }
00518
00519 static inline
00520 void set_all(vxl_byte * ptr, const vxl_byte * data)
00521 {
00522 ptr[1] = data[0];
00523 ptr[0] = data[1];
00524 ptr[2] = data[2];
00525 }
00526 };
00527
00528 #endif // vidl2_color_h_
00529