00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00032
00033
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;
00048
00049 if (exp > 16) {
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
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;
00067 unsigned int frac = (m_bits & 0x03ff) << 13;
00068
00069 if (exp == 0x1f) {
00070 exp = 0xff - ExponentBiasDelta;
00071 } else if (exp == 0) {
00072 exp = -ExponentBiasDelta;
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
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
00350
00351
00352
00353
00354
00355
00356
00357
00365 template <class ChanType, const unsigned char NumChans>
00366 class MBDLL_TEMPLATE_DECL PixelType {
00367
00368
00369
00370
00371
00372 friend class PixelType<uInt8Channel, 1>;
00373 friend class PixelType<uInt8Channel, 2>;
00374 friend class PixelType<uInt8Channel, 3>;
00375 friend class PixelType<uInt8Channel, 4>;
00376 friend class PixelType<uInt16Channel, 1>;
00377 friend class PixelType<uInt16Channel, 2>;
00378 friend class PixelType<uInt16Channel, 3>;
00379 friend class PixelType<uInt16Channel, 4>;
00380 friend class PixelType<float16Channel, 1>;
00381 friend class PixelType<float16Channel, 2>;
00382 friend class PixelType<float16Channel, 3>;
00383 friend class PixelType<float16Channel, 4>;
00384 friend class PixelType<float32Channel, 1>;
00385 friend class PixelType<float32Channel, 2>;
00386 friend class PixelType<float32Channel, 3>;
00387 friend class PixelType<float32Channel, 4>;
00388
00389 private:
00390 ChanType m_pixel[NumChans];
00391
00392 public:
00393
00395 PixelType<ChanType, NumChans> &swapRB() {
00396 if (NumChans > 2) {
00397 ChanType t = m_pixel[0];
00398 m_pixel[0] = m_pixel[2];
00399 m_pixel[2] = t;
00400 }
00401 return *this;
00402 }
00403
00405 PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 4> &p)
00406 {
00407 switch (NumChans) {
00408 case 2: m_pixel[1] = p.m_pixel[3];
00409 case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77 +
00410 (uInt8)p.m_pixel[1]*150 +
00411 (uInt8)p.m_pixel[2]*28));
00412 break;
00413
00414 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00415 m_pixel[2] = p.m_pixel[2];
00416 break;
00417 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00418 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00419 break;
00420 }
00421 }
00422
00424 PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 3> &p)
00425 {
00426 switch (NumChans) {
00427 case 2: m_pixel[1] = ChanType( float32Channel( 1.0f ) );
00428 case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77 +
00429 (uInt8)p.m_pixel[1]*150 +
00430 (uInt8)p.m_pixel[2]*28));
00431 break;
00432 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00433 m_pixel[2] = p.m_pixel[2];
00434 break;
00435 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00436 m_pixel[2] = p.m_pixel[2];
00437 m_pixel[3] = ChanType(float32Channel(1.0f));
00438 break;
00439 }
00440 }
00441
00443 PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 2> &p)
00444 {
00445 switch (NumChans) {
00446 case 1: m_pixel[0] = p.m_pixel[0];
00447 break;
00448 case 2: m_pixel[0] = p.m_pixel[0];
00449 m_pixel[1] = p.m_pixel[1];
00450 break;
00451 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00452 m_pixel[2] = p.m_pixel[0];
00453 break;
00454 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00455 m_pixel[2] = p.m_pixel[0];
00456 m_pixel[3] = p.m_pixel[1];
00457 break;
00458 }
00459 }
00460
00462 PixelType<ChanType, NumChans>(const PixelType<uInt8Channel, 1> &p)
00463 {
00464 switch (NumChans) {
00465 case 2: m_pixel[1] = ChanType( float32Channel( 1.0f ) );
00466 case 1: m_pixel[0] = p.m_pixel[0];
00467 break;
00468 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00469 m_pixel[2] = p.m_pixel[0];
00470 break;
00471 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00472 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f)); ;
00473 break;
00474 }
00475 }
00476
00477
00479 PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 4> &p)
00480 {
00481 switch (NumChans) {
00482
00483 case 2: m_pixel[1] = p.m_pixel[3];
00484 case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
00485 (((uInt16)p.m_pixel[1]*38666)>>16) +
00486 (((uInt16)p.m_pixel[2]*7209 )>>16)));
00487 break;
00488
00489 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00490 m_pixel[2] = p.m_pixel[2];
00491 break;
00492 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00493 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00494 break;
00495 }
00496 }
00497
00499 PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 3> &p)
00500 {
00501 switch (NumChans) {
00502 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00503 case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
00504 (((uInt16)p.m_pixel[1]*38666)>>16) +
00505 (((uInt16)p.m_pixel[2]*7209 )>>16)));
00506 break;
00507 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00508 m_pixel[2] = p.m_pixel[2];
00509 break;
00510 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00511 m_pixel[2] = p.m_pixel[2];
00512 m_pixel[3] = ChanType(float32Channel(1.0f));
00513 break;
00514 }
00515 }
00516
00518 PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 2> &p)
00519 {
00520 switch (NumChans) {
00521 case 1: m_pixel[0] = p.m_pixel[0];
00522 break;
00523 case 2: m_pixel[0] = p.m_pixel[0];
00524 m_pixel[1] = p.m_pixel[1];
00525 break;
00526 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00527 m_pixel[2] = p.m_pixel[0];
00528 break;
00529 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00530 m_pixel[2] = p.m_pixel[0];
00531 m_pixel[3] = p.m_pixel[1];
00532 break;
00533 }
00534 }
00535
00537 PixelType<ChanType, NumChans>(const PixelType<uInt16Channel, 1> &p)
00538 {
00539 switch (NumChans) {
00540 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00541 case 1: m_pixel[0] = p.m_pixel[0];
00542 break;
00543 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00544 m_pixel[2] = p.m_pixel[0];
00545 break;
00546 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00547 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00548 break;
00549 }
00550 }
00551
00552
00554 PixelType<ChanType, NumChans>(const PixelType<float16Channel, 4> &p)
00555 {
00556 switch (NumChans) {
00557 case 2: m_pixel[1] = p.m_pixel[1];
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<float16Channel, 3> &p)
00573 {
00574 switch (NumChans) {
00575 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00576 case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00577 ((float)p.m_pixel[1]*0.59f) +
00578 ((float)p.m_pixel[2]*0.11f)));
00579 break;
00580 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00581 m_pixel[2] = p.m_pixel[2];
00582 break;
00583 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00584 m_pixel[2] = p.m_pixel[2];
00585 m_pixel[3] = ChanType(float32Channel(1.0f));
00586 break;
00587 }
00588 }
00589
00591 PixelType<ChanType, NumChans>(const PixelType<float16Channel, 2> &p)
00592 {
00593 switch (NumChans) {
00594 case 1: m_pixel[0] = p.m_pixel[0];
00595 break;
00596 case 2: m_pixel[0] = p.m_pixel[0];
00597 m_pixel[1] = p.m_pixel[1];
00598 break;
00599 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00600 m_pixel[2] = p.m_pixel[0];
00601 break;
00602 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00603 m_pixel[2] = p.m_pixel[0];
00604 m_pixel[3] = p.m_pixel[1];
00605 break;
00606 }
00607 }
00608
00610 PixelType<ChanType, NumChans>(const PixelType<float16Channel, 1> &p)
00611 {
00612 switch (NumChans) {
00613 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00614 case 1: m_pixel[0] = p.m_pixel[0];
00615 break;
00616 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00617 m_pixel[2] = p.m_pixel[0];
00618 break;
00619 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00620 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00621 break;
00622 }
00623 }
00624
00625
00627 PixelType<ChanType, NumChans>(const PixelType<float32Channel, 4> &p)
00628 {
00629 switch (NumChans) {
00630 case 2: m_pixel[1] = p.m_pixel[3];
00631 case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00632 ((float)p.m_pixel[1]*0.59f) +
00633 ((float)p.m_pixel[2]*0.11f)));
00634 break;
00635 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00636 m_pixel[2] = p.m_pixel[2];
00637 break;
00638 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00639 m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
00640 break;
00641 }
00642 }
00643
00645 PixelType<ChanType, NumChans>(const PixelType<float32Channel, 3> &p)
00646 {
00647 switch (NumChans) {
00648 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00649 case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
00650 ((float)p.m_pixel[1]*0.59f) +
00651 ((float)p.m_pixel[2]*0.11f)));
00652 break;
00653 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00654 m_pixel[2] = p.m_pixel[2];
00655 break;
00656 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
00657 m_pixel[2] = p.m_pixel[2];
00658 m_pixel[3] = ChanType(float32Channel(1.0f));
00659 break;
00660 }
00661 }
00662
00664 PixelType<ChanType, NumChans>(const PixelType<float32Channel, 2> &p)
00665 {
00666 switch (NumChans) {
00667 case 1: m_pixel[0] = p.m_pixel[0];
00668 break;
00669 case 2: m_pixel[0] = p.m_pixel[0];
00670 m_pixel[1] = p.m_pixel[1];
00671 break;
00672 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00673 m_pixel[2] = p.m_pixel[0];
00674 break;
00675 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00676 m_pixel[2] = p.m_pixel[0];
00677 m_pixel[3] = p.m_pixel[1];
00678 break;
00679 }
00680 }
00681
00683 PixelType<ChanType, NumChans>(const PixelType<float32Channel, 1> &p)
00684 {
00685 switch (NumChans) {
00686 case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
00687 case 1: m_pixel[0] = p.m_pixel[0];
00688 break;
00689 case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00690 m_pixel[2] = p.m_pixel[0];
00691 break;
00692 case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
00693 m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
00694 break;
00695 }
00696 }
00697
00699 void SetLuminance(const PixelType<uInt8Channel, 4> &p)
00700 {
00701 if (NumChans == 4) {
00702 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00703 m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77 +
00704 (uInt8)p.m_pixel[1]*150 +
00705 (uInt8)p.m_pixel[2]*28)));
00706 }
00707 }
00708
00710 void SetLuminance(const PixelType<uInt8Channel, 3> &p)
00711 {
00712 if (NumChans == 4) {
00713 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00714 m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77 +
00715 (uInt8)p.m_pixel[1]*150 +
00716 (uInt8)p.m_pixel[2]*28)));
00717 }
00718 }
00719
00721 void SetLuminance(const PixelType<uInt16Channel, 4> &p)
00722 {
00723 if (NumChans == 4) {
00724 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00725 m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
00726 (((uInt16)p.m_pixel[1]*38666)>>16) +
00727 (((uInt16)p.m_pixel[2]*7209 )>>16))));
00728 }
00729 }
00730
00732 void SetLuminance(const PixelType<uInt16Channel, 3> &p)
00733 {
00734 if (NumChans == 4) {
00735 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00736 m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
00737 (((uInt16)p.m_pixel[1]*38666)>>16) +
00738 (((uInt16)p.m_pixel[2]*7209 )>>16))));
00739 }
00740 }
00741
00742
00744 void SetLuminance(const PixelType<float16Channel, 4> &p)
00745 {
00746 if (NumChans == 4) {
00747 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00748 m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00749 ((float)p.m_pixel[1]*0.59f) +
00750 ((float)p.m_pixel[2]*0.11f))));
00751 }
00752 }
00753
00755 void SetLuminance(const PixelType<float16Channel, 3> &p)
00756 {
00757 if (NumChans == 4) {
00758 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00759 m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00760 ((float)p.m_pixel[1]*0.59f) +
00761 ((float)p.m_pixel[2]*0.11f))));
00762 }
00763 }
00764
00766 void SetLuminance(const PixelType<float32Channel, 4> &p)
00767 {
00768 if (NumChans == 4) {
00769 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00770 m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00771 ((float)p.m_pixel[1]*0.59f) +
00772 ((float)p.m_pixel[2]*0.11f))));
00773 }
00774 }
00775
00777 void SetLuminance(const PixelType<float32Channel, 3> &p)
00778 {
00779 if (NumChans == 4) {
00780 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00781 m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
00782 ((float)p.m_pixel[1]*0.59f) +
00783 ((float)p.m_pixel[2]*0.11f))));
00784 }
00785 }
00786
00788 void SetLuminance(const PixelType<float32Channel, 1> &p)
00789 {
00790 if (NumChans == 4) {
00791 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00792 m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00793 }
00794 }
00795
00797 void SetLuminance(const PixelType<float16Channel, 1> &p)
00798 {
00799 if (NumChans == 4) {
00800 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00801 m_pixel[3] = ChanType(float32Channel(((float)p.m_pixel[0])));
00802 }
00803 }
00804
00806 void SetLuminance(const PixelType<uInt16Channel, 1> &p)
00807 {
00808 if (NumChans == 4) {
00809 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00810 m_pixel[3] = ChanType(uInt16Channel(((uInt16)p.m_pixel[0])));
00811 }
00812 }
00813
00815 void SetLuminance(const PixelType<uInt8Channel, 1> &p)
00816 {
00817 if (NumChans == 4) {
00818 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00819 m_pixel[3] = ChanType(uInt8Channel(((uInt8)p.m_pixel[0])));
00820 }
00821 }
00822
00823
00825 void SetInvLuminance(const PixelType<uInt8Channel, 4> &p)
00826 {
00827 if (NumChans == 4) {
00828 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00829 m_pixel[3] = ChanType(uInt16Channel(65535 -
00830 ((uInt8)p.m_pixel[0]*77 +
00831 (uInt8)p.m_pixel[1]*150 +
00832 (uInt8)p.m_pixel[2]*28)));
00833 }
00834 }
00835
00837 void SetInvLuminance(const PixelType<uInt8Channel, 3> &p)
00838 {
00839 if (NumChans == 4) {
00840 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00841 m_pixel[3] = ChanType(uInt16Channel(65535 -
00842 ((uInt8)p.m_pixel[0]*77 +
00843 (uInt8)p.m_pixel[1]*150 +
00844 (uInt8)p.m_pixel[2]*28)));
00845 }
00846 }
00847
00849 void SetInvLuminance(const PixelType<uInt16Channel, 4> &p)
00850 {
00851 if (NumChans == 4) {
00852 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00853 m_pixel[3] = ChanType(uInt16Channel(65535 -
00854 ((((uInt16)p.m_pixel[0]*19660)>>16) +
00855 (((uInt16)p.m_pixel[1]*38666)>>16) +
00856 (((uInt16)p.m_pixel[2]*7209 )>>16))));
00857 }
00858 }
00859
00861 void SetInvLuminance(const PixelType<uInt16Channel, 3> &p)
00862 {
00863 if (NumChans == 4) {
00864 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00865 m_pixel[3] = ChanType(uInt16Channel(65535 -
00866 ((((uInt16)p.m_pixel[0]*19660)>>16) +
00867 (((uInt16)p.m_pixel[1]*38666)>>16) +
00868 (((uInt16)p.m_pixel[2]*7209 )>>16))));
00869 }
00870 }
00871
00872
00874 void SetInvLuminance(const PixelType<float16Channel, 4> &p)
00875 {
00876 if (NumChans == 4) {
00877 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00878 m_pixel[3] = ChanType(float32Channel(1.0f -
00879 (((float)p.m_pixel[0]*0.30f) +
00880 ((float)p.m_pixel[1]*0.59f) +
00881 ((float)p.m_pixel[2]*0.11f))));
00882 }
00883 }
00884
00886 void SetInvLuminance(const PixelType<float16Channel, 3> &p)
00887 {
00888 if (NumChans == 4) {
00889 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00890 m_pixel[3] = ChanType(float32Channel(1.0f -
00891 (((float)p.m_pixel[0]*0.30f) +
00892 ((float)p.m_pixel[1]*0.59f) +
00893 ((float)p.m_pixel[2]*0.11f))));
00894 }
00895 }
00896
00898 void SetInvLuminance(const PixelType<float32Channel, 4> &p)
00899 {
00900 if (NumChans == 4) {
00901 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00902 m_pixel[3] = ChanType(float32Channel(1.0f -
00903 (((float)p.m_pixel[0]*0.30f) +
00904 ((float)p.m_pixel[1]*0.59f) +
00905 ((float)p.m_pixel[2]*0.11f))));
00906 }
00907 }
00908
00910 void SetInvLuminance(const PixelType<float32Channel, 3> &p)
00911 {
00912 if (NumChans == 4) {
00913 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00914 m_pixel[3] = ChanType(float32Channel(1.0f - (((float)p.m_pixel[0]*0.30f) +
00915 ((float)p.m_pixel[1]*0.59f) +
00916 ((float)p.m_pixel[2]*0.11f))));
00917 }
00918 }
00919
00921 void SetInvLuminance(const PixelType<float32Channel, 1> &p)
00922 {
00923 if (NumChans == 4) {
00924 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00925 m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00926 }
00927 }
00928
00930 void SetInvLuminance(const PixelType<float16Channel, 1> &p)
00931 {
00932 if (NumChans == 4) {
00933 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00934 m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
00935 }
00936 }
00937
00939 void SetInvLuminance(const PixelType<uInt16Channel, 1> &p)
00940 {
00941 if (NumChans == 4) {
00942 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00943 m_pixel[3] = ChanType(uInt16Channel(65535 - ((uInt16)p.m_pixel[0])));
00944 }
00945 }
00946
00948 void SetInvLuminance(const PixelType<uInt8Channel, 1> &p)
00949 {
00950 if (NumChans == 4) {
00951 m_pixel[0] = m_pixel[1] = m_pixel[2] =
00952 m_pixel[3] = ChanType(uInt8Channel(255 - ((uInt8)p.m_pixel[0])));
00953 }
00954 }
00955 };
00956
00957
00958
00960 class MBDLL_DECL ImgTile
00961 {
00962 public:
00963 int x;
00964 int y;
00965 int nx;
00966 int ny;
00969 inline ImgTile() : x(0), y(0), nx(0), ny(0) {}
00970
00978 inline ImgTile(int X, int Y, int NX, int NY) : x(X), y(Y), nx(NX), ny(NY) {}
00979
00980 #if !defined MAX
00981 #define MAX(a_, b_) (((a_) > (b_)) ? (a_) : (b_))
00982 #endif
00983 #if !defined MIN
00984 #define MIN(a_, b_) (((a_) < (b_)) ? (a_) : (b_))
00985 #endif
00986
00992 ImgTile(const ImgTile &a, const ImgTile &b)
00993 {
00994 x = MAX(a.x, b.x);
00995 y = MAX(a.y, b.y);
00996 nx = MIN(a.x+a.nx, b.x+b.nx) - x;
00997 ny = MIN(a.y+a.ny, b.y+b.ny) - y;
00998 if (nx <= 0 || ny <= 0) x = y = nx = ny = 0;
00999 }
01000
01001 inline bool isEqualTile(const ImgTile &t) const
01002 { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
01003
01004 inline bool operator ==(const ImgTile &t) const
01005 { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
01006
01007 inline bool operator !=(const ImgTile &t) const
01008 { return !(t == *this); }
01009
01011 inline bool isEmpty() const { return nx <= 0 || ny <= 0; }
01012
01013 inline void setEmpty() { x = y = nx = ny = 0; }
01014
01016 inline bool contains(const ImgTile &a) const
01017 { return x <= a.x && a.x+a.nx <= x+nx &&
01018 y <= a.y && a.y+a.ny <= y+ny;
01019 }
01020
01022 inline bool contains(int x_, int y_) const
01023 { return x <= x_ && x_ < x+nx && y <= y_ && y_ < y+ny;
01024 }
01025
01027 void clipPositive()
01028 {
01029 if (x < 0) {
01030 nx += x; x = 0;
01031 if (nx < 0) x = y = nx = ny = 0;
01032 }
01033 if (y < 0) {
01034 ny += y; y = 0;
01035 if (ny < 0) x = y = nx = ny = 0;
01036 }
01037 }
01038
01040 void ExpandToInclude(int x_, int y_)
01041 {
01042 if (isEmpty()) {
01043 x = x_; y = y_; nx = 1; ny = 1;
01044 } else {
01045 if (x_ < x) { nx += (x - x_); x = x_; }
01046 if (y_ < y) { ny += (y - y_); y = y_; }
01047
01048 if (x + nx < x_) nx = (x_ - x) + 1;
01049 if (y + ny < y_) ny = (y_ - y) + 1;
01050 }
01051 }
01052
01054 void Expand(int numPixels = 1)
01055 {
01056 x -= numPixels; y -= numPixels;
01057 numPixels <<= 1;
01058 nx += numPixels; ny += numPixels;
01059 }
01060
01062 int numPixels() const { return isEmpty() ? 0 : nx * ny; }
01063 };
01064
01065
01066
01067 #define MAX_DIRTY_REGION 8192 // same as max texture size...
01068 #define DIRTY_REGION_GRANULARITY 128 // make this a power of 2.
01069 #define DIRTY_REGION_MASK (DIRTY_REGION_GRANULARITY-1)
01070 #define DIRTY_REGION_SHIFT 7
01071 #define DIRTY_REGION_XY_SIZE ( MAX_DIRTY_REGION / DIRTY_REGION_GRANULARITY )
01072
01073
01080 class MBDLL_DECL ImgDirtyRegion {
01081 private:
01082
01083
01084 char m_DirtyChunks[DIRTY_REGION_XY_SIZE * DIRTY_REGION_XY_SIZE];
01085 int m_ChunksSet;
01086 int m_NumTiles;
01087 ImgTile *m_DirtyTiles;
01088 ImgTile m_DirtyTotalChunks;
01089 int m_InTileCount;
01090
01091 void ComputeDirtyTiles();
01092
01093
01094 void ClearDirtyTiles()
01095 {
01096 if (m_DirtyTiles) delete [] m_DirtyTiles;
01097 m_NumTiles = 0; m_DirtyTiles = 0;
01098 }
01099
01100
01101 char *Index(int x, int y)
01102 {
01103 return &m_DirtyChunks[(y * DIRTY_REGION_XY_SIZE) + x];
01104 }
01105
01106
01107 char Set(int x, int y) { char c = *Index(x, y); *Index(x, y) = 1; return c; }
01108
01109
01110 char Get(int x, int y) { return *Index(x, y); }
01111
01112 public:
01113 ImgDirtyRegion() { m_DirtyTiles = 0; ClearDirtyRegion(); }
01114 ~ImgDirtyRegion() { ClearDirtyTiles(); }
01115
01118 void AddToDirtyRegion(const ImgTile &dirtyTile);
01119
01121 void ClearDirtyRegion()
01122 {
01123 ClearDirtyTiles();
01124 memset(m_DirtyChunks, 0, DIRTY_REGION_XY_SIZE * DIRTY_REGION_XY_SIZE);
01125 m_ChunksSet = 0;
01126 m_DirtyTotalChunks.setEmpty();
01127 m_InTileCount = 0;
01128 }
01129
01131 int numTiles()
01132 {
01133 if (!m_DirtyTiles) ComputeDirtyTiles();
01134 return m_NumTiles;
01135 }
01136
01138 ImgTile Tile(int i)
01139 {
01140 return m_DirtyTiles[i];
01141 }
01142
01144 ImgTile GetTotalBounds() const
01145 {
01146 return m_DirtyTotalChunks;
01147 }
01148
01150 bool isEmpty() const { return m_DirtyTotalChunks.isEmpty(); }
01151
01153 void Union(const ImgDirtyRegion &other);
01154
01155 void DumpToLog();
01156
01157 ImgDirtyRegion& operator= ( const ImgDirtyRegion& cOther );
01158 };
01159
01160
01161
01164 class MBDLL_DECL ImgTile_AoutB_Iter : public ImgTile {
01165 private:
01166 int ax1, ax2, bx1, bx2;
01167 int ay1, ay2, by1, by2;
01168 signed char state;
01169 bool ad, bd;
01170
01171 public:
01172 ImgTile_AoutB_Iter(const ImgTile &A, const ImgTile &B) :
01173 ax1 (A.x), ax2 (A.x + A.nx - 1),
01174 bx1 (B.x), bx2 (B.x + B.nx - 1),
01175 ay1 (A.y), ay2 (A.y + A.ny - 1),
01176 by1 (B.y), by2 (B.y + B.ny - 1),
01177 state (0),
01178 ad (A.nx <= 0 || A.ny <= 0),
01179 bd (B.nx <= 0 || B.ny <= 0) {}
01180
01181 virtual bool next();
01182 };
01183
01184
01185
01186 class MBDLL_DECL ImgTileUnion : public ImgTile {
01187 public:
01188 ImgTileUnion(const ImgTile &A, const ImgTile &B);
01189 };
01190
01191
01198 class MBDLL_DECL ImgPageIterator : public ImgTile {
01199 protected:
01200 void *m_BlindData;
01201 Image *m_Image;
01202 int m_Type;
01203 void *m_PixelData;
01204 ImgTile m_SrcTile;
01205
01206
01207 public:
01216 ImgPageIterator(Image *img, const ImgTile *srcTile = 0, bool writing = false);
01217 virtual ~ImgPageIterator();
01218 virtual bool next();
01219 void *dataPtr() { return m_PixelData; }
01220 };
01221
01222
01223
01225 class MBDLL_DECL ImgLockPageIterator : public ImgPageIterator {
01226 public:
01227 typedef enum {
01228 ReadOnly,
01229 ReadWrite,
01230 WriteOnly
01231 } AccessMode;
01232
01233 protected:
01234 bool m_SmartImage;
01235 AccessMode m_Mode;
01236
01237 public:
01238 ImgLockPageIterator(Image *img, const ImgTile *srcTile = 0, AccessMode mode = ReadOnly);
01239 ~ImgLockPageIterator();
01240
01241 virtual bool next();
01242 void *dataPtr();
01243 };
01244
01245
01255 class PixelDescriptor {
01256 public:
01258 typedef enum {
01259 uChar = 0,
01260 uShort = 1,
01261 sHalf = 2,
01262 sFloat = 3,
01264 sChar = 4,
01265 sShort = 5,
01266 uInt = 6,
01267 sInt = 7,
01268 sDouble = 8
01269 } ChannelType;
01270
01273 typedef enum {
01274 orderNONE = 0,
01275 orderRGBA = 1,
01276 orderABGR = 2,
01277 orderBGRA = 3,
01278 orderARGB = 4,
01279 orderRGB = 5,
01280 orderBGR = 6
01281 } MemoryChannelOrder;
01282
01283 protected:
01284 char m_cCount;
01285 ChannelType m_channelType;
01286 MemoryChannelOrder m_channelOrder;
01287 bool m_PreMultiplied;
01290 public:
01291
01292 PixelDescriptor(char cCount,
01293 ChannelType channelType,
01294 MemoryChannelOrder channelOrder,
01295 bool PreMultiplied)
01296 : m_cCount (cCount)
01297 , m_channelType (channelType)
01298 , m_channelOrder (channelOrder)
01299 , m_PreMultiplied(PreMultiplied) {}
01300
01302 int channelSize() const {
01303 static const unsigned char s_channelByteCount[] = {1, 2, 2, 4, 1, 2, 4, 4, 8};
01304 return s_channelByteCount[m_channelType];
01305 }
01306
01308 int channelBitSize() const {
01309 return channelSize() * 8;
01310 }
01311
01313 int pixelSize() const {
01314 return channelSize() * m_cCount;
01315 }
01316
01318 int pixelBitSize() const {
01319 return pixelSize() * 8;
01320 }
01321
01323 ChannelType channelType() const { return m_channelType; }
01324
01326 MemoryChannelOrder channelOrder() const { return m_channelOrder; }
01327
01330 bool premultiplied() const { return m_PreMultiplied; }
01331
01333 int channelCount() const { return m_cCount; }
01334
01336 void setChannelCount(int c) { m_cCount = c; }
01337
01339 bool operator == (const PixelDescriptor &pd) const
01340 { return (m_cCount == pd.m_cCount &&
01341 m_channelType == pd.m_channelType &&
01342 m_channelOrder == pd.m_channelOrder &&
01343 m_PreMultiplied == pd.m_PreMultiplied);
01344 }
01345 };
01346
01347
01348
01349
01353 class ImageDescriptor : public PixelDescriptor {
01354
01355 public:
01357 enum ResUnit { k_PixelsPerInch = 1,
01358 k_PixelsPerCentimeter = 2
01359 };
01360
01361 protected:
01362 ImgTile m_Bounds;
01364 float m_xResolution;
01365 float m_yResolution;
01366 ResUnit m_ResolutionUnits;
01368 public:
01369
01382 ImageDescriptor(int x, int y, int nx, int ny,
01383 MemoryChannelOrder order = orderRGBA,
01384 bool premult = true,
01385 char nc = 4, ChannelType ct = uChar) :
01386 PixelDescriptor(nc, ct, order, premult),
01387 m_Bounds(x, y, nx, ny),
01388 m_xResolution(100.0f), m_yResolution(100.0f),
01389 m_ResolutionUnits(k_PixelsPerInch) {}
01390
01401 ImageDescriptor(int nx, int ny,
01402 MemoryChannelOrder order = orderRGBA,
01403 bool premult = true,
01404 char nc = 4, ChannelType ct = uChar) :
01405 PixelDescriptor(nc, ct, order, premult),
01406 m_Bounds(0, 0, nx, ny) {}
01407
01409 ImageDescriptor() :
01410 PixelDescriptor(4, uChar, orderRGBA, true),
01411 m_Bounds(0,0,0,0) {}
01412
01415 int numBytes() const { return m_Bounds.nx * m_Bounds.ny * pixelSize(); }
01416
01418 int strideBytes() const { return m_Bounds.nx * pixelSize(); }
01419
01421 int xSize() const { return m_Bounds.nx; }
01422
01424 int ySize() const { return m_Bounds.ny; }
01425
01427 int cSize() const { return m_cCount; }
01428
01432 bool sizeEqual(const ImageDescriptor &o) const
01433 { return ((xSize() == o.xSize()) && (ySize() == o.ySize())); }
01434
01436 void setSize(int nx, int ny) { m_Bounds.nx = nx; m_Bounds.ny = ny; }
01437
01439 const ImgTile &getBounds() const { return m_Bounds; }
01440
01447 void getResolutionInfo(float &xRes, float &yRes, ResUnit &unit) const
01448 {
01449 xRes = m_xResolution; yRes = m_yResolution, unit = m_ResolutionUnits;
01450 }
01451
01458 void setResolutionInfo(float xRes, float yRes, ResUnit unit)
01459 {
01460 m_xResolution = xRes; m_yResolution = yRes, m_ResolutionUnits = unit;
01461 }
01462
01463 friend class Image;
01464 };
01465
01466
01467
01474 typedef bool (*ProxyInterruptFunction)(void);
01475
01476 #define MAX_PROXY_LEVEL 4
01477
01478
01503
01504 class MBDLL_DECL Image : public Node
01505 {
01506
01507 DECLARE_CLASS;
01508
01509 friend class ImgPageIterator;
01510 friend class ImgLockPageIterator;
01511
01512
01513 public:
01515 typedef enum {
01516 Type_Invalid = 0,
01517 Type_Memory,
01518 Type_Virtual
01519 } ImageType;
01520
01522 enum Format
01523 {
01524 e8integer = 0,
01525 e16integer,
01526 e32integer,
01527 e16float,
01528 e32float,
01529 e16depth,
01530 e24depth,
01531 e32depth,
01532 eUnknown,
01533 eInvalid,
01534 };
01535
01536 virtual ~Image( void );
01537
01538 protected:
01539
01540 Image( void );
01541
01542 unsigned char m_FillPixel[16];
01543 ImageDescriptor m_Descriptor;
01544
01545 ImageType m_ImageType;
01546
01547 unsigned char m_ProxyLevel;
01548 Image *m_pProxyImages[MAX_PROXY_LEVEL+1];
01549 bool m_bDownsampleProxyTo8Bit;
01550
01551 ProxyInterruptFunction m_pProxyIntFcn;
01552
01553 void markProxyDirty()
01554 {
01555 for (int i = 0; i < MAX_PROXY_LEVEL+1; ++i) {
01556 if (m_pProxyImages[i]) {
01557 delete m_pProxyImages[i]; m_pProxyImages[i] = 0;
01558 }
01559 }
01560 }
01561
01562 virtual bool regenerateProxy();
01563 bool isProxyDirty() const
01564 { return (m_ProxyLevel > 0) ? (m_pProxyImages[m_ProxyLevel] == 0) : false; }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578 virtual bool GenerateProxy(Image *targetImg, int level, bool DownsampleTo8Bits = true);
01579
01580
01581 public:
01582
01585 void UnitTest(int iterations);
01586
01587 virtual bool isAllocated() const;
01588
01589
01590
01591 static QString AllSupportedExtensions( bool bRGBAOnly = false,
01592 bool bRead = true,
01593 bool bDesc = false,
01594 bool bPSD = true,
01595 QString sDelimiter = ";");
01596
01598 ImageType getType() const { return m_ImageType; }
01599
01601 const ImageDescriptor &getDescriptor() const { return m_Descriptor; }
01602
01603
01608 void setProxyDownsampleTo8Bit(bool downsampleTo8Bit = true)
01609 {
01610 if (m_bDownsampleProxyTo8Bit != downsampleTo8Bit) {
01611 m_bDownsampleProxyTo8Bit = downsampleTo8Bit;
01612 markProxyDirty();
01613 }
01614 }
01615
01616 bool getProxyDownsampleTo8Bit() const { return m_bDownsampleProxyTo8Bit; }
01617
01619 void clearProxyImages() { markProxyDirty(); }
01620
01624 void SetProxyInterruptFunction(ProxyInterruptFunction fcnPtr = 0)
01625 { m_pProxyIntFcn = fcnPtr; }
01626
01627
01635 unsigned char getProxyLevel() const { return m_ProxyLevel; }
01636
01638 bool setProxyLevel(unsigned char newLevel) {
01639 if ( xSize()>>newLevel == 0 || ySize()>>newLevel == 0 )
01640 return false;
01641 if (newLevel > MAX_PROXY_LEVEL) newLevel = MAX_PROXY_LEVEL;
01642 if (newLevel != m_ProxyLevel) {
01643 m_ProxyLevel = newLevel;
01644 }
01645
01646 return true;
01647 }
01648
01654 Image *getProxyImage()
01655 {
01656 if (m_ProxyLevel == 0) return this;
01657
01658 if ( m_pProxyImages[m_ProxyLevel] ) return m_pProxyImages[m_ProxyLevel];
01659
01660 bool generated = regenerateProxy();
01661 if (!generated && m_pProxyImages[m_ProxyLevel] != 0) {
01662 delete m_pProxyImages[m_ProxyLevel];
01663 m_pProxyImages[m_ProxyLevel] = 0;
01664 }
01665 return m_pProxyImages[m_ProxyLevel];
01666 }
01667
01669 int xSize() const { return m_Descriptor.xSize(); }
01670
01672 int ySize() const { return m_Descriptor.ySize(); }
01673
01675 int cSize() const { return m_Descriptor.cSize(); }
01676
01678 int curWidth() const { return Width() >> getProxyLevel(); }
01679
01681 int curHeight() const { return Height() >> getProxyLevel(); }
01682
01684 ImageDescriptor::MemoryChannelOrder channelOrder() const { return m_Descriptor.m_channelOrder; }
01685
01687 const ImgTile &getBounds() const { return m_Descriptor.getBounds(); }
01688
01689
01700 void getFillColor(void *fillPixel, const PixelDescriptor *pd = 0) const;
01701
01702
01713 void setFillColor(const void *fillPixel, const PixelDescriptor *pd = 0);
01714
01715
01733 void getTile(int x, int y, int nx, int ny, void *data,
01734 const PixelDescriptor *pd = 0)
01735 { getTile(ImgTile(x, y, nx, ny), data, pd); }
01736
01737
01738
01762 void getSubTile(int x, int y, int nx, int ny, void *data,
01763 int dx, int dy, int dnx, int dny,
01764 const PixelDescriptor *pd = 0)
01765 { getSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
01766
01767
01768
01784 void getTile(const ImgTile &srcTile, void *data,
01785 const PixelDescriptor *pd = 0)
01786 { getSubTile(srcTile, data, srcTile, pd); }
01787
01788
01807 virtual void getSubTile(const ImgTile &srcTile, void *data,
01808 const ImgTile &targetBounds,
01809 const PixelDescriptor *pd = 0);
01810
01811
01812
01833 void setTile(int x, int y, int nx, int ny, void *data,
01834 const PixelDescriptor *pd = 0)
01835 { setTile(ImgTile(x, y, nx, ny), data, pd); }
01836
01837
01864 void setSubTile(int x, int y, int nx, int ny, const void *data,
01865 int dx, int dy, int dnx, int dny,
01866 const PixelDescriptor *pd = 0)
01867 { setSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
01868
01869
01885 void setTile(const ImgTile &dstTile, const void *data,
01886 const PixelDescriptor *pd = 0)
01887 { setSubTile(dstTile, data, dstTile, pd); }
01888
01889
01908 virtual void setSubTile(const ImgTile &dstTile, const void *data,
01909 const ImgTile &sourceBounds,
01910 const PixelDescriptor *pd = 0);
01911
01912
01937 void copyTile(int x, int y, int nx, int ny, Image &fromImg,
01938 int ox, int oy)
01939 { copyTile(ImgTile(x, y, nx, ny), fromImg, ox, oy); }
01940
01941
01942
01964 virtual void copyTile(const ImgTile &dstTile, Image &fromImg,
01965 int ox, int oy);
01966
01967
01981 virtual void copyAll(Image &fromImg)
01982 {
01983 ImgTile srcBounds(fromImg.getBounds());
01984 copyTile(srcBounds, fromImg, srcBounds.x, srcBounds.y);
01985 }
01986
01988 virtual void Clear();
01989
01990
02015 void fillTile(int x, int y, int nx, int ny, void *pixelData,
02016 const PixelDescriptor *pd = 0,
02017 const ImgTile *maskTile = 0)
02018 { fillTile(ImgTile(x, y, nx, ny), pixelData, pd, maskTile); }
02019
02020
02040 void fillTile(const ImgTile &dstTile, const void *pixelData,
02041 const PixelDescriptor *pd,
02042 const ImgTile *maskTile);
02043
02044
02063 virtual void fillTile(const ImgTile &dstTile,
02064 const void *pixelData,
02065 const PixelDescriptor *pd = 0);
02066
02067
02077 virtual void getPageSize(int &nx, int &ny);
02078
02079
02092 ImgPageIterator *getPageIterator(int x, int y, int nx, int ny)
02093 { return getPageIterator(ImgTile(x, y, nx, ny)); }
02094
02095
02105 virtual ImgPageIterator *getPageIterator(const ImgTile &srcTile);
02106
02107
02123 ImgLockPageIterator *lockPageSet(int x, int y, int nx, int ny,
02124 ImgLockPageIterator::AccessMode mode)
02125 { return lockPageSet(ImgTile(x, y, nx, ny), mode); }
02126
02127
02140 virtual ImgLockPageIterator *lockPageSet(const ImgTile &srcTile,
02141 ImgLockPageIterator::AccessMode mode);
02142
02143 static ImageDescriptor::MemoryChannelOrder optimizedChannelOrder();
02144
02145 static void ConvertPixels(void *dst, const void *src, int numPix,
02146 const PixelDescriptor &dstDesc,
02147 const PixelDescriptor *srcDesc = 0);
02148
02150 void CopyInverseLuminance(const Image &srcImage);
02151
02153 void CopyLuminance(const Image &srcImage);
02154
02171 virtual QString SupportedExtensions( bool bRGBAOnly = false,
02172 bool bRead = true,
02173 bool bDesc = false,
02174 bool bPSD = true,
02175 QString sDelimiter = ";") const;
02176
02181 virtual void Create( unsigned int iWidth, unsigned int iHeight,
02182 unsigned int iChannelCount, Format eFormat = e8integer,
02183 bool Tiled = false,
02184 ImageDescriptor::MemoryChannelOrder eOrder = ImageDescriptor::orderRGBA);
02185
02189 virtual void Load( const QString &sFileName, int iLayerIndex = 0, bool tiled = false );
02190
02191 virtual bool GetPSDLayerMeta ( void *pPSDFile, int iLayerIndex,
02192 QString &layerName, int &blendMode,
02193 float &opacity, bool &locked,
02194 bool &visible, bool &transLocked);
02195
02203 virtual bool LoadPSDLayer ( void *pPSDFile,
02204 int iLayerIndex,
02205 bool Tiled = false,
02206 bool premult = true );
02207
02208
02209 virtual Image *ComputeDifferenceMask(Image *otherImg, int expansionRadius,
02210 int AARadius, bool &anyDiffs);
02211
02220 virtual bool SavePSDLayerMeta ( void *pPSDFile,
02221 int iLayerIndex,
02222 const QString&pLayerName,
02223 float opacity = 1.0f,
02224 bool visible = true,
02225 bool locked = false,
02226 int xOff = 0,
02227 int yOff = 0,
02228 int blendMode = -1);
02229
02239 virtual bool SavePSDLayer ( void *pPSDFile,
02240 int iLayerIndex,
02241 const QString&pLayerName,
02242 float opacity = 1.0f,
02243 bool visible = true,
02244 bool locked = false,
02245 bool needs_unpremult = true,
02246 int xOff = 0,
02247 int yOff = 0);
02248
02254 virtual void *OpenPSDFile(const QString &pFileName, bool writing = false);
02255
02258 virtual bool GetPSDFileInfo(void *psdFile, int *width, int *height, int *numChannels,
02259 int *bitDepth, int *numLayers, int *curLayer);
02260
02263 virtual bool SetPSDFileInfo(void *psdFile, int width, int height, int numChannels,
02264 int bitDepth, int numLayers, int curLayer);
02265
02267 virtual bool ClosePSDFile(void *psdFile);
02268
02269
02277 virtual void Save( const QString &sFileName, bool bForce = true,
02278 Material *pMaterial = NULL,
02279 float uStart = 0.0f, float vStart = 0.0f,
02280 bool force_1_Channel_To_4_Channel = false);
02281
02283 virtual unsigned int Width( void ) const;
02284
02286 virtual unsigned int Height( void ) const;
02287
02289 virtual Format Format( void ) const;
02290
02292 virtual unsigned int ChannelCount( void ) const;
02293
02295 virtual unsigned int BytesPerPixel( void ) const;
02296
02298 unsigned int curBytesPerPixel() const { return (getProxyLevel() != 0) ? ChannelCount() : BytesPerPixel(); }
02299
02301 virtual unsigned int TotalBytes( void ) const;
02302
02304 unsigned int curTotalBytes(void) const { return curWidth() * curHeight() * curBytesPerPixel(); }
02305
02310 virtual void SetValueAt( unsigned int iXPos, unsigned int iYPos,
02311 unsigned int iChannel, float fValue );
02312
02316 virtual float ValueAt( unsigned int iXPos, unsigned int iYPos,
02317 unsigned int iChannel ) const;
02318
02322 virtual float ValueAt( float fXPos, float fYPos, unsigned int iChannel ) const;
02323
02326 virtual void SetColorAt( unsigned int iXPos, unsigned int iYPos,
02327 const Color &cColor );
02328
02330 virtual Color ColorAt( unsigned int iXPos, unsigned int iYPos ) const;
02331
02333 virtual Color ColorAt( float fXPos, float fYPos ) const;
02334
02338 virtual QImage *ConvertToQImage( );
02339
02341 virtual void ConvertFromQImage( QImage &qImg, bool tiled = false);
02342
02346 virtual bool Fragmented() const;
02347
02349 virtual bool Tiled() const;
02350
02352 bool Versioned() const { return Tiled(); }
02353
02356 virtual bool NewVersion();
02357
02361 virtual bool PrevVersion();
02362
02366 virtual bool NextVersion();
02367
02369 virtual int NumVersions();
02370
02374 virtual bool MergeOldestVersions();
02375
02380 virtual bool PurgeNewerVersions();
02381
02384 virtual bool PurgeAllButCurrentVersion();
02385
02391 virtual void *Data( int iRow = -1, bool writing = true );
02392 virtual const void *Data( int iRow = -1, bool writing = false ) const;
02393
02394
02400 virtual void DrawUVs(Material *pMaterial,
02401 float uStart = 0.0f, float vStart = 0.0f,
02402 bool baseLevel = true);
02403
02404
02407 virtual void scaleTileBilinear_4Chan_uchar(float x, float y, float nx, float ny,
02408 unsigned int *data,
02409 int dx, int dy, int dnx, int dny,
02410 float xScale, float yScale) const;
02411
02412
02413
02420 virtual void GenerateUpscaled(Image *targetImg, int factor);
02421
02422
02425 static void MultiplyRGBByAlpha_uc4(unsigned char *buffer, int numPixels);
02426
02428 virtual bool isDirty() const;
02429
02433 virtual void setDirty();
02434
02436 virtual void setClean();
02437
02439 virtual void VerticalFlip();
02440
02442 virtual void AdjustImageCacheSize();
02443
02445 virtual void ConvertTo4Channel();
02446
02447 };
02448
02449
02450 MBDLL_DECL AttributeWidget *CreateNewImageWidget( QWidget *pParent, int iWidth,
02451 AttributePointer<Image> *pImage );
02452 template <> inline
02453 AttributeWidget *AttributePointer<Image>::CreateEditorWidget( QWidget *pParent, int iWidth )
02454 { return CreateNewImageWidget( pParent, iWidth, this ); };
02455
02456 class MBDLL_DECL EnvironmentMap : public Node
02457 {
02458 DECLARE_CLASS;
02459
02460 protected:
02461
02462 EnvironmentMap( void );
02463
02464 public:
02468 virtual bool Load( const QString &sFileName );
02471 virtual unsigned int ConvertToOpenGLTexture( void );
02472 };
02473
02474
02475
02477
02478
02479 #define cu_int const unsigned int
02480 #define u_int unsigned int
02481 #define u_short unsigned short
02482 #define u_char unsigned char
02483
02484 #define inline __forceinline
02485
02489 template <class ChannelType, cu_int nch>
02490 class MBDLL_TEMPLATE_DECL ImageAccessorBase
02491 {
02492 private:
02493 u_int m_Stride;
02494 u_int m_Height;
02495 u_int m_chans;
02496 Image *m_Image;
02497 ChannelType *m_pData;
02498
02499 public:
02500 ImageAccessorBase(Image *parent)
02501 {
02502 m_Stride = parent->Width();
02503 m_Height = parent->Height();
02504 m_chans = parent->ChannelCount();
02505 m_Image = parent;
02506 m_pData = (ChannelType *)parent->Data();
02507 }
02508
02509 u_int Width() const { return m_Stride; }
02510 u_int Height() const { return m_Height; }
02511 u_int ChannelCount() const { return m_chans; }
02512
02516 inline void SetValueAt(u_int X, u_int Y, u_int Ch, float fVal);
02517
02519 inline float ValueAt(u_int X, u_int Y, u_int Ch) const;
02520
02524 inline void SetColorAt( u_int X, u_int Y, const Color &cColor );
02525
02526 inline void *AddrAt(u_int X, u_int Y, u_int Ch);
02527 };
02528
02529
02530 template <class ChannelType, cu_int nch>
02531 class MBDLL_TEMPLATE_DECL ImageAccessor : public ImageAccessorBase<ChannelType, nch>
02532 {
02533 public:
02534 ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, nch>(parent)
02535 {
02536 }
02537
02539 inline Color ColorAt( u_int X, u_int Y ) const;
02540 };
02541
02542
02543
02544 template <class ChannelType>
02545 class ImageAccessor<ChannelType, 3> : public ImageAccessorBase<ChannelType, 3>
02546 {
02547 public:
02548 ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 3>(parent)
02549 {
02550 }
02551
02553 inline Color ColorAt( u_int X, u_int Y ) const
02554 {
02555 return Color(
02556 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,0),
02557 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,1),
02558 ImageAccessorBase<ChannelType, 3>::ValueAt(X,Y,2),
02559 1);
02560 }
02561 };
02562
02563
02564 template <class ChannelType>
02565 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 2> : public ImageAccessorBase<ChannelType, 2>
02566 {
02567 public:
02568 ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 2>(parent)
02569 {
02570 }
02571
02573 inline Color ColorAt( u_int X, u_int Y ) const
02574 {
02575 return Color(
02576 ImageAccessorBase<ChannelType, 2>::ValueAt(X,Y,0),
02577 ImageAccessorBase<ChannelType, 2>::ValueAt(X,Y,1),
02578 0, 1);
02579 }
02580 };
02581
02582
02583 template <class ChannelType>
02584 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 1> : public ImageAccessorBase<ChannelType, 1>
02585 {
02586 public:
02587 ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 1>(parent)
02588 {
02589 }
02590
02592 inline Color ColorAt( u_int X, u_int Y ) const
02593 {
02594 return Color(ImageAccessorBase<ChannelType, 1>::ValueAt(X,Y,0), 0, 0, 1);
02595 }
02596 };
02597
02598
02599 template <>
02600 inline void *ImageAccessorBase<u_char, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02601 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
02602 template <>
02603 inline void *ImageAccessorBase<u_char, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02604 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02605 template <>
02606 inline void *ImageAccessorBase<u_char, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02607 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02608 template <>
02609 inline void *ImageAccessorBase<u_char, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02610 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02611
02612 template <>
02613 inline void *ImageAccessorBase<u_short, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02614 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
02615 template <>
02616 inline void *ImageAccessorBase<u_short, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02617 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02618 template <>
02619 inline void *ImageAccessorBase<u_short, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02620 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02621 template <>
02622 inline void *ImageAccessorBase<u_short, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02623 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02624
02625
02626 template <>
02627 inline void *ImageAccessorBase<float, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02628 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
02629 template <>
02630 inline void *ImageAccessorBase<float, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02631 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02632 template <>
02633 inline void *ImageAccessorBase<float, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02634 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02635 template <>
02636 inline void *ImageAccessorBase<float, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02637 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02638
02639 template <>
02640 inline void *ImageAccessorBase<half_, 1>::AddrAt(u_int X, u_int Y, u_int Ch)
02641 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
02642 template <>
02643 inline void *ImageAccessorBase<half_, 2>::AddrAt(u_int X, u_int Y, u_int Ch)
02644 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02645 template <>
02646 inline void *ImageAccessorBase<half_, 3>::AddrAt(u_int X, u_int Y, u_int Ch)
02647 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02648 template <>
02649 inline void *ImageAccessorBase<half_, 4>::AddrAt(u_int X, u_int Y, u_int Ch)
02650 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02651
02652
02653 template <>
02654 inline void ImageAccessorBase<u_char, 1>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02655 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_char)(255.0f * fVal); }
02656 template <>
02657 inline void ImageAccessorBase<u_char, 2>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02658 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_char)(255.0f * fVal); }
02659 template <>
02660 inline void ImageAccessorBase<u_char, 3>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02661 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_char)(255.0f * fVal); }
02662 template <>
02663 inline void ImageAccessorBase<u_char, 4>::SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
02664 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_char)(255.0f * fVal); }
02665
02666 template <>
02667 inline void ImageAccessorBase<u_short, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02668 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_short)(65535.0f * fVal); }
02669 template <>
02670 inline void ImageAccessorBase<u_short, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02671 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_short)(65535.0f * fVal); }
02672 template <>
02673 inline void ImageAccessorBase<u_short, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02674 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_short)(65535.0f * fVal); }
02675 template <>
02676 inline void ImageAccessorBase<u_short, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02677 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_short)(65535.0f * fVal); }
02678
02679
02680 template <>
02681 inline void ImageAccessorBase<u_int, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02682 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_int)(0xffffffff * fVal); }
02683 template <>
02684 inline void ImageAccessorBase<u_int, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02685 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_int)(0xffffffff * fVal); }
02686 template <>
02687 inline void ImageAccessorBase<u_int, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02688 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_int)(0xffffffff * fVal); }
02689 template <>
02690 inline void ImageAccessorBase<u_int, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02691 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_int)(0xffffffff * fVal); }
02692
02693 template <>
02694 inline void ImageAccessorBase<float, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02695 { m_pData[Ch + ((X + m_Stride * Y) )] = fVal; }
02696 template <>
02697 inline void ImageAccessorBase<float, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02698 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = fVal; }
02699 template <>
02700 inline void ImageAccessorBase<float, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02701 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
02702 template <>
02703 inline void ImageAccessorBase<float, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02704 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
02705
02706 template <>
02707 inline float ImageAccessorBase<u_char, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02708 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/255.0f); }
02709 template <>
02710 inline float ImageAccessorBase<u_char, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02711 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/255.0f); }
02712 template <>
02713 inline float ImageAccessorBase<u_char, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02714 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/255.0f); }
02715 template <>
02716 inline float ImageAccessorBase<u_char, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02717 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/255.0f); }
02718
02719 template <>
02720 inline float ImageAccessorBase<u_short, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02721 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/65535.0f); }
02722 template <>
02723 inline float ImageAccessorBase<u_short, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02724 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/65535.0f); }
02725 template <>
02726 inline float ImageAccessorBase<u_short, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02727 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/65535.0f); }
02728 template <>
02729 inline float ImageAccessorBase<u_short, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02730 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/65535.0f); }
02731
02732 template <>
02733 inline float ImageAccessorBase<u_int, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02734 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/float(0xffffffff)); }
02735 template <>
02736 inline float ImageAccessorBase<u_int, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02737 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/float(0xffffffff)); }
02738 template <>
02739 inline float ImageAccessorBase<u_int, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02740 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/float(0xffffffff)); }
02741 template <>
02742 inline float ImageAccessorBase<u_int, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02743 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/float(0xffffffff)); }
02744
02745 template <>
02746 inline float ImageAccessorBase<float, 1>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02747 { return m_pData[Ch + ((X + m_Stride * Y) )]; }
02748 template <>
02749 inline float ImageAccessorBase<float, 2>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02750 { return m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
02751 template <>
02752 inline float ImageAccessorBase<float, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02753 { return m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
02754 template <>
02755 inline float ImageAccessorBase<float, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02756 { return m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
02757
02758
02759
02760
02761 template <>
02762 inline Color ImageAccessor<float, 4>::ColorAt(u_int X, u_int Y) const
02763 {
02764 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02765 };
02766
02767
02768 template <>
02769 inline Color ImageAccessor<u_char, 4>::ColorAt(u_int X, u_int Y) const
02770 {
02771 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02772 };
02773
02774
02775 template <>
02776 inline Color ImageAccessor<u_short, 4>::ColorAt(u_int X, u_int Y) const
02777 {
02778 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02779 };
02780
02781
02782 template <>
02783 inline Color ImageAccessor<u_short, 3>::ColorAt(u_int X, u_int Y) const
02784 {
02785 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02786 };
02787
02788
02789 template <>
02790 inline Color ImageAccessor<float, 3>::ColorAt(u_int X, u_int Y) const
02791 {
02792 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02793 };
02794
02795
02796 template <>
02797 inline Color ImageAccessor<u_char, 3>::ColorAt(u_int X, u_int Y) const
02798 {
02799 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02800 };
02801
02802
02803 template <>
02804 inline float ImageAccessorBase<half_, 3>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02805 { return float(m_pData[Ch + ((X + m_Stride * Y) * 3)]); }
02806
02807
02808 template <>
02809 inline float ImageAccessorBase<half_, 4>::ValueAt( u_int X, u_int Y, u_int Ch ) const
02810 { return float(m_pData[Ch + ((X + m_Stride * Y) * 4)]); }
02811
02812
02813 template <>
02814 inline void ImageAccessorBase<half_, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02815 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
02816
02817
02818 template <>
02819 inline void ImageAccessorBase<half_, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
02820 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
02821
02822
02823
02824 template <>
02825 inline Color ImageAccessor<half_, 4>::ColorAt(u_int X, u_int Y) const
02826 {
02827 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
02828 };
02829
02830
02831 template <>
02832 inline Color ImageAccessor<half_, 3>::ColorAt(u_int X, u_int Y) const
02833 {
02834 return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
02835 };
02836
02837
02838
02839 template <>
02840 inline void ImageAccessorBase<float, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02841 {
02842 SetValueAt(X, Y, 0, c.r);
02843 SetValueAt(X, Y, 1, c.g);
02844 SetValueAt(X, Y, 2, c.b);
02845 SetValueAt(X, Y, 3, c.a);
02846 };
02847
02848
02849 template <>
02850 inline void ImageAccessorBase<float, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02851 {
02852 SetValueAt(X, Y, 0, c.r);
02853 SetValueAt(X, Y, 1, c.g);
02854 SetValueAt(X, Y, 2, c.b);
02855 };
02856
02857
02858 template <>
02859 inline void ImageAccessorBase<half_, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02860 {
02861 SetValueAt(X, Y, 0, c.r);
02862 SetValueAt(X, Y, 1, c.g);
02863 SetValueAt(X, Y, 2, c.b);
02864 SetValueAt(X, Y, 3, c.a);
02865 };
02866
02867
02868 template <>
02869 inline void ImageAccessorBase<half_, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02870 {
02871 SetValueAt(X, Y, 0, c.r);
02872 SetValueAt(X, Y, 1, c.g);
02873 SetValueAt(X, Y, 2, c.b);
02874 };
02875
02876
02877 template <>
02878 inline void ImageAccessorBase<u_short, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02879 {
02880 SetValueAt(X, Y, 0, c.r);
02881 SetValueAt(X, Y, 1, c.g);
02882 SetValueAt(X, Y, 2, c.b);
02883 SetValueAt(X, Y, 3, c.a);
02884 };
02885
02886
02887 template <>
02888 inline void ImageAccessorBase<u_short, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02889 {
02890 SetValueAt(X, Y, 0, c.r);
02891 SetValueAt(X, Y, 1, c.g);
02892 SetValueAt(X, Y, 2, c.b);
02893 };
02894
02895
02896 template <>
02897 inline void ImageAccessorBase<u_char, 4>::SetColorAt(u_int X, u_int Y, const Color &c)
02898 {
02899 SetValueAt(X, Y, 0, c.r);
02900 SetValueAt(X, Y, 1, c.g);
02901 SetValueAt(X, Y, 2, c.b);
02902 SetValueAt(X, Y, 3, c.a);
02903 };
02904
02905
02906 template <>
02907 inline void ImageAccessorBase<u_char, 3>::SetColorAt(u_int X, u_int Y, const Color &c)
02908 {
02909 SetValueAt(X, Y, 0, c.r);
02910 SetValueAt(X, Y, 1, c.g);
02911 SetValueAt(X, Y, 2, c.b);
02912 };
02913
02914
02915
02916
02918 static inline void SnapOutTile(ImgTile &t)
02919 {
02920 static const int TILE_SNAP = (128-1);
02921 t.nx += t.x - 1; t.ny += t.y - 1;
02922 t.x &= ~TILE_SNAP; t.y &= ~TILE_SNAP;
02923 t.nx += TILE_SNAP; t.ny += TILE_SNAP;
02924 t.nx &= ~TILE_SNAP; t.ny &= ~TILE_SNAP;
02925 t.nx -= t.x; t.ny -= t.y;
02926 }
02927
02928
02929
02930 #undef cu_int
02931 #undef u_int
02932 #undef u_short
02933 #undef u_char
02934 #undef inline
02935
02936
02937
02938 };
02939 #endif