Mudbox/image.h Source File

image.h
Go to the documentation of this file.
1 //**************************************************************************/
2 // Copyright (c) 2008 Autodesk, Inc.
3 // All rights reserved.
4 //
5 // Use of this software is subject to the terms of the Autodesk license
6 // agreement provided at the time of installation or download, or which
7 // otherwise accompanies this software in either electronic or hard copy form.
8 //
9 //**************************************************************************/
10 // DESCRIPTION:
11 // CREATED: October 2008
12 //**************************************************************************/
13 
14 #if !defined IMAGE_H_
15 #define IMAGE_H_
16 
17 namespace mudbox {
18 
19 
20 class Image;
21 class SubdivisionLevel;
22 class TexturePool;
23 
30 
31 // These member fcns are inlined for a reason; THESE ARE EXTREMELY PERFORMANCE CRITICAL!
32 // DO NOT change this file or "clean it up" by removing inlines. Unless you really know
33 // what you are doing, you will make it significantly slower.
34 //
35 private:
36  unsigned short m_bits;
37  void setBits(unsigned short newbits) { m_bits = newbits; }
38 
39 public:
40  half_ () {};
41  half_ (float f)
42  {
43  unsigned int x = *(unsigned int *)&f;
44  unsigned int frac = (x >> 13) & 0x03ff;
45  int exp = (int)((x >> 23) & 0xff) - 127;
46 
47  m_bits = (x >> 16) & 0x8000; // extract the sign bit
48 
49  if (exp > 16) { // handle overflows/underflows
50  exp = 16;
51  frac = 0x03ff;
52  } else if (exp <= -15) {
53  frac = 0;
54  exp = -15;
55  }
56 
57  m_bits |= ((exp + 15) << 10) | frac;
58  }
59 
60 public:
61  // Conversion to float ~ 15 cycles
62  #define ExponentBiasDelta (127-15)
63  operator float () const
64  {
65  int exp = (m_bits >> 10) & 0x1f;
66  unsigned int f = (m_bits & 0x8000) << 16; // extract the sign bit
67  unsigned int frac = (m_bits & 0x03ff) << 13;
68 
69  if (exp == 0x1f) { // convert 16-bit FP inf/NaN to 32-bit inf/NaN value
70  exp = 0xff - ExponentBiasDelta;
71  } else if (exp == 0) {
72  exp = -ExponentBiasDelta; // convert 16-bit FP zero/denorm to 32-bit zero/denorm value
73  }
74 
75  f |= ((exp + ExponentBiasDelta) << 23) | frac;
76  return *(float *)&f;
77  }
78 
79  half_ &operator = (float f)
80  {
81  *this = half_ (f);
82  return *this;
83  }
84 };
85 
86 //------------------------------------------------------------------------------
87 typedef unsigned char uInt8;
88 typedef unsigned short uInt16;
89 
90 
91 class uInt8Channel;
92 class uInt16Channel;
93 class float16Channel;
94 class float32Channel;
95 
96 //------------------------------------------------------------------------------
99 class uInt8Channel {
100 private:
101  uInt8 m_data;
102 
103 public:
104  inline uInt8Channel(const float32Channel &d);
105  inline uInt8Channel(const float16Channel &d);
106  inline uInt8Channel(const uInt16Channel &d);
107  uInt8Channel(const uInt8Channel &d) { m_data = uInt8(d); }
108 
109  uInt8Channel(uInt8 d) { m_data = (d); }
111 
112  inline uInt8Channel & operator = (const float32Channel &d);
113  inline uInt8Channel & operator = (const float16Channel &d);
114  inline uInt8Channel & operator = (const uInt16Channel &d);
116  {
117  m_data = uInt8(d);
118  return *this;
119  }
120 
121  inline uInt8Channel & operator = (uInt8 d)
122  {
123  m_data = uInt8(d);
124  return *this;
125  }
126 
127  operator float () const { return m_data * (1.0f/255.0f); }
128  operator half_ () const { return half_(m_data * (1.0f/255.0f)); }
129  operator uInt16 () const { return (m_data << 8) + m_data; }
130  operator uInt8 () const { return m_data; }
131 };
132 
133 
134 //------------------------------------------------------------------------------
137 private:
138  uInt16 m_data;
139 
140 public:
141  inline uInt16Channel(const float32Channel &d);
142  inline uInt16Channel(const float16Channel &d);
143  uInt16Channel(const uInt16Channel &d) { m_data = uInt16(d); }
144  uInt16Channel(const uInt8Channel &d) { m_data = uInt16(d); }
145  uInt16Channel(uInt16 d) { m_data = (d); }
147 
148  inline uInt16Channel & operator = (const float32Channel &d);
149  inline uInt16Channel & operator = (const float16Channel &d);
150 
152  {
153  m_data = uInt16(d);
154  return *this;
155  }
156 
157  inline uInt16Channel & operator = (uInt16 d)
158  {
159  m_data = uInt16(d);
160  return *this;
161  }
162 
164  {
165  m_data = uInt16(d);
166  return *this;
167  }
168 
169  operator float () const { return m_data * (1.0f/65535.0f); }
170  operator half_ () const { return half_(m_data * (1.0f/65535.0f)); }
171  operator uInt16 () const { return m_data; }
172  operator uInt8 () const { return uInt8(m_data >> 8); }
173 };
174 
175 
176 //------------------------------------------------------------------------------
177 // The data type for a 32 bit float image channel.
179 private:
180  float m_data;
181 
182 public:
183  float32Channel(const float32Channel &d) { m_data = float(d); }
184  inline float32Channel(const float16Channel &d);
185  float32Channel(const uInt16Channel &d) { m_data = float(d); }
186  float32Channel(const uInt8Channel &d) { m_data = float(d); }
187  float32Channel(float d) { m_data = (d); }
189 
191  {
192  *(float *)this = *(float *)&d;
193  return *this;
194  }
195 
197  {
198  *this = float32Channel(d);
199  return *this;
200  }
201 
203  {
204  *this = float32Channel(d);
205  return *this;
206  }
207 
208  inline float32Channel & operator = (float d)
209  {
210  *this = float32Channel(d);
211  return *this;
212  }
213 
215  {
216  *this = float32Channel(d);
217  return *this;
218  }
219 
220  operator float () const { return m_data; }
221  operator half_ () const { return half_(m_data); }
222  operator uInt16 () const
223  {
224  if (m_data < 0.0f) return 0;
225  if (m_data > 1.0f) return 65535;
226  return uInt16(m_data * 65535.0f);
227  }
228  operator uInt8 () const
229  {
230  if (m_data < 0.0f) return 0;
231  if (m_data > 1.0f) return 255;
232  return uInt8(m_data * 255.0f);
233  }
234 };
235 
236 
237 //------------------------------------------------------------------------------
240 private:
241  half_ m_data;
242 
243 public:
244  float16Channel(const float32Channel &d) { m_data = float(d); }
245  float16Channel(const float16Channel &d) { m_data = float(d); }
246  float16Channel(const uInt16Channel &d) { m_data = float(d); }
247  float16Channel(const uInt8Channel &d) { m_data = float(d); }
248  float16Channel(const half_ &d) { m_data = (d); }
250 
252  {
253  *this = float16Channel(d);
254  return *this;
255  }
256 
258  {
259  *(uInt16 *)this = *(uInt16 *)&d;
260  return *this;
261  }
262 
264  {
265  *this = float16Channel(d);
266  return *this;
267  }
268 
269  inline float16Channel & operator = (const half_ &d)
270  {
271  *this = float16Channel(d);
272  return *this;
273  }
274 
276  {
277  *this = float16Channel(d);
278  return *this;
279  }
280 
281  operator float () const { return float(m_data); }
282  operator half_ () const { return m_data; }
283 
284  operator uInt16 () const
285  { float d = float(m_data);
286  if (d < 0.0f) return 0;
287  if (d > 1.0f) return 65535;
288  return uInt16(d * 65535.0f);
289  }
290  operator uInt8 () const
291  { float d = float(m_data);
292  if (d < 0.0f) return 0;
293  if (d > 1.0f) return 255;
294  return uInt8(d * 255.0f);
295  }
296 };
297 
298 
299 //------------------------------------------------------------------------------
300 inline uInt8Channel::uInt8Channel(const float32Channel &d) { m_data = uInt8(d); }
301 inline uInt8Channel::uInt8Channel(const float16Channel &d) { m_data = uInt8(d); }
302 inline uInt8Channel::uInt8Channel(const uInt16Channel &d) { m_data = uInt8(d); }
303 
304 //------------------------------------------------------------------------------
306 {
307  m_data = uInt8(d);
308  return *this;
309 }
310 
311 //------------------------------------------------------------------------------
313 {
314  m_data = uInt8(d);
315  return *this;
316 }
317 
318 //------------------------------------------------------------------------------
320 {
321  m_data = uInt8(d);
322  return *this;
323 }
324 
325 
326 //------------------------------------------------------------------------------
327 inline uInt16Channel::uInt16Channel(const float32Channel &d) { m_data = uInt16(d); }
328 inline uInt16Channel::uInt16Channel(const float16Channel &d) { m_data = uInt16(d); }
329 
330 //------------------------------------------------------------------------------
332 {
333  m_data = uInt16(d);
334  return *this;
335 }
336 
337 //------------------------------------------------------------------------------
339 {
340  m_data = uInt16(d);
341  return *this;
342 }
343 
344 
345 //------------------------------------------------------------------------------
346 inline float32Channel::float32Channel(const float16Channel &d) { m_data = float(d); }
347 
348 //----------------------------------------------------------------------------------
349 // Now we define the pixel types -- 1, 2, 3, and 4 channels. templated by
350 // one of the above channel types -- the channel types handle converting between
351 // each other, and the pixel types handle converting between them.
352 // 1 -> 3 or 4 channel -- replicates the single channel through the target channels
353 // 3 -> 4 channel copies the rgb, and sets the a to 1.0. 4 -> 3 channel copies the
354 // RGB. 4 & 3 -> 1 channel takes the luminance of the rgb channels and stores it
355 // in the single channel.
356 //
357 
365 template <class ChanType, const unsigned char NumChans>
367 
368  // allow the various instantiations of this class to
369  // access each others private data members... Also has the
370  // beneficial side effect of causing a compile error if
371  // someone tries to instantiate one that is not listed here.
372  friend class PixelType<uInt8Channel, 1>;
373  friend class PixelType<uInt8Channel, 2>;
374  friend class PixelType<uInt8Channel, 3>;
375  friend class PixelType<uInt8Channel, 4>;
376  friend class PixelType<uInt16Channel, 1>;
377  friend class PixelType<uInt16Channel, 2>;
378  friend class PixelType<uInt16Channel, 3>;
379  friend class PixelType<uInt16Channel, 4>;
380  friend class PixelType<float16Channel, 1>;
381  friend class PixelType<float16Channel, 2>;
382  friend class PixelType<float16Channel, 3>;
383  friend class PixelType<float16Channel, 4>;
384  friend class PixelType<float32Channel, 1>;
385  friend class PixelType<float32Channel, 2>;
386  friend class PixelType<float32Channel, 3>;
387  friend class PixelType<float32Channel, 4>;
388 
389 private:
390  ChanType m_pixel[NumChans];
391 
392 public:
393 
396  if (NumChans > 2) { // conditional will be resolved at compile time.
397  ChanType t = m_pixel[0];
398  m_pixel[0] = m_pixel[2];
399  m_pixel[2] = t;
400  }
401  return *this;
402  }
403 
406  {
407  switch (NumChans) { // this switch gets resolved at compile time
408  case 2: m_pixel[1] = p.m_pixel[3]; // intentional fall through.
409  case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77 +
410  (uInt8)p.m_pixel[1]*150 +
411  (uInt8)p.m_pixel[2]*28));
412  break;
413  // cppcheck mistakenly warns about array bounds here -- ignore it.
414  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
415  m_pixel[2] = p.m_pixel[2];
416  break;
417  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
418  m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
419  break;
420  }
421  }
422 
425  {
426  switch (NumChans) { // this switch gets resolved at compile time
427  case 2: m_pixel[1] = ChanType( float32Channel( 1.0f ) ); // intentional fall through.
428  case 1: m_pixel[0] = ChanType(uInt16Channel((uInt8)p.m_pixel[0]*77 +
429  (uInt8)p.m_pixel[1]*150 +
430  (uInt8)p.m_pixel[2]*28));
431  break;
432  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
433  m_pixel[2] = p.m_pixel[2];
434  break;
435  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
436  m_pixel[2] = p.m_pixel[2];
437  m_pixel[3] = ChanType(float32Channel(1.0f));
438  break;
439  }
440  }
441 
444  {
445  switch (NumChans) { // this switch gets resolved at compile time
446  case 1: m_pixel[0] = p.m_pixel[0];
447  break;
448  case 2: m_pixel[0] = p.m_pixel[0];
449  m_pixel[1] = p.m_pixel[1];
450  break;
451  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
452  m_pixel[2] = p.m_pixel[0];
453  break;
454  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
455  m_pixel[2] = p.m_pixel[0];
456  m_pixel[3] = p.m_pixel[1];
457  break;
458  }
459  }
460 
463  {
464  switch (NumChans) { // this switch gets resolved at compile time
465  case 2: m_pixel[1] = ChanType( float32Channel( 1.0f ) ); // intentional fall through.
466  case 1: m_pixel[0] = p.m_pixel[0];
467  break;
468  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
469  m_pixel[2] = p.m_pixel[0];
470  break;
471  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
472  m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f)); ;
473  break;
474  }
475  }
476 
477 
480  {
481  switch (NumChans) { // this switch gets resolved at compile time
482 
483  case 2: m_pixel[1] = p.m_pixel[3]; // intentional fallthrough.
484  case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
485  (((uInt16)p.m_pixel[1]*38666)>>16) +
486  (((uInt16)p.m_pixel[2]*7209 )>>16)));
487  break;
488 
489  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
490  m_pixel[2] = p.m_pixel[2];
491  break;
492  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
493  m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
494  break;
495  }
496  }
497 
500  {
501  switch (NumChans) { // this switch gets resolved at compile time
502  case 2: m_pixel[1] = ChanType(float32Channel(1.0f)); // intentional fallthrough
503  case 1: m_pixel[0] = ChanType(uInt16Channel((((uInt16)p.m_pixel[0]*19660)>>16) +
504  (((uInt16)p.m_pixel[1]*38666)>>16) +
505  (((uInt16)p.m_pixel[2]*7209 )>>16)));
506  break;
507  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
508  m_pixel[2] = p.m_pixel[2];
509  break;
510  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
511  m_pixel[2] = p.m_pixel[2];
512  m_pixel[3] = ChanType(float32Channel(1.0f));
513  break;
514  }
515  }
516 
519  {
520  switch (NumChans) { // this switch gets resolved at compile time
521  case 1: m_pixel[0] = p.m_pixel[0];
522  break;
523  case 2: m_pixel[0] = p.m_pixel[0];
524  m_pixel[1] = p.m_pixel[1];
525  break;
526  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
527  m_pixel[2] = p.m_pixel[0];
528  break;
529  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
530  m_pixel[2] = p.m_pixel[0];
531  m_pixel[3] = p.m_pixel[1];
532  break;
533  }
534  }
535 
538  {
539  switch (NumChans) { // this switch gets resolved at compile time
540  case 2: m_pixel[1] = ChanType(float32Channel(1.0f)); // intentional fallthrough
541  case 1: m_pixel[0] = p.m_pixel[0];
542  break;
543  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
544  m_pixel[2] = p.m_pixel[0];
545  break;
546  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
547  m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
548  break;
549  }
550  }
551 
552 
555  {
556  switch (NumChans) { // this switch gets resolved at compile time
557  case 2: m_pixel[1] = p.m_pixel[1];
558  case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
559  ((float)p.m_pixel[1]*0.59f) +
560  ((float)p.m_pixel[2]*0.11f)));
561  break;
562  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
563  m_pixel[2] = p.m_pixel[2];
564  break;
565  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
566  m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
567  break;
568  }
569  }
570 
573  {
574  switch (NumChans) { // this switch gets resolved at compile time
575  case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
576  case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
577  ((float)p.m_pixel[1]*0.59f) +
578  ((float)p.m_pixel[2]*0.11f)));
579  break;
580  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
581  m_pixel[2] = p.m_pixel[2];
582  break;
583  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
584  m_pixel[2] = p.m_pixel[2];
585  m_pixel[3] = ChanType(float32Channel(1.0f));
586  break;
587  }
588  }
589 
592  {
593  switch (NumChans) { // this switch gets resolved at compile time
594  case 1: m_pixel[0] = p.m_pixel[0];
595  break;
596  case 2: m_pixel[0] = p.m_pixel[0];
597  m_pixel[1] = p.m_pixel[1];
598  break;
599  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
600  m_pixel[2] = p.m_pixel[0];
601  break;
602  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
603  m_pixel[2] = p.m_pixel[0];
604  m_pixel[3] = p.m_pixel[1];
605  break;
606  }
607  }
608 
611  {
612  switch (NumChans) { // this switch gets resolved at compile time
613  case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
614  case 1: m_pixel[0] = p.m_pixel[0];
615  break;
616  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
617  m_pixel[2] = p.m_pixel[0];
618  break;
619  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
620  m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
621  break;
622  }
623  }
624 
625 
628  {
629  switch (NumChans) { // this switch gets resolved at compile time
630  case 2: m_pixel[1] = p.m_pixel[3];
631  case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
632  ((float)p.m_pixel[1]*0.59f) +
633  ((float)p.m_pixel[2]*0.11f)));
634  break;
635  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
636  m_pixel[2] = p.m_pixel[2];
637  break;
638  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
639  m_pixel[2] = p.m_pixel[2]; m_pixel[3] = p.m_pixel[3];
640  break;
641  }
642  }
643 
646  {
647  switch (NumChans) { // this switch gets resolved at compile time
648  case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
649  case 1: m_pixel[0] = ChanType(float32Channel(((float)p.m_pixel[0]*0.30f) +
650  ((float)p.m_pixel[1]*0.59f) +
651  ((float)p.m_pixel[2]*0.11f)));
652  break;
653  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
654  m_pixel[2] = p.m_pixel[2];
655  break;
656  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[1];
657  m_pixel[2] = p.m_pixel[2];
658  m_pixel[3] = ChanType(float32Channel(1.0f));
659  break;
660  }
661  }
662 
665  {
666  switch (NumChans) { // this switch gets resolved at compile time
667  case 1: m_pixel[0] = p.m_pixel[0];
668  break;
669  case 2: m_pixel[0] = p.m_pixel[0];
670  m_pixel[1] = p.m_pixel[1];
671  break;
672  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
673  m_pixel[2] = p.m_pixel[0];
674  break;
675  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
676  m_pixel[2] = p.m_pixel[0];
677  m_pixel[3] = p.m_pixel[1];
678  break;
679  }
680  }
681 
684  {
685  switch (NumChans) { // this switch gets resolved at compile time
686  case 2: m_pixel[1] = ChanType(float32Channel(1.0f));
687  case 1: m_pixel[0] = p.m_pixel[0];
688  break;
689  case 3: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
690  m_pixel[2] = p.m_pixel[0];
691  break;
692  case 4: m_pixel[0] = p.m_pixel[0]; m_pixel[1] = p.m_pixel[0];
693  m_pixel[2] = p.m_pixel[0]; m_pixel[3] = ChanType(float32Channel(1.0f));
694  break;
695  }
696  }
697 
700  {
701  if (NumChans == 4) {
702  m_pixel[0] = m_pixel[1] = m_pixel[2] =
703  m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77 +
704  (uInt8)p.m_pixel[1]*150 +
705  (uInt8)p.m_pixel[2]*28)));
706  }
707  }
708 
711  {
712  if (NumChans == 4) {
713  m_pixel[0] = m_pixel[1] = m_pixel[2] =
714  m_pixel[3] = ChanType(uInt16Channel(((uInt8)p.m_pixel[0]*77 +
715  (uInt8)p.m_pixel[1]*150 +
716  (uInt8)p.m_pixel[2]*28)));
717  }
718  }
719 
722  {
723  if (NumChans == 4) {
724  m_pixel[0] = m_pixel[1] = m_pixel[2] =
725  m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
726  (((uInt16)p.m_pixel[1]*38666)>>16) +
727  (((uInt16)p.m_pixel[2]*7209 )>>16))));
728  }
729  }
730 
733  {
734  if (NumChans == 4) {
735  m_pixel[0] = m_pixel[1] = m_pixel[2] =
736  m_pixel[3] = ChanType(uInt16Channel(((((uInt16)p.m_pixel[0]*19660)>>16) +
737  (((uInt16)p.m_pixel[1]*38666)>>16) +
738  (((uInt16)p.m_pixel[2]*7209 )>>16))));
739  }
740  }
741 
742 
745  {
746  if (NumChans == 4) {
747  m_pixel[0] = m_pixel[1] = m_pixel[2] =
748  m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
749  ((float)p.m_pixel[1]*0.59f) +
750  ((float)p.m_pixel[2]*0.11f))));
751  }
752  }
753 
756  {
757  if (NumChans == 4) {
758  m_pixel[0] = m_pixel[1] = m_pixel[2] =
759  m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
760  ((float)p.m_pixel[1]*0.59f) +
761  ((float)p.m_pixel[2]*0.11f))));
762  }
763  }
764 
767  {
768  if (NumChans == 4) {
769  m_pixel[0] = m_pixel[1] = m_pixel[2] =
770  m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
771  ((float)p.m_pixel[1]*0.59f) +
772  ((float)p.m_pixel[2]*0.11f))));
773  }
774  }
775 
778  {
779  if (NumChans == 4) {
780  m_pixel[0] = m_pixel[1] = m_pixel[2] =
781  m_pixel[3] = ChanType(float32Channel((((float)p.m_pixel[0]*0.30f) +
782  ((float)p.m_pixel[1]*0.59f) +
783  ((float)p.m_pixel[2]*0.11f))));
784  }
785  }
786 
789  {
790  if (NumChans == 4) {
791  m_pixel[0] = m_pixel[1] = m_pixel[2] =
792  m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
793  }
794  }
795 
798  {
799  if (NumChans == 4) {
800  m_pixel[0] = m_pixel[1] = m_pixel[2] =
801  m_pixel[3] = ChanType(float32Channel(((float)p.m_pixel[0])));
802  }
803  }
804 
807  {
808  if (NumChans == 4) {
809  m_pixel[0] = m_pixel[1] = m_pixel[2] =
810  m_pixel[3] = ChanType(uInt16Channel(((uInt16)p.m_pixel[0])));
811  }
812  }
813 
816  {
817  if (NumChans == 4) {
818  m_pixel[0] = m_pixel[1] = m_pixel[2] =
819  m_pixel[3] = ChanType(uInt8Channel(((uInt8)p.m_pixel[0])));
820  }
821  }
822 
823 
826  {
827  if (NumChans == 4) {
828  m_pixel[0] = m_pixel[1] = m_pixel[2] =
829  m_pixel[3] = ChanType(uInt16Channel(65535 -
830  ((uInt8)p.m_pixel[0]*77 +
831  (uInt8)p.m_pixel[1]*150 +
832  (uInt8)p.m_pixel[2]*28)));
833  }
834  }
835 
838  {
839  if (NumChans == 4) {
840  m_pixel[0] = m_pixel[1] = m_pixel[2] =
841  m_pixel[3] = ChanType(uInt16Channel(65535 -
842  ((uInt8)p.m_pixel[0]*77 +
843  (uInt8)p.m_pixel[1]*150 +
844  (uInt8)p.m_pixel[2]*28)));
845  }
846  }
847 
850  {
851  if (NumChans == 4) {
852  m_pixel[0] = m_pixel[1] = m_pixel[2] =
853  m_pixel[3] = ChanType(uInt16Channel(65535 -
854  ((((uInt16)p.m_pixel[0]*19660)>>16) +
855  (((uInt16)p.m_pixel[1]*38666)>>16) +
856  (((uInt16)p.m_pixel[2]*7209 )>>16))));
857  }
858  }
859 
862  {
863  if (NumChans == 4) {
864  m_pixel[0] = m_pixel[1] = m_pixel[2] =
865  m_pixel[3] = ChanType(uInt16Channel(65535 -
866  ((((uInt16)p.m_pixel[0]*19660)>>16) +
867  (((uInt16)p.m_pixel[1]*38666)>>16) +
868  (((uInt16)p.m_pixel[2]*7209 )>>16))));
869  }
870  }
871 
872 
875  {
876  if (NumChans == 4) {
877  m_pixel[0] = m_pixel[1] = m_pixel[2] =
878  m_pixel[3] = ChanType(float32Channel(1.0f -
879  (((float)p.m_pixel[0]*0.30f) +
880  ((float)p.m_pixel[1]*0.59f) +
881  ((float)p.m_pixel[2]*0.11f))));
882  }
883  }
884 
887  {
888  if (NumChans == 4) {
889  m_pixel[0] = m_pixel[1] = m_pixel[2] =
890  m_pixel[3] = ChanType(float32Channel(1.0f -
891  (((float)p.m_pixel[0]*0.30f) +
892  ((float)p.m_pixel[1]*0.59f) +
893  ((float)p.m_pixel[2]*0.11f))));
894  }
895  }
896 
899  {
900  if (NumChans == 4) {
901  m_pixel[0] = m_pixel[1] = m_pixel[2] =
902  m_pixel[3] = ChanType(float32Channel(1.0f -
903  (((float)p.m_pixel[0]*0.30f) +
904  ((float)p.m_pixel[1]*0.59f) +
905  ((float)p.m_pixel[2]*0.11f))));
906  }
907  }
908 
911  {
912  if (NumChans == 4) {
913  m_pixel[0] = m_pixel[1] = m_pixel[2] =
914  m_pixel[3] = ChanType(float32Channel(1.0f - (((float)p.m_pixel[0]*0.30f) +
915  ((float)p.m_pixel[1]*0.59f) +
916  ((float)p.m_pixel[2]*0.11f))));
917  }
918  }
919 
922  {
923  if (NumChans == 4) {
924  m_pixel[0] = m_pixel[1] = m_pixel[2] =
925  m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
926  }
927  }
928 
931  {
932  if (NumChans == 4) {
933  m_pixel[0] = m_pixel[1] = m_pixel[2] =
934  m_pixel[3] = ChanType(float32Channel(1.0f - ((float)p.m_pixel[0])));
935  }
936  }
937 
940  {
941  if (NumChans == 4) {
942  m_pixel[0] = m_pixel[1] = m_pixel[2] =
943  m_pixel[3] = ChanType(uInt16Channel(65535 - ((uInt16)p.m_pixel[0])));
944  }
945  }
946 
949  {
950  if (NumChans == 4) {
951  m_pixel[0] = m_pixel[1] = m_pixel[2] =
952  m_pixel[3] = ChanType(uInt8Channel(255 - ((uInt8)p.m_pixel[0])));
953  }
954  }
955 };
956 
957 
958 //------------------------------------------------------------------------------
961 {
962 public:
963  int x;
964  int y;
965  int nx;
966  int ny;
969  inline ImgTile() : x(0), y(0), nx(0), ny(0) {}
970 
978  inline ImgTile(int X, int Y, int NX, int NY) : x(X), y(Y), nx(NX), ny(NY) {}
979 
980  #if !defined MAX
981  #define MAX(a_, b_) (((a_) > (b_)) ? (a_) : (b_))
982  #endif
983  #if !defined MIN
984  #define MIN(a_, b_) (((a_) < (b_)) ? (a_) : (b_))
985  #endif
986 
992  ImgTile(const ImgTile &a, const ImgTile &b)
993  {
994  x = MAX(a.x, b.x);
995  y = MAX(a.y, b.y);
996  nx = MIN(a.x+a.nx, b.x+b.nx) - x;
997  ny = MIN(a.y+a.ny, b.y+b.ny) - y;
998  if (nx <= 0 || ny <= 0) x = y = nx = ny = 0;
999  }
1000 
1001  inline bool isEqualTile(const ImgTile &t) const
1002  { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
1003 
1004  inline bool operator ==(const ImgTile &t) const
1005  { return x == t.x && y == t.y && nx == t.nx && ny == t.ny; }
1006 
1007  inline bool operator !=(const ImgTile &t) const
1008  { return !(t == *this); }
1009 
1011  inline bool isEmpty() const { return nx <= 0 || ny <= 0; }
1012 
1013  inline void setEmpty() { x = y = nx = ny = 0; }
1014 
1016  inline bool contains(const ImgTile &a) const
1017  { return x <= a.x && a.x+a.nx <= x+nx &&
1018  y <= a.y && a.y+a.ny <= y+ny;
1019  }
1020 
1022  inline bool contains(int x_, int y_) const
1023  { return x <= x_ && x_ < x+nx && y <= y_ && y_ < y+ny;
1024  }
1025 
1028  {
1029  if (x < 0) {
1030  nx += x; x = 0;
1031  if (nx < 0) x = y = nx = ny = 0;
1032  }
1033  if (y < 0) {
1034  ny += y; y = 0;
1035  if (ny < 0) x = y = nx = ny = 0;
1036  }
1037  }
1038 
1040  void ExpandToInclude(int x_, int y_)
1041  {
1042  if (isEmpty()) {
1043  x = x_; y = y_; nx = 1; ny = 1;
1044  } else {
1045  if (x_ < x) { nx += (x - x_); x = x_; }
1046  if (y_ < y) { ny += (y - y_); y = y_; }
1047 
1048  if (x + nx < x_) nx = (x_ - x) + 1;
1049  if (y + ny < y_) ny = (y_ - y) + 1;
1050  }
1051  }
1052 
1054  void Expand(int numPixels = 1)
1055  {
1056  x -= numPixels; y -= numPixels;
1057  numPixels <<= 1;
1058  nx += numPixels; ny += numPixels;
1059  }
1060 
1062  int numPixels() const { return isEmpty() ? 0 : nx * ny; }
1063 };
1064 
1065 
1066 //------------------------------------------------------------------------------
1067 #define MAX_DIRTY_REGION (8192+128) // same as max texture size...
1068 #define DIRTY_REGION_GRANULARITY 128 // make this a power of 2.
1069 #define DIRTY_REGION_MASK (DIRTY_REGION_GRANULARITY-1)
1070 #define DIRTY_REGION_SHIFT 7
1071 #define DIRTY_REGION_XY_SIZE ( MAX_DIRTY_REGION / DIRTY_REGION_GRANULARITY )
1072 
1073 //------------------------------------------------------------------------------
1080 class MBDLL_DECL ImgDirtyRegion { // should be 4K + 16 bytes when the max texture size is 8Kx8K texels
1081 private:
1082  // each char in this array represents a 128x128 pixel region of an image
1083  // using char as it is guaranteed to be 1 byte. bool is not.
1084  char m_DirtyChunks[DIRTY_REGION_XY_SIZE * DIRTY_REGION_XY_SIZE];
1085  int m_ChunksSet;
1086  int m_NumTiles;
1087  ImgTile *m_DirtyTiles;
1088  ImgTile m_DirtyTotalChunks;
1089  int m_InTileCount;
1090 
1091  void ComputeDirtyTiles();
1092 
1093  // this just clears the output tile list, not the bit-map.
1094  void ClearDirtyTiles()
1095  {
1096  if (m_DirtyTiles) delete [] m_DirtyTiles;
1097  m_NumTiles = 0; m_DirtyTiles = 0;
1098  }
1099 
1100  // compute the address of the byte for a chunk at the given chunk coordinates
1101  char *Index(int x, int y)
1102  {
1103  return &m_DirtyChunks[(y * DIRTY_REGION_XY_SIZE) + x];
1104  }
1105 
1106  // set the value at the specified image coordinates to 1, return the old value.
1107  char Set(int x, int y) { char c = *Index(x, y); *Index(x, y) = 1; return c; }
1108 
1109  // return the value at the specified chunk coordinates.
1110  char Get(int x, int y) { return *Index(x, y); }
1111 
1112 public:
1113  ImgDirtyRegion() { m_DirtyTiles = 0; ClearDirtyRegion(); }
1114  ~ImgDirtyRegion() { ClearDirtyTiles(); }
1115 
1118  void AddToDirtyRegion(const ImgTile &dirtyTile);
1119 
1122  {
1123  ClearDirtyTiles();
1124  memset(m_DirtyChunks, 0, DIRTY_REGION_XY_SIZE * DIRTY_REGION_XY_SIZE);
1125  m_ChunksSet = 0;
1126  m_DirtyTotalChunks.setEmpty();
1127  m_InTileCount = 0;
1128  }
1129 
1131  int numTiles()
1132  {
1133  if (!m_DirtyTiles) ComputeDirtyTiles();
1134  return m_NumTiles;
1135  }
1136 
1138  ImgTile Tile(int i)
1139  {
1140  return m_DirtyTiles[i];
1141  }
1142 
1145  {
1146  return m_DirtyTotalChunks;
1147  }
1148 
1150  bool isEmpty() const { return m_DirtyTotalChunks.isEmpty(); }
1151 
1153  void Union(const ImgDirtyRegion &other);
1154 
1155  void DumpToLog();
1156 
1157  ImgDirtyRegion& operator= ( const ImgDirtyRegion& cOther );
1158 };
1159 
1160 
1161 //------------------------------------------------------------------------------
1165 private:
1166  int ax1, ax2, bx1, bx2;
1167  int ay1, ay2, by1, by2;
1168  signed char state;
1169  bool ad, bd;
1170 
1171 public:
1172  ImgTile_AoutB_Iter(const ImgTile &A, const ImgTile &B) :
1173  ax1 (A.x), ax2 (A.x + A.nx - 1),
1174  bx1 (B.x), bx2 (B.x + B.nx - 1),
1175  ay1 (A.y), ay2 (A.y + A.ny - 1),
1176  by1 (B.y), by2 (B.y + B.ny - 1),
1177  state (0),
1178  ad (A.nx <= 0 || A.ny <= 0),
1179  bd (B.nx <= 0 || B.ny <= 0) {}
1180 
1181  virtual bool next();
1182 };
1183 
1184 
1185 //-----------------------------------------------------------------------------
1187 public:
1188  ImgTileUnion(const ImgTile &A, const ImgTile &B);
1189 };
1190 
1191 
1199 protected:
1202  int m_Type;
1205 
1206 
1207 public:
1216  ImgPageIterator(Image *img, const ImgTile *srcTile = 0, bool writing = false);
1217  virtual ~ImgPageIterator();
1218  virtual bool next();
1219  void *dataPtr() { return m_PixelData; }
1220 };
1221 
1222 
1223 //------------------------------------------------------------------------------
1226 public:
1227  typedef enum {
1230  WriteOnly
1231  } AccessMode;
1232 
1233 protected:
1236 
1237 public:
1238  ImgLockPageIterator(Image *img, const ImgTile *srcTile = 0, AccessMode mode = ReadOnly);
1240 
1241  virtual bool next();
1242  void *dataPtr();
1243 };
1244 
1245 //------------------------------------------------------------------------------
1256 public:
1258  typedef enum {
1259  uChar = 0,
1260  uShort = 1,
1261  sHalf = 2,
1262  sFloat = 3,
1264  sChar = 4,
1265  sShort = 5,
1266  uInt = 6,
1267  sInt = 7,
1268  sDouble = 8
1269  } ChannelType;
1270 
1273  typedef enum {
1279  orderRGB = 5,
1282 
1283 protected:
1284  char m_cCount;
1290 public:
1291 
1292  PixelDescriptor(char cCount,
1295  bool PreMultiplied)
1296  : m_cCount (cCount)
1297  , m_channelType (channelType)
1298  , m_channelOrder (channelOrder)
1299  , m_PreMultiplied(PreMultiplied) {}
1300 
1302  int channelSize() const {
1303  static const unsigned char s_channelByteCount[] = {1, 2, 2, 4, 1, 2, 4, 4, 8};
1304  return s_channelByteCount[m_channelType];
1305  }
1306 
1308  int channelBitSize() const {
1309  return channelSize() * 8;
1310  }
1311 
1313  int pixelSize() const {
1314  return channelSize() * m_cCount;
1315  }
1316 
1318  int pixelBitSize() const {
1319  return pixelSize() * 8;
1320  }
1321 
1324 
1327 
1330  bool premultiplied() const { return m_PreMultiplied; }
1331 
1333  int channelCount() const { return m_cCount; }
1334 
1336  void setChannelCount(int c) { m_cCount = c; }
1337 
1339  bool operator == (const PixelDescriptor &pd) const
1340  { return (m_cCount == pd.m_cCount &&
1341  m_channelType == pd.m_channelType &&
1342  m_channelOrder == pd.m_channelOrder &&
1343  m_PreMultiplied == pd.m_PreMultiplied);
1344  }
1345 };
1346 
1347 
1348 
1349 //------------------------------------------------------------------------------
1354 
1355 public:
1359  };
1360 
1361 protected:
1368 public:
1369 
1382  ImageDescriptor(int x, int y, int nx, int ny,
1383  MemoryChannelOrder order = orderRGBA,
1384  bool premult = true,
1385  char nc = 4, ChannelType ct = uChar) :
1386  PixelDescriptor(nc, ct, order, premult),
1387  m_Bounds(x, y, nx, ny),
1388  m_xResolution(100.0f), m_yResolution(100.0f),
1389  m_ResolutionUnits(k_PixelsPerInch) {}
1390 
1402  MemoryChannelOrder order = orderRGBA,
1403  bool premult = true,
1404  char nc = 4, ChannelType ct = uChar) :
1405  PixelDescriptor(nc, ct, order, premult),
1406  m_Bounds(0, 0, nx, ny) {}
1407 
1410  PixelDescriptor(4, uChar, orderRGBA, true),
1411  m_Bounds(0,0,0,0) {}
1412 
1415  int numBytes() const { return m_Bounds.nx * m_Bounds.ny * pixelSize(); }
1416 
1418  int strideBytes() const { return m_Bounds.nx * pixelSize(); }
1419 
1421  int xSize() const { return m_Bounds.nx; }
1422 
1424  int ySize() const { return m_Bounds.ny; }
1425 
1427  int cSize() const { return m_cCount; }
1428 
1432  bool sizeEqual(const ImageDescriptor &o) const
1433  { return ((xSize() == o.xSize()) && (ySize() == o.ySize())); }
1434 
1436  void setSize(int nx, int ny) { m_Bounds.nx = nx; m_Bounds.ny = ny; }
1437 
1439  const ImgTile &getBounds() const { return m_Bounds; }
1440 
1447  void getResolutionInfo(float &xRes, float &yRes, ResUnit &unit) const
1448  {
1449  xRes = m_xResolution; yRes = m_yResolution, unit = m_ResolutionUnits;
1450  }
1451 
1458  void setResolutionInfo(float xRes, float yRes, ResUnit unit)
1459  {
1460  m_xResolution = xRes; m_yResolution = yRes, m_ResolutionUnits = unit;
1461  }
1462 
1463  friend class Image;
1464 };
1465 
1466 
1467 //------------------------------------------------------------------------------
1474 typedef bool (*ProxyInterruptFunction)(void);
1475 
1476 #define MAX_PROXY_LEVEL 4
1477 
1478 //------------------------------------------------------------------------------
1503 
1504 class MBDLL_DECL Image : public Node
1505 {
1506 
1507  DECLARE_CLASS;
1508 
1509  friend class ImgPageIterator;
1510  friend class ImgLockPageIterator;
1511 
1512 
1513 public:
1515  typedef enum {
1516  Type_Invalid = 0,
1518  Type_Virtual
1519  } ImageType;
1520 
1522  enum Format
1523  {
1524  e8integer = 0,
1534  };
1535 
1536  virtual ~Image( void );
1537 
1538 protected:
1539 
1540  Image( void );
1541 
1542  unsigned char m_FillPixel[16]; // fill color -- largest supported pixel is 16 bytes.
1543  ImageDescriptor m_Descriptor; // how to interpret the pixel data
1544 
1546 
1547  unsigned char m_ProxyLevel;
1548  Image *m_pProxyImages[MAX_PROXY_LEVEL+1];
1550 
1552 
1554  {
1555  for (int i = 0; i < MAX_PROXY_LEVEL+1; ++i) {
1556  if (m_pProxyImages[i]) {
1557  delete m_pProxyImages[i]; m_pProxyImages[i] = 0;
1558  }
1559  }
1560  }
1561 
1562  virtual bool regenerateProxy();
1563  bool isProxyDirty() const
1564  { return (m_ProxyLevel > 0) ? (m_pProxyImages[m_ProxyLevel] == 0) : false; }
1565 
1566 
1567  // Generate a downsampled proxy of this image. The targetImg is created,
1568  // and populated. Current levels supported are 1, 2, and 3.
1569  // (representing 1/2, 1/4, and 1/8 size proxies)
1570  // This function only works on tiled images.
1571  // Works on 1, 2, and 4 channel images. (not 3 channel)
1572  // uchar, ushort, half, and float images are supported on input.
1573  // Output will be uchar by default, but if you set DownsampleTo8Bits
1574  // to false, the output image will have the same channel datatype
1575  // as the input image. With float images, no clamping will take place
1576  // when not downsampling to 8 bit per channel.
1577 
1578  virtual bool GenerateProxy(Image *targetImg, int level, bool DownsampleTo8Bits = true);
1579 
1580 
1581 public:
1582 
1585  void UnitTest(int iterations);
1586 
1587  virtual bool isAllocated() const;
1588 
1589  // Return a list of all extensions from all of our descendent classes.
1590  //
1591  static QString AllSupportedExtensions( bool bRGBAOnly = false,
1592  bool bRead = true,
1593  bool bDesc = false,
1594  bool bPSD = true,
1595  QString sDelimiter = ";");
1596 
1598  ImageType getType() const { return m_ImageType; }
1599 
1601  const ImageDescriptor &getDescriptor() const { return m_Descriptor; }
1602 
1603 
1608  void setProxyDownsampleTo8Bit(bool downsampleTo8Bit = true)
1609  {
1610  if (m_bDownsampleProxyTo8Bit != downsampleTo8Bit) {
1611  m_bDownsampleProxyTo8Bit = downsampleTo8Bit;
1612  markProxyDirty();
1613  }
1614  }
1615 
1616  bool getProxyDownsampleTo8Bit() const { return m_bDownsampleProxyTo8Bit; }
1617 
1619  void clearProxyImages() { markProxyDirty(); }
1620 
1625  { m_pProxyIntFcn = fcnPtr; }
1626 
1627 
1635  unsigned char getProxyLevel() const { return m_ProxyLevel; }
1636 
1638  bool setProxyLevel(unsigned char newLevel) {
1639  if ( xSize()>>newLevel == 0 || ySize()>>newLevel == 0 )
1640  return false;
1641  if (newLevel > MAX_PROXY_LEVEL) newLevel = MAX_PROXY_LEVEL;
1642  if (newLevel != m_ProxyLevel) {
1643  m_ProxyLevel = newLevel;
1644  }
1645 
1646  return true;
1647  }
1648 
1655  {
1656  if (m_ProxyLevel == 0) return this;
1657 
1658  if ( m_pProxyImages[m_ProxyLevel] ) return m_pProxyImages[m_ProxyLevel];
1659 
1660  bool generated = regenerateProxy();
1661  if (!generated && m_pProxyImages[m_ProxyLevel] != 0) {
1662  delete m_pProxyImages[m_ProxyLevel];
1663  m_pProxyImages[m_ProxyLevel] = 0;
1664  }
1665  return m_pProxyImages[m_ProxyLevel];
1666  }
1667 
1669  int xSize() const { return m_Descriptor.xSize(); }
1670 
1672  int ySize() const { return m_Descriptor.ySize(); }
1673 
1675  int cSize() const { return m_Descriptor.cSize(); }
1676 
1678  int curWidth() const { return Width() >> getProxyLevel(); }
1679 
1681  int curHeight() const { return Height() >> getProxyLevel(); }
1682 
1685 
1687  const ImgTile &getBounds() const { return m_Descriptor.getBounds(); }
1688 
1689  //====================================================================
1700  void getFillColor(void *fillPixel, const PixelDescriptor *pd = 0) const;
1701 
1702  //====================================================================
1713  void setFillColor(const void *fillPixel, const PixelDescriptor *pd = 0);
1714 
1715  //====================================================================
1733  void getTile(int x, int y, int nx, int ny, void *data,
1734  const PixelDescriptor *pd = 0)
1735  { getTile(ImgTile(x, y, nx, ny), data, pd); }
1736 
1737 
1738  //====================================================================
1762  void getSubTile(int x, int y, int nx, int ny, void *data,
1763  int dx, int dy, int dnx, int dny,
1764  const PixelDescriptor *pd = 0)
1765  { getSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
1766 
1767 
1768  //====================================================================
1784  void getTile(const ImgTile &srcTile, void *data,
1785  const PixelDescriptor *pd = 0)
1786  { getSubTile(srcTile, data, srcTile, pd); }
1787 
1788  //====================================================================
1807  virtual void getSubTile(const ImgTile &srcTile, void *data,
1808  const ImgTile &targetBounds,
1809  const PixelDescriptor *pd = 0);
1810 
1811 
1812  //====================================================================
1833  void setTile(int x, int y, int nx, int ny, void *data,
1834  const PixelDescriptor *pd = 0)
1835  { setTile(ImgTile(x, y, nx, ny), data, pd); }
1836 
1837  //====================================================================
1864  void setSubTile(int x, int y, int nx, int ny, const void *data,
1865  int dx, int dy, int dnx, int dny,
1866  const PixelDescriptor *pd = 0)
1867  { setSubTile(ImgTile(x, y, nx, ny), data, ImgTile(dx, dy, dnx, dny), pd); }
1868 
1869  //====================================================================
1885  void setTile(const ImgTile &dstTile, const void *data,
1886  const PixelDescriptor *pd = 0)
1887  { setSubTile(dstTile, data, dstTile, pd); }
1888 
1889  //====================================================================
1908  virtual void setSubTile(const ImgTile &dstTile, const void *data,
1909  const ImgTile &sourceBounds,
1910  const PixelDescriptor *pd = 0);
1911 
1912  //====================================================================
1937  void copyTile(int x, int y, int nx, int ny, Image &fromImg,
1938  int ox, int oy)
1939  { copyTile(ImgTile(x, y, nx, ny), fromImg, ox, oy); }
1940 
1941 
1942  //====================================================================
1964  virtual void copyTile(const ImgTile &dstTile, Image &fromImg,
1965  int ox, int oy);
1966 
1967  //====================================================================
1981  virtual void copyAll(Image &fromImg)
1982  {
1983  ImgTile srcBounds(fromImg.getBounds());
1984  copyTile(srcBounds, fromImg, srcBounds.x, srcBounds.y);
1985  }
1986 
1988  virtual void Clear();
1989 
1990  //====================================================================
2015  void fillTile(int x, int y, int nx, int ny, void *pixelData,
2016  const PixelDescriptor *pd = 0,
2017  const ImgTile *maskTile = 0)
2018  { fillTile(ImgTile(x, y, nx, ny), pixelData, pd, maskTile); }
2019 
2020  //====================================================================
2040  void fillTile(const ImgTile &dstTile, const void *pixelData,
2041  const PixelDescriptor *pd,
2042  const ImgTile *maskTile);
2043 
2044  //====================================================================
2063  virtual void fillTile(const ImgTile &dstTile,
2064  const void *pixelData,
2065  const PixelDescriptor *pd = 0);
2066 
2067  //====================================================================
2077  virtual void getPageSize(int &nx, int &ny);
2078 
2079  //====================================================================
2092  ImgPageIterator *getPageIterator(int x, int y, int nx, int ny)
2093  { return getPageIterator(ImgTile(x, y, nx, ny)); }
2094 
2095  //====================================================================
2105  virtual ImgPageIterator *getPageIterator(const ImgTile &srcTile);
2106 
2107  //====================================================================
2123  ImgLockPageIterator *lockPageSet(int x, int y, int nx, int ny,
2125  { return lockPageSet(ImgTile(x, y, nx, ny), mode); }
2126 
2127  //====================================================================
2140  virtual ImgLockPageIterator *lockPageSet(const ImgTile &srcTile,
2142 
2143  static ImageDescriptor::MemoryChannelOrder optimizedChannelOrder();
2144 
2145  static void ConvertPixels(void *dst, const void *src, int numPix,
2146  const PixelDescriptor &dstDesc,
2147  const PixelDescriptor *srcDesc = 0);
2148 
2150  void CopyInverseLuminance(const Image &srcImage);
2151 
2153  void CopyLuminance(const Image &srcImage);
2154 
2156  virtual void PutInverseLuminance(Image &targetImage) const;
2157 
2159  virtual void PutLuminance(Image &targetImage) const;
2160 
2177  virtual QString SupportedExtensions( bool bRGBAOnly = false,
2178  bool bRead = true,
2179  bool bDesc = false,
2180  bool bPSD = true,
2181  QString sDelimiter = ";") const;
2182 
2187  virtual void Create( unsigned int iWidth, unsigned int iHeight,
2188  unsigned int iChannelCount, Format eFormat = e8integer,
2189  bool Tiled = false,
2191 
2195  virtual void Load( const QString &sFileName, int iLayerIndex = 0, bool tiled = false );
2196 
2197  virtual bool GetPSDLayerMeta ( void *pPSDFile, int iLayerIndex,
2198  QString &layerName, int &blendMode,
2199  float &opacity, bool &locked,
2200  bool &visible, bool &transLocked);
2201 
2209  virtual bool LoadPSDLayer ( void *pPSDFile,
2210  int iLayerIndex,
2211  bool Tiled = false,
2212  bool premult = true );
2213 
2214 
2215  virtual Image *ComputeDifferenceMask(Image *otherImg, int expansionRadius,
2216  int AARadius, bool &anyDiffs);
2217 
2226  virtual bool SavePSDLayerMeta ( void *pPSDFile,
2227  int iLayerIndex,
2228  const QString&pLayerName,
2229  float opacity = 1.0f,
2230  bool visible = true,
2231  bool locked = false,
2232  int xOff = 0,
2233  int yOff = 0,
2234  int blendMode = -1);
2235 
2245  virtual bool SavePSDLayer ( void *pPSDFile,
2246  int iLayerIndex,
2247  const QString&pLayerName,
2248  float opacity = 1.0f,
2249  bool visible = true,
2250  bool locked = false,
2251  bool needs_unpremult = true,
2252  int xOff = 0,
2253  int yOff = 0);
2254 
2260  virtual void *OpenPSDFile(const QString &pFileName, bool writing = false);
2261 
2264  virtual bool GetPSDFileInfo(void *psdFile, int *width, int *height, int *numChannels,
2265  int *bitDepth, int *numLayers, int *curLayer);
2266 
2269  virtual bool SetPSDFileInfo(void *psdFile, int width, int height, int numChannels,
2270  int bitDepth, int numLayers, int curLayer);
2271 
2273  virtual bool ClosePSDFile(void *psdFile);
2274 
2275 
2283  virtual void Save( const QString &sFileName, bool bForce = true,
2284  Material *pMaterial = NULL,
2285  float uStart = 0.0f, float vStart = 0.0f,
2286  bool force_1_Channel_To_4_Channel = false);
2287 
2289  virtual unsigned int Width( void ) const;
2290 
2292  virtual unsigned int Height( void ) const;
2293 
2295  virtual Format Format( void ) const;
2296 
2298  virtual unsigned int ChannelCount( void ) const;
2299 
2301  virtual unsigned int BytesPerPixel( void ) const;
2302 
2304  unsigned int curBytesPerPixel() const { return (getProxyLevel() != 0) ? ChannelCount() : BytesPerPixel(); }
2305 
2307  virtual unsigned int TotalBytes( void ) const;
2308 
2310  unsigned int curTotalBytes(void) const { return curWidth() * curHeight() * curBytesPerPixel(); }
2311 
2316  virtual void SetValueAt( unsigned int iXPos, unsigned int iYPos,
2317  unsigned int iChannel, float fValue );
2318 
2322  virtual float ValueAt( unsigned int iXPos, unsigned int iYPos,
2323  unsigned int iChannel ) const;
2324 
2328  virtual float ValueAt( float fXPos, float fYPos, unsigned int iChannel ) const;
2329 
2332  virtual void SetColorAt( unsigned int iXPos, unsigned int iYPos,
2333  const Color &cColor );
2334 
2336  virtual Color ColorAt( unsigned int iXPos, unsigned int iYPos ) const;
2337 
2339  virtual Color ColorAt( float fXPos, float fYPos ) const;
2340 
2344  virtual QImage *ConvertToQImage( );
2345 
2347  virtual void ConvertFromQImage( QImage &qImg, bool tiled = false);
2348 
2352  virtual bool Fragmented() const;
2353 
2355  virtual bool Tiled() const;
2356 
2358  bool Versioned() const { return Tiled(); }
2359 
2362  virtual bool NewVersion();
2363 
2367  virtual bool PrevVersion();
2368 
2372  virtual bool NextVersion();
2373 
2375  virtual int NumVersions();
2376 
2380  virtual bool MergeOldestVersions();
2381 
2386  virtual bool PurgeNewerVersions();
2387 
2390  virtual bool PurgeAllButCurrentVersion();
2391 
2397  virtual void *Data( int iRow = -1, bool writing = true );
2398  virtual const void *Data( int iRow = -1, bool writing = false ) const;
2399 
2400 
2406  virtual void DrawUVs(Material *pMaterial,
2407  float uStart = 0.0f, float vStart = 0.0f,
2408  bool baseLevel = true);
2409 
2410 
2413  virtual void scaleTileBilinear_4Chan_uchar(float x, float y, float nx, float ny, // src tile (from this image)
2414  unsigned int *data, // target buffer
2415  int dx, int dy, int dnx, int dny, // target location and size of target buffer
2416  float xScale, float yScale) const; // scale factors
2417 
2418 
2419 
2426  virtual void GenerateUpscaled(Image *targetImg, int factor);
2427 
2428 
2431  static void MultiplyRGBByAlpha_uc4(unsigned char *buffer, int numPixels);
2432 
2434  virtual bool isDirty() const;
2435 
2439  virtual void setDirty();
2440 
2442  virtual void setClean();
2443 
2445  virtual void VerticalFlip();
2446 
2448  virtual void AdjustImageCacheSize();
2449 
2451  virtual void ConvertTo4Channel();
2452 
2453 };
2454 
2455 //------------------------------------------------------------------------------
2456 MBDLL_DECL AttributeWidget *CreateNewImageWidget( QWidget *pParent, int iWidth,
2457  AttributePointer<Image> *pImage );
2458 template <> inline
2459 AttributeWidget *AttributePointer<Image>::CreateEditorWidget( QWidget *pParent, int iWidth )
2460 { return CreateNewImageWidget( pParent, iWidth, this ); };
2461 
2463 {
2464  DECLARE_CLASS;
2465 
2466 protected:
2467 
2468  EnvironmentMap( void );
2469 
2470 public:
2474  virtual bool Load( const QString &sFileName );
2477  virtual unsigned int ConvertToOpenGLTexture( void );
2478 };
2479 
2480 
2481 //------------------------------------------------------------------------------
2483 
2484 // these are just shorthand -- they're undefined later in this file
2485 #define cu_int const unsigned int
2486 #define u_int unsigned int
2487 #define u_short unsigned short
2488 #define u_char unsigned char
2489 
2490 #define inline __forceinline
2491 
2495 template <class ChannelType, cu_int nch>
2497 {
2498 private:
2499  u_int m_Stride;
2500  u_int m_Height;
2501  u_int m_chans;
2502  Image *m_Image;
2503  ChannelType *m_pData;
2504 
2505 public:
2507  {
2508  m_Stride = parent->Width();
2509  m_Height = parent->Height();
2510  m_chans = parent->ChannelCount();
2511  m_Image = parent;
2512  m_pData = (ChannelType *)parent->Data();
2513  }
2514 
2515  u_int Width() const { return m_Stride; }
2516  u_int Height() const { return m_Height; }
2517  u_int ChannelCount() const { return m_chans; }
2518 
2522  inline void SetValueAt(u_int X, u_int Y, u_int Ch, float fVal);
2523 
2525  inline float ValueAt(u_int X, u_int Y, u_int Ch) const;
2526 
2530  inline void SetColorAt( u_int X, u_int Y, const Color &cColor );
2531 
2532  inline void *AddrAt(u_int X, u_int Y, u_int Ch);
2533 };
2534 
2535 //------------------------------------------------------------------------------
2536 template <class ChannelType, cu_int nch>
2537 class MBDLL_TEMPLATE_DECL ImageAccessor : public ImageAccessorBase<ChannelType, nch>
2538 {
2539 public:
2540  ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, nch>(parent)
2541  {
2542  }
2543 
2545  inline Color ColorAt( u_int X, u_int Y ) const;
2546 };
2547 
2548 
2549 //------------------------------------------------------------------------------
2550 template <class ChannelType>
2551 class ImageAccessor<ChannelType, 3> : public ImageAccessorBase<ChannelType, 3>
2552 {
2553 public:
2554  ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 3>(parent)
2555  {
2556  }
2557 
2559  inline Color ColorAt( u_int X, u_int Y ) const
2560  {
2561  return Color(
2565  1);
2566  }
2567 };
2568 
2569 //------------------------------------------------------------------------------
2570 template <class ChannelType>
2571 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 2> : public ImageAccessorBase<ChannelType, 2>
2572 {
2573 public:
2574  ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 2>(parent)
2575  {
2576  }
2577 
2579  inline Color ColorAt( u_int X, u_int Y ) const
2580  {
2581  return Color(
2584  0, 1);
2585  }
2586 };
2587 
2588 //------------------------------------------------------------------------------
2589 template <class ChannelType>
2590 class MBDLL_TEMPLATE_DECL ImageAccessor<ChannelType, 1> : public ImageAccessorBase<ChannelType, 1>
2591 {
2592 public:
2593  ImageAccessor(Image *parent) : ImageAccessorBase<ChannelType, 1>(parent)
2594  {
2595  }
2596 
2598  inline Color ColorAt( u_int X, u_int Y ) const
2599  {
2600  return Color(ImageAccessorBase<ChannelType, 1>::ValueAt(X,Y,0), 0, 0, 1);
2601  }
2602 };
2603 
2604 //------------------------------------------------------------------------------
2605 template <>
2607 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
2608 template <>
2610 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
2611 template <>
2613 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
2614 template <>
2616 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
2617 
2618 template <>
2620 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
2621 template <>
2623 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
2624 template <>
2626 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
2627 template <>
2629 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
2630 
2631 
2632 template <>
2634 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
2635 template <>
2637 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
2638 template <>
2640 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
2641 template <>
2643 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
2644 
2645 template <>
2647 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) )]; }
2648 template <>
2650 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
2651 template <>
2653 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
2654 template <>
2656 { return (void *)&m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
2657 
2658 // implement the inline member fcns with specialization...
2659 template <>
2661 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_char)(255.0f * fVal); }
2662 template <>
2664 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_char)(255.0f * fVal); }
2665 template <>
2667 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_char)(255.0f * fVal); }
2668 template <>
2670 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_char)(255.0f * fVal); }
2671 
2672 template <>
2673 inline void ImageAccessorBase<u_short, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2674 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_short)(65535.0f * fVal); }
2675 template <>
2676 inline void ImageAccessorBase<u_short, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2677 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_short)(65535.0f * fVal); }
2678 template <>
2679 inline void ImageAccessorBase<u_short, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2680 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_short)(65535.0f * fVal); }
2681 template <>
2682 inline void ImageAccessorBase<u_short, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2683 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_short)(65535.0f * fVal); }
2684 
2685 //template <class ChannelType, cu_int nch>
2686 template <>
2687 inline void ImageAccessorBase<u_int, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2688 { m_pData[Ch + ((X + m_Stride * Y) )] = (u_int)(0xffffffff * fVal); }
2689 template <>
2690 inline void ImageAccessorBase<u_int, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2691 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = (u_int)(0xffffffff * fVal); }
2692 template <>
2693 inline void ImageAccessorBase<u_int, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2694 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = (u_int)(0xffffffff * fVal); }
2695 template <>
2696 inline void ImageAccessorBase<u_int, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2697 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = (u_int)(0xffffffff * fVal); }
2698 
2699 template <>
2700 inline void ImageAccessorBase<float, 1>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2701 { m_pData[Ch + ((X + m_Stride * Y) )] = fVal; }
2702 template <>
2703 inline void ImageAccessorBase<float, 2>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2704 { m_pData[Ch + ((X + m_Stride * Y) * 2)] = fVal; }
2705 template <>
2706 inline void ImageAccessorBase<float, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2707 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
2708 template <>
2709 inline void ImageAccessorBase<float, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2710 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
2711 
2712 template <>
2714 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/255.0f); }
2715 template <>
2717 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/255.0f); }
2718 template <>
2720 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/255.0f); }
2721 template <>
2723 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/255.0f); }
2724 
2725 template <>
2727 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/65535.0f); }
2728 template <>
2730 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/65535.0f); }
2731 template <>
2733 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/65535.0f); }
2734 template <>
2736 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/65535.0f); }
2737 
2738 template <>
2740 { return m_pData[Ch + ((X + m_Stride * Y) )] * (1.0f/float(0xffffffff)); }
2741 template <>
2743 { return m_pData[Ch + ((X + m_Stride * Y) * 2)] * (1.0f/float(0xffffffff)); }
2744 template <>
2746 { return m_pData[Ch + ((X + m_Stride * Y) * 3)] * (1.0f/float(0xffffffff)); }
2747 template <>
2749 { return m_pData[Ch + ((X + m_Stride * Y) * 4)] * (1.0f/float(0xffffffff)); }
2750 
2751 template <>
2753 { return m_pData[Ch + ((X + m_Stride * Y) )]; }
2754 template <>
2756 { return m_pData[Ch + ((X + m_Stride * Y) * 2)]; }
2757 template <>
2759 { return m_pData[Ch + ((X + m_Stride * Y) * 3)]; }
2760 template <>
2762 { return m_pData[Ch + ((X + m_Stride * Y) * 4)]; }
2763 
2764 
2765 
2766 //------------------------------------------------------------------------------
2767 template <>
2769 {
2770  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
2771 };
2772 
2773 //------------------------------------------------------------------------------
2774 template <>
2776 {
2777  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
2778 };
2779 
2780 //------------------------------------------------------------------------------
2781 template <>
2783 {
2784  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
2785 };
2786 
2787 //------------------------------------------------------------------------------
2788 template <>
2790 {
2791  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
2792 };
2793 
2794 //------------------------------------------------------------------------------
2795 template <>
2797 {
2798  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
2799 };
2800 
2801 //------------------------------------------------------------------------------
2802 template <>
2804 {
2805  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
2806 };
2807 
2808 //------------------------------------------------------------------------------
2809 template <>
2811 { return float(m_pData[Ch + ((X + m_Stride * Y) * 3)]); }
2812 
2813 //------------------------------------------------------------------------------
2814 template <>
2816 { return float(m_pData[Ch + ((X + m_Stride * Y) * 4)]); }
2817 
2818 //------------------------------------------------------------------------------
2819 template <>
2820 inline void ImageAccessorBase<half_, 3>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2821 { m_pData[Ch + ((X + m_Stride * Y) * 3)] = fVal; }
2822 
2823 //------------------------------------------------------------------------------
2824 template <>
2825 inline void ImageAccessorBase<half_, 4>::SetValueAt( u_int X, u_int Y, u_int Ch, float fVal )
2826 { m_pData[Ch + ((X + m_Stride * Y) * 4)] = fVal; }
2827 
2828 
2829 //------------------------------------------------------------------------------
2830 template <>
2832 {
2833  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), ValueAt(X,Y,3));
2834 };
2835 
2836 //------------------------------------------------------------------------------
2837 template <>
2839 {
2840  return Color(ValueAt(X,Y,0), ValueAt(X,Y,1), ValueAt(X,Y,2), 1.0f);
2841 };
2842 
2843 
2844 //------------------------------------------------------------------------------
2845 template <>
2847 {
2848  SetValueAt(X, Y, 0, c.r);
2849  SetValueAt(X, Y, 1, c.g);
2850  SetValueAt(X, Y, 2, c.b);
2851  SetValueAt(X, Y, 3, c.a);
2852 };
2853 
2854 //------------------------------------------------------------------------------
2855 template <>
2857 {
2858  SetValueAt(X, Y, 0, c.r);
2859  SetValueAt(X, Y, 1, c.g);
2860  SetValueAt(X, Y, 2, c.b);
2861 };
2862 
2863 //------------------------------------------------------------------------------
2864 template <>
2866 {
2867  SetValueAt(X, Y, 0, c.r);
2868  SetValueAt(X, Y, 1, c.g);
2869  SetValueAt(X, Y, 2, c.b);
2870  SetValueAt(X, Y, 3, c.a);
2871 };
2872 
2873 //------------------------------------------------------------------------------
2874 template <>
2876 {
2877  SetValueAt(X, Y, 0, c.r);
2878  SetValueAt(X, Y, 1, c.g);
2879  SetValueAt(X, Y, 2, c.b);
2880 };
2881 
2882 //------------------------------------------------------------------------------
2883 template <>
2885 {
2886  SetValueAt(X, Y, 0, c.r);
2887  SetValueAt(X, Y, 1, c.g);
2888  SetValueAt(X, Y, 2, c.b);
2889  SetValueAt(X, Y, 3, c.a);
2890 };
2891 
2892 //------------------------------------------------------------------------------
2893 template <>
2895 {
2896  SetValueAt(X, Y, 0, c.r);
2897  SetValueAt(X, Y, 1, c.g);
2898  SetValueAt(X, Y, 2, c.b);
2899 };
2900 
2901 //------------------------------------------------------------------------------
2902 template <>
2904 {
2905  SetValueAt(X, Y, 0, c.r);
2906  SetValueAt(X, Y, 1, c.g);
2907  SetValueAt(X, Y, 2, c.b);
2908  SetValueAt(X, Y, 3, c.a);
2909 };
2910 
2911 //------------------------------------------------------------------------------
2912 template <>
2914 {
2915  SetValueAt(X, Y, 0, c.r);
2916  SetValueAt(X, Y, 1, c.g);
2917  SetValueAt(X, Y, 2, c.b);
2918 };
2919 
2920 
2921 
2922 //------------------------------------------------------------------------------
2924 static inline void SnapOutTile(ImgTile &t)
2925 {
2926  static const int TILE_SNAP = (128-1); // must be ((2^i)-1).
2927  t.nx += t.x - 1; t.ny += t.y - 1;
2928  t.x &= ~TILE_SNAP; t.y &= ~TILE_SNAP;
2929  t.nx += TILE_SNAP; t.ny += TILE_SNAP;
2930  t.nx &= ~TILE_SNAP; t.ny &= ~TILE_SNAP;
2931  t.nx -= t.x; t.ny -= t.y;
2932 }
2933 
2934 
2935 //------------------------------------------------------------------------------
2936 #undef cu_int
2937 #undef u_int
2938 #undef u_short
2939 #undef u_char
2940 #undef inline
2941 
2942 //------------------------------------------------------------------------------
2943 
2944 }; // end of namespace mudbox
2945 #endif
void SetLuminance(const PixelType< uInt16Channel, 4 > &p)
RGBA = Luminance of input.
Definition: image.h:721
ImageDescriptor(int x, int y, int nx, int ny, MemoryChannelOrder order=orderRGBA, bool premult=true, char nc=4, ChannelType ct=uChar)
Constructor – make a descriptor...
Definition: image.h:1382
void SetInvLuminance(const PixelType< float16Channel, 3 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:886
Describe an image pixel; how to interpret a piece of pixel data.
Definition: image.h:1255
PixelDescriptor(char cCount, ChannelType channelType, MemoryChannelOrder channelOrder, bool PreMultiplied)
Definition: image.h:1292
virtual unsigned int Height(void) const
Return the height of the image in pixels.
ImageDescriptor()
default constructor – RGBA, premult, 4 channel uChar, size 0 x 0 pixels.
Definition: image.h:1409
unsigned int(APIENTRYP PFNGLXGETAGPOFFSETMESAPROC)(const void *pointer)
Definition: GLee.h:10762
void SetLuminance(const PixelType< uInt8Channel, 3 > &p)
RGBA = Luminance of input.
Definition: image.h:710
void setChannelCount(int c)
set the number of channels – 1, 2, 3, or 4
Definition: image.h:1336
bool contains(int x_, int y_) const
return true if this tile includes the specified point
Definition: image.h:1022
GLenum GLint GLint y
Definition: GLee.h:876
int channelCount() const
return the number of channels – 1, 2, 3, or 4
Definition: image.h:1333
Color ColorAt(u_int X, u_int Y) const
Get the value at a given coordinate.
Definition: image.h:2598
GLint mode
Definition: GLee.h:4479
IEEE754 single precision.
Definition: image.h:1262
Color ColorAt(u_int X, u_int Y) const
Get the value at a given coordinate.
uInt8Channel(const uInt8Channel &d)
Definition: image.h:107
Base class for unit test objects.
Definition: UnitTest.h:24
int int int int * dy
Definition: GLee.h:10535
#define MBDLL_TEMPLATE_DECL
Definition: dllinterface.h:44
u_int ChannelCount() const
Definition: image.h:2517
#define u_char
Definition: image.h:2488
void copyTile(int x, int y, int nx, int ny, Image &fromImg, int ox, int oy)
Copies a rectangular region of pixels from a source image to this image.
Definition: image.h:1937
GLint level
Definition: GLee.h:905
void fillTile(int x, int y, int nx, int ny, void *pixelData, const PixelDescriptor *pd=0, const ImgTile *maskTile=0)
Fills a rectangular region of pixels in the image with a constant color.
Definition: image.h:2015
bool isEqualTile(const ImgTile &t) const
Definition: image.h:1001
int nx
x size of the tile (width)
Definition: image.h:965
void SetProxyInterruptFunction(ProxyInterruptFunction fcnPtr=0)
When generating proxy images, periodically, the interrupt function will be polled.
Definition: image.h:1624
Color ColorAt(u_int X, u_int Y) const
Get the value at a given coordinate.
Definition: image.h:2559
Color ColorAt(u_int X, u_int Y) const
Get the value at a given coordinate.
Definition: image.h:2579
virtual void * Data(int iRow=-1, bool writing=true)
Get a pointer to the raw data of a row of the image.
float16Channel(const uInt8Channel &d)
Definition: image.h:247
u_int Height() const
Definition: image.h:2516
S10E5 half precision floating point.
Definition: image.h:1261
void SetInvLuminance(const PixelType< uInt8Channel, 3 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:837
void SetInvLuminance(const PixelType< uInt8Channel, 1 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:948
uInt16Channel(uInt16 d)
Definition: image.h:145
ProxyInterruptFunction m_pProxyIntFcn
Definition: image.h:1551
bool getProxyDownsampleTo8Bit() const
Definition: image.h:1616
#define u_short
Definition: image.h:2487
GLenum GLsizei width
Definition: GLee.h:873
void SetLuminance(const PixelType< uInt16Channel, 3 > &p)
RGBA = Luminance of input.
Definition: image.h:732
bool m_PreMultiplied
true if RGB is premultiplied by A
Definition: image.h:1287
ImageDescriptor m_Descriptor
Definition: image.h:1543
Format
Image channel datatype type.
Definition: image.h:1522
int ySize() const
return the y Size of the image
Definition: image.h:1424
virtual unsigned int Width(void) const
Return the width of the image in pixels.
int cSize() const
Get the channel count of the image.
Definition: image.h:1675
ImgTile(const ImgTile &a, const ImgTile &b)
Construct a tile by computing the intersection fo the two input tiles.
Definition: image.h:992
GLuint src
Definition: GLee.h:7190
float32Channel(float d)
Definition: image.h:187
Describe an image, specifically how to interpret pixel data.
Definition: image.h:1353
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
#define MAX(a_, b_)
Definition: image.h:981
GLfloat ny
Definition: GLee.h:5410
Iterate over a specified region of an image in optimal order, and locking it in CPU memory...
Definition: image.h:1225
#define u_int
Definition: image.h:2486
ImageDescriptor::MemoryChannelOrder channelOrder() const
Get the channel ordering of the image.
Definition: image.h:1684
half_(float f)
Definition: image.h:41
unsigned char m_ProxyLevel
Definition: image.h:1547
Half precision (16 bit) float class.
Definition: image.h:29
int pixelBitSize() const
return the size of a pixel in bits
Definition: image.h:1318
int numBytes() const
return the number of bytes the raw image pixels will occupy – not necessarily accurate for VirtualIm...
Definition: image.h:1415
bool isProxyDirty() const
Definition: image.h:1563
This is the base class for most classes in the Mudbox SDK.
Definition: node.h:740
float16Channel(const half_ &d)
Definition: image.h:248
float32Channel(const float32Channel &d)
Definition: image.h:183
ImageAccessor(Image *parent)
Definition: image.h:2540
Implement a somewhat smarter image region that a simple rectangle.
Definition: image.h:1080
const ImgTile & getBounds() const
returns the bounds of the image – the origin of this rect may not be at 0,0
Definition: image.h:1687
int cSize() const
return the channel count of the image
Definition: image.h:1427
The data type for a 16 bit float image channel.
Definition: image.h:239
float32Channel & operator=(const float32Channel &d)
Definition: image.h:190
int ySize() const
Get the y size of the image.
Definition: image.h:1672
bool m_bDownsampleProxyTo8Bit
Definition: image.h:1549
void getResolutionInfo(float &xRes, float &yRes, ResUnit &unit) const
return the horizontal and vertical resolution of the image
Definition: image.h:1447
int xSize() const
Get the x size of the image.
Definition: image.h:1669
void * AddrAt(u_int X, u_int Y, u_int Ch)
void SetLuminance(const PixelType< float16Channel, 3 > &p)
RGBA = Luminance of input.
Definition: image.h:755
IEEE754 double precision (not currently supported)
Definition: image.h:1268
float32Channel(const uInt8Channel &d)
Definition: image.h:186
physically contiguous image or striped
Definition: image.h:1517
bool operator==(const Attribute &cA, const AttributeInstance< type > &cB)
This operator compares the two attributes and NOT their values.
Definition: node.h:577
MBDLL_DECL AttributeWidget * CreateNewImageWidget(QWidget *pParent, int iWidth, AttributePointer< Image > *pImage)
bool contains(const ImgTile &a) const
return true if this tile includes the specified tile
Definition: image.h:1016
Represents a color with four components: red, green, blue, alpha.
Definition: math.h:674
float16Channel & operator=(const float32Channel &d)
Definition: image.h:251
ResUnit
Resolution units (mainly used so resolution is preserved in PSD & TIFF files)
Definition: image.h:1357
int y
y origin of the tile
Definition: image.h:964
void SetLuminance(const PixelType< float16Channel, 1 > &p)
RGBA = Luminance of input.
Definition: image.h:797
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: GLee.h:880
float b
Definition: math.h:783
void SetLuminance(const PixelType< uInt16Channel, 1 > &p)
RGBA = Luminance of input.
Definition: image.h:806
GLint GLvoid * img
Definition: GLee.h:1216
void getTile(const ImgTile &srcTile, void *data, const PixelDescriptor *pd=0)
Reads a rectangular region of pixels from the image into a buffer.
Definition: image.h:1784
void SetValueAt(u_int X, u_int Y, u_int Ch, float fVal)
Set value for a specified texel.
void ExpandToInclude(int x_, int y_)
Expand this tile to include the specified point.
Definition: image.h:1040
unsigned 32 bit int (not currently supported)
Definition: image.h:1266
MemoryChannelOrder
Describe channel ordering for 4 channel images – these are the order of the channels in memory...
Definition: image.h:1273
void SetInvLuminance(const PixelType< uInt8Channel, 4 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:825
bool setProxyLevel(unsigned char newLevel)
set the current proxy level
Definition: image.h:1638
GLenum GLsizei GLsizei height
Definition: GLee.h:883
void ClearDirtyRegion()
clear the dirty region – resets it completely.
Definition: image.h:1121
float32Channel(const uInt16Channel &d)
Definition: image.h:185
void setSubTile(int x, int y, int nx, int ny, const void *data, int dx, int dy, int dnx, int dny, const PixelDescriptor *pd=0)
Writes a rectangular region of pixels from the image into a buffer.
Definition: image.h:1864
int channelBitSize() const
return the size of a pixel channel in bits
Definition: image.h:1308
Definition: qimage.h:87
#define DIRTY_REGION_XY_SIZE
Definition: image.h:1071
PixelType< ChanType, NumChans > & swapRB()
Swap the red and blue channels – converts RGBA to BGRA and back.
Definition: image.h:395
static void SnapOutTile(ImgTile &t)
Snaps a tile out to 128 pixel aligned boundaries.
Definition: image.h:2924
void SetInvLuminance(const PixelType< uInt16Channel, 3 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:861
unsigned char uInt8
Definition: image.h:87
signed 32 bit int (not currently supported)
Definition: image.h:1267
bool premultiplied() const
returns true if the RGB values are premultiplied by the A values, false otherwise.
Definition: image.h:1330
float g
Definition: math.h:783
float ValueAt(u_int X, u_int Y, u_int Ch) const
Get the value at a given coordinate.
bool isEmpty() const
return true if the region is empty
Definition: image.h:1150
GLenum GLint x
Definition: GLee.h:876
char m_cCount
number of channels in the image – 1, 3, or 4
Definition: image.h:1284
Iterates over a specified region of an image in optimal order.
Definition: image.h:1198
void SetInvLuminance(const PixelType< float32Channel, 4 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:898
Reverse of RGB for 3 channel images.
Definition: image.h:1280
void setProxyDownsampleTo8Bit(bool downsampleTo8Bit=true)
The default when generating proxys is to downsample them to 8 bit/channel this can make them signific...
Definition: image.h:1608
Image * getProxyImage()
get the proxy image.
Definition: image.h:1654
void setTile(const ImgTile &dstTile, const void *data, const PixelDescriptor *pd=0)
Writes a rectangular region of pixels to the image from a buffer.
Definition: image.h:1885
int x
x origin of the tile
Definition: image.h:963
ChannelType m_channelType
Channel type.
Definition: image.h:1285
#define MIN(a_, b_)
Definition: image.h:984
int curWidth() const
get the width of the current proxy level of the image
Definition: image.h:1678
ImgTile GetTotalBounds() const
return the total bounds of the dirty region as one rectangle.
Definition: image.h:1144
The ImageAccessorBase class gives you very fast access to pixels when the data type and channel count...
Definition: image.h:2496
void SetLuminance(const PixelType< uInt8Channel, 4 > &p)
RGBA = Luminance of input.
Definition: image.h:699
void getSubTile(int x, int y, int nx, int ny, void *data, int dx, int dy, int dnx, int dny, const PixelDescriptor *pd=0)
Reads a rectangular region of pixels from the image into a buffer.
Definition: image.h:1762
GLfloat GLfloat GLfloat GLfloat nx
Definition: GLee.h:5412
The data type for a 16 bit image channel. 0-65535 maps to 0.0 to 1.0.
Definition: image.h:136
ResUnit m_ResolutionUnits
units – 1 == inch, 2 == centimeter (same as in PSD files)
Definition: image.h:1366
const ImgTile & getBounds() const
return the bounds of the image
Definition: image.h:1439
bool operator!=(const QByteArray &a1, const QByteArray &a2)
Definition: qbytearray.h:533
#define MAX_PROXY_LEVEL
Definition: image.h:1476
virtual unsigned int ChannelCount(void) const
Return the number of channels in the image.
uInt16Channel(const uInt8Channel &d)
Definition: image.h:144
void Expand(int numPixels=1)
Grow the tile by the specified number of pixels on all 4 sides.
Definition: image.h:1054
GLubyte GLubyte b
Definition: GLee.h:5404
A promise that the data in this page will not be modified.
Definition: image.h:1228
u_int Width() const
Definition: image.h:2515
float m_xResolution
horizontal resolution in pixels per unit
Definition: image.h:1364
int numTiles()
get the number of tiles in the region
Definition: image.h:1131
void setSize(int nx, int ny)
Set the size of the image in pixels.
Definition: image.h:1436
The data type for a 8 bit image channel.
Definition: image.h:99
unsigned int curTotalBytes(void) const
Return the number of bytes used by the whole image (current proxy level)
Definition: image.h:2310
GLfloat GLfloat p
Definition: GLee.h:5416
ChannelType channelType() const
Get the channel type of the image/pixel.
Definition: image.h:1323
ImgTile()
Create a default empty tile.
Definition: image.h:969
ImgLockPageIterator * lockPageSet(int x, int y, int nx, int ny, ImgLockPageIterator::AccessMode mode)
Returns a tile iterator that will iterate over the pages of this image in an optimal order...
Definition: image.h:2123
GLuint buffer
Definition: GLee.h:1557
const GLubyte * c
Definition: GLee.h:5419
float16Channel(const uInt16Channel &d)
Definition: image.h:246
unsigned short uInt16
Definition: image.h:88
void SetInvLuminance(const PixelType< uInt16Channel, 1 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:939
MemoryChannelOrder channelOrder() const
Get the channel ordering of the image/pixel.
Definition: image.h:1326
ImageDescriptor(int nx, int ny, MemoryChannelOrder order=orderRGBA, bool premult=true, char nc=4, ChannelType ct=uChar)
Constructor – make a descriptor...
Definition: image.h:1401
Class: ConvolutionKernel.
Definition: array.h:15
void SetInvLuminance(const PixelType< float32Channel, 3 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:910
bool(* ProxyInterruptFunction)(void)
Proxy generation is interruptible.
Definition: image.h:1474
MemoryChannelOrder m_channelOrder
channel ordering
Definition: image.h:1286
ImgPageIterator * getPageIterator(int x, int y, int nx, int ny)
Returns a tile iterator that will iterate over the pages of this image in an optimal order...
Definition: image.h:2092
ImgTile(int X, int Y, int NX, int NY)
Create a tile as specified in the parameters.
Definition: image.h:978
void getTile(int x, int y, int nx, int ny, void *data, const PixelDescriptor *pd=0)
Reads a rectangular region of pixels from the image into a buffer.
Definition: image.h:1733
float m_yResolution
vertical resolution in pixels per unit
Definition: image.h:1365
GLubyte GLubyte GLubyte a
Definition: GLee.h:5404
int int int * dx
Definition: GLee.h:10535
void SetLuminance(const PixelType< float32Channel, 4 > &p)
RGBA = Luminance of input.
Definition: image.h:766
uInt8Channel(uInt8 d)
Definition: image.h:109
uInt16Channel(const uInt16Channel &d)
Definition: image.h:143
ChannelType
Describe the data type of a single channel of a pixel.
Definition: image.h:1258
int numPixels() const
return the number of pixels contained in this tile
Definition: image.h:1062
ImgTile m_Bounds
Bounds of the image – some images may not have a 0,0 origin.
Definition: image.h:1362
#define ExponentBiasDelta
Definition: image.h:62
Describes a material of a geometry including its surface colors, transparency and texture information...
Definition: material.h:73
Represents a rectangle. Used to specify rectangular regions of an image.
Definition: image.h:960
void setTile(int x, int y, int nx, int ny, void *data, const PixelDescriptor *pd=0)
Writes a rectangular region of pixels to the image from a buffer.
Definition: image.h:1833
void clearProxyImages()
clear and deallocate any proxy images.
Definition: image.h:1619
bool Versioned() const
returns true if this is a tiled and versioned image
Definition: image.h:2358
GLuint dst
Definition: GLee.h:6952
unsigned int curBytesPerPixel() const
Return the number of bytes used by a pixel at the current proxy level.
Definition: image.h:2304
void SetLuminance(const PixelType< float32Channel, 1 > &p)
RGBA = Luminance of input.
Definition: image.h:788
#define DECLARE_CLASS
This macro should be used in declaration of classes which are inherited from the Node class (or any d...
Definition: node.h:91
ImgTile Tile(int i)
return the i'th tile in the region (no bounds checking performed)
Definition: image.h:1138
RGB – for 3 channel images.
Definition: image.h:1279
void clipPositive()
Clip the tile so it will not extend into the negative quadrants.
Definition: image.h:1027
virtual void copyAll(Image &fromImg)
Copies all of the pixels from a source image to this image.
Definition: image.h:1981
void SetInvLuminance(const PixelType< float32Channel, 1 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:921
const ImageDescriptor & getDescriptor() const
get the full descriptor for the image
Definition: image.h:1601
int curHeight() const
get the height of the current proxy level of the image
Definition: image.h:1681
int xSize() const
return the x Size of the image
Definition: image.h:1421
float a
Definition: math.h:783
void SetLuminance(const PixelType< uInt8Channel, 1 > &p)
RGBA = Luminance of input.
Definition: image.h:815
ImgTile_AoutB_Iter(const ImgTile &A, const ImgTile &B)
Definition: image.h:1172
void setEmpty()
Definition: image.h:1013
uInt16Channel & operator=(const float32Channel &d)
Definition: image.h:331
void SetInvLuminance(const PixelType< float16Channel, 4 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:874
GLdouble GLdouble t
Definition: GLee.h:1181
bool isEmpty() const
return true of this tile is empty
Definition: image.h:1011
int ny
y size of the tile (height)
Definition: image.h:966
float16Channel(const float16Channel &d)
Definition: image.h:245
void SetColorAt(u_int X, u_int Y, const Color &cColor)
Set value for a specified texel.
unsigned 16 bit short.
Definition: image.h:1260
Optimal ordering on windows & Mac.
Definition: image.h:1277
float r
Definition: math.h:783
This is the base image type defining the interface to images.
Definition: image.h:1504
GLclampf f
Definition: GLee.h:9303
bool operator==(const PixelDescriptor &pd) const
returns true if the pixel descriptors are equal
Definition: image.h:1339
ImageType
used to identify what type of image any particular instance is.
Definition: image.h:1515
int channelSize() const
return the size of a pixel channel in bytes
Definition: image.h:1302
unsigned char getProxyLevel() const
get the Proxy level of the image – 0 = no proxying.
Definition: image.h:1635
A templated pixel type class, where the channel type and number of channels are arguments.
Definition: image.h:366
int pixelSize() const
return the size of a pixel in bytes
Definition: image.h:1313
This is invalid for 4 channel images – used for 1 channel.
Definition: image.h:1274
#define MBDLL_DECL
Definition: dllinterface.h:35
bool sizeEqual(const ImageDescriptor &o) const
return true if the x and y dimensions are equal
Definition: image.h:1432
void SetInvLuminance(const PixelType< float16Channel, 1 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:930
void SetLuminance(const PixelType< float32Channel, 3 > &p)
RGBA = Luminance of input.
Definition: image.h:777
signed 16 bit short (not currently supported)
Definition: image.h:1265
signed 8 bit char (not currently supported)
Definition: image.h:1264
ImageAccessorBase(Image *parent)
Definition: image.h:2506
Iterates over a the region of tile A that is outside tile B.
Definition: image.h:1164
ImageType m_ImageType
Definition: image.h:1545
float16Channel(const float32Channel &d)
Definition: image.h:244
uInt8Channel & operator=(const float32Channel &d)
Definition: image.h:305
ImageType getType() const
return the image type.
Definition: image.h:1598
void SetLuminance(const PixelType< float16Channel, 4 > &p)
RGBA = Luminance of input.
Definition: image.h:744
int strideBytes() const
return the number of bytes wide that the image is
Definition: image.h:1418
void setResolutionInfo(float xRes, float yRes, ResUnit unit)
set the horizontal and vertical resolution of the image
Definition: image.h:1458
void SetInvLuminance(const PixelType< uInt16Channel, 4 > &p)
RGBA = 1 - Luminance of input.
Definition: image.h:849
unsigned 8 bit char
Definition: image.h:1259
void markProxyDirty()
Definition: image.h:1553