1 // This is core/vidl/vidl_pixel_format.h 2 #ifndef vidl_pixel_format_h_ 3 #define vidl_pixel_format_h_ 4 //: 5 // \file 6 // \brief Supported pixel formats for video frames 7 // 8 // \author Matt Leotta 9 // \date 13 Jan 2006 10 // 11 // This file defines the set of known video frame pixel formats. 12 // The enum vidl_pixel_format enumerates the types while the 13 // template specializations of vidl_pixel_traits define their 14 // basic traits. These specializations are defined using the 15 // macro vidl_pt_mac. The pixel traits are: 16 // - <b>name</b> a string representation for the format 17 // - <b>type</b> the VXL C++ type used to return a pixel component 18 // - <b>bits per pixel</b> the number of bits used to represent a pixel 19 // - <b>number of channels</b> the number of color channels encoded 20 // (now determined by color) 21 // - <b>color</b> the color encoding of the pixels (i.e. RGB, YUV) 22 // - <b>arrangement</b> the way pixels are arranged in memory. This 23 // could be in single file, packed into macropixels, or in planes. 24 // - <b>chroma shift X</b> the chroma subsampling factor is 2 ^ shift 25 // in the horizontal direction. 26 // - <b>chroma shift Y</b> the chroma subsampling factor is 2 ^ shift 27 // in the vertical direction. 28 // 29 // vidl_pixel_format differs from vil_pixel_format in that the 30 // vidl formats are representations typically used by video 31 // hardware and in video codecs to encode a frame. The vil pixel 32 // formats are more useful for image processing and are related 33 // to the C++ data types that may be arranged in a regular array 34 // to make an image. A vidl_pixel_format may have components 35 // in multiple planes of different sizes or may have data from 36 // multiple image pixels encoded as a single macro pixel. 37 // 38 // This file also contains several functions to check the traits 39 // of a pixel format at runtime. These functions use template 40 // metaprogramming to generate conditionals that probe the formats 41 // defined in this file. So you don't need to modify these functions 42 // when you add a new pixel format into this header file. 43 44 #include <string> 45 #include <cstddef> 46 #include <iosfwd> 47 #include <typeinfo> 48 #ifdef _MSC_VER 49 # include <vcl_msvc_warnings.h> 50 #endif 51 #include <vxl_config.h> 52 #include <vidl/vidl_export.h> 53 54 //: Describes the format of pixel encoding in a video frame buffer 55 enum vidl_pixel_format 56 { 57 VIDL_PIXEL_FORMAT_UNKNOWN = -1, 58 59 VIDL_PIXEL_FORMAT_RGB_24, 60 VIDL_PIXEL_FORMAT_RGB_24P, 61 VIDL_PIXEL_FORMAT_BGR_24, 62 VIDL_PIXEL_FORMAT_RGBA_32, 63 VIDL_PIXEL_FORMAT_RGBA_32P, 64 VIDL_PIXEL_FORMAT_RGB_565, 65 VIDL_PIXEL_FORMAT_RGB_555, 66 67 VIDL_PIXEL_FORMAT_YUV_444P, 68 VIDL_PIXEL_FORMAT_YUV_422P, 69 VIDL_PIXEL_FORMAT_YUV_420P, 70 VIDL_PIXEL_FORMAT_YVU_420P, 71 VIDL_PIXEL_FORMAT_YUV_411P, 72 VIDL_PIXEL_FORMAT_YUV_410P, 73 VIDL_PIXEL_FORMAT_UYV_444, 74 VIDL_PIXEL_FORMAT_YUYV_422, 75 VIDL_PIXEL_FORMAT_UYVY_422, 76 VIDL_PIXEL_FORMAT_UYVY_411, 77 78 VIDL_PIXEL_FORMAT_MONO_1, 79 VIDL_PIXEL_FORMAT_MONO_8, 80 VIDL_PIXEL_FORMAT_MONO_16, 81 VIDL_PIXEL_FORMAT_MONO_F32, 82 VIDL_PIXEL_FORMAT_RGB_F32, 83 VIDL_PIXEL_FORMAT_RGB_F32P, 84 85 // Add values here 86 VIDL_PIXEL_FORMAT_ENUM_END 87 }; 88 89 90 //: Describes the color encoding of a pixel format 91 enum vidl_pixel_color 92 { 93 VIDL_PIXEL_COLOR_UNKNOWN = -1, 94 95 VIDL_PIXEL_COLOR_MONO, 96 VIDL_PIXEL_COLOR_RGB, 97 VIDL_PIXEL_COLOR_RGBA, 98 VIDL_PIXEL_COLOR_YUV, 99 100 // Add values here 101 102 VIDL_PIXEL_COLOR_ENUM_END 103 }; 104 105 106 //: Describes the arrangement of pixels in a pixel format 107 enum vidl_pixel_arrangement 108 { 109 VIDL_PIXEL_ARRANGE_UNKNOWN = -1, 110 111 VIDL_PIXEL_ARRANGE_SINGLE, 112 VIDL_PIXEL_ARRANGE_PACKED, 113 VIDL_PIXEL_ARRANGE_PLANAR, 114 VIDL_PIXEL_ARRANGE_PALETTE, 115 116 // Add values here 117 118 VIDL_PIXEL_ARRANGE_ENUM_END 119 }; 120 121 122 //: Traits of the pixel formats 123 // - name a string name for the format 124 // - bits_per_pixel the effective number of bits per pixel 125 // - color the color mode used 126 // - planar are the pixel components arranged on multiple planes 127 // - packed are the pixels packed into macro pixels 128 struct vidl_pixel_traits 129 { 130 std::string name; 131 const std::type_info* type; 132 unsigned bits_per_pixel; 133 unsigned num_channels; 134 vidl_pixel_color color; 135 vidl_pixel_arrangement arrangement; 136 unsigned chroma_shift_x; 137 unsigned chroma_shift_y; 138 }; 139 140 // ***** Start: temporary hack to avoid conflict ***** 141 #ifdef min 142 #undef min 143 #endif 144 #ifdef max 145 #undef max 146 #endif 147 // ***** End: temporary hack to avoid conflict ***** 148 149 //: Define limits on the minimum and maximum pixel values 150 // Also define \a chroma_zero as the U and V value to represent 151 // gray (no color) in YUV encoding 152 template <class T> 153 struct vidl_pixel_limits; 154 155 template <> 156 struct vidl_pixel_limits<vxl_byte> 157 { 158 static inline vxl_byte min() {return 0x00;} 159 static inline vxl_byte max() {return 0xFF;} 160 static inline vxl_byte chroma_zero() {return 0x80;} 161 }; 162 163 template <> 164 struct vidl_pixel_limits<bool> 165 { 166 static inline bool min() {return false;} 167 static inline bool max() {return true;} 168 // chroma zero is not well defined, YUV can't be boolean 169 static inline bool chroma_zero() {return false;} 170 }; 171 172 template <> 173 struct vidl_pixel_limits<vxl_uint_16> 174 { 175 static inline vxl_uint_16 min() {return 0x0000;} 176 static inline vxl_uint_16 max() {return 0xFFFF;} 177 static inline vxl_uint_16 chroma_zero() {return 0x8000;} 178 }; 179 180 template <> 181 struct vidl_pixel_limits<float> 182 { 183 static inline float min() {return 0.0f;} 184 static inline float max() {return 1.0f;} 185 static inline float chroma_zero() {return 0.0f;} 186 }; 187 188 template <> 189 struct vidl_pixel_limits<double> 190 { 191 static inline double min() {return 0.0;} 192 static inline double max() {return 1.0;} 193 static inline double chroma_zero() {return 0.0f;} 194 }; 195 196 197 //: Define the color traits for each vidl_pixel_color 198 // For now this is just the number of channels 199 template <vidl_pixel_color color_type> 200 struct vidl_color_traits_of; 201 #define vidl_ct_mac(COL,NC)\ 202 template <> \ 203 struct vidl_color_traits_of<VIDL_PIXEL_COLOR_##COL> \ 204 {\ 205 enum { num_channels = (NC) }; \ 206 } 207 208 vidl_ct_mac( UNKNOWN, 0 ); 209 vidl_ct_mac( MONO, 1 ); 210 vidl_ct_mac( RGB, 3 ); 211 vidl_ct_mac( RGBA, 4 ); 212 vidl_ct_mac( YUV, 3 ); 213 214 #undef vidl_ct_mac 215 216 217 //: Define traits for a given vidl_pixel_format 218 // All pixel traits should be defined using the macro below 219 // The anonymous enums allow the values available to the 220 // compiler to for use in generic programming. For values 221 // that are already enums, a function is provided so the 222 // user does not need to worry about enum type clashes. 223 template <vidl_pixel_format pix_type> 224 struct vidl_pixel_traits_of; 225 #define vidl_pt_mac(FMT,NAME,T,BPP,CLR,ARNG,XCS,YCS)\ 226 template <> \ 227 struct vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT> \ 228 {\ 229 static inline std::string name() { return NAME; }\ 230 typedef T type;\ 231 enum { bits_per_pixel = (BPP) };\ 232 enum { num_channels = vidl_color_traits_of<VIDL_PIXEL_COLOR_##CLR>::num_channels };\ 233 static inline vidl_pixel_color color() { return VIDL_PIXEL_COLOR_##CLR; }\ 234 enum { color_idx = VIDL_PIXEL_COLOR_##CLR };\ 235 static inline vidl_pixel_arrangement arrangement() { return VIDL_PIXEL_ARRANGE_##ARNG; }\ 236 enum { arrangement_idx = VIDL_PIXEL_ARRANGE_##ARNG };\ 237 enum { chroma_shift_x = (XCS) };\ 238 enum { chroma_shift_y = (YCS) };\ 239 } 240 241 // format name type bpp color arrange xcs ycs 242 // ------ --------- ---- --- ------- ------- --- --- 243 vidl_pt_mac( UNKNOWN, "unknown", void, 0, UNKNOWN, UNKNOWN, 0, 0 ); 244 245 vidl_pt_mac( RGB_24, "RGB 24", vxl_byte, 24, RGB, SINGLE, 0, 0 ); 246 vidl_pt_mac( RGB_24P, "RGB 24P", vxl_byte, 24, RGB, PLANAR, 0, 0 ); 247 vidl_pt_mac( BGR_24, "BGR 24", vxl_byte, 24, RGB, SINGLE, 0, 0 ); 248 vidl_pt_mac( RGBA_32, "RGBA 32", vxl_byte, 32, RGBA, SINGLE, 0, 0 ); 249 vidl_pt_mac( RGBA_32P, "RGBA 32P", vxl_byte, 32, RGBA, PLANAR, 0, 0 ); 250 vidl_pt_mac( RGB_565, "RGB 565", vxl_byte, 16, RGB, SINGLE, 0, 0 ); 251 vidl_pt_mac( RGB_555, "RGB 555", vxl_byte, 16, RGB, SINGLE, 0, 0 ); 252 253 vidl_pt_mac( YUV_444P, "YUV 444P", vxl_byte, 24, YUV, PLANAR, 0, 0 ); 254 vidl_pt_mac( YUV_422P, "YUV 422P", vxl_byte, 16, YUV, PLANAR, 1, 0 ); 255 vidl_pt_mac( YUV_420P, "YUV 420P", vxl_byte, 12, YUV, PLANAR, 1, 1 ); 256 vidl_pt_mac( YVU_420P, "YVU 420P", vxl_byte, 12, YUV, PLANAR, 1, 1 ); 257 vidl_pt_mac( YUV_411P, "YUV 411P", vxl_byte, 12, YUV, PLANAR, 2, 0 ); 258 vidl_pt_mac( YUV_410P, "YUV 410P", vxl_byte, 10, YUV, PLANAR, 2, 1 ); 259 vidl_pt_mac( UYV_444, "UYV 444", vxl_byte, 24, YUV, SINGLE, 0, 0 ); 260 vidl_pt_mac( YUYV_422, "YUYV 422", vxl_byte, 16, YUV, PACKED, 1, 0 ); 261 vidl_pt_mac( UYVY_422, "UYVY 422", vxl_byte, 16, YUV, PACKED, 1, 0 ); 262 vidl_pt_mac( UYVY_411, "UYVY 411", vxl_byte, 12, YUV, PACKED, 2, 0 ); 263 264 vidl_pt_mac( MONO_1, "Mono 1", bool, 1, MONO, SINGLE, 0, 0 ); 265 vidl_pt_mac( MONO_8, "Mono 8", vxl_byte, 8, MONO, SINGLE, 0, 0 ); 266 vidl_pt_mac( MONO_16, "Mono 16", vxl_uint_16, 16, MONO, SINGLE, 0, 0 ); 267 vidl_pt_mac( MONO_F32, "Mono float 32", vxl_ieee_32, 32, MONO, SINGLE, 0, 0 ); 268 vidl_pt_mac( RGB_F32, "RGB float 32", vxl_ieee_32, 96, RGB, SINGLE, 0, 0 ); 269 vidl_pt_mac( RGB_F32P, "RGB float 32P", vxl_ieee_32, 96, RGB, PLANAR, 0, 0 ); 270 271 #undef vidl_pt_mac 272 273 274 //: Define the packing order for each packed vidl_pixel_format 275 // The main purpose of this struct is to define a static 276 // array of pointer offsets to describe the packing. 277 // 278 // The array vidl_pixel_pack_of<format>::offset is a 2D array 279 // of pointer offsets from the start of the macro pixel. The 280 // size of the array is macro-pixel-size by number-of-channels. 281 // The value offset[i][j] gives the offset to the jth channel 282 // of the ith pixel in the current macro-pixel. For example, 283 // offset[1][0] gives the 'Y' channel (if YUV) or 'R' channel 284 // (if RGB) of the second pixel in the macro pixel 285 // 286 // \note the offset arrays are defined in vidl_pixel_format.cxx 287 template <vidl_pixel_format pix_type> 288 struct vidl_pixel_pack_of; 289 #define vidl_pp_mac(FMT)\ 290 template <> \ 291 struct vidl_pixel_pack_of<VIDL_PIXEL_FORMAT_##FMT> \ 292 {\ 293 enum { macro_pix_size = 1<<vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT>::chroma_shift_x }; \ 294 enum { num_channels = vidl_pixel_traits_of<VIDL_PIXEL_FORMAT_##FMT>::num_channels }; \ 295 static VIDL_EXPORT const std::ptrdiff_t offset[macro_pix_size][num_channels]; \ 296 } 297 298 vidl_pp_mac( YUYV_422 ); 299 vidl_pp_mac( UYVY_422 ); 300 vidl_pp_mac( UYVY_411 ); 301 302 #undef vidl_pp_mac 303 304 305 //============================================================================= 306 // The following functions provide runtime lookup of pixel traits 307 // These use template metaprogramming to generate the conditionals to 308 // check the traits of each vidl_pixel_format. You do not need to 309 // modify the function definitions when adding new types. 310 311 312 //: Return the number of channels needed in a color mode 313 unsigned 314 vidl_pixel_color_num_channels(vidl_pixel_color c); 315 316 317 //: Return the set of traits for pixel format f 318 vidl_pixel_traits 319 vidl_pixel_format_traits(vidl_pixel_format f); 320 321 322 //: Return the typeid of the pixel format datatype 323 inline const std::type_info& 324 vidl_pixel_format_typeid(vidl_pixel_format f) 325 { 326 return *vidl_pixel_format_traits(f).type; 327 } 328 329 //: Return the effective number of bits per image pixel in pixel format f 330 inline unsigned 331 vidl_pixel_format_bpp(vidl_pixel_format f) 332 { 333 return vidl_pixel_format_traits(f).bits_per_pixel; 334 } 335 336 337 //: Return the number of color channels encoded in pixel format f 338 inline unsigned 339 vidl_pixel_format_num_channels(vidl_pixel_format f) 340 { 341 return vidl_pixel_format_traits(f).num_channels; 342 } 343 344 345 //: Return the color encoding for the pixel format 346 inline vidl_pixel_color 347 vidl_pixel_format_color(vidl_pixel_format f) 348 { 349 return vidl_pixel_format_traits(f).color; 350 } 351 352 353 //: Return the pixel arrangement for a given format 354 inline vidl_pixel_arrangement 355 vidl_pixel_format_arrangement(vidl_pixel_format f) 356 { 357 return vidl_pixel_format_traits(f).arrangement; 358 } 359 360 361 //: Return the chroma shift in the horizontal direction 362 inline unsigned 363 vidl_pixel_format_chroma_shift_x(vidl_pixel_format f) 364 { 365 return vidl_pixel_format_traits(f).chroma_shift_x; 366 } 367 368 369 //: Return the chroma shift in the vertical direction 370 inline unsigned 371 vidl_pixel_format_chroma_shift_y(vidl_pixel_format f) 372 { 373 return vidl_pixel_format_traits(f).chroma_shift_y; 374 } 375 376 377 //: Output a pretty string representing the pixel format. 378 std::ostream & 379 operator << (std::ostream &os, vidl_pixel_format f); 380 381 382 //: Convert a string into a pixel format. 383 inline std::string 384 vidl_pixel_format_to_string(vidl_pixel_format f) 385 { 386 return vidl_pixel_format_traits(f).name; 387 } 388 389 390 //: Convert a string into a pixel format. 391 vidl_pixel_format 392 vidl_pixel_format_from_string(const std::string& s); 393 394 395 //: Compute the size (in bytes) of a \a ni x \a nj image buffer of pixel format \a f 396 unsigned 397 vidl_pixel_format_buffer_size(unsigned ni, unsigned nj, vidl_pixel_format f); 398 399 #endif // vidl_pixel_format_h_ 400