1/*****************************************************************************/
2// Copyright 2006-2008 Adobe Systems Incorporated
3// All Rights Reserved.
4//
5// NOTICE: Adobe permits you to use, modify, and distribute this file in
6// accordance with the terms of the Adobe license agreement accompanying it.
7/*****************************************************************************/
8
9/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_pixel_buffer.h#1 $ */
10/* $DateTime: 2012/05/30 13:28:51 $ */
11/* $Change: 832332 $ */
12/* $Author: tknoll $ */
13
14/** \file
15 * Support for holding buffers of sample data.
16 */
17
18/*****************************************************************************/
19
20#ifndef __dng_pixel_buffer__
21#define __dng_pixel_buffer__
22
23/*****************************************************************************/
24
25#include "dng_assertions.h"
26#include "dng_rect.h"
27#include "dng_safe_arithmetic.h"
28#include "dng_tag_types.h"
29
30/*****************************************************************************/
31
32/// Compute best set of step values for a given source and destination area and stride.
33
34void OptimizeOrder (const void *&sPtr,
35 void *&dPtr,
36 uint32 sPixelSize,
37 uint32 dPixelSize,
38 uint32 &count0,
39 uint32 &count1,
40 uint32 &count2,
41 int32 &sStep0,
42 int32 &sStep1,
43 int32 &sStep2,
44 int32 &dStep0,
45 int32 &dStep1,
46 int32 &dStep2);
47
48void OptimizeOrder (const void *&sPtr,
49 uint32 sPixelSize,
50 uint32 &count0,
51 uint32 &count1,
52 uint32 &count2,
53 int32 &sStep0,
54 int32 &sStep1,
55 int32 &sStep2);
56
57void OptimizeOrder (void *&dPtr,
58 uint32 dPixelSize,
59 uint32 &count0,
60 uint32 &count1,
61 uint32 &count2,
62 int32 &dStep0,
63 int32 &dStep1,
64 int32 &dStep2);
65
66/*****************************************************************************/
67
68#define qDebugPixelType 0
69
70#if qDebugPixelType
71
72#define ASSERT_PIXEL_TYPE(typeVal) CheckPixelType (typeVal)
73
74#else
75
76#define ASSERT_PIXEL_TYPE(typeVal) DNG_ASSERT (fPixelType == typeVal, "Pixel type access mismatch")
77
78#endif
79
80/*****************************************************************************/
81
82/// \brief Holds a buffer of pixel data with "pixel geometry" metadata.
83///
84/// The pixel geometry describes the layout in terms of how many planes, rows and columns
85/// plus the steps (in bytes) between each column, row and plane.
86
87class dng_pixel_buffer
88 {
89
90 public:
91
92 // Area this buffer holds.
93
94 dng_rect fArea;
95
96 // Range of planes this buffer holds.
97
98 uint32 fPlane;
99 uint32 fPlanes;
100
101 // Steps between pixels.
102
103 int32 fRowStep;
104 int32 fColStep;
105 int32 fPlaneStep;
106
107 // Basic pixel type (TIFF tag type code).
108
109 uint32 fPixelType;
110
111 // Size of pixel type in bytes.
112
113 uint32 fPixelSize;
114
115 // Pointer to buffer's data.
116
117 void *fData;
118
119 // Do we have write-access to this data?
120
121 bool fDirty;
122
123 private:
124
125 void * InternalPixel (int32 row,
126 int32 col,
127 uint32 plane = 0) const
128 {
129
130 // Ensure pixel to be accessed lies inside valid area.
131 if (row < fArea.t || row >= fArea.b ||
132 col < fArea.l || col >= fArea.r ||
133 plane < fPlane || (plane - fPlane) >= fPlanes)
134 {
135 ThrowProgramError ("Out-of-range pixel access");
136 }
137
138 // Compute offset of pixel.
139 const int64 rowOffset = SafeInt64Mult(fRowStep,
140 static_cast<int64> (row) - static_cast<int64> (fArea.t));
141 const int64 colOffset = SafeInt64Mult(fColStep,
142 static_cast<int64> (col) - static_cast<int64> (fArea.l));
143 const int64 planeOffset = SafeInt64Mult(fPlaneStep,
144 static_cast<int64> (plane - fPlane));
145 const int64 offset = SafeInt64Mult(static_cast<int64>(fPixelSize),
146 SafeInt64Add(SafeInt64Add(rowOffset, colOffset), planeOffset));
147
148 // Add offset to buffer base address.
149 return static_cast<void *> (static_cast<uint8 *> (fData) + offset);
150
151 }
152
153 #if qDebugPixelType
154
155 void CheckPixelType (uint32 pixelType) const;
156
157 #endif
158
159 public:
160
161 dng_pixel_buffer ();
162
163 /// Note: This constructor is for internal use only and should not be
164 /// considered part of the DNG SDK API.
165 ///
166 /// Initialize the pixel buffer according to the given parameters (see
167 /// below). May throw an error if arithmetic overflow occurs when
168 /// computing the row, column or plane step, or if an invalid value was
169 /// passed for planarConfiguration.
170 ///
171 /// \param size Area covered by the pixel buffer
172 /// \param plane Index of the first plane
173 /// \param planes Number of planes
174 /// \param pixelType Pixel data type (one of the values defined in
175 /// dng_tag_types.h)
176 /// \param planarConfiguration Layout of the pixel planes in memory: One
177 /// of pcInterleaved, pcPlanar, or pcRowInterleaved (defined in
178 /// dng_tag_values.h)
179 /// \param data Pointer to the pixel data
180 dng_pixel_buffer (const dng_rect &area, uint32 plane, uint32 planes,
181 uint32 pixelType, uint32 planarConfiguration,
182 void *data);
183
184 dng_pixel_buffer (const dng_pixel_buffer &buffer);
185
186 dng_pixel_buffer & operator= (const dng_pixel_buffer &buffer);
187
188 virtual ~dng_pixel_buffer ();
189
190 /// Get the range of pixel values.
191 /// \retval Range of value a pixel can take. (Meaning [0, max] for unsigned case. Signed case is biased so [-32768, max - 32768].)
192
193 uint32 PixelRange () const;
194
195 /// Get extent of pixels in buffer
196 /// \retval Rectangle giving valid extent of buffer.
197
198 const dng_rect & Area () const
199 {
200 return fArea;
201 }
202
203 /// Number of planes of image data.
204 /// \retval Number of planes held in buffer.
205
206 uint32 Planes () const
207 {
208 return fPlanes;
209 }
210
211 /// Step, in pixels not bytes, between rows of data in buffer.
212 /// \retval row step in pixels. May be negative.
213
214 int32 RowStep () const
215 {
216 return fRowStep;
217 }
218
219 /// Step, in pixels not bytes, between planes of data in buffer.
220 /// \retval plane step in pixels. May be negative.
221
222 int32 PlaneStep () const
223 {
224 return fPlaneStep;
225 }
226
227 /// Get read-only untyped (void *) pointer to pixel data starting at a specific pixel in the buffer.
228 /// \param row Start row for buffer pointer.
229 /// \param col Start column for buffer pointer.
230 /// \param plane Start plane for buffer pointer.
231 /// \retval Pointer to pixel data as void *.
232
233 const void * ConstPixel (int32 row,
234 int32 col,
235 uint32 plane = 0) const
236 {
237
238 return InternalPixel (row, col, plane);
239
240 }
241
242 /// Get a writable untyped (void *) pointer to pixel data starting at a specific pixel in the buffer.
243 /// \param row Start row for buffer pointer.
244 /// \param col Start column for buffer pointer.
245 /// \param plane Start plane for buffer pointer.
246 /// \retval Pointer to pixel data as void *.
247
248 void * DirtyPixel (int32 row,
249 int32 col,
250 uint32 plane = 0)
251 {
252
253 DNG_ASSERT (fDirty, "Dirty access to const pixel buffer");
254
255 return InternalPixel (row, col, plane);
256
257 }
258
259 /// Get read-only uint8 * to pixel data starting at a specific pixel in the buffer.
260 /// \param row Start row for buffer pointer.
261 /// \param col Start column for buffer pointer.
262 /// \param plane Start plane for buffer pointer.
263 /// \retval Pointer to pixel data as uint8 *.
264
265 const uint8 * ConstPixel_uint8 (int32 row,
266 int32 col,
267 uint32 plane = 0) const
268 {
269
270 ASSERT_PIXEL_TYPE (ttByte);
271
272 return (const uint8 *) ConstPixel (row, col, plane);
273
274 }
275
276 /// Get a writable uint8 * to pixel data starting at a specific pixel in the buffer.
277 /// \param row Start row for buffer pointer.
278 /// \param col Start column for buffer pointer.
279 /// \param plane Start plane for buffer pointer.
280 /// \retval Pointer to pixel data as uint8 *.
281
282 uint8 * DirtyPixel_uint8 (int32 row,
283 int32 col,
284 uint32 plane = 0)
285 {
286
287 ASSERT_PIXEL_TYPE (ttByte);
288
289 return (uint8 *) DirtyPixel (row, col, plane);
290
291 }
292
293 /// Get read-only int8 * to pixel data starting at a specific pixel in the buffer.
294 /// \param row Start row for buffer pointer.
295 /// \param col Start column for buffer pointer.
296 /// \param plane Start plane for buffer pointer.
297 /// \retval Pointer to pixel data as int8 *.
298
299 const int8 * ConstPixel_int8 (int32 row,
300 int32 col,
301 uint32 plane = 0) const
302 {
303
304 ASSERT_PIXEL_TYPE (ttSByte);
305
306 return (const int8 *) ConstPixel (row, col, plane);
307
308 }
309
310 /// Get a writable int8 * to pixel data starting at a specific pixel in the buffer.
311 /// \param row Start row for buffer pointer.
312 /// \param col Start column for buffer pointer.
313 /// \param plane Start plane for buffer pointer.
314 /// \retval Pointer to pixel data as int8 *.
315
316 int8 * DirtyPixel_int8 (int32 row,
317 int32 col,
318 uint32 plane = 0)
319 {
320
321 ASSERT_PIXEL_TYPE (ttSByte);
322
323 return (int8 *) DirtyPixel (row, col, plane);
324
325 }
326
327 /// Get read-only uint16 * to pixel data starting at a specific pixel in the buffer.
328 /// \param row Start row for buffer pointer.
329 /// \param col Start column for buffer pointer.
330 /// \param plane Start plane for buffer pointer.
331 /// \retval Pointer to pixel data as uint16 *.
332
333 const uint16 * ConstPixel_uint16 (int32 row,
334 int32 col,
335 uint32 plane = 0) const
336 {
337
338 ASSERT_PIXEL_TYPE (ttShort);
339
340 return (const uint16 *) ConstPixel (row, col, plane);
341
342 }
343
344 /// Get a writable uint16 * to pixel data starting at a specific pixel in the buffer.
345 /// \param row Start row for buffer pointer.
346 /// \param col Start column for buffer pointer.
347 /// \param plane Start plane for buffer pointer.
348 /// \retval Pointer to pixel data as uint16 *.
349
350 uint16 * DirtyPixel_uint16 (int32 row,
351 int32 col,
352 uint32 plane = 0)
353 {
354
355 ASSERT_PIXEL_TYPE (ttShort);
356
357 return (uint16 *) DirtyPixel (row, col, plane);
358
359 }
360
361 /// Get read-only int16 * to pixel data starting at a specific pixel in the buffer.
362 /// \param row Start row for buffer pointer.
363 /// \param col Start column for buffer pointer.
364 /// \param plane Start plane for buffer pointer.
365 /// \retval Pointer to pixel data as int16 *.
366
367 const int16 * ConstPixel_int16 (int32 row,
368 int32 col,
369 uint32 plane = 0) const
370 {
371
372 ASSERT_PIXEL_TYPE (ttSShort);
373
374 return (const int16 *) ConstPixel (row, col, plane);
375
376 }
377
378 /// Get a writable int16 * to pixel data starting at a specific pixel in the buffer.
379 /// \param row Start row for buffer pointer.
380 /// \param col Start column for buffer pointer.
381 /// \param plane Start plane for buffer pointer.
382 /// \retval Pointer to pixel data as int16 *.
383
384 int16 * DirtyPixel_int16 (int32 row,
385 int32 col,
386 uint32 plane = 0)
387 {
388
389 ASSERT_PIXEL_TYPE (ttSShort);
390
391 return (int16 *) DirtyPixel (row, col, plane);
392
393 }
394
395 /// Get read-only uint32 * to pixel data starting at a specific pixel in the buffer.
396 /// \param row Start row for buffer pointer.
397 /// \param col Start column for buffer pointer.
398 /// \param plane Start plane for buffer pointer.
399 /// \retval Pointer to pixel data as uint32 *.
400
401 const uint32 * ConstPixel_uint32 (int32 row,
402 int32 col,
403 uint32 plane = 0) const
404 {
405
406 ASSERT_PIXEL_TYPE (ttLong);
407
408 return (const uint32 *) ConstPixel (row, col, plane);
409
410 }
411
412 /// Get a writable uint32 * to pixel data starting at a specific pixel in the buffer.
413 /// \param row Start row for buffer pointer.
414 /// \param col Start column for buffer pointer.
415 /// \param plane Start plane for buffer pointer.
416 /// \retval Pointer to pixel data as uint32 *.
417
418 uint32 * DirtyPixel_uint32 (int32 row,
419 int32 col,
420 uint32 plane = 0)
421 {
422
423 ASSERT_PIXEL_TYPE (ttLong);
424
425 return (uint32 *) DirtyPixel (row, col, plane);
426
427 }
428
429 /// Get read-only int32 * to pixel data starting at a specific pixel in the buffer.
430 /// \param row Start row for buffer pointer.
431 /// \param col Start column for buffer pointer.
432 /// \param plane Start plane for buffer pointer.
433 /// \retval Pointer to pixel data as int32 *.
434
435 const int32 * ConstPixel_int32 (int32 row,
436 int32 col,
437 uint32 plane = 0) const
438 {
439
440 ASSERT_PIXEL_TYPE (ttSLong);
441
442 return (const int32 *) ConstPixel (row, col, plane);
443
444 }
445
446 /// Get a writable int32 * to pixel data starting at a specific pixel in the buffer.
447 /// \param row Start row for buffer pointer.
448 /// \param col Start column for buffer pointer.
449 /// \param plane Start plane for buffer pointer.
450 /// \retval Pointer to pixel data as int32 *.
451
452 int32 * DirtyPixel_int32 (int32 row,
453 int32 col,
454 uint32 plane = 0)
455 {
456
457 ASSERT_PIXEL_TYPE (ttSLong);
458
459 return (int32 *) DirtyPixel (row, col, plane);
460
461 }
462
463 /// Get read-only real32 * to pixel data starting at a specific pixel in the buffer.
464 /// \param row Start row for buffer pointer.
465 /// \param col Start column for buffer pointer.
466 /// \param plane Start plane for buffer pointer.
467 /// \retval Pointer to pixel data as real32 *.
468
469 const real32 * ConstPixel_real32 (int32 row,
470 int32 col,
471 uint32 plane = 0) const
472 {
473
474 ASSERT_PIXEL_TYPE (ttFloat);
475
476 return (const real32 *) ConstPixel (row, col, plane);
477
478 }
479
480 /// Get a writable real32 * to pixel data starting at a specific pixel in the buffer.
481 /// \param row Start row for buffer pointer.
482 /// \param col Start column for buffer pointer.
483 /// \param plane Start plane for buffer pointer.
484 /// \retval Pointer to pixel data as real32 *.
485
486 real32 * DirtyPixel_real32 (int32 row,
487 int32 col,
488 uint32 plane = 0)
489 {
490
491 ASSERT_PIXEL_TYPE (ttFloat);
492
493 return (real32 *) DirtyPixel (row, col, plane);
494
495 }
496
497 /// Initialize a rectangular area of pixel buffer to a constant.
498 /// \param area Rectangle of pixel buffer to set.
499 /// \param plane Plane to start filling on.
500 /// \param planes Number of planes to fill.
501 /// \param value Constant value to set pixels to.
502
503 void SetConstant (const dng_rect &area,
504 uint32 plane,
505 uint32 planes,
506 uint32 value);
507
508 /// Initialize a rectangular area of pixel buffer to a constant unsigned 8-bit value.
509 /// \param area Rectangle of pixel buffer to set.
510 /// \param plane Plane to start filling on.
511 /// \param planes Number of planes to fill.
512 /// \param value Constant uint8 value to set pixels to.
513
514 void SetConstant_uint8 (const dng_rect &area,
515 uint32 plane,
516 uint32 planes,
517 uint8 value)
518 {
519
520 DNG_ASSERT (fPixelType == ttByte, "Mismatched pixel type");
521
522 SetConstant (area, plane, planes, (uint32) value);
523
524 }
525
526 /// Initialize a rectangular area of pixel buffer to a constant unsigned 16-bit value.
527 /// \param area Rectangle of pixel buffer to set.
528 /// \param plane Plane to start filling on.
529 /// \param planes Number of planes to fill.
530 /// \param value Constant uint16 value to set pixels to.
531
532 void SetConstant_uint16 (const dng_rect &area,
533 uint32 plane,
534 uint32 planes,
535 uint16 value)
536 {
537
538 DNG_ASSERT (fPixelType == ttShort, "Mismatched pixel type");
539
540 SetConstant (area, plane, planes, (uint32) value);
541
542 }
543
544 /// Initialize a rectangular area of pixel buffer to a constant signed 16-bit value.
545 /// \param area Rectangle of pixel buffer to set.
546 /// \param plane Plane to start filling on.
547 /// \param planes Number of planes to fill.
548 /// \param value Constant int16 value to set pixels to.
549
550 void SetConstant_int16 (const dng_rect &area,
551 uint32 plane,
552 uint32 planes,
553 int16 value)
554 {
555
556 DNG_ASSERT (fPixelType == ttSShort, "Mismatched pixel type");
557
558 SetConstant (area, plane, planes, (uint32) (uint16) value);
559
560 }
561
562 /// Initialize a rectangular area of pixel buffer to a constant unsigned 32-bit value.
563 /// \param area Rectangle of pixel buffer to set.
564 /// \param plane Plane to start filling on.
565 /// \param planes Number of planes to fill.
566 /// \param value Constant uint32 value to set pixels to.
567
568 void SetConstant_uint32 (const dng_rect &area,
569 uint32 plane,
570 uint32 planes,
571 uint32 value)
572 {
573
574 DNG_ASSERT (fPixelType == ttLong, "Mismatched pixel type");
575
576 SetConstant (area, plane, planes, value);
577
578 }
579
580 /// Initialize a rectangular area of pixel buffer to a constant real 32-bit value.
581 /// \param area Rectangle of pixel buffer to set.
582 /// \param plane Plane to start filling on.
583 /// \param planes Number of planes to fill.
584 /// \param value Constant real32 value to set pixels to.
585
586 void SetConstant_real32 (const dng_rect &area,
587 uint32 plane,
588 uint32 planes,
589 real32 value)
590 {
591
592 DNG_ASSERT (fPixelType == ttFloat, "Mismatched pixel type");
593
594 union
595 {
596 uint32 i;
597 real32 f;
598 } x;
599
600 x.f = value;
601
602 SetConstant (area, plane, planes, x.i);
603
604 }
605
606 /// Initialize a rectangular area of pixel buffer to zeros.
607 /// \param area Rectangle of pixel buffer to zero.
608 /// \param area Area to zero
609 /// \param plane Plane to start filling on.
610 /// \param planes Number of planes to fill.
611
612 void SetZero (const dng_rect &area,
613 uint32 plane,
614 uint32 planes);
615
616 /// Copy image data from an area of one pixel buffer to same area of another.
617 /// \param src Buffer to copy from.
618 /// \param area Rectangle of pixel buffer to copy.
619 /// \param srcPlane Plane to start copy in src.
620 /// \param dstPlane Plane to start copy in dst.
621 /// \param planes Number of planes to copy.
622
623 void CopyArea (const dng_pixel_buffer &src,
624 const dng_rect &area,
625 uint32 srcPlane,
626 uint32 dstPlane,
627 uint32 planes);
628
629 /// Copy image data from an area of one pixel buffer to same area of another.
630 /// \param src Buffer to copy from.
631 /// \param area Rectangle of pixel buffer to copy.
632 /// \param plane Plane to start copy in src and this.
633 /// \param planes Number of planes to copy.
634
635 void CopyArea (const dng_pixel_buffer &src,
636 const dng_rect &area,
637 uint32 plane,
638 uint32 planes)
639 {
640
641 CopyArea (src, area, plane, plane, planes);
642
643 }
644
645 /// Calculate the offset phase of destination rectangle relative to source rectangle.
646 /// Phase is based on a 0,0 origin and the notion of repeating srcArea across dstArea.
647 /// It is the number of pixels into srcArea to start repeating from when tiling dstArea.
648 /// \retval dng_point containing horizontal and vertical phase.
649
650 static dng_point RepeatPhase (const dng_rect &srcArea,
651 const dng_rect &dstArea);
652
653 /// Repeat the image data in srcArea across dstArea.
654 /// (Generally used for padding operations.)
655 /// \param srcArea Area to repeat from.
656 /// \param dstArea Area to fill with data from srcArea.
657
658 void RepeatArea (const dng_rect &srcArea,
659 const dng_rect &dstArea);
660
661 /// Replicates a sub-area of a buffer to fill the entire buffer.
662
663 void RepeatSubArea (const dng_rect subArea,
664 uint32 repeatV = 1,
665 uint32 repeatH = 1);
666
667 /// Apply a right shift (C++ oerpator >>) to all pixel values. Only implemented for 16-bit (signed or unsigned) pixel buffers.
668 /// \param shift Number of bits by which to right shift each pixel value.
669
670 void ShiftRight (uint32 shift);
671
672 /// Change metadata so pixels are iterated in opposite horizontal order.
673 /// This operation does not require movement of actual pixel data.
674
675 void FlipH ();
676
677 /// Change metadata so pixels are iterated in opposite vertical order.
678 /// This operation does not require movement of actual pixel data.
679
680 void FlipV ();
681
682 /// Change metadata so pixels are iterated in opposite plane order.
683 /// This operation does not require movement of actual pixel data.
684
685 void FlipZ (); // Flip planes
686
687 /// Return true if the contents of an area of the pixel buffer area are the same as those of another.
688 /// \param rhs Buffer to compare against.
689 /// \param area Rectangle of pixel buffer to test.
690 /// \param plane Plane to start comparing.
691 /// \param planes Number of planes to compare.
692 /// \retval bool true if areas are equal, false otherwise.
693
694 bool EqualArea (const dng_pixel_buffer &rhs,
695 const dng_rect &area,
696 uint32 plane,
697 uint32 planes) const;
698
699 /// Return the absolute value of the maximum difference between two pixel buffers. Used for comparison testing with tolerance
700 /// \param rhs Buffer to compare against.
701 /// \param area Rectangle of pixel buffer to test.
702 /// \param plane Plane to start comparing.
703 /// \param planes Number of planes to compare.
704 /// \retval larges absolute value difference between the corresponding pixels each buffer across area.
705
706 real64 MaximumDifference (const dng_pixel_buffer &rhs,
707 const dng_rect &area,
708 uint32 plane,
709 uint32 planes) const;
710
711 };
712
713/*****************************************************************************/
714
715#endif
716
717/*****************************************************************************/
718