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