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