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 34 void 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 48 void 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 57 void 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 87 class 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 Area()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 Planes()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 RowStep()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 PlaneStep()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 SetConstant_uint8(const dng_rect & area,uint32 plane,uint32 planes,uint8 value)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 SetConstant_uint16(const dng_rect & area,uint32 plane,uint32 planes,uint16 value)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 SetConstant_int16(const dng_rect & area,uint32 plane,uint32 planes,int16 value)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 SetConstant_uint32(const dng_rect & area,uint32 plane,uint32 planes,uint32 value)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 SetConstant_real32(const dng_rect & area,uint32 plane,uint32 planes,real32 value)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 CopyArea(const dng_pixel_buffer & src,const dng_rect & area,uint32 plane,uint32 planes)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