image.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 2008 Autodesk, Inc.
00003 // All rights reserved.
00004 //
00005 // Use of this software is subject to the terms of the Autodesk license
00006 // agreement provided at the time of installation or download, or which
00007 // otherwise accompanies this software in either electronic or hard copy form.
00008 //
00009 //**************************************************************************/
00010 // DESCRIPTION:
00011 // CREATED: October 2008
00012 //**************************************************************************/
00013 
00014 #if !defined IMAGE_H_
00015 #define IMAGE_H_
00016 
00017 namespace mudbox {
00018 
00019 
00020 class Image;
00021 class SubdivisionLevel;
00022 class TexturePool;
00023 
00029 class MBDLL_DECL half_ {
00030 
00031 // These member fcns are inlined for a reason; THESE ARE EXTREMELY PERFORMANCE CRITICAL!
00032 // DO NOT change this file or "clean it up" by removing inlines. Unless you really know
00033 // what you are doing, you will make it significantly slower.
00034 //
00035 private:
00036     unsigned short m_bits;
00037     void setBits(unsigned short newbits) { m_bits = newbits; }
00038 
00039 public:
00040     half_ () {};
00041     half_ (float f)
00042     {
00043         unsigned int   x    = *(unsigned int *)&f;
00044         unsigned int   frac = (x >> 13) & 0x03ff;
00045         int            exp  = (int)((x >> 23) & 0xff) - 127;
00046 
00047         m_bits = (x >> 16) & 0x8000;  // extract the sign bit
00048 
00049         if (exp > 16) {      // handle overflows/underflows
00050             exp  = 16;
00051             frac = 0x03ff;
00052         } else if (exp <= -15) {
00053             frac = 0;
00054             exp  = -15;
00055         }
00056 
00057         m_bits |= ((exp + 15) << 10) | frac;
00058     }
00059 
00060 public:
00061     // Conversion to float ~ 15 cycles
00062     #define ExponentBiasDelta (127-15)
00063     operator float () const
00064     {
00065         int           exp  = (m_bits >> 10) & 0x1f;
00066         unsigned int  f    = (m_bits & 0x8000) << 16; // extract the sign bit
00067         unsigned int  frac = (m_bits & 0x03ff) << 13;
00068 
00069         if (exp == 0x1f) {      // convert 16-bit FP inf/NaN to 32-bit inf/NaN value
00070             exp =  0xff - ExponentBiasDelta;
00071         } else if (exp == 0) {
00072             exp = -ExponentBiasDelta;  // convert 16-bit FP zero/denorm to 32-bit zero/denorm value
00073         }
00074 
00075         f |= ((exp + ExponentBiasDelta) << 23) | frac;
00076         return *(float *)&f;
00077     }
00078 
00079     half_ &operator = (float f)
00080     {
00081         *this = half_ (f);
00082         return *this;
00083     }
00084 };
00085 
00086 //------------------------------------------------------------------------------
00087 typedef unsigned char  uInt8;
00088 typedef unsigned short uInt16;
00089 
00090 
00091 class uInt8Channel;
00092 class uInt16Channel;
00093 class float16Channel;
00094 class float32Channel;
00095 
00096 //------------------------------------------------------------------------------
00099 class uInt8Channel {
00100 private:
00101     uInt8 m_data;
00102 
00103 public:
00104     inline uInt8Channel(const float32Channel &d);
00105     inline uInt8Channel(const float16Channel &d);
00106     inline uInt8Channel(const uInt16Channel  &d);
00107     uInt8Channel(const uInt8Channel   &d) { m_data = uInt8(d); }
00108 
00109     uInt8Channel(uInt8 d)  { m_data = (d); }
00110     uInt8Channel() {}
00111 
00112     inline uInt8Channel & operator = (const float32Channel &d);
00113     inline uInt8Channel & operator = (const float16Channel &d);
00114     inline uInt8Channel & operator = (const uInt16Channel  &d);
00115     inline uInt8Channel & operator = (const uInt8Channel   &d)
00116     {
00117         m_data = uInt8(d);
00118         return *this;
00119     }
00120 
00121     inline uInt8Channel & operator = (uInt8 d)
00122     {
00123         m_data = uInt8(d);
00124         return *this;
00125     }
00126 
00127     operator float ()  const { return m_data * (1.0f/255.0f); }
00128     operator half_ ()  const { return half_(m_data * (1.0f/255.0f)); }
00129     operator uInt16 () const { return (m_data << 8) + m_data; }
00130     operator uInt8 ()  const { return m_data; }
00131 };
00132 
00133 
00134 //------------------------------------------------------------------------------
00136 class uInt16Channel {
00137 private:
00138     uInt16 m_data;
00139 
00140 public:
00141     inline uInt16Channel(const float32Channel &d);
00142     inline uInt16Channel(const float16Channel &d);
00143     uInt16Channel(const uInt16Channel  &d) { m_data = uInt16(d); }
00144     uInt16Channel(const uInt8Channel   &d) { m_data = uInt16(d); }
00145     uInt16Channel(uInt16 d)                { m_data = (d); }
00146     uInt16Channel() {}
00147 
00148     inline uInt16Channel & operator = (const float32Channel &d);
00149     inline uInt16Channel & operator = (const float16Channel &d);
00150 
00151     inline uInt16Channel & operator = (const uInt16Channel &d)
00152     {
00153         m_data = uInt16(d);
00154         return *this;
00155     }
00156 
00157     inline uInt16Channel & operator = (uInt16 d)
00158     {
00159         m_data = uInt16(d);
00160         return *this;
00161     }
00162 
00163     inline uInt16Channel & operator = (const uInt8Channel &d)
00164     {
00165         m_data = uInt16(d);
00166         return *this;
00167     }
00168 
00169     operator float ()  const { return m_data * (1.0f/65535.0f); }
00170     operator half_ ()  const { return half_(m_data * (1.0f/65535.0f)); }
00171     operator uInt16 () const { return m_data;               }
00172     operator uInt8 ()  const { return uInt8(m_data >> 8);   }
00173 };
00174 
00175 
00176 //------------------------------------------------------------------------------
00177 // The data type for a 32 bit float image channel.
00178 class float32Channel {
00179 private:
00180     float m_data;
00181 
00182 public:
00183     float32Channel(const float32Channel &d) { m_data = float(d); }
00184     inline float32Channel(const float16Channel &d);
00185     float32Channel(const uInt16Channel  &d) { m_data = float(d); }
00186     float32Channel(const uInt8Channel   &d) { m_data = float(d); }
00187     float32Channel(float                d)  { m_data = (d); }
00188     float32Channel() {}
00189 
00190     inline float32Channel & operator = (const float32Channel &d)
00191     {
00192         *(float *)this = *(float *)&d;
00193         return *this;
00194     }
00195 
00196     inline float32Channel & operator = (const float16Channel &d)
00197     {
00198         *this = float32Channel(d);
00199         return *this;
00200     }
00201 
00202     inline float32Channel & operator = (const uInt16Channel &d)
00203     {
00204         *this = float32Channel(d);
00205         return *this;
00206     }
00207 
00208     inline float32Channel & operator = (float d)
00209     {
00210         *this = float32Channel(d);
00211         return *this;
00212     }
00213 
00214     inline float32Channel & operator = (const uInt8Channel &d)
00215     {
00216         *this = float32Channel(d);
00217         return *this;
00218     }
00219 
00220     operator float ()  const { return m_data; }
00221     operator half_ ()  const { return half_(m_data); }
00222     operator uInt16 () const
00223         {
00224             if (m_data < 0.0f) return 0;
00225             if (m_data > 1.0f) return 65535;
00226             return uInt16(m_data * 65535.0f);
00227         }
00228     operator uInt8 ()  const
00229         {
00230             if (m_data < 0.0f) return 0;
00231             if (m_data > 1.0f) return 255;
00232             return uInt8(m_data * 255.0f);
00233         }
00234 };
00235 
00236 
00237 //------------------------------------------------------------------------------
00239 class float16Channel {
00240 private:
00241     half_ m_data;
00242 
00243 public:
00244     float16Channel(const float32Channel &d) { m_data = float(d); }
00245     float16Channel(const float16Channel &d) { m_data = float(d); }
00246     float16Channel(const uInt16Channel  &d) { m_data = float(d); }
00247     float16Channel(const uInt8Channel   &d) { m_data = float(d); }
00248     float16Channel(const half_          &d) { m_data = (d); }
00249     float16Channel() {}
00250 
00251     inline float16Channel & operator = (const float32Channel &d)
00252     {
00253         *this = float16Channel(d);
00254         return *this;
00255     }
00256 
00257     inline float16Channel & operator = (const float16Channel &d)
00258     {
00259         *(uInt16 *)this = *(uInt16 *)&d;
00260         return *this;
00261     }
00262 
00263     inline float16Channel & operator = (const uInt16Channel &d)
00264     {
00265         *this = float16Channel(d);
00266         return *this;
00267     }
00268 
00269     inline float16Channel & operator = (const half_ &d)
00270     {
00271         *this = float16Channel(d);
00272         return *this;
00273     }
00274 
00275     inline float16Channel & operator = (const uInt8Channel &d)
00276     {
00277         *this = float16Channel(d);
00278         return *this;
00279     }
00280 
00281     operator float ()  const { return float(m_data); }
00282     operator half_ ()  const { return m_data; }
00283 
00284     operator uInt16 () const
00285         {   float d = float(m_data);
00286             if (d < 0.0f) return 0;
00287             if (d > 1.0f) return 65535;
00288             return uInt16(d * 65535.0f);
00289         }
00290     operator uInt8 ()  const
00291         {   float d = float(m_data);
00292             if (d < 0.0f) return 0;
00293             if (d > 1.0f) return 255;
00294             return uInt8(d * 255.0f);
00295         }
00296 };
00297 
00298 
00299 //------------------------------------------------------------------------------
00300 inline uInt8Channel::uInt8Channel(const float32Channel &d) { m_data = uInt8(d); }
00301 inline uInt8Channel::uInt8Channel(const float16Channel &d) { m_data = uInt8(d); }
00302 inline uInt8Channel::uInt8Channel(const uInt16Channel  &d) { m_data = uInt8(d); }
00303 
00304 //------------------------------------------------------------------------------
00305 inline uInt8Channel & uInt8Channel::operator = (const float32Channel &d)
00306 {
00307     m_data = uInt8(d);
00308     return *this;
00309 }
00310 
00311 //------------------------------------------------------------------------------
00312 inline uInt8Channel & uInt8Channel::operator = (const float16Channel &d)
00313 {
00314     m_data = uInt8(d);
00315     return *this;
00316 }
00317 
00318 //------------------------------------------------------------------------------
00319 inline uInt8Channel & uInt8Channel::operator = (const uInt16Channel &d)
00320 {
00321     m_data = uInt8(d);
00322     return *this;
00323 }
00324 
00325 
00326 //------------------------------------------------------------------------------
00327 inline uInt16Channel::uInt16Channel(const float32Channel &d) { m_data = uInt16(d); }
00328 inline uInt16Channel::uInt16Channel(const float16Channel &d) { m_data = uInt16(d); }
00329 
00330 //------------------------------------------------------------------------------
00331 inline uInt16Channel & uInt16Channel::operator = (const float32Channel &d)
00332 {
00333     m_data = uInt16(d);
00334     return *this;
00335 }
00336 
00337 //------------------------------------------------------------------------------
00338 inline uInt16Channel & uInt16Channel::operator = (const float16Channel &d)
00339 {
00340     m_data = uInt16(d);
00341     return *this;
00342 }
00343 
00344 
00345 //------------------------------------------------------------------------------
00346 inline float32Channel::float32Channel(const float16Channel &d) { m_data = float(d); }
00347 
00348 //----------------------------------------------------------------------------------
00349 // Now we define the pixel types -- 1, 3, and 4 channels. templated by
00350 // one of the above channel types -- the channel types handle converting between
00351 // each other, and the pixel types handle converting between them.
00352 // 1 -> 3  or 4 channel -- replicates the single channel through the target channels
00353 // 3 -> 4 channel copies the rgb, and sets the a to 1.0. 4 -> 3 channel copies the
00354 // RGB. 4 & 3 -> 1 channel takes the luminance of the rgb channels and stores it
00355 // in the single channel.
00356 //
00357 
00365 template <class ChanType, const unsigned char NumChans>
00366 class MBDLL_TEMPLATE_DECL PixelType {
00367 
00368     // allow the various instantiations of this class to
00369     // access each others private data members... Also has the
00370     // beneficial side effect of causing a compile error if
00371     // someone tries to instantiate one that is not listed here.
00372     friend class PixelType<uInt8Channel,   1>;
00373     friend class PixelType<uInt8Channel,   3>;
00374     friend class PixelType<uInt8Channel,   4>;
00375     friend class PixelType<uInt16Channel,  1>;
00376     friend class PixelType<uInt16Channel,  3>;
00377     friend class PixelType<uInt16Channel,  4>;
00378     friend class PixelType<float16Channel, 1>;
00379     friend class PixelType<float16Channel, 3>;
00380     friend class PixelType<float16Channel, 4>;
00381     friend class PixelType<float32Channel, 1>;
00382     friend class PixelType<float32Channel, 3>;
00383     friend class PixelType<float32Channel, 4>;
00384 
00385 private:
00386     ChanType m_pixel[NumChans];
00387 
00388 public:
00389 
00391     PixelType<ChanType, NumChans> &swapRB() {
00392         if (NumChans > 2) { // conditional will be resolved at compile time.
00393             ChanType t = m_pixel[0];
00394             m_pixel[0] = m_pixel[2];
00395             m_pixel[2] = t;
00396         }
00397         return *this;
00398     }
00399 
00401     PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 4> &p)
00402     {
00403         switch (NumChans) { // this switch gets resolved at compile time
00404         case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77  +
00405                                                     (uInt8)p.m_pixel[1]*150 +
00406                                                     (uInt8)p.m_pixel[2]*28));
00407         break;
00408         // cppcheck mistakenly warns about array bounds here -- ignore it.
00409         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00410                 m_pixel[2] = p.m_pixel[2];
00411         break;
00412         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00413                 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00414         break;
00415         }
00416     }
00417 
00419     PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 3> &p)
00420     {
00421         switch (NumChans) { // this switch gets resolved at compile time
00422         case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77  +
00423                                                     (uInt8)p.m_pixel[1]*150 +
00424                                                     (uInt8)p.m_pixel[2]*28));
00425         break;
00426         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00427                 m_pixel[2] = p.m_pixel[2];
00428         break;
00429         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00430                 m_pixel[2] = p.m_pixel[2];
00431                 m_pixel[3] = ChanType(float32Channel(1.0f));
00432         break;
00433         }
00434     }
00435 
00437     PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 1> &p)
00438     {
00439         switch (NumChans) { // this switch gets resolved at compile time
00440         case 1: m_pixel[0] = p.m_pixel[0];
00441         break;
00442         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00443                 m_pixel[2] = p.m_pixel[0];
00444         break;
00445         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00446                 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f)); ;
00447         break;
00448         }
00449     }
00450 
00451 
00453     PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 4> &p)
00454     {
00455         switch (NumChans) { // this switch gets resolved at compile time
00456         case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
00457                                                     (((uInt16)p.m_pixel[1]*38666)>>16) +
00458                                                     (((uInt16)p.m_pixel[2]*7209 )>>16)));
00459         break;
00460         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00461                 m_pixel[2] = p.m_pixel[2];
00462         break;
00463         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00464                 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00465         break;
00466         }
00467     }
00468 
00470     PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 3> &p)
00471     {
00472         switch (NumChans) { // this switch gets resolved at compile time
00473         case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
00474                                                     (((uInt16)p.m_pixel[1]*38666)>>16) +
00475                                                     (((uInt16)p.m_pixel[2]*7209 )>>16)));
00476         break;
00477         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00478                 m_pixel[2] = p.m_pixel[2];
00479         break;
00480         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00481                 m_pixel[2] = p.m_pixel[2];
00482                 m_pixel[3] = ChanType(float32Channel(1.0f));
00483         break;
00484         }
00485     }
00486 
00488     PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 1> &p)
00489     {
00490         switch (NumChans) { // this switch gets resolved at compile time
00491         case 1: m_pixel[0] = p.m_pixel[0];
00492         break;
00493         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00494                 m_pixel[2] = p.m_pixel[0];
00495         break;
00496         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00497                 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00498         break;
00499         }
00500     }
00501 
00502 
00504     PixelType<ChanType, NumChans>(const PixelType<float16Channel, 4> &p)
00505     {
00506         switch (NumChans) { // this switch gets resolved at compile time
00507         case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00508                                                      ((float)p.m_pixel[1]*0.59f) +
00509                                                      ((float)p.m_pixel[2]*0.11f)));
00510         break;
00511         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00512                 m_pixel[2] = p.m_pixel[2];
00513         break;
00514         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00515                 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00516         break;
00517         }
00518     }
00519 
00521     PixelType<ChanType, NumChans>(const PixelType<float16Channel, 3> &p)
00522     {
00523         switch (NumChans) { // this switch gets resolved at compile time
00524         case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00525                                                      ((float)p.m_pixel[1]*0.59f) +
00526                                                      ((float)p.m_pixel[2]*0.11f)));
00527         break;
00528         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00529                 m_pixel[2] = p.m_pixel[2];
00530         break;
00531         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00532                 m_pixel[2] = p.m_pixel[2];
00533                 m_pixel[3] = ChanType(float32Channel(1.0f));
00534         break;
00535         }
00536     }
00537 
00539     PixelType<ChanType, NumChans>(const PixelType<float16Channel, 1> &p)
00540     {
00541         switch (NumChans) { // this switch gets resolved at compile time
00542         case 1: m_pixel[0] = p.m_pixel[0];
00543         break;
00544         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00545                 m_pixel[2] = p.m_pixel[0];
00546         break;
00547         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00548                 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00549         break;
00550         }
00551     }
00552 
00553 
00555     PixelType<ChanType, NumChans>(const PixelType<float32Channel, 4> &p)
00556     {
00557         switch (NumChans) { // this switch gets resolved at compile time
00558         case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00559                                                      ((float)p.m_pixel[1]*0.59f) +
00560                                                      ((float)p.m_pixel[2]*0.11f)));
00561         break;
00562         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00563                 m_pixel[2] = p.m_pixel[2];
00564         break;
00565         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00566                 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00567         break;
00568         }
00569     }
00570 
00572     PixelType<ChanType, NumChans>(const PixelType<float32Channel, 3> &p)
00573     {
00574         switch (NumChans) { // this switch gets resolved at compile time
00575         case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00576                                                      ((float)p.m_pixel[1]*0.59f) +
00577                                                      ((float)p.m_pixel[2]*0.11f)));
00578         break;
00579         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00580                 m_pixel[2] = p.m_pixel[2];
00581         break;
00582         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00583                 m_pixel[2] = p.m_pixel[2];
00584                 m_pixel[3] = ChanType(float32Channel(1.0f));
00585         break;
00586         }
00587     }
00588 
00590     PixelType<ChanType, NumChans>(const PixelType<float32Channel, 1> &p)
00591     {
00592         switch (NumChans) { // this switch gets resolved at compile time
00593         case 1: m_pixel[0] = p.m_pixel[0];
00594         break;
00595         case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00596                 m_pixel[2] = p.m_pixel[0];
00597         break;
00598         case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00599                 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00600         break;
00601         }
00602     }
00603 
00604 
00606     void SetLuminance(const PixelType<uInt8Channel, 4> &p)
00607     {
00608         if (NumChans == 4) {
00609             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00610             m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77  +
00611                                                  (uInt8)p.m_pixel[1]*150 +
00612                                                  (uInt8)p.m_pixel[2]*28)));
00613         }
00614     }
00615 
00617     void SetLuminance(const PixelType<uInt8Channel, 3> &p)
00618     {
00619         if (NumChans == 4) {
00620             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00621             m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77  +
00622                                                  (uInt8)p.m_pixel[1]*150 +
00623                                                  (uInt8)p.m_pixel[2]*28)));
00624         }
00625     }
00626 
00628     void SetLuminance(const PixelType<uInt16Channel, 4> &p)
00629     {
00630         if (NumChans == 4) {
00631             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00632             m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
00633                                                  (((uInt16)p.m_pixel[1]*38666)>>16) +
00634                                                  (((uInt16)p.m_pixel[2]*7209 )>>16))));
00635         }
00636     }
00637 
00639     void SetLuminance(const PixelType<uInt16Channel, 3> &p)
00640     {
00641         if (NumChans == 4) {
00642             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00643             m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
00644                                                  (((uInt16)p.m_pixel[1]*38666)>>16) +
00645                                                  (((uInt16)p.m_pixel[2]*7209 )>>16))));
00646         }
00647     }
00648 
00649 
00651     void SetLuminance(const PixelType<float16Channel, 4> &p)
00652     {
00653         if (NumChans == 4) {
00654             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00655             m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00656                                                   ((float)p.m_pixel[1]*0.59f) +
00657                                                   ((float)p.m_pixel[2]*0.11f))));
00658         }
00659     }
00660 
00662     void SetLuminance(const PixelType<float16Channel, 3> &p)
00663     {
00664         if (NumChans == 4) {
00665             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00666             m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00667                                                   ((float)p.m_pixel[1]*0.59f) +
00668                                                   ((float)p.m_pixel[2]*0.11f))));
00669         }
00670     }
00671 
00673     void SetLuminance(const PixelType<float32Channel, 4> &p)
00674     {
00675         if (NumChans == 4) {
00676             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00677             m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00678                                                   ((float)p.m_pixel[1]*0.59f) +
00679                                                   ((float)p.m_pixel[2]*0.11f))));
00680         }
00681     }
00682 
00684     void SetLuminance(const PixelType<float32Channel, 3> &p)
00685     {
00686         if (NumChans == 4) {
00687             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00688             m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00689                                                   ((float)p.m_pixel[1]*0.59f) +
00690                                                   ((float)p.m_pixel[2]*0.11f))));
00691         }
00692     }
00693 
00695     void SetLuminance(const PixelType<float32Channel, 1> &p)
00696     {
00697         if (NumChans == 4) {
00698             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00699             m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00700         }
00701     }
00702 
00704     void SetLuminance(const PixelType<float16Channel, 1> &p)
00705     {
00706         if (NumChans == 4) {
00707             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00708             m_pixel[3] = ChanType(float32Channel(((float)p.m_pixel[0])));
00709         }
00710     }
00711 
00713     void SetLuminance(const PixelType<uInt16Channel, 1> &p)
00714     {
00715         if (NumChans == 4) {
00716             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00717             m_pixel[3] = ChanType(uInt16Channel(((uInt16)p.m_pixel[0])));
00718         }
00719     }
00720 
00722     void SetLuminance(const PixelType<uInt8Channel, 1> &p)
00723     {
00724         if (NumChans == 4) {
00725             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00726             m_pixel[3] = ChanType(uInt8Channel(((uInt8)p.m_pixel[0])));
00727         }
00728     }
00729 
00730 
00732     void SetInvLuminance(const PixelType<uInt8Channel, 4> &p)
00733     {
00734         if (NumChans == 4) {
00735             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00736             m_pixel[3] = ChanType(uInt16Channel(65535 -
00737                                                 ((uInt8)p.m_pixel[0]*77  +
00738                                                  (uInt8)p.m_pixel[1]*150 +
00739                                                  (uInt8)p.m_pixel[2]*28)));
00740         }
00741     }
00742 
00744     void SetInvLuminance(const PixelType<uInt8Channel, 3> &p)
00745     {
00746         if (NumChans == 4) {
00747             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00748             m_pixel[3] = ChanType(uInt16Channel(65535 -
00749                                                 ((uInt8)p.m_pixel[0]*77  +
00750                                                  (uInt8)p.m_pixel[1]*150 +
00751                                                  (uInt8)p.m_pixel[2]*28)));
00752         }
00753     }
00754 
00756     void SetInvLuminance(const PixelType<uInt16Channel, 4> &p)
00757     {
00758         if (NumChans == 4) {
00759             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00760             m_pixel[3] = ChanType(uInt16Channel(65535 -
00761                                                 ((((uInt16)p.m_pixel[0]*19660)>>16) +
00762                                                  (((uInt16)p.m_pixel[1]*38666)>>16) +
00763                                                  (((uInt16)p.m_pixel[2]*7209 )>>16))));
00764         }
00765     }
00766 
00768     void SetInvLuminance(const PixelType<uInt16Channel, 3> &p)
00769     {
00770         if (NumChans == 4) {
00771             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00772             m_pixel[3] = ChanType(uInt16Channel(65535 -
00773                                                 ((((uInt16)p.m_pixel[0]*19660)>>16) +
00774                                                  (((uInt16)p.m_pixel[1]*38666)>>16) +
00775                                                  (((uInt16)p.m_pixel[2]*7209 )>>16))));
00776         }
00777     }
00778 
00779 
00781     void SetInvLuminance(const PixelType<float16Channel, 4> &p)
00782     {
00783         if (NumChans == 4) {
00784             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00785             m_pixel[3] = ChanType(float32Channel(1.0f -
00786                                                  (((float)p.m_pixel[0]*0.30f) +
00787                                                   ((float)p.m_pixel[1]*0.59f) +
00788                                                   ((float)p.m_pixel[2]*0.11f))));
00789         }
00790     }
00791 
00793     void SetInvLuminance(const PixelType<float16Channel, 3> &p)
00794     {
00795         if (NumChans == 4) {
00796             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00797             m_pixel[3] = ChanType(float32Channel(1.0f -
00798                                                  (((float)p.m_pixel[0]*0.30f) +
00799                                                   ((float)p.m_pixel[1]*0.59f) +
00800                                                   ((float)p.m_pixel[2]*0.11f))));
00801         }
00802     }
00803 
00805     void SetInvLuminance(const PixelType<float32Channel, 4> &p)
00806     {
00807         if (NumChans == 4) {
00808             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00809             m_pixel[3] = ChanType(float32Channel(1.0f -
00810                                                  (((float)p.m_pixel[0]*0.30f) +
00811                                                   ((float)p.m_pixel[1]*0.59f) +
00812                                                   ((float)p.m_pixel[2]*0.11f))));
00813         }
00814     }
00815 
00817     void SetInvLuminance(const PixelType<float32Channel, 3> &p)
00818     {
00819         if (NumChans == 4) {
00820             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00821             m_pixel[3] = ChanType(float32Channel(1.0f - (((float)p.m_pixel[0]*0.30f) +
00822                                                          ((float)p.m_pixel[1]*0.59f) +
00823                                                          ((float)p.m_pixel[2]*0.11f))));
00824         }
00825     }
00826 
00828     void SetInvLuminance(const PixelType<float32Channel, 1> &p)
00829     {
00830         if (NumChans == 4) {
00831             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00832             m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00833         }
00834     }
00835 
00837     void SetInvLuminance(const PixelType<float16Channel, 1> &p)
00838     {
00839         if (NumChans == 4) {
00840             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00841             m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00842         }
00843     }
00844 
00846     void SetInvLuminance(const PixelType<uInt16Channel, 1> &p)
00847     {
00848         if (NumChans == 4) {
00849             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00850             m_pixel[3] = ChanType(uInt16Channel(65535 - ((uInt16)p.m_pixel[0])));
00851         }
00852     }
00853 
00855     void SetInvLuminance(const PixelType<uInt8Channel, 1> &p)
00856     {
00857         if (NumChans == 4) {
00858             m_pixel[0] = m_pixel[1] = m_pixel[2] = 
00859             m_pixel[3] = ChanType(uInt8Channel(255 - ((uInt8)p.m_pixel[0])));
00860         }
00861     }
00862 };
00863 
00864 
00865 //------------------------------------------------------------------------------
00867 class MBDLL_DECL ImgTile
00868 {
00869 public:
00870     int  x;   
00871     int  y;   
00872     int  nx;  
00873     int  ny;  
00876     inline ImgTile() : x(0), y(0), nx(0), ny(0) {}
00877 
00885     inline ImgTile(int X, int Y, int NX, int NY) : x(X), y(Y), nx(NX), ny(NY) {}
00886 
00887     #if !defined MAX
00888     #define MAX(a_, b_) (((a_) > (b_)) ? (a_) : (b_))
00889     #endif
00890     #if !defined MIN
00891     #define MIN(a_, b_) (((a_) < (b_)) ? (a_) : (b_))
00892     #endif
00893 
00899     ImgTile(const ImgTile &a, const ImgTile &b)
00900     {
00901         x  = MAX(a.x, b.x);
00902         y  = MAX(a.y, b.y);
00903         nx = MIN(a.x+a.nx, b.x+b.nx) - x;
00904         ny = MIN(a.y+a.ny, b.y+b.ny) - y;
00905         if (nx <= 0 || ny <= 0) x = y = nx = ny = 0;
00906     }
00907 
00908     inline bool isEqualTile(const ImgTile &t) const
00909     { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
00910 
00911     inline bool operator ==(const ImgTile &t) const
00912     { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
00913 
00914     inline bool operator !=(const ImgTile &t) const
00915     { return !(t == *this); }
00916 
00918     inline bool isEmpty() const { return nx <= 0 || ny <= 0; }
00919 
00920     inline void setEmpty() { x = y = nx = ny = 0; }
00921 
00923     inline bool contains(const ImgTile &a) const
00924     { return x <= a.x && a.x+a.nx <= x+nx &&
00925              y <= a.y && a.y+a.ny <= y+ny;
00926     }
00927 
00929     inline bool contains(int x_, int y_) const
00930     { return x <= x_ && x_ < x+nx && y <= y_ && y_ < y+ny;
00931     }
00932 
00934     void clipPositive()
00935     {
00936         if (x < 0) {
00937             nx += x; x = 0;
00938             if (nx < 0) x = y = nx = ny = 0;
00939         }
00940         if (y < 0) {
00941             ny += y; y = 0;
00942             if (ny < 0) x = y = nx = ny = 0;
00943         }
00944     }
00945 
00947     void ExpandToInclude(int x_, int y_)
00948     {
00949         if (isEmpty()) {
00950             x = x_; y = y_; nx = 1; ny = 1;
00951         } else {
00952             if (x_ < x) { nx += (x - x_); x = x_; }
00953             if (y_ < y) { ny += (y - y_); y = y_; }
00954 
00955             if (x + nx < x_) nx = (x_ - x) + 1;
00956             if (y + ny < y_) ny = (y_ - y) + 1;
00957         }
00958     }
00959 
00961     void Expand(int numPixels = 1)
00962     {
00963         x  -= numPixels; y  -= numPixels;
00964         numPixels <<= 1;
00965         nx += numPixels; ny += numPixels;
00966     }
00967 
00969     int numPixels() const { return isEmpty() ? 0 : nx * ny; }
00970 };
00971 
00972 
00973 //------------------------------------------------------------------------------
00976 class MBDLL_DECL ImgTile_AoutB_Iter : public ImgTile {
00977 private:
00978     int            ax1, ax2, bx1, bx2;
00979     int            ay1, ay2, by1, by2;
00980     signed char    state;
00981     bool           ad,  bd;
00982 
00983 public:
00984     ImgTile_AoutB_Iter(const ImgTile &A, const ImgTile &B) :
00985         ax1   (A.x), ax2 (A.x + A.nx - 1),
00986         bx1   (B.x), bx2 (B.x + B.nx - 1),
00987         ay1   (A.y), ay2 (A.y + A.ny - 1),
00988         by1   (B.y), by2 (B.y + B.ny - 1),
00989         state (0),
00990         ad    (A.nx <= 0 || A.ny <= 0),
00991         bd    (B.nx <= 0 || B.ny <= 0) {}
00992 
00993     virtual bool next();
00994 };
00995 
00996 
00997 //-----------------------------------------------------------------------------
00998 class MBDLL_DECL ImgTileUnion : public ImgTile {
00999 public:
01000     ImgTileUnion(const ImgTile &A, const ImgTile &B);
01001 };
01002 
01003 
01010 class MBDLL_DECL ImgPageIterator : public ImgTile {
01011 protected:
01012     void    *m_BlindData;
01013     Image   *m_Image;
01014     int      m_Type;
01015     void    *m_PixelData;
01016     ImgTile  m_SrcTile;
01017 
01018 
01019 public:
01028     ImgPageIterator(Image *img, const ImgTile *srcTile = 0, bool writing = false);
01029     virtual ~ImgPageIterator();
01030     virtual bool  next();
01031     void         *dataPtr() { return m_PixelData; }
01032 };
01033 
01034 
01035 //------------------------------------------------------------------------------
01037 class MBDLL_DECL ImgLockPageIterator : public ImgPageIterator {
01038 public:
01039     typedef enum {
01040         ReadOnly,   
01041         ReadWrite,  
01042         WriteOnly   
01043     } AccessMode;
01044 
01045 protected:
01046     bool        m_SmartImage;
01047     AccessMode  m_Mode;
01048 
01049 public:
01050     ImgLockPageIterator(Image *img, const ImgTile *srcTile = 0, AccessMode mode = ReadOnly);
01051     ~ImgLockPageIterator();
01052 
01053     virtual bool  next();
01054     void         *dataPtr();
01055 };
01056 
01057 //------------------------------------------------------------------------------
01067 class PixelDescriptor {
01068 public:
01070     typedef enum {
01071         uChar   = 0,  
01072         uShort  = 1,  
01073         sHalf   = 2,  
01074         sFloat  = 3,  
01076         sChar   = 4,  
01077         sShort  = 5,  
01078         uInt    = 6,  
01079         sInt    = 7,  
01080         sDouble = 8   
01081     } ChannelType;
01082 
01085     typedef enum {
01086         orderNONE = 0, 
01087         orderRGBA = 1, 
01088         orderABGR = 2, 
01089         orderBGRA = 3, 
01090         orderARGB = 4, 
01091         orderRGB  = 5, 
01092         orderBGR  = 6  
01093     } MemoryChannelOrder;
01094 
01095 protected:
01096     char                m_cCount;        
01097     ChannelType         m_channelType;   
01098     MemoryChannelOrder  m_channelOrder;  
01099     bool                m_PreMultiplied; 
01102 public:
01103 
01104     PixelDescriptor(char                cCount,
01105                     ChannelType         channelType,
01106                     MemoryChannelOrder  channelOrder,
01107                     bool                PreMultiplied)
01108         : m_cCount       (cCount)
01109         , m_channelType  (channelType)
01110         , m_channelOrder (channelOrder)
01111         , m_PreMultiplied(PreMultiplied) {}
01112 
01114     int channelSize() const {
01115         const unsigned char s_channelByteCount[] = {1, 2, 2, 4, 1, 2, 4, 4, 8};
01116         return s_channelByteCount[m_channelType];
01117     }
01118 
01120     int channelBitSize() const {
01121         return channelSize() * 8;
01122     }
01123 
01125     int pixelSize() const {
01126         return channelSize() * m_cCount;
01127     }
01128 
01130     int pixelBitSize() const {
01131         return pixelSize() * 8;
01132     }
01133 
01135     ChannelType channelType() const { return m_channelType; }
01136 
01138     MemoryChannelOrder channelOrder() const { return m_channelOrder; }
01139 
01142     bool premultiplied() const { return m_PreMultiplied; }
01143 
01145     int channelCount() const   { return m_cCount; }
01146 
01148     bool operator == (const PixelDescriptor &pd) const
01149     { return (m_cCount         == pd.m_cCount        &&
01150               m_channelType    == pd.m_channelType   &&
01151               m_channelOrder   == pd.m_channelOrder  &&
01152               m_PreMultiplied  == pd.m_PreMultiplied);
01153     }
01154 };
01155 
01156 
01157 
01158 //------------------------------------------------------------------------------
01162 class ImageDescriptor : public PixelDescriptor {
01163 
01164 public:
01166     enum ResUnit { k_PixelsPerInch       = 1, 
01167                    k_PixelsPerCentimeter = 2  
01168     };
01169 
01170 protected:
01171     ImgTile   m_Bounds; 
01173     float     m_xResolution;      
01174     float     m_yResolution;      
01175     ResUnit   m_ResolutionUnits;  
01177 public:
01178 
01191     ImageDescriptor(int x, int y, int nx, int ny,
01192                     MemoryChannelOrder order = orderRGBA,
01193                     bool premult = true,
01194                     char nc = 4, ChannelType ct = uChar) :
01195         PixelDescriptor(nc, ct, order, premult),
01196         m_Bounds(x, y, nx, ny),
01197         m_xResolution(100.0f), m_yResolution(100.0f),
01198         m_ResolutionUnits(k_PixelsPerInch) {}
01199 
01210     ImageDescriptor(int nx, int ny,
01211                     MemoryChannelOrder order = orderRGBA,
01212                     bool premult = true,
01213                     char nc = 4, ChannelType ct = uChar) :
01214         PixelDescriptor(nc, ct, order, premult),
01215         m_Bounds(0, 0, nx, ny) {}
01216 
01218     ImageDescriptor() :
01219         PixelDescriptor(4, uChar,  orderRGBA, true),
01220         m_Bounds(0,0,0,0) {}
01221 
01224     int numBytes() const    { return m_Bounds.nx * m_Bounds.ny * pixelSize(); }
01225 
01227     int strideBytes() const { return m_Bounds.nx * pixelSize(); }
01228 
01230     int xSize() const { return m_Bounds.nx;  }
01231 
01233     int ySize() const { return m_Bounds.ny;  }
01234 
01236     int cSize() const { return m_cCount; }
01237 
01241     bool sizeEqual(const ImageDescriptor &o) const
01242         { return ((xSize() == o.xSize()) && (ySize() == o.ySize())); }
01243 
01245     void setSize(int nx, int ny) { m_Bounds.nx = nx; m_Bounds.ny = ny; }
01246 
01248     const ImgTile &getBounds() const { return m_Bounds; }
01249 
01256     void getResolutionInfo(float &xRes, float &yRes, ResUnit &unit) const
01257     {
01258         xRes = m_xResolution; yRes = m_yResolution, unit = m_ResolutionUnits;
01259     }
01260 
01267     void setResolutionInfo(float xRes, float yRes, ResUnit unit)
01268     {
01269         m_xResolution = xRes; m_yResolution = yRes, m_ResolutionUnits = unit;
01270     }
01271 
01272     friend class Image;
01273 };
01274 
01275 //------------------------------------------------------------------------------
01300 
01301 class MBDLL_DECL Image : public Node
01302 {
01303 
01304     DECLARE_CLASS;
01305 
01306     friend class ImgPageIterator;
01307     friend class ImgLockPageIterator;
01308 
01309 
01310 public:
01312     typedef enum {
01313         Type_Invalid = 0,
01314         Type_Memory,       
01315         Type_Virtual       
01316     } ImageType;
01317 
01319     enum Format
01320     {
01321         e8integer = 0,
01322         e16integer,
01323         e32integer,
01324         e16float,
01325         e32float,
01326         e16depth,
01327         e24depth,
01328         e32depth,
01329         eUnknown,
01330         eInvalid,
01331     };
01332 
01333     virtual ~Image( void );
01334 
01335 protected:
01336 
01337     Image( void );
01338 
01339     unsigned char    m_FillPixel[16]; // fill color -- largest supported pixel is 16 bytes.
01340     ImageDescriptor  m_Descriptor;    // how to interpret the pixel data
01341 
01342     ImageType        m_ImageType;
01343 
01344     bool             m_ProxyDirty;
01345     unsigned char    m_ProxyLevel;
01346 
01347     Image           *m_pProxyImage;
01348 
01349     void             markProxyDirty() 
01350     { 
01351         if (m_pProxyImage) {
01352             delete m_pProxyImage;
01353             m_pProxyImage = 0; 
01354             m_ProxyDirty  = true;
01355         }
01356     }
01357 
01358     virtual void     regenerateProxy();
01359     bool             isProxyDirty() const { return m_ProxyDirty; }
01360 
01361 
01362 public:
01371     virtual void GenerateProxy(Image *targetImg, int factor);
01372 
01375     void UnitTest(int iterations);
01376 
01377     virtual bool isAllocated() const;
01378 
01379     // Return a list of all extensions from all of our descendent classes.
01380     //
01381     static QString  AllSupportedExtensions( bool bRGBAOnly = false, 
01382                                             bool bRead     = true, 
01383                                             bool bDesc     = false,
01384                                             bool bPSD      = true,
01385                                             QString sDelimiter = ";");
01386 
01388     ImageType getType() const { return m_ImageType; }
01389 
01391     const ImageDescriptor  &getDescriptor() const  { return m_Descriptor; }
01392 
01400     unsigned char   getProxyLevel() const { return m_ProxyLevel; }
01401 
01403     bool        setProxyLevel(unsigned char newLevel) { 
01404         if( xSize()>>newLevel == 0 || ySize()>>newLevel == 0 )
01405             return false;
01406         if (newLevel > 3) newLevel = 3;
01407         if (newLevel != m_ProxyLevel) {
01408             m_ProxyLevel = newLevel;
01409             markProxyDirty();
01410         }
01411         return true;
01412     }
01413 
01417     Image         *getProxyImage() 
01418     {
01419         if (m_ProxyLevel == 0) return this;
01420         if (isProxyDirty()||!m_pProxyImage) regenerateProxy();
01421         return m_pProxyImage;
01422     }
01423 
01425     int            xSize() const { return m_Descriptor.xSize(); }
01426 
01428     int            ySize() const { return m_Descriptor.ySize(); }
01429 
01431     int            cSize() const { return m_Descriptor.cSize(); }
01432 
01434     int            curWidth()  const { return Width() >> getProxyLevel(); }
01435 
01437     int            curHeight() const { return Height() >> getProxyLevel(); }
01438 
01440     ImageDescriptor::MemoryChannelOrder channelOrder() const { return m_Descriptor.m_channelOrder; }
01441 
01443     const ImgTile  &getBounds() const { return m_Descriptor.getBounds(); }
01444 
01445     //====================================================================
01456     void  getFillColor(void *fillPixel, const PixelDescriptor *pd = 0) const;
01457 
01458     //====================================================================
01469     void  setFillColor(const void *fillPixel, const PixelDescriptor *pd = 0);
01470 
01471     //====================================================================
01489     void  getTile(int x, int y, int nx, int ny, void *data,
01490                   const PixelDescriptor *pd = 0)
01491        { getTile(ImgTile(x, y, nx, ny), data, pd); }
01492 
01493 
01494     //====================================================================
01518     void  getSubTile(int x,  int y,  int nx,  int ny, void *data,
01519                      int dx, int dy, int dnx, int dny,
01520                      const PixelDescriptor *pd = 0)
01521        { getSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
01522 
01523 
01524     //====================================================================
01540     void getTile(const ImgTile &srcTile, void *data,
01541                  const PixelDescriptor *pd = 0)
01542        { getSubTile(srcTile, data, srcTile, pd); }
01543 
01544     //====================================================================
01563     virtual void getSubTile(const ImgTile &srcTile, void *data,
01564                             const ImgTile &targetBounds,
01565                             const PixelDescriptor *pd = 0);
01566 
01567 
01568     //====================================================================
01589     void setTile(int x, int y, int nx, int ny, void *data,
01590                  const PixelDescriptor *pd = 0)
01591        { setTile(ImgTile(x, y, nx, ny), data, pd); }
01592 
01593     //====================================================================
01620     void setSubTile(int x,  int y,  int nx,  int ny, const void *data,
01621                     int dx, int dy, int dnx, int dny,
01622                     const PixelDescriptor *pd = 0)
01623        { setSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
01624 
01625     //====================================================================
01641     void setTile(const ImgTile &dstTile, const void *data,
01642                  const PixelDescriptor *pd = 0)
01643        { setSubTile(dstTile, data, dstTile, pd); }
01644 
01645     //====================================================================
01664     virtual void setSubTile(const ImgTile &dstTile, const void *data,
01665                             const ImgTile &sourceBounds,
01666                             const PixelDescriptor *pd = 0);
01667 
01668     //====================================================================
01693     void copyTile(int x, int y, int nx, int ny, Image &fromImg,
01694                   int ox, int oy)
01695        { copyTile(ImgTile(x, y, nx, ny), fromImg, ox, oy); }
01696 
01697 
01698     //====================================================================
01720     virtual void copyTile(const ImgTile &dstTile, Image &fromImg,
01721                           int ox, int oy);
01722 
01724     virtual void Clear();
01725 
01726     //====================================================================
01751     void fillTile(int x, int y, int nx, int ny, void *pixelData,
01752                   const PixelDescriptor *pd       = 0,
01753                   const ImgTile         *maskTile = 0)
01754     { fillTile(ImgTile(x, y, nx, ny), pixelData, pd, maskTile); }
01755 
01756     //====================================================================
01776     void fillTile(const ImgTile &dstTile, const void *pixelData,
01777                   const PixelDescriptor *pd,
01778                   const ImgTile         *maskTile);
01779 
01780     //====================================================================
01799     virtual void fillTile(const ImgTile         &dstTile,
01800                           const void            *pixelData,
01801                           const PixelDescriptor *pd = 0);
01802 
01803     //====================================================================
01813     virtual void getPageSize(int &nx, int &ny);
01814 
01815     //====================================================================
01828     ImgPageIterator *getPageIterator(int x, int y, int nx, int ny)
01829     { return getPageIterator(ImgTile(x, y, nx, ny)); }
01830 
01831     //====================================================================
01841     virtual ImgPageIterator *getPageIterator(const ImgTile &srcTile);
01842 
01843     //====================================================================
01859     ImgLockPageIterator *lockPageSet(int x, int y, int nx, int ny,
01860                                      ImgLockPageIterator::AccessMode mode)
01861     { return lockPageSet(ImgTile(x, y, nx, ny), mode); }
01862 
01863     //====================================================================
01876     virtual ImgLockPageIterator *lockPageSet(const ImgTile &srcTile,
01877                                              ImgLockPageIterator::AccessMode mode);
01878 
01879     static ImageDescriptor::MemoryChannelOrder optimizedChannelOrder();
01880 
01881     static void ConvertPixels(void *dst, const void *src, int numPix,
01882                               const PixelDescriptor &dstDesc,
01883                               const PixelDescriptor *srcDesc = 0);
01884 
01886     void CopyInverseLuminance(const Image &srcImage);
01887 
01889     void CopyLuminance(const Image &srcImage);
01890 
01907     virtual QString SupportedExtensions( bool bRGBAOnly = false,
01908                                         bool bRead     = true,
01909                                         bool bDesc     = false,
01910                                         bool bPSD      = true,
01911                                         QString sDelimiter = ";") const;
01912 
01917     virtual void Create( unsigned int iWidth, unsigned int iHeight,
01918                          unsigned int iChannelCount, Format eFormat = e8integer,
01919                          bool Tiled = false,
01920                         ImageDescriptor::MemoryChannelOrder eOrder = ImageDescriptor::orderRGBA);
01921 
01925     virtual void Load( const QString &sFileName, int iLayerIndex = 0 );
01926 
01928     virtual void LoadChannel( const QString  &sFileName,
01929                               unsigned int   iChannelIndex,
01930                               int            iLayerIndex = 0 );
01931 
01932     virtual bool GetPSDLayerMeta ( void *pPSDFile, int iLayerIndex, 
01933                                    QString &layerName, int &blendMode,
01934                                    float &opacity, bool &locked, 
01935                                    bool &visible, bool &transLocked);
01936 
01944     virtual bool LoadPSDLayer ( void *pPSDFile,
01945                                 int   iLayerIndex,
01946                                 bool  Tiled = false,
01947                                 bool  premult = true );
01948 
01949 
01950     virtual Image *ComputeDifferenceMask(Image *otherImg, int expansionRadius,
01951                                          int AARadius, bool &anyDiffs);
01952 
01961     virtual bool SavePSDLayerMeta ( void         *pPSDFile,
01962                                     int           iLayerIndex,
01963                                     const QString&pLayerName,
01964                                     float         opacity = 1.0f,
01965                                     bool          visible = true,
01966                                     bool          locked  = false,
01967                                     int           xOff    = 0,
01968                                     int           yOff    = 0,
01969                                     int           blendMode = -1);
01970 
01980     virtual bool SavePSDLayer ( void         *pPSDFile,
01981                                 int           iLayerIndex,
01982                                 const QString&pLayerName,
01983                                 float         opacity = 1.0f,
01984                                 bool          visible = true,
01985                                 bool          locked  = false,
01986                                 bool          needs_unpremult = true,
01987                                 int           xOff    = 0,
01988                                 int           yOff    = 0);
01989 
01995     virtual void *OpenPSDFile(const QString &pFileName, bool writing = false);
01996 
01999     virtual bool  GetPSDFileInfo(void *psdFile, int *width, int *height, int *numChannels,
02000                                  int *bitDepth, int *numLayers, int *curLayer);
02001 
02004     virtual bool  SetPSDFileInfo(void *psdFile, int width, int height, int numChannels,
02005                                  int bitDepth, int numLayers, int curLayer);
02006 
02008     virtual bool ClosePSDFile(void *psdFile);
02009 
02010 
02018     virtual void Save( const QString &sFileName, bool bForce = true,
02019                        Material *pMaterial = NULL,
02020                        float uStart = 0.0f, float vStart = 0.0f,
02021                        bool force_1_Channel_To_4_Channel = false);
02022 
02024     virtual unsigned int Width( void ) const;
02025 
02027     virtual unsigned int Height( void ) const;
02028 
02030     virtual Format Format( void ) const;
02031 
02033     virtual unsigned int ChannelCount( void ) const;
02034 
02036     virtual unsigned int BytesPerPixel( void ) const;
02037 
02039     unsigned int         curBytesPerPixel() const { return (getProxyLevel() != 0) ? ChannelCount() : BytesPerPixel(); }
02040 
02042     virtual unsigned int TotalBytes( void ) const;
02043 
02045     unsigned int         curTotalBytes(void) const { return curWidth() * curHeight() * curBytesPerPixel(); }
02046 
02051     virtual void SetValueAt( unsigned int iXPos, unsigned int iYPos,
02052                              unsigned int iChannel, float fValue );
02053 
02057     virtual float ValueAt( unsigned int iXPos, unsigned int iYPos,
02058                            unsigned int iChannel ) const;
02059 
02063     virtual float ValueAt( float fXPos, float fYPos, unsigned int iChannel ) const;
02064 
02067     virtual void SetColorAt( unsigned int iXPos, unsigned int iYPos,
02068                              const Color &cColor );
02069 
02071     virtual Color ColorAt( unsigned int iXPos, unsigned int iYPos ) const;
02072 
02074     virtual Color ColorAt( float fXPos, float fYPos ) const;
02075 
02079     virtual QImage *ConvertToQImage( );
02080 
02082     virtual void ConvertFromQImage( QImage &qImg);
02083 
02087     virtual bool Fragmented() const;
02088 
02090     virtual bool Tiled() const;
02091 
02093     bool Versioned() const { return Tiled(); }
02094 
02097     virtual bool NewVersion();
02098 
02102     virtual bool PrevVersion();
02103 
02107     virtual bool NextVersion();
02108 
02110     virtual int  NumVersions();
02111 
02115     virtual bool MergeOldestVersions();
02116 
02121     virtual bool PurgeNewerVersions();
02122 
02125     virtual bool PurgeAllButCurrentVersion();
02126 
02132     virtual void *Data( int iRow = -1, bool writing = true );
02133     virtual const void *Data( int iRow = -1, bool writing = false ) const;
02134 
02135 
02141     virtual void DrawUVs(Material *pMaterial,
02142                          float uStart = 0.0f, float vStart = 0.0f,
02143                          bool baseLevel = true);
02144 
02145 
02148     virtual void scaleTileBilinear_4Chan_uchar(float x, float y, float nx, float ny, // src tile (from this image)
02149                                                unsigned int *data,                   // target buffer 
02150                                                int dx, int dy, int dnx, int dny,     // target location and size of target buffer
02151                                                float xScale, float yScale) const;    // scale factors
02152 
02153 
02154 
02161     virtual void GenerateUpscaled(Image *targetImg, int factor);
02162 
02163 
02166     static void MultiplyRGBByAlpha_uc4(unsigned char *buffer, int numPixels);
02167 
02169     virtual bool   isDirty() const;
02170 
02174     virtual void   setDirty();
02175 
02177     virtual void   setClean();
02178 
02180     virtual void   VerticalFlip(); 
02181 
02182 };
02183 
02184 //------------------------------------------------------------------------------
02185 MBDLL_DECL AttributeWidget *CreateNewImageWidget( QWidget *pParent, int iWidth,
02186                                                   AttributePointer<Image> *pImage );
02187 template <> inline
02188 AttributeWidget *AttributePointer<Image>::CreateEditorWidget( QWidget *pParent, int iWidth )
02189 { return CreateNewImageWidget( pParent, iWidth, this ); };
02190 
02191 class MBDLL_DECL EnvironmentMap : public Node
02192 {
02193     DECLARE_CLASS;
02194 
02195 protected:
02196 
02197     EnvironmentMap( void );
02198 
02199 public:
02203     virtual bool Load( const QString &sFileName );
02206     virtual unsigned int ConvertToOpenGLTexture( void );
02207 };
02208 
02209 
02210 //------------------------------------------------------------------------------
02212 
02213 // these are just shorthand -- they're undefined later in this file
02214 #define cu_int  const unsigned int
02215 #define u_int   unsigned int
02216 #define u_short unsigned short
02217 #define u_char  unsigned char
02218 
02219 #define inline __forceinline
02220 
02224 template <class ChannelType, cu_int nch>
02225 class MBDLL_TEMPLATE_DECL ImageAccessorBase
02226 {
02227 private:
02228     u_int        m_Stride;
02229     u_int        m_Height;
02230     u_int        m_chans;
02231     Image       *m_Image;
02232     ChannelType *m_pData;
02233 
02234 public:
02235     ImageAccessorBase(Image *parent)
02236     {
02237         m_Stride = parent->Width();
02238         m_Height = parent->Height();
02239         m_chans  = parent->ChannelCount();
02240         m_Image  = parent;
02241         m_pData  = (ChannelType *)parent->Data();
02242     }
02243 
02244     u_int Width()        const { return m_Stride; }
02245     u_int Height()       const { return m_Height; }
02246     u_int ChannelCount() const { return m_chans;  }
02247 
02251     inline void  SetValueAt(u_int X, u_int Y, u_int Ch, float fVal);
02252 
02254     inline float ValueAt(u_int X, u_int Y, u_int Ch) const;
02255 
02259     inline void  SetColorAt( u_int X, u_int Y, const Color &cColor );
02260 
02261     inline void *AddrAt(u_int X, u_int Y, u_int Ch);
02262 };
02263 
02264 //------------------------------------------------------------------------------
02265 template <class ChannelType, cu_int nch>
02266 class MBDLL_TEMPLATE_DECL ImageAccessor : public ImageAccessorBase<ChannelType, nch>
02267 {
02268 public:
02269     ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, nch>(parent)
02270     {
02271     }
02272 
02274     inline Color ColorAt( u_int X, u_int Y ) const;
02275 };
02276 
02277 //------------------------------------------------------------------------------
02278 template <>
02279 inline void *ImageAccessorBase<u_char, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02280 { return (void *)&m_pData[Ch + ((X + m_Stride * Y)    )]; }
02281 template <>
02282 inline void *ImageAccessorBase<u_char, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02283 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02284 template <>
02285 inline void *ImageAccessorBase<u_char, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02286 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02287 template <>
02288 inline void *ImageAccessorBase<u_char, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02289 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02290 
02291 template <>
02292 inline void *ImageAccessorBase<u_short, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02293 { return (void *)&m_pData[Ch + ((X + m_Stride * Y)    )]; }
02294 template <>
02295 inline void *ImageAccessorBase<u_short, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02296 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02297 template <>
02298 inline void *ImageAccessorBase<u_short, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02299 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02300 template <>
02301 inline void *ImageAccessorBase<u_short, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02302 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02303 
02304 
02305 template <>
02306 inline void *ImageAccessorBase<float, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02307 { return (void *)&m_pData[Ch + ((X + m_Stride * Y)    )]; }
02308 template <>
02309 inline void *ImageAccessorBase<float, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02310 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02311 template <>
02312 inline void *ImageAccessorBase<float, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02313 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02314 template <>
02315 inline void *ImageAccessorBase<float, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02316 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02317 
02318 template <>
02319 inline void *ImageAccessorBase<half_, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02320 { return (void *)&m_pData[Ch + ((X + m_Stride * Y)    )]; }
02321 template <>
02322 inline void *ImageAccessorBase<half_, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02323 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02324 template <>
02325 inline void *ImageAccessorBase<half_, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02326 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02327 template <>
02328 inline void *ImageAccessorBase<half_, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02329 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02330 
02331 // implement the inline member fcns with specialization...
02332 template <>
02333 inline void ImageAccessorBase<u_char, 1>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02334 { m_pData[Ch + ((X + m_Stride * Y)    )] = (u_char)(255.0f * fVal); }
02335 template <>
02336 inline void ImageAccessorBase<u_char, 2>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02337 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_char)(255.0f * fVal); }
02338 template <>
02339 inline void ImageAccessorBase<u_char, 3>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02340 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_char)(255.0f * fVal); }
02341 template <>
02342 inline void ImageAccessorBase<u_char, 4>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02343 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_char)(255.0f * fVal); }
02344 
02345 template <>
02346 inline void ImageAccessorBase<u_short, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02347 { m_pData[Ch + ((X + m_Stride * Y)    )] = (u_short)(65535.0f * fVal); }
02348 template <>
02349 inline void ImageAccessorBase<u_short, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02350 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_short)(65535.0f * fVal); }
02351 template <>
02352 inline void ImageAccessorBase<u_short, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02353 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_short)(65535.0f * fVal); }
02354 template <>
02355 inline void ImageAccessorBase<u_short, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02356 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_short)(65535.0f * fVal); }
02357 
02358 //template <class ChannelType, cu_int nch>
02359 template <>
02360 inline void ImageAccessorBase<u_int, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02361 { m_pData[Ch + ((X + m_Stride * Y)    )] = (u_int)(0xffffffff * fVal); }
02362 template <>
02363 inline void ImageAccessorBase<u_int, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02364 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_int)(0xffffffff * fVal); }
02365 template <>
02366 inline void ImageAccessorBase<u_int, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02367 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_int)(0xffffffff * fVal); }
02368 template <>
02369 inline void ImageAccessorBase<u_int, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02370 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_int)(0xffffffff * fVal); }
02371 
02372 template <>
02373 inline void ImageAccessorBase<float, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02374 { m_pData[Ch + ((X + m_Stride * Y)    )] = fVal; }
02375 template <>
02376 inline void ImageAccessorBase<float, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02377 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = fVal; }
02378 template <>
02379 inline void ImageAccessorBase<float, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02380 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
02381 template <>
02382 inline void ImageAccessorBase<float, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02383 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
02384 
02385 template <>
02386 inline float ImageAccessorBase<u_char, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02387 { return m_pData[Ch + ((X + m_Stride * Y)    )] * (1.0f/255.0f); }
02388 template <>
02389 inline float ImageAccessorBase<u_char, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02390 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/255.0f); }
02391 template <>
02392 inline float ImageAccessorBase<u_char, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02393 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/255.0f); }
02394 template <>
02395 inline float ImageAccessorBase<u_char, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02396 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/255.0f); }
02397 
02398 template <>
02399 inline float ImageAccessorBase<u_short, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02400 { return m_pData[Ch + ((X + m_Stride * Y)    )] * (1.0f/65535.0f); }
02401 template <>
02402 inline float ImageAccessorBase<u_short, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02403 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/65535.0f); }
02404 template <>
02405 inline float ImageAccessorBase<u_short, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02406 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/65535.0f); }
02407 template <>
02408 inline float ImageAccessorBase<u_short, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02409 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/65535.0f); }
02410 
02411 template <>
02412 inline float ImageAccessorBase<u_int, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02413 { return m_pData[Ch + ((X + m_Stride * Y)    )] * (1.0f/float(0xffffffff)); }
02414 template <>
02415 inline float ImageAccessorBase<u_int, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02416 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/float(0xffffffff)); }
02417 template <>
02418 inline float ImageAccessorBase<u_int, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02419 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/float(0xffffffff)); }
02420 template <>
02421 inline float ImageAccessorBase<u_int, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02422 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/float(0xffffffff)); }
02423 
02424 template <>
02425 inline float ImageAccessorBase<float, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02426 { return m_pData[Ch + ((X + m_Stride * Y)    )]; }
02427 template <>
02428 inline float ImageAccessorBase<float, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02429 { return m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02430 template <>
02431 inline float ImageAccessorBase<float, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02432 { return m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02433 template <>
02434 inline float ImageAccessorBase<float, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02435 { return m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02436 
02437 
02438 
02439 //------------------------------------------------------------------------------
02440 template <>
02441 inline Color ImageAccessor<float, 4>::ColorAt(u_int X, u_int Y) const
02442 {
02443     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02444 };
02445 
02446 //------------------------------------------------------------------------------
02447 template <>
02448 inline Color ImageAccessor<u_char, 4>::ColorAt(u_int X, u_int Y) const
02449 {
02450     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02451 };
02452 
02453 //------------------------------------------------------------------------------
02454 template <>
02455 inline Color ImageAccessor<u_short, 4>::ColorAt(u_int X, u_int Y) const
02456 {
02457     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02458 };
02459 
02460 //------------------------------------------------------------------------------
02461 template <>
02462 inline Color ImageAccessor<u_short, 3>::ColorAt(u_int X, u_int Y) const
02463 {
02464     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02465 };
02466 
02467 //------------------------------------------------------------------------------
02468 template <>
02469 inline Color ImageAccessor<float, 3>::ColorAt(u_int X, u_int Y) const
02470 {
02471     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02472 };
02473 
02474 //------------------------------------------------------------------------------
02475 template <>
02476 inline Color ImageAccessor<u_char, 3>::ColorAt(u_int X, u_int Y) const
02477 {
02478     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02479 };
02480 
02481 //------------------------------------------------------------------------------
02482 template <>
02483 inline float ImageAccessorBase<half_, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02484 { return float(m_pData[Ch + ((X + m_Stride * Y) * 3)]); }
02485 
02486 //------------------------------------------------------------------------------
02487 template <>
02488 inline float ImageAccessorBase<half_, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02489 { return float(m_pData[Ch + ((X + m_Stride * Y) * 4)]); }
02490 
02491 //------------------------------------------------------------------------------
02492 template <>
02493 inline void ImageAccessorBase<half_, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02494 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
02495 
02496 //------------------------------------------------------------------------------
02497 template <>
02498 inline void ImageAccessorBase<half_, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02499 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
02500 
02501 
02502 //------------------------------------------------------------------------------
02503 template <>
02504 inline Color ImageAccessor<half_, 4>::ColorAt(u_int X, u_int Y) const
02505 {
02506     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02507 };
02508 
02509 //------------------------------------------------------------------------------
02510 template <>
02511 inline Color ImageAccessor<half_, 3>::ColorAt(u_int X, u_int Y) const
02512 {
02513     return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02514 };
02515 
02516 
02517 //------------------------------------------------------------------------------
02518 template <>
02519 inline void ImageAccessorBase<float, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02520 {
02521     SetValueAt(X, Y, 0, c.r);
02522     SetValueAt(X, Y, 1, c.g);
02523     SetValueAt(X, Y, 2, c.b);
02524     SetValueAt(X, Y, 3, c.a);
02525 };
02526 
02527 //------------------------------------------------------------------------------
02528 template <>
02529 inline void ImageAccessorBase<float, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02530 {
02531     SetValueAt(X, Y, 0, c.r);
02532     SetValueAt(X, Y, 1, c.g);
02533     SetValueAt(X, Y, 2, c.b);
02534 };
02535 
02536 //------------------------------------------------------------------------------
02537 template <>
02538 inline void ImageAccessorBase<half_, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02539 {
02540     SetValueAt(X, Y, 0, c.r);
02541     SetValueAt(X, Y, 1, c.g);
02542     SetValueAt(X, Y, 2, c.b);
02543     SetValueAt(X, Y, 3, c.a);
02544 };
02545 
02546 //------------------------------------------------------------------------------
02547 template <>
02548 inline void ImageAccessorBase<half_, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02549 {
02550     SetValueAt(X, Y, 0, c.r);
02551     SetValueAt(X, Y, 1, c.g);
02552     SetValueAt(X, Y, 2, c.b);
02553 };
02554 
02555 //------------------------------------------------------------------------------
02556 template <>
02557 inline void ImageAccessorBase<u_short, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02558 {
02559     SetValueAt(X, Y, 0, c.r);
02560     SetValueAt(X, Y, 1, c.g);
02561     SetValueAt(X, Y, 2, c.b);
02562     SetValueAt(X, Y, 3, c.a);
02563 };
02564 
02565 //------------------------------------------------------------------------------
02566 template <>
02567 inline void ImageAccessorBase<u_short, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02568 {
02569     SetValueAt(X, Y, 0, c.r);
02570     SetValueAt(X, Y, 1, c.g);
02571     SetValueAt(X, Y, 2, c.b);
02572 };
02573 
02574 //------------------------------------------------------------------------------
02575 template <>
02576 inline void ImageAccessorBase<u_char, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02577 {
02578     SetValueAt(X, Y, 0, c.r);
02579     SetValueAt(X, Y, 1, c.g);
02580     SetValueAt(X, Y, 2, c.b);
02581     SetValueAt(X, Y, 3, c.a);
02582 };
02583 
02584 //------------------------------------------------------------------------------
02585 template <>
02586 inline void ImageAccessorBase<u_char, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02587 {
02588     SetValueAt(X, Y, 0, c.r);
02589     SetValueAt(X, Y, 1, c.g);
02590     SetValueAt(X, Y, 2, c.b);
02591 };
02592 
02593 
02594 //------------------------------------------------------------------------------
02595 template <class ChannelType>
02596 class ImageAccessor<ChannelType, 3> : public ImageAccessorBase<ChannelType, 3>
02597 {
02598 public:
02599     ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 3>(parent)
02600     {
02601     }
02602 
02604     inline Color ColorAt( u_int X, u_int Y ) const
02605     {
02606         return Color(
02607                 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,0),
02608                 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,1),
02609                 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,2),
02610                 1);
02611     }
02612 };
02613 
02614 //------------------------------------------------------------------------------
02615 template <class ChannelType>
02616 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 2> : public ImageAccessorBase<ChannelType, 2>
02617 {
02618 public:
02619     ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 2>(parent)
02620     {
02621     }
02622 
02624     inline Color ColorAt( u_int X, u_int Y ) const
02625     {
02626         return Color(
02627                 ImageAccessorBase<ChannelType, 2>::ValueAt(X,Y,0),
02628                 ImageAccessorBase<ChannelType, 2>::ValueAt(X,Y,1),
02629                 0, 1);
02630     }
02631 };
02632 
02633 //------------------------------------------------------------------------------
02634 template <class ChannelType>
02635 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 1> : public ImageAccessorBase<ChannelType, 1>
02636 {
02637 public:
02638     ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 1>(parent)
02639     {
02640     }
02641 
02643     inline Color ColorAt( u_int X, u_int Y ) const
02644     {
02645         return Color(ImageAccessorBase<ChannelType, 1>::ValueAt(X,Y,0), 0, 0, 1);
02646     }
02647 };
02648 
02649 
02650 //------------------------------------------------------------------------------
02652 static inline void SnapOutTile(ImgTile &t)
02653 {
02654     static const int TILE_SNAP  = (128-1); // must be ((2^i)-1). 
02655     t.nx  += t.x - 1;    t.ny  += t.y - 1;
02656     t.x   &= ~TILE_SNAP; t.y   &= ~TILE_SNAP;
02657     t.nx  +=  TILE_SNAP; t.ny  +=  TILE_SNAP;
02658     t.nx  &= ~TILE_SNAP; t.ny  &= ~TILE_SNAP;
02659     t.nx  -= t.x;        t.ny  -= t.y;
02660 }
02661 
02662 
02663 //------------------------------------------------------------------------------
02664 #undef cu_int
02665 #undef u_int
02666 #undef u_short
02667 #undef u_char
02668 #undef inline
02669 
02670 //------------------------------------------------------------------------------
02671 
02672 }; // end of namespace mudbox
02673 #endif