gml_YUVColor.h

00001 // gml_YUVColor.h --
00002 // 
00003 //  Defines the gml_TColor_YUV class template
00004 // 
00005 // Copyright (c) 2004 CLIPS-IMAG
00006 // 
00007 // See the file "gml_LicenseTerms.txt" for information on usage and redistribution
00008 // of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00009 // 
00010 //  Created on January 9, 2004 (JL).
00011 
00012 #ifndef __GML_YUVCOLOR__
00013 #define __GML_YUVCOLOR__
00014 
00015 #include <float.h>
00016 #include <assert.h>
00017 #include "gml/base/gml_Attributes.h"
00018 #include "gml/base/gml_Types.h"
00019 #include "gml/math/gml_Math.h"
00020 
00021 ///
00022 /// gml_TColor_YUV_888 --
00023 ///   A union type used to represent YUV-encoded color pixels.
00024 ///
00025 template <typename Channel> class gml_TColor_YUV {
00026 public:
00027   ///
00028   /// Constructor --
00029   ///   Convert a 24-bit RGB triplet into YUV and fill in the object.
00030   ///
00031   gml_TColor_YUV (UInt8 const r, UInt8 const g, UInt8 const b) {
00032     Float32 const cr = 0.299;
00033     Float32 const cg = 0.587;
00034     Float32 const cb = 0.114;
00035     Float32 const cu = 0.5/(1.0-cb);
00036     Float32 const cv = 0.5/(1.0-cr);
00037     Float32 y, u, v;
00038     
00039     y = cr*r + cg*g + cb*b;
00040     u = cu * (b - y);
00041     v = cv * (r - y);
00042 
00043     Y = LFloor ((219.0/256.0) * y + 16.5);  // nominal range: 16..235
00044     U = LFloor ((224.0/256.0) * u + 128.5); // 16..240
00045     V = LFloor ((224.0/256.0) * v + 128.5); // 16..240
00046 
00047     /*
00048     // code from libdc1394/dc1394_conversions.h
00049     Y = Clamp (  (306*r + 601*g + 117*b) >> 10,        0, 255);
00050     U = Clamp (((-172*r - 340*g + 512*b) >> 10) + 128, 0, 255);
00051     V = Clamp ( ((512*r - 429*g -  83*b) >> 10) + 128, 0, 255);
00052     */
00053   }
00054 
00055   ///
00056   /// Constructor --
00057   ///   Fill the structure from data in memory
00058   ///
00059   gml_TColor_YUV (const void *const ptr)
00060   {
00061     *this = *((gml_TColor_YUV < Channel > *)ptr);
00062   }
00063 
00064   ///
00065   /// Constructor --
00066   ///   Leave the structure `as is'. I.e. probably zero.
00067   ///
00068   gml_TColor_YUV () { }
00069 
00070   ///
00071   /// Print --
00072   ///   Dump a representation of the pixel to stdout: channels in hex and
00073   ///   in degrees, percent, percent format.
00074   ///   @warning no newline appended !
00075   ///
00076   void Print () 
00077   {
00078     printf ("% 4d % 4d % 4d", Y, U, V);
00079   }
00080 
00081   ///
00082   /// Store --
00083   ///   Place the structure's data in memory
00084   ///
00085   void Store (void *const ptr)
00086   {
00087     *((gml_TColor_YUV<Channel> *) ptr) = *this;
00088   }
00089 
00090   ///
00091   /// Convert --
00092   ///   Convert the YUV data in this object to a 24 bit RGB triplet.
00093   ///
00094   void Convert (UInt8 &r, UInt8 &g, UInt8 &b)
00095   {
00096     SInt32 const u   = U - 128;
00097     SInt32 const v   = V - 128;
00098     SInt32 const y   = 76309 * (Y - 16); // (255/219)*65536
00099     SInt32 const crv = 104597;
00100     SInt32 const cbu = 132201;
00101     SInt32 const cgu = 25675;
00102     SInt32 const cgv = 53279;
00103 
00104     r = Clamp ((y + crv*v         + 32768) >> 16, 0L, 255L);
00105     g = Clamp ((y - cgu*u - cgv*v + 32768) >> 16, 0L, 255L);
00106     b = Clamp ((y + cbu*u         + 32786) >> 16, 0L, 255L);
00107 
00108     /*
00109     // code from libdc1394/dc1394_conversions.h
00110     r = Clamp (Y + ((V*1436) >> 10),        0, 255);
00111     g = Clamp (Y - ((U*352 + V*731) >> 10), 0, 255);
00112     b = Clamp (Y + ((U*1814) >> 10),        0, 255);
00113     */
00114   }
00115 
00116   ///
00117   /// Distance --
00118   ///   Compute the 16-bit distance to another YUV pixel.
00119   ///   Not implemented.
00120   ///
00121   UInt16 Distance (const gml_TColor_YUV<Channel> other)
00122   {
00123     return 0;
00124   }
00125 
00126   static UInt8  const sChannelBits = 8 * sizeof (Channel);       ///< bits per channel
00127   static UInt64 const sChannelMax  = (1 << sChannelBits) - 1;    ///< max channel value
00128 
00129   struct {                          ///< structure for transparent channel access
00130     #if BYTE_ORDER == BIG_ENDIAN
00131         Channel Y;                  ///< luminance
00132         Channel U;                  ///< red chrominance
00133         Channel V;                  ///< blue chrominance
00134     #else
00135         Channel Y;                  ///< luminance
00136         Channel U;                  ///< blue chrominance
00137         Channel V;                  ///< red chrominance
00138     #endif
00139   } GML_PACKED;
00140 
00141 };
00142 
00143 //
00144 // gml_TColor_YUV_888 --
00145 //
00146 typedef gml_TColor_YUV <UInt8>  gml_TColor_YUV_888;
00147 
00148 #endif /* __GML_YUVCOLOR__ */
00149 
Generated on Tue Jun 12 14:03:27 2007 for gml by Doxygen 1.5.2.