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