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, 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) {
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) {
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
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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];
01340 ImageDescriptor m_Descriptor;
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
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,
02149 unsigned int *data,
02150 int dx, int dy, int dnx, int dny,
02151 float xScale, float yScale) const;
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
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
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
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);
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 };
02673 #endif