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.cpp#1 $ */ 10/* $DateTime: 2012/05/30 13:28:51 $ */ 11/* $Change: 832332 $ */ 12/* $Author: tknoll $ */ 13 14/*****************************************************************************/ 15 16#include "dng_pixel_buffer.h" 17 18#include "dng_bottlenecks.h" 19#include "dng_exceptions.h" 20#include "dng_flags.h" 21#include "dng_safe_arithmetic.h" 22#include "dng_tag_types.h" 23#include "dng_tag_values.h" 24#include "dng_utils.h" 25 26/*****************************************************************************/ 27 28namespace { 29 30bool SafeUint32ToInt32Mult(uint32 arg1, uint32 arg2, int32 *result) { 31 uint32 uint32_result; 32 return SafeUint32Mult(arg1, arg2, &uint32_result) && 33 ConvertUint32ToInt32(uint32_result, result); 34} 35 36} // namespace 37 38/*****************************************************************************/ 39 40void OptimizeOrder (const void *&sPtr, 41 void *&dPtr, 42 uint32 sPixelSize, 43 uint32 dPixelSize, 44 uint32 &count0, 45 uint32 &count1, 46 uint32 &count2, 47 int32 &sStep0, 48 int32 &sStep1, 49 int32 &sStep2, 50 int32 &dStep0, 51 int32 &dStep1, 52 int32 &dStep2) 53 { 54 55 uint32 step0; 56 uint32 step1; 57 uint32 step2; 58 59 // Optimize the order for the data that is most spread out. 60 61 uint32 sRange = Abs_int32 (sStep0) * (count0 - 1) + 62 Abs_int32 (sStep1) * (count1 - 1) + 63 Abs_int32 (sStep2) * (count2 - 1); 64 65 uint32 dRange = Abs_int32 (dStep0) * (count0 - 1) + 66 Abs_int32 (dStep1) * (count1 - 1) + 67 Abs_int32 (dStep2) * (count2 - 1); 68 69 if (dRange >= sRange) 70 { 71 72 if (dStep0 < 0) 73 { 74 75 sPtr = (const void *) 76 (((const uint8 *) sPtr) + (int32)(count0 - 1) * sStep0 * (int32)sPixelSize); 77 78 dPtr = (void *) 79 (((uint8 *) dPtr) + (int32)(count0 - 1) * dStep0 * (int32)dPixelSize); 80 81 sStep0 = -sStep0; 82 dStep0 = -dStep0; 83 84 } 85 86 if (dStep1 < 0) 87 { 88 89 sPtr = (const void *) 90 (((const uint8 *) sPtr) + (int32)(count1 - 1) * sStep1 * (int32)sPixelSize); 91 92 dPtr = (void *) 93 (((uint8 *) dPtr) + (int32)(count1 - 1) * dStep1 * (int32)dPixelSize); 94 95 sStep1 = -sStep1; 96 dStep1 = -dStep1; 97 98 } 99 100 if (dStep2 < 0) 101 { 102 103 sPtr = (const void *) 104 (((const uint8 *) sPtr) + (int32)(count2 - 1) * sStep2 * (int32)sPixelSize); 105 106 dPtr = (void *) 107 (((uint8 *) dPtr) + (int32)(count2 - 1) * dStep2 * (int32)dPixelSize); 108 109 sStep2 = -sStep2; 110 dStep2 = -dStep2; 111 112 } 113 114 step0 = (uint32) dStep0; 115 step1 = (uint32) dStep1; 116 step2 = (uint32) dStep2; 117 118 } 119 120 else 121 { 122 123 if (sStep0 < 0) 124 { 125 126 sPtr = (const void *) 127 (((const uint8 *) sPtr) + (int32)(count0 - 1) * sStep0 * (int32)sPixelSize); 128 129 dPtr = (void *) 130 (((uint8 *) dPtr) + (int32)(count0 - 1) * dStep0 * (int32)dPixelSize); 131 132 sStep0 = -sStep0; 133 dStep0 = -dStep0; 134 135 } 136 137 if (sStep1 < 0) 138 { 139 140 sPtr = (const void *) 141 (((const uint8 *) sPtr) + (int32)(count1 - 1) * sStep1 * (int32)sPixelSize); 142 143 dPtr = (void *) 144 (((uint8 *) dPtr) + (int32)(count1 - 1) * dStep1 * (int32)dPixelSize); 145 146 sStep1 = -sStep1; 147 dStep1 = -dStep1; 148 149 } 150 151 if (sStep2 < 0) 152 { 153 154 sPtr = (const void *) 155 (((const uint8 *) sPtr) + (int32)(count2 - 1) * sStep2 * (int32)sPixelSize); 156 157 dPtr = (void *) 158 (((uint8 *) dPtr) + (int32)(count2 - 1) * dStep2 * (int32)dPixelSize); 159 160 sStep2 = -sStep2; 161 dStep2 = -dStep2; 162 163 } 164 165 step0 = (uint32) sStep0; 166 step1 = (uint32) sStep1; 167 step2 = (uint32) sStep2; 168 169 } 170 171 if (count0 == 1) step0 = 0xFFFFFFFF; 172 if (count1 == 1) step1 = 0xFFFFFFFF; 173 if (count2 == 1) step2 = 0xFFFFFFFF; 174 175 uint32 index0; 176 uint32 index1; 177 uint32 index2; 178 179 if (step0 >= step1) 180 { 181 182 if (step1 >= step2) 183 { 184 index0 = 0; 185 index1 = 1; 186 index2 = 2; 187 } 188 189 else if (step2 >= step0) 190 { 191 index0 = 2; 192 index1 = 0; 193 index2 = 1; 194 } 195 196 else 197 { 198 index0 = 0; 199 index1 = 2; 200 index2 = 1; 201 } 202 203 } 204 205 else 206 { 207 208 if (step0 >= step2) 209 { 210 index0 = 1; 211 index1 = 0; 212 index2 = 2; 213 } 214 215 else if (step2 >= step1) 216 { 217 index0 = 2; 218 index1 = 1; 219 index2 = 0; 220 } 221 222 else 223 { 224 index0 = 1; 225 index1 = 2; 226 index2 = 0; 227 } 228 229 } 230 231 uint32 count [3]; 232 233 count [0] = count0; 234 count [1] = count1; 235 count [2] = count2; 236 237 count0 = count [index0]; 238 count1 = count [index1]; 239 count2 = count [index2]; 240 241 int32 step [3]; 242 243 step [0] = sStep0; 244 step [1] = sStep1; 245 step [2] = sStep2; 246 247 sStep0 = step [index0]; 248 sStep1 = step [index1]; 249 sStep2 = step [index2]; 250 251 step [0] = dStep0; 252 step [1] = dStep1; 253 step [2] = dStep2; 254 255 dStep0 = step [index0]; 256 dStep1 = step [index1]; 257 dStep2 = step [index2]; 258 259 if (sStep0 == ((int32) count1) * sStep1 && 260 dStep0 == ((int32) count1) * dStep1) 261 { 262 count1 *= count0; 263 count0 = 1; 264 } 265 266 if (sStep1 == ((int32) count2) * sStep2 && 267 dStep1 == ((int32) count2) * dStep2) 268 { 269 count2 *= count1; 270 count1 = 1; 271 } 272 273 } 274 275/*****************************************************************************/ 276 277void OptimizeOrder (const void *&sPtr, 278 uint32 sPixelSize, 279 uint32 &count0, 280 uint32 &count1, 281 uint32 &count2, 282 int32 &sStep0, 283 int32 &sStep1, 284 int32 &sStep2) 285 { 286 287 void *dPtr = NULL; 288 289 int32 dStep0 = sStep0; 290 int32 dStep1 = sStep1; 291 int32 dStep2 = sStep2; 292 293 OptimizeOrder (sPtr, 294 dPtr, 295 sPixelSize, 296 sPixelSize, 297 count0, 298 count1, 299 count2, 300 sStep0, 301 sStep1, 302 sStep2, 303 dStep0, 304 dStep1, 305 dStep2); 306 307 } 308 309/*****************************************************************************/ 310 311void OptimizeOrder (void *&dPtr, 312 uint32 dPixelSize, 313 uint32 &count0, 314 uint32 &count1, 315 uint32 &count2, 316 int32 &dStep0, 317 int32 &dStep1, 318 int32 &dStep2) 319 { 320 321 const void *sPtr = NULL; 322 323 int32 sStep0 = dStep0; 324 int32 sStep1 = dStep1; 325 int32 sStep2 = dStep2; 326 327 OptimizeOrder (sPtr, 328 dPtr, 329 dPixelSize, 330 dPixelSize, 331 count0, 332 count1, 333 count2, 334 sStep0, 335 sStep1, 336 sStep2, 337 dStep0, 338 dStep1, 339 dStep2); 340 341 } 342 343/*****************************************************************************/ 344 345dng_pixel_buffer::dng_pixel_buffer () 346 347 : fArea () 348 , fPlane (0) 349 , fPlanes (1) 350 , fRowStep (1) 351 , fColStep (1) 352 , fPlaneStep (1) 353 , fPixelType (ttUndefined) 354 , fPixelSize (0) 355 , fData (NULL) 356 , fDirty (true) 357 358 { 359 360 } 361 362/*****************************************************************************/ 363 364dng_pixel_buffer::dng_pixel_buffer (const dng_rect &area, 365 uint32 plane, 366 uint32 planes, 367 uint32 pixelType, 368 uint32 planarConfiguration, 369 void *data) 370 371 : fArea (area) 372 , fPlane (plane) 373 , fPlanes (planes) 374 , fRowStep (0) 375 , fColStep (0) 376 , fPlaneStep (0) 377 , fPixelType (pixelType) 378 , fPixelSize (TagTypeSize(pixelType)) 379 , fData (data) 380 , fDirty (true) 381 382 { 383 384 const char *overflowMessage = "Arithmetic overflow in pixel buffer setup"; 385 386 // Initialize fRowStep, fColStep and fPlaneStep according to the desired 387 // pixel layout. 388 switch (planarConfiguration) 389 { 390 case pcInterleaved: 391 fPlaneStep = 1; 392 if (!ConvertUint32ToInt32 (fPlanes, &fColStep) || 393 !SafeUint32ToInt32Mult (fArea.W(), fPlanes, &fRowStep)) 394 { 395 ThrowMemoryFull (overflowMessage); 396 } 397 break; 398 case pcPlanar: 399 fColStep = 1; 400 // Even though we've hardened dng_rect::W() to guarantee that it 401 // will never return a result that's out of range for an int32, 402 // we still protect the conversion for defense in depth. 403 if (!ConvertUint32ToInt32 (fArea.W(), &fRowStep) || 404 !SafeUint32ToInt32Mult (fArea.H(), fArea.W(), &fPlaneStep)) 405 { 406 ThrowMemoryFull (overflowMessage); 407 } 408 break; 409 case pcRowInterleaved: 410 case pcRowInterleavedAlign16: 411 { 412 fColStep = 1; 413 uint32 planeStepUint32; 414 if (planarConfiguration == pcRowInterleaved) 415 { 416 planeStepUint32 = fArea.W(); 417 } 418 else 419 { 420 if (!RoundUpForPixelSize (fArea.W(), fPixelSize, 421 &planeStepUint32)) 422 { 423 ThrowMemoryFull (overflowMessage); 424 } 425 } 426 if (!ConvertUint32ToInt32 (planeStepUint32, &fPlaneStep) || 427 !SafeUint32ToInt32Mult (planeStepUint32, fPlanes, &fRowStep)) 428 { 429 ThrowMemoryFull (overflowMessage); 430 } 431 break; 432 } 433 default: 434 ThrowProgramError ("Invalid value for 'planarConfiguration'"); 435 break; 436 } 437 438 } 439 440/*****************************************************************************/ 441 442dng_pixel_buffer::dng_pixel_buffer (const dng_pixel_buffer &buffer) 443 444 : fArea (buffer.fArea) 445 , fPlane (buffer.fPlane) 446 , fPlanes (buffer.fPlanes) 447 , fRowStep (buffer.fRowStep) 448 , fColStep (buffer.fColStep) 449 , fPlaneStep (buffer.fPlaneStep) 450 , fPixelType (buffer.fPixelType) 451 , fPixelSize (buffer.fPixelSize) 452 , fData (buffer.fData) 453 , fDirty (buffer.fDirty) 454 455 { 456 457 } 458 459/*****************************************************************************/ 460 461dng_pixel_buffer & dng_pixel_buffer::operator= (const dng_pixel_buffer &buffer) 462 { 463 464 fArea = buffer.fArea; 465 fPlane = buffer.fPlane; 466 fPlanes = buffer.fPlanes; 467 fRowStep = buffer.fRowStep; 468 fColStep = buffer.fColStep; 469 fPlaneStep = buffer.fPlaneStep; 470 fPixelType = buffer.fPixelType; 471 fPixelSize = buffer.fPixelSize; 472 fPixelType = buffer.fPixelType; 473 fData = buffer.fData; 474 fDirty = buffer.fDirty; 475 476 return *this; 477 478 } 479 480/*****************************************************************************/ 481 482dng_pixel_buffer::~dng_pixel_buffer () 483 { 484 485 } 486 487/*****************************************************************************/ 488 489#if qDebugPixelType 490 491void dng_pixel_buffer::CheckPixelType (uint32 pixelType) const 492 { 493 494 if (fPixelType != pixelType) 495 { 496 497 DNG_REPORT ("Pixel type access mismatch"); 498 499 } 500 501 } 502 503#endif 504 505/*****************************************************************************/ 506 507uint32 dng_pixel_buffer::PixelRange () const 508 { 509 510 switch (fPixelType) 511 { 512 513 case ttByte: 514 case ttSByte: 515 { 516 return 0x0FF; 517 } 518 519 case ttShort: 520 case ttSShort: 521 { 522 return 0x0FFFF; 523 } 524 525 case ttLong: 526 case ttSLong: 527 { 528 return 0xFFFFFFFF; 529 } 530 531 default: 532 break; 533 534 } 535 536 return 0; 537 538 } 539 540/*****************************************************************************/ 541 542void dng_pixel_buffer::SetConstant (const dng_rect &area, 543 uint32 plane, 544 uint32 planes, 545 uint32 value) 546 { 547 548 uint32 rows = area.H (); 549 uint32 cols = area.W (); 550 551 void *dPtr = DirtyPixel (area.t, 552 area.l, 553 plane); 554 555 int32 dRowStep = fRowStep; 556 int32 dColStep = fColStep; 557 int32 dPlaneStep = fPlaneStep; 558 559 OptimizeOrder (dPtr, 560 fPixelSize, 561 rows, 562 cols, 563 planes, 564 dRowStep, 565 dColStep, 566 dPlaneStep); 567 568 switch (fPixelSize) 569 { 570 571 case 1: 572 { 573 574 if (rows == 1 && cols == 1 && dPlaneStep == 1 && value == 0) 575 { 576 577 DoZeroBytes (dPtr, planes); 578 579 } 580 581 else 582 { 583 584 DoSetArea8 ((uint8 *) dPtr, 585 (uint8) value, 586 rows, 587 cols, 588 planes, 589 dRowStep, 590 dColStep, 591 dPlaneStep); 592 593 } 594 595 break; 596 597 } 598 599 case 2: 600 { 601 602 if (rows == 1 && cols == 1 && dPlaneStep == 1 && value == 0) 603 { 604 605 DoZeroBytes (dPtr, planes << 1); 606 607 } 608 609 else 610 { 611 612 DoSetArea16 ((uint16 *) dPtr, 613 (uint16) value, 614 rows, 615 cols, 616 planes, 617 dRowStep, 618 dColStep, 619 dPlaneStep); 620 621 } 622 623 break; 624 625 } 626 627 case 4: 628 { 629 630 if (rows == 1 && cols == 1 && dPlaneStep == 1 && value == 0) 631 { 632 633 DoZeroBytes (dPtr, planes << 2); 634 635 } 636 637 else 638 { 639 640 DoSetArea32 ((uint32 *) dPtr, 641 value, 642 rows, 643 cols, 644 planes, 645 dRowStep, 646 dColStep, 647 dPlaneStep); 648 649 } 650 651 break; 652 653 } 654 655 default: 656 { 657 658 ThrowNotYetImplemented (); 659 660 } 661 662 } 663 664 } 665 666/*****************************************************************************/ 667 668void dng_pixel_buffer::SetZero (const dng_rect &area, 669 uint32 plane, 670 uint32 planes) 671 { 672 673 uint32 value = 0; 674 675 switch (fPixelType) 676 { 677 678 case ttByte: 679 case ttShort: 680 case ttLong: 681 case ttFloat: 682 { 683 break; 684 } 685 686 case ttSShort: 687 { 688 value = 0x8000; 689 break; 690 } 691 692 default: 693 { 694 695 ThrowNotYetImplemented (); 696 697 } 698 699 } 700 701 SetConstant (area, 702 plane, 703 planes, 704 value); 705 706 } 707 708/*****************************************************************************/ 709 710void dng_pixel_buffer::CopyArea (const dng_pixel_buffer &src, 711 const dng_rect &area, 712 uint32 srcPlane, 713 uint32 dstPlane, 714 uint32 planes) 715 { 716 717 uint32 rows = area.H (); 718 uint32 cols = area.W (); 719 720 const void *sPtr = src.ConstPixel (area.t, 721 area.l, 722 srcPlane); 723 724 void *dPtr = DirtyPixel (area.t, 725 area.l, 726 dstPlane); 727 728 int32 sRowStep = src.fRowStep; 729 int32 sColStep = src.fColStep; 730 int32 sPlaneStep = src.fPlaneStep; 731 732 int32 dRowStep = fRowStep; 733 int32 dColStep = fColStep; 734 int32 dPlaneStep = fPlaneStep; 735 736 OptimizeOrder (sPtr, 737 dPtr, 738 src.fPixelSize, 739 fPixelSize, 740 rows, 741 cols, 742 planes, 743 sRowStep, 744 sColStep, 745 sPlaneStep, 746 dRowStep, 747 dColStep, 748 dPlaneStep); 749 750 if (fPixelType == src.fPixelType) 751 { 752 753 if (rows == 1 && cols == 1 && sPlaneStep == 1 && dPlaneStep == 1) 754 { 755 756 DoCopyBytes (sPtr, 757 dPtr, 758 planes * fPixelSize); 759 760 } 761 762 else switch (fPixelSize) 763 { 764 765 case 1: 766 { 767 768 DoCopyArea8 ((const uint8 *) sPtr, 769 (uint8 *) dPtr, 770 rows, 771 cols, 772 planes, 773 sRowStep, 774 sColStep, 775 sPlaneStep, 776 dRowStep, 777 dColStep, 778 dPlaneStep); 779 780 break; 781 782 } 783 784 case 2: 785 { 786 787 DoCopyArea16 ((const uint16 *) sPtr, 788 (uint16 *) dPtr, 789 rows, 790 cols, 791 planes, 792 sRowStep, 793 sColStep, 794 sPlaneStep, 795 dRowStep, 796 dColStep, 797 dPlaneStep); 798 799 break; 800 801 } 802 803 case 4: 804 { 805 806 DoCopyArea32 ((const uint32 *) sPtr, 807 (uint32 *) dPtr, 808 rows, 809 cols, 810 planes, 811 sRowStep, 812 sColStep, 813 sPlaneStep, 814 dRowStep, 815 dColStep, 816 dPlaneStep); 817 818 break; 819 820 } 821 822 default: 823 { 824 825 ThrowNotYetImplemented (); 826 827 } 828 829 } 830 831 } 832 833 else if (src.fPixelType == ttByte) 834 { 835 836 switch (fPixelType) 837 { 838 839 case ttShort: 840 { 841 842 DoCopyArea8_16 ((const uint8 *) sPtr, 843 (uint16 *) dPtr, 844 rows, 845 cols, 846 planes, 847 sRowStep, 848 sColStep, 849 sPlaneStep, 850 dRowStep, 851 dColStep, 852 dPlaneStep); 853 854 break; 855 856 } 857 858 case ttSShort: 859 { 860 861 DoCopyArea8_S16 ((const uint8 *) sPtr, 862 (int16 *) dPtr, 863 rows, 864 cols, 865 planes, 866 sRowStep, 867 sColStep, 868 sPlaneStep, 869 dRowStep, 870 dColStep, 871 dPlaneStep); 872 873 break; 874 875 } 876 877 case ttLong: 878 { 879 880 DoCopyArea8_32 ((const uint8 *) sPtr, 881 (uint32 *) dPtr, 882 rows, 883 cols, 884 planes, 885 sRowStep, 886 sColStep, 887 sPlaneStep, 888 dRowStep, 889 dColStep, 890 dPlaneStep); 891 892 break; 893 894 } 895 896 case ttFloat: 897 { 898 899 DoCopyArea8_R32 ((const uint8 *) sPtr, 900 (real32 *) dPtr, 901 rows, 902 cols, 903 planes, 904 sRowStep, 905 sColStep, 906 sPlaneStep, 907 dRowStep, 908 dColStep, 909 dPlaneStep, 910 src.PixelRange ()); 911 912 break; 913 914 } 915 916 default: 917 { 918 919 ThrowNotYetImplemented (); 920 921 } 922 923 } 924 925 } 926 927 else if (src.fPixelType == ttShort) 928 { 929 930 switch (fPixelType) 931 { 932 933 case ttByte: 934 { 935 936 DoCopyArea8 (((const uint8 *) sPtr) + (qDNGBigEndian ? 1 : 0), 937 (uint8 *) dPtr, 938 rows, 939 cols, 940 planes, 941 sRowStep << 1, 942 sColStep << 1, 943 sPlaneStep << 1, 944 dRowStep, 945 dColStep, 946 dPlaneStep); 947 948 break; 949 950 } 951 952 case ttSShort: 953 { 954 955 DoCopyArea16_S16 ((const uint16 *) sPtr, 956 (int16 *) dPtr, 957 rows, 958 cols, 959 planes, 960 sRowStep, 961 sColStep, 962 sPlaneStep, 963 dRowStep, 964 dColStep, 965 dPlaneStep); 966 967 break; 968 969 } 970 971 case ttLong: 972 { 973 974 DoCopyArea16_32 ((const uint16 *) sPtr, 975 (uint32 *) dPtr, 976 rows, 977 cols, 978 planes, 979 sRowStep, 980 sColStep, 981 sPlaneStep, 982 dRowStep, 983 dColStep, 984 dPlaneStep); 985 986 break; 987 988 } 989 990 case ttFloat: 991 { 992 993 DoCopyArea16_R32 ((const uint16 *) sPtr, 994 (real32 *) dPtr, 995 rows, 996 cols, 997 planes, 998 sRowStep, 999 sColStep, 1000 sPlaneStep, 1001 dRowStep, 1002 dColStep, 1003 dPlaneStep, 1004 src.PixelRange ()); 1005 1006 break; 1007 1008 } 1009 1010 default: 1011 { 1012 1013 ThrowNotYetImplemented (); 1014 1015 } 1016 1017 } 1018 1019 } 1020 1021 else if (src.fPixelType == ttSShort) 1022 { 1023 1024 switch (fPixelType) 1025 { 1026 1027 case ttByte: 1028 { 1029 1030 DoCopyArea8 (((const uint8 *) sPtr) + (qDNGBigEndian ? 1 : 0), 1031 (uint8 *) dPtr, 1032 rows, 1033 cols, 1034 planes, 1035 sRowStep << 1, 1036 sColStep << 1, 1037 sPlaneStep << 1, 1038 dRowStep, 1039 dColStep, 1040 dPlaneStep); 1041 1042 break; 1043 1044 } 1045 1046 case ttShort: 1047 { 1048 1049 // Moving between signed 16 bit values and unsigned 16 1050 // bit values just requires toggling the sign bit. So 1051 // we can use the "backwards" bottleneck. 1052 1053 DoCopyArea16_S16 ((const uint16 *) sPtr, 1054 (int16 *) dPtr, 1055 rows, 1056 cols, 1057 planes, 1058 sRowStep, 1059 sColStep, 1060 sPlaneStep, 1061 dRowStep, 1062 dColStep, 1063 dPlaneStep); 1064 1065 break; 1066 1067 } 1068 1069 case ttFloat: 1070 { 1071 1072 DoCopyAreaS16_R32 ((const int16 *) sPtr, 1073 (real32 *) dPtr, 1074 rows, 1075 cols, 1076 planes, 1077 sRowStep, 1078 sColStep, 1079 sPlaneStep, 1080 dRowStep, 1081 dColStep, 1082 dPlaneStep, 1083 src.PixelRange ()); 1084 1085 break; 1086 1087 } 1088 1089 default: 1090 { 1091 1092 ThrowNotYetImplemented (); 1093 1094 } 1095 1096 } 1097 1098 } 1099 1100 else if (src.fPixelType == ttLong) 1101 { 1102 1103 switch (fPixelType) 1104 { 1105 1106 case ttByte: 1107 { 1108 1109 DoCopyArea8 (((const uint8 *) sPtr) + (qDNGBigEndian ? 3 : 0), 1110 (uint8 *) dPtr, 1111 rows, 1112 cols, 1113 planes, 1114 sRowStep << 2, 1115 sColStep << 2, 1116 sPlaneStep << 2, 1117 dRowStep, 1118 dColStep, 1119 dPlaneStep); 1120 1121 break; 1122 1123 } 1124 1125 case ttShort: 1126 { 1127 1128 DoCopyArea16 (((const uint16 *) sPtr) + (qDNGBigEndian ? 1 : 0), 1129 (uint16 *) dPtr, 1130 rows, 1131 cols, 1132 planes, 1133 sRowStep << 1, 1134 sColStep << 1, 1135 sPlaneStep << 1, 1136 dRowStep, 1137 dColStep, 1138 dPlaneStep); 1139 1140 break; 1141 1142 } 1143 1144 default: 1145 { 1146 1147 ThrowNotYetImplemented (); 1148 1149 } 1150 1151 } 1152 1153 } 1154 1155 else if (src.fPixelType == ttFloat) 1156 { 1157 1158 switch (fPixelType) 1159 { 1160 1161 case ttByte: 1162 { 1163 1164 DoCopyAreaR32_8 ((const real32 *) sPtr, 1165 (uint8 *) dPtr, 1166 rows, 1167 cols, 1168 planes, 1169 sRowStep, 1170 sColStep, 1171 sPlaneStep, 1172 dRowStep, 1173 dColStep, 1174 dPlaneStep, 1175 PixelRange ()); 1176 1177 break; 1178 1179 } 1180 1181 case ttShort: 1182 { 1183 1184 DoCopyAreaR32_16 ((const real32 *) sPtr, 1185 (uint16 *) dPtr, 1186 rows, 1187 cols, 1188 planes, 1189 sRowStep, 1190 sColStep, 1191 sPlaneStep, 1192 dRowStep, 1193 dColStep, 1194 dPlaneStep, 1195 PixelRange ()); 1196 1197 break; 1198 1199 } 1200 1201 case ttSShort: 1202 { 1203 1204 DoCopyAreaR32_S16 ((const real32 *) sPtr, 1205 (int16 *) dPtr, 1206 rows, 1207 cols, 1208 planes, 1209 sRowStep, 1210 sColStep, 1211 sPlaneStep, 1212 dRowStep, 1213 dColStep, 1214 dPlaneStep, 1215 PixelRange ()); 1216 1217 break; 1218 1219 } 1220 1221 default: 1222 { 1223 1224 ThrowNotYetImplemented (); 1225 1226 } 1227 1228 } 1229 1230 } 1231 1232 else 1233 { 1234 1235 ThrowNotYetImplemented (); 1236 1237 } 1238 1239 } 1240 1241/*****************************************************************************/ 1242 1243dng_point dng_pixel_buffer::RepeatPhase (const dng_rect &srcArea, 1244 const dng_rect &dstArea) 1245 { 1246 1247 int32 repeatV = srcArea.H (); 1248 int32 repeatH = srcArea.W (); 1249 1250 int32 phaseV; 1251 int32 phaseH; 1252 1253 if (srcArea.t >= dstArea.t) 1254 { 1255 phaseV = (repeatV - ((srcArea.t - dstArea.t) % repeatV)) % repeatV; 1256 } 1257 else 1258 { 1259 phaseV = (dstArea.t - srcArea.t) % repeatV; 1260 } 1261 1262 if (srcArea.l >= dstArea.l) 1263 { 1264 phaseH = (repeatH - ((srcArea.l - dstArea.l) % repeatH)) % repeatH; 1265 } 1266 else 1267 { 1268 phaseH = (dstArea.l - srcArea.l) % repeatH; 1269 } 1270 1271 return dng_point (phaseV, phaseH); 1272 1273 } 1274 1275/*****************************************************************************/ 1276 1277void dng_pixel_buffer::RepeatArea (const dng_rect &srcArea, 1278 const dng_rect &dstArea) 1279 { 1280 1281 dng_point repeat = srcArea.Size (); 1282 1283 dng_point phase = RepeatPhase (srcArea, 1284 dstArea); 1285 1286 const void *sPtr = ConstPixel (srcArea.t, 1287 srcArea.l, 1288 fPlane); 1289 1290 void *dPtr = DirtyPixel (dstArea.t, 1291 dstArea.l, 1292 fPlane); 1293 1294 uint32 rows = dstArea.H (); 1295 uint32 cols = dstArea.W (); 1296 1297 switch (fPixelSize) 1298 { 1299 1300 case 1: 1301 { 1302 1303 DoRepeatArea8 ((const uint8 *) sPtr, 1304 (uint8 *) dPtr, 1305 rows, 1306 cols, 1307 fPlanes, 1308 fRowStep, 1309 fColStep, 1310 fPlaneStep, 1311 repeat.v, 1312 repeat.h, 1313 phase.v, 1314 phase.h); 1315 1316 break; 1317 1318 } 1319 1320 case 2: 1321 { 1322 1323 DoRepeatArea16 ((const uint16 *) sPtr, 1324 (uint16 *) dPtr, 1325 rows, 1326 cols, 1327 fPlanes, 1328 fRowStep, 1329 fColStep, 1330 fPlaneStep, 1331 repeat.v, 1332 repeat.h, 1333 phase.v, 1334 phase.h); 1335 1336 break; 1337 1338 } 1339 1340 case 4: 1341 { 1342 1343 DoRepeatArea32 ((const uint32 *) sPtr, 1344 (uint32 *) dPtr, 1345 rows, 1346 cols, 1347 fPlanes, 1348 fRowStep, 1349 fColStep, 1350 fPlaneStep, 1351 repeat.v, 1352 repeat.h, 1353 phase.v, 1354 phase.h); 1355 1356 break; 1357 1358 } 1359 1360 default: 1361 { 1362 1363 ThrowNotYetImplemented (); 1364 1365 } 1366 1367 } 1368 1369 } 1370 1371/*****************************************************************************/ 1372 1373void dng_pixel_buffer::RepeatSubArea (const dng_rect subArea, 1374 uint32 repeatV, 1375 uint32 repeatH) 1376 { 1377 1378 if (fArea.t < subArea.t) 1379 { 1380 1381 RepeatArea (dng_rect (subArea.t , fArea.l, 1382 subArea.t + repeatV, fArea.r), 1383 dng_rect (fArea.t , fArea.l, 1384 subArea.t , fArea.r)); 1385 1386 } 1387 1388 if (fArea.b > subArea.b) 1389 { 1390 1391 RepeatArea (dng_rect (subArea.b - repeatV, fArea.l, 1392 subArea.b , fArea.r), 1393 dng_rect (subArea.b , fArea.l, 1394 fArea.b , fArea.r)); 1395 1396 } 1397 1398 if (fArea.l < subArea.l) 1399 { 1400 1401 RepeatArea (dng_rect (fArea.t, subArea.l , 1402 fArea.b, subArea.l + repeatH), 1403 dng_rect (fArea.t, fArea.l , 1404 fArea.b, subArea.l )); 1405 1406 } 1407 1408 if (fArea.r > subArea.r) 1409 { 1410 1411 RepeatArea (dng_rect (fArea.t, subArea.r - repeatH, 1412 fArea.b, subArea.r ), 1413 dng_rect (fArea.t, subArea.r , 1414 fArea.b, fArea.r )); 1415 1416 } 1417 1418 } 1419 1420/*****************************************************************************/ 1421 1422void dng_pixel_buffer::ShiftRight (uint32 shift) 1423 { 1424 1425 if (fPixelType != ttShort) 1426 { 1427 1428 ThrowNotYetImplemented (); 1429 1430 } 1431 1432 uint32 rows = fArea.H (); 1433 uint32 cols = fArea.W (); 1434 1435 uint32 planes = fPlanes; 1436 1437 void *dPtr = DirtyPixel (fArea.t, 1438 fArea.l, 1439 fPlane); 1440 1441 const void *sPtr = dPtr; 1442 1443 int32 sRowStep = fRowStep; 1444 int32 sColStep = fColStep; 1445 int32 sPlaneStep = fPlaneStep; 1446 1447 int32 dRowStep = fRowStep; 1448 int32 dColStep = fColStep; 1449 int32 dPlaneStep = fPlaneStep; 1450 1451 OptimizeOrder (sPtr, 1452 dPtr, 1453 fPixelSize, 1454 fPixelSize, 1455 rows, 1456 cols, 1457 planes, 1458 sRowStep, 1459 sColStep, 1460 sPlaneStep, 1461 dRowStep, 1462 dColStep, 1463 dPlaneStep); 1464 1465 DoShiftRight16 ((uint16 *) dPtr, 1466 rows, 1467 cols, 1468 planes, 1469 dRowStep, 1470 dColStep, 1471 dPlaneStep, 1472 shift); 1473 1474 } 1475 1476/*****************************************************************************/ 1477 1478void dng_pixel_buffer::FlipH () 1479 { 1480 1481 fData = InternalPixel (fArea.t, fArea.r - 1); 1482 1483 fColStep = -fColStep; 1484 1485 } 1486 1487/*****************************************************************************/ 1488 1489void dng_pixel_buffer::FlipV () 1490 { 1491 1492 fData = InternalPixel (fArea.b - 1, fArea.l); 1493 1494 fRowStep = -fRowStep; 1495 1496 } 1497 1498/*****************************************************************************/ 1499 1500void dng_pixel_buffer::FlipZ () 1501 { 1502 1503 fData = InternalPixel (fArea.t, fArea.l, fPlanes - 1); 1504 1505 fPlaneStep = -fPlaneStep; 1506 1507 } 1508 1509/*****************************************************************************/ 1510 1511bool dng_pixel_buffer::EqualArea (const dng_pixel_buffer &src, 1512 const dng_rect &area, 1513 uint32 plane, 1514 uint32 planes) const 1515 { 1516 1517 uint32 rows = area.H (); 1518 uint32 cols = area.W (); 1519 1520 const void *sPtr = src.ConstPixel (area.t, 1521 area.l, 1522 plane); 1523 1524 const void *dPtr = ConstPixel (area.t, 1525 area.l, 1526 plane); 1527 1528 int32 sRowStep = src.fRowStep; 1529 int32 sColStep = src.fColStep; 1530 int32 sPlaneStep = src.fPlaneStep; 1531 1532 int32 dRowStep = fRowStep; 1533 int32 dColStep = fColStep; 1534 int32 dPlaneStep = fPlaneStep; 1535 1536 if (fPixelType == src.fPixelType) 1537 { 1538 1539 if (rows == 1 && cols == 1 && sPlaneStep == 1 && dPlaneStep == 1) 1540 { 1541 1542 return DoEqualBytes (sPtr, 1543 dPtr, 1544 planes * fPixelSize); 1545 1546 } 1547 1548 else switch (fPixelSize) 1549 { 1550 1551 case 1: 1552 { 1553 1554 return DoEqualArea8 ((const uint8 *) sPtr, 1555 (const uint8 *) dPtr, 1556 rows, 1557 cols, 1558 planes, 1559 sRowStep, 1560 sColStep, 1561 sPlaneStep, 1562 dRowStep, 1563 dColStep, 1564 dPlaneStep); 1565 1566 break; 1567 1568 } 1569 1570 case 2: 1571 { 1572 1573 return DoEqualArea16 ((const uint16 *) sPtr, 1574 (const uint16 *) dPtr, 1575 rows, 1576 cols, 1577 planes, 1578 sRowStep, 1579 sColStep, 1580 sPlaneStep, 1581 dRowStep, 1582 dColStep, 1583 dPlaneStep); 1584 1585 break; 1586 1587 } 1588 1589 case 4: 1590 { 1591 1592 return DoEqualArea32 ((const uint32 *) sPtr, 1593 (const uint32 *) dPtr, 1594 rows, 1595 cols, 1596 planes, 1597 sRowStep, 1598 sColStep, 1599 sPlaneStep, 1600 dRowStep, 1601 dColStep, 1602 dPlaneStep); 1603 1604 break; 1605 1606 } 1607 1608 default: 1609 { 1610 1611 ThrowNotYetImplemented (); 1612 1613 return false; 1614 1615 } 1616 1617 } 1618 1619 } 1620 1621 else 1622 return false; 1623 1624 } 1625 1626/*****************************************************************************/ 1627 1628namespace 1629 { 1630 1631 template <typename T> 1632 real64 MaxDiff (const T *src1, 1633 int32 s1RowStep, 1634 int32 s1PlaneStep, 1635 const T *src2, 1636 int32 s2RowStep, 1637 int32 s2PlaneStep, 1638 uint32 rows, 1639 uint32 cols, 1640 uint32 planes) 1641 { 1642 1643 real64 result = 0.0; 1644 1645 for (uint32 plane = 0; plane < planes; plane++) 1646 { 1647 1648 const T *src1Save = src1; 1649 const T *src2Save = src2; 1650 1651 for (uint32 row = 0; row < rows; row++) 1652 { 1653 1654 for (uint32 col = 0; col < cols; col++) 1655 { 1656 real64 diff = fabs ((real64)src1 [col] - src2 [col]); 1657 1658 if (diff > result) 1659 result = diff; 1660 1661 } 1662 1663 src1 += s1RowStep; 1664 src2 += s2RowStep; 1665 1666 } 1667 1668 src1 = src1Save + s1PlaneStep; 1669 src2 = src2Save + s2PlaneStep; 1670 1671 } 1672 1673 return result; 1674 1675 } 1676 1677 template <typename T> 1678 real64 MaxDiff (const T *src1, 1679 int32 s1ColStep, 1680 int32 s1RowStep, 1681 int32 s1PlaneStep, 1682 const T *src2, 1683 int32 s2ColStep, 1684 int32 s2RowStep, 1685 int32 s2PlaneStep, 1686 uint32 rows, 1687 uint32 cols, 1688 uint32 planes) 1689 { 1690 1691 if (s1ColStep == s2ColStep && 1692 s1ColStep == 1) 1693 return MaxDiff (src1, 1694 s1RowStep, 1695 s1PlaneStep, 1696 src2, 1697 s2RowStep, 1698 s2PlaneStep, 1699 rows, 1700 cols, 1701 planes); 1702 1703 real64 result = 0.0; 1704 1705 for (uint32 plane = 0; plane < planes; plane++) 1706 { 1707 1708 const T *src1Save = src1; 1709 const T *src2Save = src2; 1710 1711 for (uint32 row = 0; row < rows; row++) 1712 { 1713 1714 for (uint32 col = 0; col < cols; col++) 1715 { 1716 real64 diff = fabs ((real64)src1 [col * s1ColStep] - src2 [col * s2ColStep]); 1717 1718 if (diff > result) 1719 result = diff; 1720 1721 } 1722 1723 src1 += s1RowStep; 1724 src2 += s2RowStep; 1725 1726 } 1727 1728 src1 = src1Save + s1PlaneStep; 1729 src2 = src2Save + s2PlaneStep; 1730 1731 } 1732 1733 1734 return result; 1735 1736 } 1737 } 1738 1739real64 dng_pixel_buffer::MaximumDifference (const dng_pixel_buffer &rhs, 1740 const dng_rect &area, 1741 uint32 plane, 1742 uint32 planes) const 1743 { 1744 1745 uint32 rows = area.H (); 1746 uint32 cols = area.W (); 1747 1748 const void *s1Ptr = rhs.ConstPixel (area.t, 1749 area.l, 1750 plane); 1751 1752 const void *s2Ptr = ConstPixel (area.t, 1753 area.l, 1754 plane); 1755 1756 int32 s1RowStep = rhs.fRowStep; 1757 int32 s1ColStep = rhs.fColStep; 1758 int32 s1PlaneStep = rhs.fPlaneStep; 1759 1760 int32 s2RowStep = fRowStep; 1761 int32 s2ColStep = fColStep; 1762 int32 s2PlaneStep = fPlaneStep; 1763 1764 if (fPixelType == rhs.fPixelType) 1765 { 1766 1767 switch (fPixelType) 1768 { 1769 1770 case ttByte: 1771 return MaxDiff ((const uint8 *)s1Ptr, 1772 s1ColStep, 1773 s1RowStep, 1774 s1PlaneStep, 1775 (const uint8 *)s2Ptr, 1776 s2ColStep, 1777 s2RowStep, 1778 s2PlaneStep, 1779 rows, 1780 cols, 1781 planes); 1782 1783 break; 1784 1785 case ttShort: 1786 return MaxDiff ((const uint16 *)s1Ptr, 1787 s1ColStep, 1788 s1RowStep, 1789 s1PlaneStep, 1790 (const uint16 *)s2Ptr, 1791 s2ColStep, 1792 s2RowStep, 1793 s2PlaneStep, 1794 rows, 1795 cols, 1796 planes); 1797 1798 break; 1799 1800 case ttLong: 1801 return MaxDiff ((const uint32 *)s1Ptr, 1802 s1ColStep, 1803 s1RowStep, 1804 s1PlaneStep, 1805 (const uint32 *)s2Ptr, 1806 s2ColStep, 1807 s2RowStep, 1808 s2PlaneStep, 1809 rows, 1810 cols, 1811 planes); 1812 1813 break; 1814 1815 case ttSByte: 1816 return MaxDiff ((const int8 *)s1Ptr, 1817 s1ColStep, 1818 s1RowStep, 1819 s1PlaneStep, 1820 (const int8 *)s2Ptr, 1821 s2ColStep, 1822 s2RowStep, 1823 s2PlaneStep, 1824 rows, 1825 cols, 1826 planes); 1827 1828 break; 1829 1830 case ttSShort: 1831 return MaxDiff ((const int16 *)s1Ptr, 1832 s1ColStep, 1833 s1RowStep, 1834 s1PlaneStep, 1835 (const int16 *)s2Ptr, 1836 s2ColStep, 1837 s2RowStep, 1838 s2PlaneStep, 1839 rows, 1840 cols, 1841 planes); 1842 1843 break; 1844 1845 case ttSLong: 1846 return MaxDiff ((const int32 *)s1Ptr, 1847 s1ColStep, 1848 s1RowStep, 1849 s1PlaneStep, 1850 (const int32 *)s2Ptr, 1851 s2ColStep, 1852 s2RowStep, 1853 s2PlaneStep, 1854 rows, 1855 cols, 1856 planes); 1857 1858 break; 1859 1860 case ttFloat: 1861 return MaxDiff ((const real32 *)s1Ptr, 1862 s1ColStep, 1863 s1RowStep, 1864 s1PlaneStep, 1865 (const real32 *)s2Ptr, 1866 s2ColStep, 1867 s2RowStep, 1868 s2PlaneStep, 1869 rows, 1870 cols, 1871 planes); 1872 1873 break; 1874 1875 case ttDouble: 1876 return MaxDiff ((const real64 *)s1Ptr, 1877 s1ColStep, 1878 s1RowStep, 1879 s1PlaneStep, 1880 (const real64 *)s2Ptr, 1881 s2ColStep, 1882 s2RowStep, 1883 s2PlaneStep, 1884 rows, 1885 cols, 1886 planes); 1887 1888 break; 1889 1890 1891 default: 1892 { 1893 1894 ThrowNotYetImplemented (); 1895 1896 return 0.0; 1897 1898 } 1899 1900 } 1901 1902 } 1903 1904 else 1905 ThrowProgramError ("attempt to difference pixel buffers of different formats."); 1906 1907 return 0.0; 1908 1909 } 1910 1911/*****************************************************************************/ 1912