1 /*****************************************************************************/ 2 // Copyright 2006-2009 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_reference.cpp#1 $ */ 10 /* $DateTime: 2012/05/30 13:28:51 $ */ 11 /* $Change: 832332 $ */ 12 /* $Author: tknoll $ */ 13 14 /*****************************************************************************/ 15 16 #include "dng_reference.h" 17 18 #include "dng_1d_table.h" 19 #include "dng_hue_sat_map.h" 20 #include "dng_matrix.h" 21 #include "dng_resample.h" 22 #include "dng_utils.h" 23 24 /*****************************************************************************/ 25 26 // This module contains routines that should be as fast as possible, even 27 // at the expense of slight code size increases. 28 29 #include "dng_fast_module.h" 30 31 /*****************************************************************************/ 32 33 void RefZeroBytes (void *dPtr, 34 uint32 count) 35 { 36 37 memset (dPtr, 0, count); 38 39 } 40 41 /*****************************************************************************/ 42 43 void RefCopyBytes (const void *sPtr, 44 void *dPtr, 45 uint32 count) 46 { 47 48 memcpy (dPtr, sPtr, count); 49 50 } 51 52 /*****************************************************************************/ 53 54 void RefSwapBytes16 (uint16 *dPtr, 55 uint32 count) 56 { 57 58 for (uint32 j = 0; j < count; j++) 59 { 60 61 dPtr [j] = SwapBytes16 (dPtr [j]); 62 63 } 64 65 } 66 67 /*****************************************************************************/ 68 69 void RefSwapBytes32 (uint32 *dPtr, 70 uint32 count) 71 { 72 73 for (uint32 j = 0; j < count; j++) 74 { 75 76 dPtr [j] = SwapBytes32 (dPtr [j]); 77 78 } 79 80 } 81 82 /*****************************************************************************/ 83 84 void RefSetArea8 (uint8 *dPtr, 85 uint8 value, 86 uint32 rows, 87 uint32 cols, 88 uint32 planes, 89 int32 rowStep, 90 int32 colStep, 91 int32 planeStep) 92 { 93 94 for (uint32 row = 0; row < rows; row++) 95 { 96 97 uint8 *dPtr1 = dPtr; 98 99 for (uint32 col = 0; col < cols; col++) 100 { 101 102 uint8 *dPtr2 = dPtr1; 103 104 for (uint32 plane = 0; plane < planes; plane++) 105 { 106 107 *dPtr2 = value; 108 109 dPtr2 += planeStep; 110 111 } 112 113 dPtr1 += colStep; 114 115 } 116 117 dPtr += rowStep; 118 119 } 120 121 } 122 123 /*****************************************************************************/ 124 125 void RefSetArea16 (uint16 *dPtr, 126 uint16 value, 127 uint32 rows, 128 uint32 cols, 129 uint32 planes, 130 int32 rowStep, 131 int32 colStep, 132 int32 planeStep) 133 { 134 135 for (uint32 row = 0; row < rows; row++) 136 { 137 138 uint16 *dPtr1 = dPtr; 139 140 for (uint32 col = 0; col < cols; col++) 141 { 142 143 uint16 *dPtr2 = dPtr1; 144 145 for (uint32 plane = 0; plane < planes; plane++) 146 { 147 148 *dPtr2 = value; 149 150 dPtr2 += planeStep; 151 152 } 153 154 dPtr1 += colStep; 155 156 } 157 158 dPtr += rowStep; 159 160 } 161 162 } 163 164 /*****************************************************************************/ 165 166 void RefSetArea32 (uint32 *dPtr, 167 uint32 value, 168 uint32 rows, 169 uint32 cols, 170 uint32 planes, 171 int32 rowStep, 172 int32 colStep, 173 int32 planeStep) 174 { 175 176 for (uint32 row = 0; row < rows; row++) 177 { 178 179 uint32 *dPtr1 = dPtr; 180 181 for (uint32 col = 0; col < cols; col++) 182 { 183 184 uint32 *dPtr2 = dPtr1; 185 186 for (uint32 plane = 0; plane < planes; plane++) 187 { 188 189 *dPtr2 = value; 190 191 dPtr2 += planeStep; 192 193 } 194 195 dPtr1 += colStep; 196 197 } 198 199 dPtr += rowStep; 200 201 } 202 203 } 204 205 /*****************************************************************************/ 206 207 void RefCopyArea8 (const uint8 *sPtr, 208 uint8 *dPtr, 209 uint32 rows, 210 uint32 cols, 211 uint32 planes, 212 int32 sRowStep, 213 int32 sColStep, 214 int32 sPlaneStep, 215 int32 dRowStep, 216 int32 dColStep, 217 int32 dPlaneStep) 218 { 219 220 for (uint32 row = 0; row < rows; row++) 221 { 222 223 const uint8 *sPtr1 = sPtr; 224 uint8 *dPtr1 = dPtr; 225 226 for (uint32 col = 0; col < cols; col++) 227 { 228 229 const uint8 *sPtr2 = sPtr1; 230 uint8 *dPtr2 = dPtr1; 231 232 for (uint32 plane = 0; plane < planes; plane++) 233 { 234 235 *dPtr2 = *sPtr2; 236 237 sPtr2 += sPlaneStep; 238 dPtr2 += dPlaneStep; 239 240 } 241 242 sPtr1 += sColStep; 243 dPtr1 += dColStep; 244 245 } 246 247 sPtr += sRowStep; 248 dPtr += dRowStep; 249 250 } 251 252 } 253 254 /*****************************************************************************/ 255 256 void RefCopyArea16 (const uint16 *sPtr, 257 uint16 *dPtr, 258 uint32 rows, 259 uint32 cols, 260 uint32 planes, 261 int32 sRowStep, 262 int32 sColStep, 263 int32 sPlaneStep, 264 int32 dRowStep, 265 int32 dColStep, 266 int32 dPlaneStep) 267 { 268 269 for (uint32 row = 0; row < rows; row++) 270 { 271 272 const uint16 *sPtr1 = sPtr; 273 uint16 *dPtr1 = dPtr; 274 275 for (uint32 col = 0; col < cols; col++) 276 { 277 278 const uint16 *sPtr2 = sPtr1; 279 uint16 *dPtr2 = dPtr1; 280 281 for (uint32 plane = 0; plane < planes; plane++) 282 { 283 284 *dPtr2 = *sPtr2; 285 286 sPtr2 += sPlaneStep; 287 dPtr2 += dPlaneStep; 288 289 } 290 291 sPtr1 += sColStep; 292 dPtr1 += dColStep; 293 294 } 295 296 sPtr += sRowStep; 297 dPtr += dRowStep; 298 299 } 300 301 } 302 303 /*****************************************************************************/ 304 305 void RefCopyArea32 (const uint32 *sPtr, 306 uint32 *dPtr, 307 uint32 rows, 308 uint32 cols, 309 uint32 planes, 310 int32 sRowStep, 311 int32 sColStep, 312 int32 sPlaneStep, 313 int32 dRowStep, 314 int32 dColStep, 315 int32 dPlaneStep) 316 { 317 318 for (uint32 row = 0; row < rows; row++) 319 { 320 321 const uint32 *sPtr1 = sPtr; 322 uint32 *dPtr1 = dPtr; 323 324 for (uint32 col = 0; col < cols; col++) 325 { 326 327 const uint32 *sPtr2 = sPtr1; 328 uint32 *dPtr2 = dPtr1; 329 330 for (uint32 plane = 0; plane < planes; plane++) 331 { 332 333 *dPtr2 = *sPtr2; 334 335 sPtr2 += sPlaneStep; 336 dPtr2 += dPlaneStep; 337 338 } 339 340 sPtr1 += sColStep; 341 dPtr1 += dColStep; 342 343 } 344 345 sPtr += sRowStep; 346 dPtr += dRowStep; 347 348 } 349 350 } 351 352 /*****************************************************************************/ 353 354 void RefCopyArea8_16 (const uint8 *sPtr, 355 uint16 *dPtr, 356 uint32 rows, 357 uint32 cols, 358 uint32 planes, 359 int32 sRowStep, 360 int32 sColStep, 361 int32 sPlaneStep, 362 int32 dRowStep, 363 int32 dColStep, 364 int32 dPlaneStep) 365 { 366 367 for (uint32 row = 0; row < rows; row++) 368 { 369 370 const uint8 *sPtr1 = sPtr; 371 uint16 *dPtr1 = dPtr; 372 373 for (uint32 col = 0; col < cols; col++) 374 { 375 376 const uint8 *sPtr2 = sPtr1; 377 uint16 *dPtr2 = dPtr1; 378 379 for (uint32 plane = 0; plane < planes; plane++) 380 { 381 382 *dPtr2 = *sPtr2; 383 384 sPtr2 += sPlaneStep; 385 dPtr2 += dPlaneStep; 386 387 } 388 389 sPtr1 += sColStep; 390 dPtr1 += dColStep; 391 392 } 393 394 sPtr += sRowStep; 395 dPtr += dRowStep; 396 397 } 398 399 } 400 401 /*****************************************************************************/ 402 403 void RefCopyArea8_S16 (const uint8 *sPtr, 404 int16 *dPtr, 405 uint32 rows, 406 uint32 cols, 407 uint32 planes, 408 int32 sRowStep, 409 int32 sColStep, 410 int32 sPlaneStep, 411 int32 dRowStep, 412 int32 dColStep, 413 int32 dPlaneStep) 414 { 415 416 for (uint32 row = 0; row < rows; row++) 417 { 418 419 const uint8 *sPtr1 = sPtr; 420 int16 *dPtr1 = dPtr; 421 422 for (uint32 col = 0; col < cols; col++) 423 { 424 425 const uint8 *sPtr2 = sPtr1; 426 int16 *dPtr2 = dPtr1; 427 428 for (uint32 plane = 0; plane < planes; plane++) 429 { 430 431 int16 x = *sPtr; 432 433 *dPtr2 = x ^ 0x8000; 434 435 sPtr2 += sPlaneStep; 436 dPtr2 += dPlaneStep; 437 438 } 439 440 sPtr1 += sColStep; 441 dPtr1 += dColStep; 442 443 } 444 445 sPtr += sRowStep; 446 dPtr += dRowStep; 447 448 } 449 450 } 451 452 /*****************************************************************************/ 453 454 void RefCopyArea8_32 (const uint8 *sPtr, 455 uint32 *dPtr, 456 uint32 rows, 457 uint32 cols, 458 uint32 planes, 459 int32 sRowStep, 460 int32 sColStep, 461 int32 sPlaneStep, 462 int32 dRowStep, 463 int32 dColStep, 464 int32 dPlaneStep) 465 { 466 467 for (uint32 row = 0; row < rows; row++) 468 { 469 470 const uint8 *sPtr1 = sPtr; 471 uint32 *dPtr1 = dPtr; 472 473 for (uint32 col = 0; col < cols; col++) 474 { 475 476 const uint8 *sPtr2 = sPtr1; 477 uint32 *dPtr2 = dPtr1; 478 479 for (uint32 plane = 0; plane < planes; plane++) 480 { 481 482 *dPtr2 = *sPtr2; 483 484 sPtr2 += sPlaneStep; 485 dPtr2 += dPlaneStep; 486 487 } 488 489 sPtr1 += sColStep; 490 dPtr1 += dColStep; 491 492 } 493 494 sPtr += sRowStep; 495 dPtr += dRowStep; 496 497 } 498 499 } 500 501 /*****************************************************************************/ 502 503 void RefCopyArea16_S16 (const uint16 *sPtr, 504 int16 *dPtr, 505 uint32 rows, 506 uint32 cols, 507 uint32 planes, 508 int32 sRowStep, 509 int32 sColStep, 510 int32 sPlaneStep, 511 int32 dRowStep, 512 int32 dColStep, 513 int32 dPlaneStep) 514 { 515 516 for (uint32 row = 0; row < rows; row++) 517 { 518 519 const uint16 *sPtr1 = sPtr; 520 int16 *dPtr1 = dPtr; 521 522 for (uint32 col = 0; col < cols; col++) 523 { 524 525 const uint16 *sPtr2 = sPtr1; 526 int16 *dPtr2 = dPtr1; 527 528 for (uint32 plane = 0; plane < planes; plane++) 529 { 530 531 *dPtr2 = *sPtr2 ^ 0x8000; 532 533 sPtr2 += sPlaneStep; 534 dPtr2 += dPlaneStep; 535 536 } 537 538 sPtr1 += sColStep; 539 dPtr1 += dColStep; 540 541 } 542 543 sPtr += sRowStep; 544 dPtr += dRowStep; 545 546 } 547 548 } 549 550 /*****************************************************************************/ 551 552 void RefCopyArea16_32 (const uint16 *sPtr, 553 uint32 *dPtr, 554 uint32 rows, 555 uint32 cols, 556 uint32 planes, 557 int32 sRowStep, 558 int32 sColStep, 559 int32 sPlaneStep, 560 int32 dRowStep, 561 int32 dColStep, 562 int32 dPlaneStep) 563 { 564 565 for (uint32 row = 0; row < rows; row++) 566 { 567 568 const uint16 *sPtr1 = sPtr; 569 uint32 *dPtr1 = dPtr; 570 571 for (uint32 col = 0; col < cols; col++) 572 { 573 574 const uint16 *sPtr2 = sPtr1; 575 uint32 *dPtr2 = dPtr1; 576 577 for (uint32 plane = 0; plane < planes; plane++) 578 { 579 580 *dPtr2 = *sPtr2; 581 582 sPtr2 += sPlaneStep; 583 dPtr2 += dPlaneStep; 584 585 } 586 587 sPtr1 += sColStep; 588 dPtr1 += dColStep; 589 590 } 591 592 sPtr += sRowStep; 593 dPtr += dRowStep; 594 595 } 596 597 } 598 599 /*****************************************************************************/ 600 601 void RefCopyArea8_R32 (const uint8 *sPtr, 602 real32 *dPtr, 603 uint32 rows, 604 uint32 cols, 605 uint32 planes, 606 int32 sRowStep, 607 int32 sColStep, 608 int32 sPlaneStep, 609 int32 dRowStep, 610 int32 dColStep, 611 int32 dPlaneStep, 612 uint32 pixelRange) 613 { 614 615 real32 scale = 1.0f / (real32) pixelRange; 616 617 for (uint32 row = 0; row < rows; row++) 618 { 619 620 const uint8 *sPtr1 = sPtr; 621 real32 *dPtr1 = dPtr; 622 623 for (uint32 col = 0; col < cols; col++) 624 { 625 626 const uint8 *sPtr2 = sPtr1; 627 real32 *dPtr2 = dPtr1; 628 629 for (uint32 plane = 0; plane < planes; plane++) 630 { 631 632 *dPtr2 = scale * (real32) *sPtr2; 633 634 sPtr2 += sPlaneStep; 635 dPtr2 += dPlaneStep; 636 637 } 638 639 sPtr1 += sColStep; 640 dPtr1 += dColStep; 641 642 } 643 644 sPtr += sRowStep; 645 dPtr += dRowStep; 646 647 } 648 649 } 650 651 /*****************************************************************************/ 652 653 void RefCopyArea16_R32 (const uint16 *sPtr, 654 real32 *dPtr, 655 uint32 rows, 656 uint32 cols, 657 uint32 planes, 658 int32 sRowStep, 659 int32 sColStep, 660 int32 sPlaneStep, 661 int32 dRowStep, 662 int32 dColStep, 663 int32 dPlaneStep, 664 uint32 pixelRange) 665 { 666 667 real32 scale = 1.0f / (real32) pixelRange; 668 669 for (uint32 row = 0; row < rows; row++) 670 { 671 672 const uint16 *sPtr1 = sPtr; 673 real32 *dPtr1 = dPtr; 674 675 for (uint32 col = 0; col < cols; col++) 676 { 677 678 const uint16 *sPtr2 = sPtr1; 679 real32 *dPtr2 = dPtr1; 680 681 for (uint32 plane = 0; plane < planes; plane++) 682 { 683 684 *dPtr2 = scale * (real32) *sPtr2; 685 686 sPtr2 += sPlaneStep; 687 dPtr2 += dPlaneStep; 688 689 } 690 691 sPtr1 += sColStep; 692 dPtr1 += dColStep; 693 694 } 695 696 sPtr += sRowStep; 697 dPtr += dRowStep; 698 699 } 700 701 } 702 703 /*****************************************************************************/ 704 705 void RefCopyAreaS16_R32 (const int16 *sPtr, 706 real32 *dPtr, 707 uint32 rows, 708 uint32 cols, 709 uint32 planes, 710 int32 sRowStep, 711 int32 sColStep, 712 int32 sPlaneStep, 713 int32 dRowStep, 714 int32 dColStep, 715 int32 dPlaneStep, 716 uint32 pixelRange) 717 { 718 719 real32 scale = 1.0f / (real32) pixelRange; 720 721 for (uint32 row = 0; row < rows; row++) 722 { 723 724 const int16 *sPtr1 = sPtr; 725 real32 *dPtr1 = dPtr; 726 727 for (uint32 col = 0; col < cols; col++) 728 { 729 730 const int16 *sPtr2 = sPtr1; 731 real32 *dPtr2 = dPtr1; 732 733 for (uint32 plane = 0; plane < planes; plane++) 734 { 735 736 int32 x = (*sPtr ^ 0x8000); 737 738 *dPtr2 = scale * (real32) x; 739 740 sPtr2 += sPlaneStep; 741 dPtr2 += dPlaneStep; 742 743 } 744 745 sPtr1 += sColStep; 746 dPtr1 += dColStep; 747 748 } 749 750 sPtr += sRowStep; 751 dPtr += dRowStep; 752 753 } 754 755 } 756 757 /*****************************************************************************/ 758 759 void RefCopyAreaR32_8 (const real32 *sPtr, 760 uint8 *dPtr, 761 uint32 rows, 762 uint32 cols, 763 uint32 planes, 764 int32 sRowStep, 765 int32 sColStep, 766 int32 sPlaneStep, 767 int32 dRowStep, 768 int32 dColStep, 769 int32 dPlaneStep, 770 uint32 pixelRange) 771 { 772 773 real32 scale = (real32) pixelRange; 774 775 for (uint32 row = 0; row < rows; row++) 776 { 777 778 const real32 *sPtr1 = sPtr; 779 uint8 *dPtr1 = dPtr; 780 781 for (uint32 col = 0; col < cols; col++) 782 { 783 784 const real32 *sPtr2 = sPtr1; 785 uint8 *dPtr2 = dPtr1; 786 787 for (uint32 plane = 0; plane < planes; plane++) 788 { 789 790 *dPtr2 = (uint8) (Pin_Overrange (*sPtr2) * scale + 0.5f); 791 792 sPtr2 += sPlaneStep; 793 dPtr2 += dPlaneStep; 794 795 } 796 797 sPtr1 += sColStep; 798 dPtr1 += dColStep; 799 800 } 801 802 sPtr += sRowStep; 803 dPtr += dRowStep; 804 805 } 806 807 } 808 809 /*****************************************************************************/ 810 811 void RefCopyAreaR32_16 (const real32 *sPtr, 812 uint16 *dPtr, 813 uint32 rows, 814 uint32 cols, 815 uint32 planes, 816 int32 sRowStep, 817 int32 sColStep, 818 int32 sPlaneStep, 819 int32 dRowStep, 820 int32 dColStep, 821 int32 dPlaneStep, 822 uint32 pixelRange) 823 { 824 825 real32 scale = (real32) pixelRange; 826 827 for (uint32 row = 0; row < rows; row++) 828 { 829 830 const real32 *sPtr1 = sPtr; 831 uint16 *dPtr1 = dPtr; 832 833 for (uint32 col = 0; col < cols; col++) 834 { 835 836 const real32 *sPtr2 = sPtr1; 837 uint16 *dPtr2 = dPtr1; 838 839 for (uint32 plane = 0; plane < planes; plane++) 840 { 841 842 *dPtr2 = (uint16) (Pin_Overrange (*sPtr2) * scale + 0.5f); 843 844 sPtr2 += sPlaneStep; 845 dPtr2 += dPlaneStep; 846 847 } 848 849 sPtr1 += sColStep; 850 dPtr1 += dColStep; 851 852 } 853 854 sPtr += sRowStep; 855 dPtr += dRowStep; 856 857 } 858 859 } 860 861 /*****************************************************************************/ 862 863 void RefCopyAreaR32_S16 (const real32 *sPtr, 864 int16 *dPtr, 865 uint32 rows, 866 uint32 cols, 867 uint32 planes, 868 int32 sRowStep, 869 int32 sColStep, 870 int32 sPlaneStep, 871 int32 dRowStep, 872 int32 dColStep, 873 int32 dPlaneStep, 874 uint32 pixelRange) 875 { 876 877 real32 scale = (real32) pixelRange; 878 879 for (uint32 row = 0; row < rows; row++) 880 { 881 882 const real32 *sPtr1 = sPtr; 883 int16 *dPtr1 = dPtr; 884 885 for (uint32 col = 0; col < cols; col++) 886 { 887 888 const real32 *sPtr2 = sPtr1; 889 int16 *dPtr2 = dPtr1; 890 891 for (uint32 plane = 0; plane < planes; plane++) 892 { 893 894 int32 x = (int32) (Pin_Overrange (*sPtr2) * scale + 0.5f); 895 896 *dPtr2 = (int16) (x ^ 0x8000); 897 898 sPtr2 += sPlaneStep; 899 dPtr2 += dPlaneStep; 900 901 } 902 903 sPtr1 += sColStep; 904 dPtr1 += dColStep; 905 906 } 907 908 sPtr += sRowStep; 909 dPtr += dRowStep; 910 911 } 912 913 } 914 915 /*****************************************************************************/ 916 917 void RefRepeatArea8 (const uint8 *sPtr, 918 uint8 *dPtr, 919 uint32 rows, 920 uint32 cols, 921 uint32 planes, 922 int32 rowStep, 923 int32 colStep, 924 int32 planeStep, 925 uint32 repeatV, 926 uint32 repeatH, 927 uint32 phaseV, 928 uint32 phaseH) 929 { 930 931 const uint8 *sPtr0 = sPtr + phaseV * rowStep + 932 phaseH * colStep; 933 934 int32 backStepV = (repeatV - 1) * rowStep; 935 int32 backStepH = (repeatH - 1) * colStep; 936 937 for (uint32 row = 0; row < rows; row++) 938 { 939 940 const uint8 *sPtr1 = sPtr0; 941 uint8 *dPtr1 = dPtr; 942 943 uint32 colPhase = phaseH; 944 945 for (uint32 col = 0; col < cols; col++) 946 { 947 948 const uint8 *sPtr2 = sPtr1; 949 uint8 *dPtr2 = dPtr1; 950 951 for (uint32 plane = 0; plane < planes; plane++) 952 { 953 954 *dPtr2 = *sPtr2; 955 956 sPtr2 += planeStep; 957 dPtr2 += planeStep; 958 959 } 960 961 if (++colPhase == repeatH) 962 { 963 colPhase = 0; 964 sPtr1 -= backStepH; 965 } 966 else 967 { 968 sPtr1 += colStep; 969 } 970 971 dPtr1 += colStep; 972 973 } 974 975 if (++phaseV == repeatV) 976 { 977 phaseV = 0; 978 sPtr0 -= backStepV; 979 } 980 else 981 { 982 sPtr0 += rowStep; 983 } 984 985 dPtr += rowStep; 986 987 } 988 989 } 990 991 /*****************************************************************************/ 992 993 void RefRepeatArea16 (const uint16 *sPtr, 994 uint16 *dPtr, 995 uint32 rows, 996 uint32 cols, 997 uint32 planes, 998 int32 rowStep, 999 int32 colStep, 1000 int32 planeStep, 1001 uint32 repeatV, 1002 uint32 repeatH, 1003 uint32 phaseV, 1004 uint32 phaseH) 1005 { 1006 1007 const uint16 *sPtr0 = sPtr + phaseV * rowStep + 1008 phaseH * colStep; 1009 1010 int32 backStepV = (repeatV - 1) * rowStep; 1011 int32 backStepH = (repeatH - 1) * colStep; 1012 1013 for (uint32 row = 0; row < rows; row++) 1014 { 1015 1016 const uint16 *sPtr1 = sPtr0; 1017 uint16 *dPtr1 = dPtr; 1018 1019 uint32 colPhase = phaseH; 1020 1021 for (uint32 col = 0; col < cols; col++) 1022 { 1023 1024 const uint16 *sPtr2 = sPtr1; 1025 uint16 *dPtr2 = dPtr1; 1026 1027 for (uint32 plane = 0; plane < planes; plane++) 1028 { 1029 1030 *dPtr2 = *sPtr2; 1031 1032 sPtr2 += planeStep; 1033 dPtr2 += planeStep; 1034 1035 } 1036 1037 if (++colPhase == repeatH) 1038 { 1039 colPhase = 0; 1040 sPtr1 -= backStepH; 1041 } 1042 else 1043 { 1044 sPtr1 += colStep; 1045 } 1046 1047 dPtr1 += colStep; 1048 1049 } 1050 1051 if (++phaseV == repeatV) 1052 { 1053 phaseV = 0; 1054 sPtr0 -= backStepV; 1055 } 1056 else 1057 { 1058 sPtr0 += rowStep; 1059 } 1060 1061 dPtr += rowStep; 1062 1063 } 1064 1065 } 1066 1067 /*****************************************************************************/ 1068 1069 void RefRepeatArea32 (const uint32 *sPtr, 1070 uint32 *dPtr, 1071 uint32 rows, 1072 uint32 cols, 1073 uint32 planes, 1074 int32 rowStep, 1075 int32 colStep, 1076 int32 planeStep, 1077 uint32 repeatV, 1078 uint32 repeatH, 1079 uint32 phaseV, 1080 uint32 phaseH) 1081 { 1082 1083 const uint32 *sPtr0 = sPtr + phaseV * rowStep + 1084 phaseH * colStep; 1085 1086 int32 backStepV = (repeatV - 1) * rowStep; 1087 int32 backStepH = (repeatH - 1) * colStep; 1088 1089 for (uint32 row = 0; row < rows; row++) 1090 { 1091 1092 const uint32 *sPtr1 = sPtr0; 1093 uint32 *dPtr1 = dPtr; 1094 1095 uint32 colPhase = phaseH; 1096 1097 for (uint32 col = 0; col < cols; col++) 1098 { 1099 1100 const uint32 *sPtr2 = sPtr1; 1101 uint32 *dPtr2 = dPtr1; 1102 1103 for (uint32 plane = 0; plane < planes; plane++) 1104 { 1105 1106 *dPtr2 = *sPtr2; 1107 1108 sPtr2 += planeStep; 1109 dPtr2 += planeStep; 1110 1111 } 1112 1113 if (++colPhase == repeatH) 1114 { 1115 colPhase = 0; 1116 sPtr1 -= backStepH; 1117 } 1118 else 1119 { 1120 sPtr1 += colStep; 1121 } 1122 1123 dPtr1 += colStep; 1124 1125 } 1126 1127 if (++phaseV == repeatV) 1128 { 1129 phaseV = 0; 1130 sPtr0 -= backStepV; 1131 } 1132 else 1133 { 1134 sPtr0 += rowStep; 1135 } 1136 1137 dPtr += rowStep; 1138 1139 } 1140 1141 } 1142 1143 /*****************************************************************************/ 1144 1145 void RefShiftRight16 (uint16 *dPtr, 1146 uint32 rows, 1147 uint32 cols, 1148 uint32 planes, 1149 int32 rowStep, 1150 int32 colStep, 1151 int32 planeStep, 1152 uint32 shift) 1153 { 1154 1155 for (uint32 row = 0; row < rows; row++) 1156 { 1157 1158 uint16 *dPtr1 = dPtr; 1159 1160 for (uint32 col = 0; col < cols; col++) 1161 { 1162 1163 uint16 *dPtr2 = dPtr1; 1164 1165 for (uint32 plane = 0; plane < planes; plane++) 1166 { 1167 1168 *dPtr2 >>= shift; 1169 1170 dPtr2 += planeStep; 1171 1172 } 1173 1174 dPtr1 += colStep; 1175 1176 } 1177 1178 dPtr += rowStep; 1179 1180 } 1181 1182 } 1183 1184 /*****************************************************************************/ 1185 1186 void RefBilinearRow16 (const uint16 *sPtr, 1187 uint16 *dPtr, 1188 uint32 cols, 1189 uint32 patPhase, 1190 uint32 patCount, 1191 const uint32 * kernCounts, 1192 const int32 * const * kernOffsets, 1193 const uint16 * const * kernWeights, 1194 uint32 sShift) 1195 { 1196 1197 for (uint32 j = 0; j < cols; j++) 1198 { 1199 1200 const uint16 *p = sPtr + (j >> sShift); 1201 1202 uint32 count = kernCounts [patPhase]; 1203 1204 const int32 *offsets = kernOffsets [patPhase]; 1205 const uint16 *weights = kernWeights [patPhase]; 1206 1207 if (++patPhase == patCount) 1208 { 1209 patPhase = 0; 1210 } 1211 1212 uint32 total = 128; 1213 1214 for (uint32 k = 0; k < count; k++) 1215 { 1216 1217 int32 offset = offsets [k]; 1218 uint32 weight = weights [k]; 1219 1220 uint32 pixel = p [offset]; 1221 1222 total += pixel * weight; 1223 1224 } 1225 1226 dPtr [j] = (uint16) (total >> 8); 1227 1228 } 1229 1230 } 1231 1232 /*****************************************************************************/ 1233 1234 void RefBilinearRow32 (const real32 *sPtr, 1235 real32 *dPtr, 1236 uint32 cols, 1237 uint32 patPhase, 1238 uint32 patCount, 1239 const uint32 * kernCounts, 1240 const int32 * const * kernOffsets, 1241 const real32 * const * kernWeights, 1242 uint32 sShift) 1243 { 1244 1245 for (uint32 j = 0; j < cols; j++) 1246 { 1247 1248 const real32 *p = sPtr + (j >> sShift); 1249 1250 uint32 count = kernCounts [patPhase]; 1251 1252 const int32 *offsets = kernOffsets [patPhase]; 1253 const real32 *weights = kernWeights [patPhase]; 1254 1255 if (++patPhase == patCount) 1256 { 1257 patPhase = 0; 1258 } 1259 1260 real32 total = 0.0f; 1261 1262 for (uint32 k = 0; k < count; k++) 1263 { 1264 1265 int32 offset = offsets [k]; 1266 real32 weight = weights [k]; 1267 1268 real32 pixel = p [offset]; 1269 1270 total += pixel * weight; 1271 1272 } 1273 1274 dPtr [j] = total; 1275 1276 } 1277 1278 } 1279 1280 /*****************************************************************************/ 1281 1282 void RefBaselineABCtoRGB (const real32 *sPtrA, 1283 const real32 *sPtrB, 1284 const real32 *sPtrC, 1285 real32 *dPtrR, 1286 real32 *dPtrG, 1287 real32 *dPtrB, 1288 uint32 count, 1289 const dng_vector &cameraWhite, 1290 const dng_matrix &cameraToRGB) 1291 { 1292 1293 real32 clipA = (real32) cameraWhite [0]; 1294 real32 clipB = (real32) cameraWhite [1]; 1295 real32 clipC = (real32) cameraWhite [2]; 1296 1297 real32 m00 = (real32) cameraToRGB [0] [0]; 1298 real32 m01 = (real32) cameraToRGB [0] [1]; 1299 real32 m02 = (real32) cameraToRGB [0] [2]; 1300 1301 real32 m10 = (real32) cameraToRGB [1] [0]; 1302 real32 m11 = (real32) cameraToRGB [1] [1]; 1303 real32 m12 = (real32) cameraToRGB [1] [2]; 1304 1305 real32 m20 = (real32) cameraToRGB [2] [0]; 1306 real32 m21 = (real32) cameraToRGB [2] [1]; 1307 real32 m22 = (real32) cameraToRGB [2] [2]; 1308 1309 for (uint32 col = 0; col < count; col++) 1310 { 1311 1312 real32 A = sPtrA [col]; 1313 real32 B = sPtrB [col]; 1314 real32 C = sPtrC [col]; 1315 1316 A = Min_real32 (A, clipA); 1317 B = Min_real32 (B, clipB); 1318 C = Min_real32 (C, clipC); 1319 1320 real32 r = m00 * A + m01 * B + m02 * C; 1321 real32 g = m10 * A + m11 * B + m12 * C; 1322 real32 b = m20 * A + m21 * B + m22 * C; 1323 1324 r = Pin_real32 (0.0f, r, 1.0f); 1325 g = Pin_real32 (0.0f, g, 1.0f); 1326 b = Pin_real32 (0.0f, b, 1.0f); 1327 1328 dPtrR [col] = r; 1329 dPtrG [col] = g; 1330 dPtrB [col] = b; 1331 1332 } 1333 1334 } 1335 1336 /*****************************************************************************/ 1337 1338 void RefBaselineABCDtoRGB (const real32 *sPtrA, 1339 const real32 *sPtrB, 1340 const real32 *sPtrC, 1341 const real32 *sPtrD, 1342 real32 *dPtrR, 1343 real32 *dPtrG, 1344 real32 *dPtrB, 1345 uint32 count, 1346 const dng_vector &cameraWhite, 1347 const dng_matrix &cameraToRGB) 1348 { 1349 1350 real32 clipA = (real32) cameraWhite [0]; 1351 real32 clipB = (real32) cameraWhite [1]; 1352 real32 clipC = (real32) cameraWhite [2]; 1353 real32 clipD = (real32) cameraWhite [3]; 1354 1355 real32 m00 = (real32) cameraToRGB [0] [0]; 1356 real32 m01 = (real32) cameraToRGB [0] [1]; 1357 real32 m02 = (real32) cameraToRGB [0] [2]; 1358 real32 m03 = (real32) cameraToRGB [0] [3]; 1359 1360 real32 m10 = (real32) cameraToRGB [1] [0]; 1361 real32 m11 = (real32) cameraToRGB [1] [1]; 1362 real32 m12 = (real32) cameraToRGB [1] [2]; 1363 real32 m13 = (real32) cameraToRGB [1] [3]; 1364 1365 real32 m20 = (real32) cameraToRGB [2] [0]; 1366 real32 m21 = (real32) cameraToRGB [2] [1]; 1367 real32 m22 = (real32) cameraToRGB [2] [2]; 1368 real32 m23 = (real32) cameraToRGB [2] [3]; 1369 1370 for (uint32 col = 0; col < count; col++) 1371 { 1372 1373 real32 A = sPtrA [col]; 1374 real32 B = sPtrB [col]; 1375 real32 C = sPtrC [col]; 1376 real32 D = sPtrD [col]; 1377 1378 A = Min_real32 (A, clipA); 1379 B = Min_real32 (B, clipB); 1380 C = Min_real32 (C, clipC); 1381 D = Min_real32 (D, clipD); 1382 1383 real32 r = m00 * A + m01 * B + m02 * C + m03 * D; 1384 real32 g = m10 * A + m11 * B + m12 * C + m13 * D; 1385 real32 b = m20 * A + m21 * B + m22 * C + m23 * D; 1386 1387 r = Pin_real32 (0.0f, r, 1.0f); 1388 g = Pin_real32 (0.0f, g, 1.0f); 1389 b = Pin_real32 (0.0f, b, 1.0f); 1390 1391 dPtrR [col] = r; 1392 dPtrG [col] = g; 1393 dPtrB [col] = b; 1394 1395 } 1396 1397 } 1398 1399 /*****************************************************************************/ 1400 1401 void RefBaselineHueSatMap (const real32 *sPtrR, 1402 const real32 *sPtrG, 1403 const real32 *sPtrB, 1404 real32 *dPtrR, 1405 real32 *dPtrG, 1406 real32 *dPtrB, 1407 uint32 count, 1408 const dng_hue_sat_map &lut, 1409 const dng_1d_table *encodeTable, 1410 const dng_1d_table *decodeTable) 1411 { 1412 1413 uint32 hueDivisions; 1414 uint32 satDivisions; 1415 uint32 valDivisions; 1416 1417 lut.GetDivisions (hueDivisions, 1418 satDivisions, 1419 valDivisions); 1420 1421 real32 hScale = (hueDivisions < 2) ? 0.0f : (hueDivisions * (1.0f / 6.0f)); 1422 real32 sScale = (real32) ((int32) satDivisions - 1); 1423 real32 vScale = (real32) ((int32) valDivisions - 1); 1424 1425 int32 maxHueIndex0 = (int32) hueDivisions - 1; 1426 int32 maxSatIndex0 = (int32) satDivisions - 2; 1427 int32 maxValIndex0 = (int32) valDivisions - 2; 1428 1429 const bool hasEncodeTable = ((encodeTable != NULL) && (encodeTable->Table () != NULL)); 1430 const bool hasDecodeTable = ((decodeTable != NULL) && (decodeTable->Table () != NULL)); 1431 1432 const bool hasTable = hasEncodeTable && hasDecodeTable; 1433 1434 const dng_hue_sat_map::HSBModify *tableBase = lut.GetConstDeltas (); 1435 1436 int32 hueStep = satDivisions; 1437 int32 valStep = hueDivisions * hueStep; 1438 1439 #if 0 // Not required with "2.5D" table optimization. 1440 1441 if (valDivisions < 2) 1442 { 1443 valStep = 0; 1444 maxValIndex0 = 0; 1445 } 1446 1447 #endif 1448 1449 for (uint32 j = 0; j < count; j++) 1450 { 1451 1452 real32 r = sPtrR [j]; 1453 real32 g = sPtrG [j]; 1454 real32 b = sPtrB [j]; 1455 1456 real32 h, s, v; 1457 1458 DNG_RGBtoHSV (r, g, b, h, s, v); 1459 1460 real32 vEncoded = v; 1461 1462 real32 hueShift; 1463 real32 satScale; 1464 real32 valScale; 1465 1466 if (valDivisions < 2) // Optimize most common case of "2.5D" table. 1467 { 1468 1469 real32 hScaled = h * hScale; 1470 real32 sScaled = s * sScale; 1471 1472 int32 hIndex0 = (int32) hScaled; 1473 int32 sIndex0 = (int32) sScaled; 1474 1475 sIndex0 = Min_int32 (sIndex0, maxSatIndex0); 1476 1477 int32 hIndex1 = hIndex0 + 1; 1478 1479 if (hIndex0 >= maxHueIndex0) 1480 { 1481 hIndex0 = maxHueIndex0; 1482 hIndex1 = 0; 1483 } 1484 1485 real32 hFract1 = hScaled - (real32) hIndex0; 1486 real32 sFract1 = sScaled - (real32) sIndex0; 1487 1488 real32 hFract0 = 1.0f - hFract1; 1489 real32 sFract0 = 1.0f - sFract1; 1490 1491 const dng_hue_sat_map::HSBModify *entry00 = tableBase + hIndex0 * hueStep + 1492 sIndex0; 1493 1494 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep; 1495 1496 real32 hueShift0 = hFract0 * entry00->fHueShift + 1497 hFract1 * entry01->fHueShift; 1498 1499 real32 satScale0 = hFract0 * entry00->fSatScale + 1500 hFract1 * entry01->fSatScale; 1501 1502 real32 valScale0 = hFract0 * entry00->fValScale + 1503 hFract1 * entry01->fValScale; 1504 1505 entry00++; 1506 entry01++; 1507 1508 real32 hueShift1 = hFract0 * entry00->fHueShift + 1509 hFract1 * entry01->fHueShift; 1510 1511 real32 satScale1 = hFract0 * entry00->fSatScale + 1512 hFract1 * entry01->fSatScale; 1513 1514 real32 valScale1 = hFract0 * entry00->fValScale + 1515 hFract1 * entry01->fValScale; 1516 1517 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; 1518 satScale = sFract0 * satScale0 + sFract1 * satScale1; 1519 valScale = sFract0 * valScale0 + sFract1 * valScale1; 1520 1521 } 1522 1523 else 1524 { 1525 1526 if (hasTable) 1527 { 1528 vEncoded = encodeTable->Interpolate (Pin_real32 (v)); 1529 } 1530 1531 real32 hScaled = h * hScale; 1532 real32 sScaled = s * sScale; 1533 real32 vScaled = vEncoded * vScale; 1534 1535 int32 hIndex0 = (int32) hScaled; 1536 int32 sIndex0 = (int32) sScaled; 1537 int32 vIndex0 = (int32) vScaled; 1538 1539 sIndex0 = Min_int32 (sIndex0, maxSatIndex0); 1540 vIndex0 = Min_int32 (vIndex0, maxValIndex0); 1541 1542 int32 hIndex1 = hIndex0 + 1; 1543 1544 if (hIndex0 >= maxHueIndex0) 1545 { 1546 hIndex0 = maxHueIndex0; 1547 hIndex1 = 0; 1548 } 1549 1550 real32 hFract1 = hScaled - (real32) hIndex0; 1551 real32 sFract1 = sScaled - (real32) sIndex0; 1552 real32 vFract1 = vScaled - (real32) vIndex0; 1553 1554 real32 hFract0 = 1.0f - hFract1; 1555 real32 sFract0 = 1.0f - sFract1; 1556 real32 vFract0 = 1.0f - vFract1; 1557 1558 const dng_hue_sat_map::HSBModify *entry00 = tableBase + vIndex0 * valStep + 1559 hIndex0 * hueStep + 1560 sIndex0; 1561 1562 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep; 1563 1564 const dng_hue_sat_map::HSBModify *entry10 = entry00 + valStep; 1565 const dng_hue_sat_map::HSBModify *entry11 = entry01 + valStep; 1566 1567 real32 hueShift0 = vFract0 * (hFract0 * entry00->fHueShift + 1568 hFract1 * entry01->fHueShift) + 1569 vFract1 * (hFract0 * entry10->fHueShift + 1570 hFract1 * entry11->fHueShift); 1571 1572 real32 satScale0 = vFract0 * (hFract0 * entry00->fSatScale + 1573 hFract1 * entry01->fSatScale) + 1574 vFract1 * (hFract0 * entry10->fSatScale + 1575 hFract1 * entry11->fSatScale); 1576 1577 real32 valScale0 = vFract0 * (hFract0 * entry00->fValScale + 1578 hFract1 * entry01->fValScale) + 1579 vFract1 * (hFract0 * entry10->fValScale + 1580 hFract1 * entry11->fValScale); 1581 1582 entry00++; 1583 entry01++; 1584 entry10++; 1585 entry11++; 1586 1587 real32 hueShift1 = vFract0 * (hFract0 * entry00->fHueShift + 1588 hFract1 * entry01->fHueShift) + 1589 vFract1 * (hFract0 * entry10->fHueShift + 1590 hFract1 * entry11->fHueShift); 1591 1592 real32 satScale1 = vFract0 * (hFract0 * entry00->fSatScale + 1593 hFract1 * entry01->fSatScale) + 1594 vFract1 * (hFract0 * entry10->fSatScale + 1595 hFract1 * entry11->fSatScale); 1596 1597 real32 valScale1 = vFract0 * (hFract0 * entry00->fValScale + 1598 hFract1 * entry01->fValScale) + 1599 vFract1 * (hFract0 * entry10->fValScale + 1600 hFract1 * entry11->fValScale); 1601 1602 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; 1603 satScale = sFract0 * satScale0 + sFract1 * satScale1; 1604 valScale = sFract0 * valScale0 + sFract1 * valScale1; 1605 1606 } 1607 1608 hueShift *= (6.0f / 360.0f); // Convert to internal hue range. 1609 1610 h += hueShift; 1611 1612 s = Min_real32 (s * satScale, 1.0f); 1613 1614 vEncoded = Pin_real32 (vEncoded * valScale); 1615 1616 v = hasTable ? decodeTable->Interpolate (vEncoded) : vEncoded; 1617 1618 DNG_HSVtoRGB (h, s, v, r, g, b); 1619 1620 dPtrR [j] = r; 1621 dPtrG [j] = g; 1622 dPtrB [j] = b; 1623 1624 } 1625 1626 } 1627 1628 /*****************************************************************************/ 1629 1630 void RefBaselineRGBtoGray (const real32 *sPtrR, 1631 const real32 *sPtrG, 1632 const real32 *sPtrB, 1633 real32 *dPtrG, 1634 uint32 count, 1635 const dng_matrix &matrix) 1636 { 1637 1638 real32 m00 = (real32) matrix [0] [0]; 1639 real32 m01 = (real32) matrix [0] [1]; 1640 real32 m02 = (real32) matrix [0] [2]; 1641 1642 for (uint32 col = 0; col < count; col++) 1643 { 1644 1645 real32 R = sPtrR [col]; 1646 real32 G = sPtrG [col]; 1647 real32 B = sPtrB [col]; 1648 1649 real32 g = m00 * R + m01 * G + m02 * B; 1650 1651 g = Pin_real32 (0.0f, g, 1.0f); 1652 1653 dPtrG [col] = g; 1654 1655 } 1656 1657 } 1658 1659 /*****************************************************************************/ 1660 1661 void RefBaselineRGBtoRGB (const real32 *sPtrR, 1662 const real32 *sPtrG, 1663 const real32 *sPtrB, 1664 real32 *dPtrR, 1665 real32 *dPtrG, 1666 real32 *dPtrB, 1667 uint32 count, 1668 const dng_matrix &matrix) 1669 { 1670 1671 real32 m00 = (real32) matrix [0] [0]; 1672 real32 m01 = (real32) matrix [0] [1]; 1673 real32 m02 = (real32) matrix [0] [2]; 1674 1675 real32 m10 = (real32) matrix [1] [0]; 1676 real32 m11 = (real32) matrix [1] [1]; 1677 real32 m12 = (real32) matrix [1] [2]; 1678 1679 real32 m20 = (real32) matrix [2] [0]; 1680 real32 m21 = (real32) matrix [2] [1]; 1681 real32 m22 = (real32) matrix [2] [2]; 1682 1683 for (uint32 col = 0; col < count; col++) 1684 { 1685 1686 real32 R = sPtrR [col]; 1687 real32 G = sPtrG [col]; 1688 real32 B = sPtrB [col]; 1689 1690 real32 r = m00 * R + m01 * G + m02 * B; 1691 real32 g = m10 * R + m11 * G + m12 * B; 1692 real32 b = m20 * R + m21 * G + m22 * B; 1693 1694 r = Pin_real32 (0.0f, r, 1.0f); 1695 g = Pin_real32 (0.0f, g, 1.0f); 1696 b = Pin_real32 (0.0f, b, 1.0f); 1697 1698 dPtrR [col] = r; 1699 dPtrG [col] = g; 1700 dPtrB [col] = b; 1701 1702 } 1703 1704 } 1705 1706 /*****************************************************************************/ 1707 1708 void RefBaseline1DTable (const real32 *sPtr, 1709 real32 *dPtr, 1710 uint32 count, 1711 const dng_1d_table &table) 1712 { 1713 1714 for (uint32 col = 0; col < count; col++) 1715 { 1716 1717 real32 x = sPtr [col]; 1718 1719 real32 y = table.Interpolate (x); 1720 1721 dPtr [col] = y; 1722 1723 } 1724 1725 } 1726 1727 /*****************************************************************************/ 1728 1729 void RefBaselineRGBTone (const real32 *sPtrR, 1730 const real32 *sPtrG, 1731 const real32 *sPtrB, 1732 real32 *dPtrR, 1733 real32 *dPtrG, 1734 real32 *dPtrB, 1735 uint32 count, 1736 const dng_1d_table &table) 1737 { 1738 1739 for (uint32 col = 0; col < count; col++) 1740 { 1741 1742 real32 r = sPtrR [col]; 1743 real32 g = sPtrG [col]; 1744 real32 b = sPtrB [col]; 1745 1746 real32 rr; 1747 real32 gg; 1748 real32 bb; 1749 1750 #define RGBTone(r, g, b, rr, gg, bb)\ 1751 {\ 1752 \ 1753 DNG_ASSERT (r >= g && g >= b && r > b, "Logic Error RGBTone");\ 1754 \ 1755 rr = table.Interpolate (r);\ 1756 bb = table.Interpolate (b);\ 1757 \ 1758 gg = bb + ((rr - bb) * (g - b) / (r - b));\ 1759 \ 1760 } 1761 1762 if (r >= g) 1763 { 1764 1765 if (g > b) 1766 { 1767 1768 // Case 1: r >= g > b 1769 1770 RGBTone (r, g, b, rr, gg, bb); 1771 1772 } 1773 1774 else if (b > r) 1775 { 1776 1777 // Case 2: b > r >= g 1778 1779 RGBTone (b, r, g, bb, rr, gg); 1780 1781 } 1782 1783 else if (b > g) 1784 { 1785 1786 // Case 3: r >= b > g 1787 1788 RGBTone (r, b, g, rr, bb, gg); 1789 1790 } 1791 1792 else 1793 { 1794 1795 // Case 4: r >= g == b 1796 1797 DNG_ASSERT (r >= g && g == b, "Logic Error 2"); 1798 1799 rr = table.Interpolate (r); 1800 gg = table.Interpolate (g); 1801 bb = gg; 1802 1803 } 1804 1805 } 1806 1807 else 1808 { 1809 1810 if (r >= b) 1811 { 1812 1813 // Case 5: g > r >= b 1814 1815 RGBTone (g, r, b, gg, rr, bb); 1816 1817 } 1818 1819 else if (b > g) 1820 { 1821 1822 // Case 6: b > g > r 1823 1824 RGBTone (b, g, r, bb, gg, rr); 1825 1826 } 1827 1828 else 1829 { 1830 1831 // Case 7: g >= b > r 1832 1833 RGBTone (g, b, r, gg, bb, rr); 1834 1835 } 1836 1837 } 1838 1839 #undef RGBTone 1840 1841 dPtrR [col] = rr; 1842 dPtrG [col] = gg; 1843 dPtrB [col] = bb; 1844 1845 } 1846 1847 } 1848 1849 /*****************************************************************************/ 1850 1851 void RefResampleDown16 (const uint16 *sPtr, 1852 uint16 *dPtr, 1853 uint32 sCount, 1854 int32 sRowStep, 1855 const int16 *wPtr, 1856 uint32 wCount, 1857 uint32 pixelRange) 1858 { 1859 1860 for (uint32 j = 0; j < sCount; j++) 1861 { 1862 1863 int32 total = 8192; 1864 1865 const uint16 *s = sPtr + j; 1866 1867 for (uint32 k = 0; k < wCount; k++) 1868 { 1869 1870 total += wPtr [k] * (int32) s [0]; 1871 1872 s += sRowStep; 1873 1874 } 1875 1876 dPtr [j] = (uint16) Pin_int32 (0, 1877 total >> 14, 1878 pixelRange); 1879 1880 } 1881 1882 } 1883 1884 /*****************************************************************************/ 1885 1886 void RefResampleDown32 (const real32 *sPtr, 1887 real32 *dPtr, 1888 uint32 sCount, 1889 int32 sRowStep, 1890 const real32 *wPtr, 1891 uint32 wCount) 1892 { 1893 1894 uint32 col; 1895 1896 // Process first row. 1897 1898 real32 w = wPtr [0]; 1899 1900 for (col = 0; col < sCount; col++) 1901 { 1902 1903 dPtr [col] = w * sPtr [col]; 1904 1905 } 1906 1907 sPtr += sRowStep; 1908 1909 // Process middle rows. 1910 1911 for (uint32 j = 1; j < wCount - 1; j++) 1912 { 1913 1914 w = wPtr [j]; 1915 1916 for (col = 0; col < sCount; col++) 1917 { 1918 1919 dPtr [col] += w * sPtr [col]; 1920 1921 } 1922 1923 sPtr += sRowStep; 1924 1925 } 1926 1927 // Process last row. 1928 1929 w = wPtr [wCount - 1]; 1930 1931 for (col = 0; col < sCount; col++) 1932 { 1933 1934 dPtr [col] = Pin_real32 (0.0f, 1935 dPtr [col] + w * sPtr [col], 1936 1.0f); 1937 1938 } 1939 1940 } 1941 1942 /******************************************************************************/ 1943 1944 void RefResampleAcross16 (const uint16 *sPtr, 1945 uint16 *dPtr, 1946 uint32 dCount, 1947 const int32 *coord, 1948 const int16 *wPtr, 1949 uint32 wCount, 1950 uint32 wStep, 1951 uint32 pixelRange) 1952 { 1953 1954 for (uint32 j = 0; j < dCount; j++) 1955 { 1956 1957 int32 sCoord = coord [j]; 1958 1959 int32 sFract = sCoord & kResampleSubsampleMask; 1960 int32 sPixel = sCoord >> kResampleSubsampleBits; 1961 1962 const int16 *w = wPtr + sFract * wStep; 1963 const uint16 *s = sPtr + sPixel; 1964 1965 int32 total = w [0] * (int32) s [0]; 1966 1967 for (uint32 k = 1; k < wCount; k++) 1968 { 1969 1970 total += w [k] * (int32) s [k]; 1971 1972 } 1973 1974 dPtr [j] = (uint16) Pin_int32 (0, 1975 (total + 8192) >> 14, 1976 pixelRange); 1977 1978 } 1979 1980 } 1981 1982 /******************************************************************************/ 1983 1984 void RefResampleAcross32 (const real32 *sPtr, 1985 real32 *dPtr, 1986 uint32 dCount, 1987 const int32 *coord, 1988 const real32 *wPtr, 1989 uint32 wCount, 1990 uint32 wStep) 1991 { 1992 1993 for (uint32 j = 0; j < dCount; j++) 1994 { 1995 1996 int32 sCoord = coord [j]; 1997 1998 int32 sFract = sCoord & kResampleSubsampleMask; 1999 int32 sPixel = sCoord >> kResampleSubsampleBits; 2000 2001 const real32 *w = wPtr + sFract * wStep; 2002 const real32 *s = sPtr + sPixel; 2003 2004 real32 total = w [0] * s [0]; 2005 2006 for (uint32 k = 1; k < wCount; k++) 2007 { 2008 2009 total += w [k] * s [k]; 2010 2011 } 2012 2013 dPtr [j] = Pin_real32 (0.0f, total, 1.0f); 2014 2015 } 2016 2017 } 2018 2019 /*****************************************************************************/ 2020 2021 bool RefEqualBytes (const void *sPtr, 2022 const void *dPtr, 2023 uint32 count) 2024 { 2025 2026 return memcmp (dPtr, sPtr, count) == 0; 2027 2028 } 2029 2030 /*****************************************************************************/ 2031 2032 bool RefEqualArea8 (const uint8 *sPtr, 2033 const uint8 *dPtr, 2034 uint32 rows, 2035 uint32 cols, 2036 uint32 planes, 2037 int32 sRowStep, 2038 int32 sColStep, 2039 int32 sPlaneStep, 2040 int32 dRowStep, 2041 int32 dColStep, 2042 int32 dPlaneStep) 2043 { 2044 2045 for (uint32 row = 0; row < rows; row++) 2046 { 2047 2048 const uint8 *sPtr1 = sPtr; 2049 const uint8 *dPtr1 = dPtr; 2050 2051 for (uint32 col = 0; col < cols; col++) 2052 { 2053 2054 const uint8 *sPtr2 = sPtr1; 2055 const uint8 *dPtr2 = dPtr1; 2056 2057 for (uint32 plane = 0; plane < planes; plane++) 2058 { 2059 2060 if (*dPtr2 != *sPtr2) 2061 return false; 2062 2063 sPtr2 += sPlaneStep; 2064 dPtr2 += dPlaneStep; 2065 2066 } 2067 2068 sPtr1 += sColStep; 2069 dPtr1 += dColStep; 2070 2071 } 2072 2073 sPtr += sRowStep; 2074 dPtr += dRowStep; 2075 2076 } 2077 2078 return true; 2079 2080 } 2081 2082 /*****************************************************************************/ 2083 2084 bool RefEqualArea16 (const uint16 *sPtr, 2085 const uint16 *dPtr, 2086 uint32 rows, 2087 uint32 cols, 2088 uint32 planes, 2089 int32 sRowStep, 2090 int32 sColStep, 2091 int32 sPlaneStep, 2092 int32 dRowStep, 2093 int32 dColStep, 2094 int32 dPlaneStep) 2095 { 2096 2097 for (uint32 row = 0; row < rows; row++) 2098 { 2099 2100 const uint16 *sPtr1 = sPtr; 2101 const uint16 *dPtr1 = dPtr; 2102 2103 for (uint32 col = 0; col < cols; col++) 2104 { 2105 2106 const uint16 *sPtr2 = sPtr1; 2107 const uint16 *dPtr2 = dPtr1; 2108 2109 for (uint32 plane = 0; plane < planes; plane++) 2110 { 2111 2112 if (*dPtr2 != *sPtr2) 2113 return false; 2114 2115 sPtr2 += sPlaneStep; 2116 dPtr2 += dPlaneStep; 2117 2118 } 2119 2120 sPtr1 += sColStep; 2121 dPtr1 += dColStep; 2122 2123 } 2124 2125 sPtr += sRowStep; 2126 dPtr += dRowStep; 2127 2128 } 2129 2130 return true; 2131 2132 } 2133 2134 /*****************************************************************************/ 2135 2136 bool RefEqualArea32 (const uint32 *sPtr, 2137 const uint32 *dPtr, 2138 uint32 rows, 2139 uint32 cols, 2140 uint32 planes, 2141 int32 sRowStep, 2142 int32 sColStep, 2143 int32 sPlaneStep, 2144 int32 dRowStep, 2145 int32 dColStep, 2146 int32 dPlaneStep) 2147 { 2148 2149 for (uint32 row = 0; row < rows; row++) 2150 { 2151 2152 const uint32 *sPtr1 = sPtr; 2153 const uint32 *dPtr1 = dPtr; 2154 2155 for (uint32 col = 0; col < cols; col++) 2156 { 2157 2158 const uint32 *sPtr2 = sPtr1; 2159 const uint32 *dPtr2 = dPtr1; 2160 2161 for (uint32 plane = 0; plane < planes; plane++) 2162 { 2163 2164 if (*dPtr2 != *sPtr2) 2165 return false; 2166 2167 sPtr2 += sPlaneStep; 2168 dPtr2 += dPlaneStep; 2169 2170 } 2171 2172 sPtr1 += sColStep; 2173 dPtr1 += dColStep; 2174 2175 } 2176 2177 sPtr += sRowStep; 2178 dPtr += dRowStep; 2179 2180 } 2181 2182 return true; 2183 2184 } 2185 2186 /*****************************************************************************/ 2187 2188 void RefVignetteMask16 (uint16 *mPtr, 2189 uint32 rows, 2190 uint32 cols, 2191 int32 rowStep, 2192 int64 offsetH, 2193 int64 offsetV, 2194 int64 stepH, 2195 int64 stepV, 2196 uint32 tBits, 2197 const uint16 *table) 2198 { 2199 2200 uint32 tShift = 32 - tBits; 2201 uint32 tRound = (1 << (tShift - 1)); 2202 uint32 tLimit = 1 << tBits; 2203 2204 for (uint32 row = 0; row < rows; row++) 2205 { 2206 2207 int64 baseDelta = (offsetV + 32768) >> 16; 2208 2209 baseDelta = baseDelta * baseDelta + tRound; 2210 2211 int64 deltaH = offsetH + 32768; 2212 2213 for (uint32 col = 0; col < cols; col++) 2214 { 2215 2216 int64 temp = deltaH >> 16; 2217 2218 int64 delta = baseDelta + (temp * temp); 2219 2220 uint32 index = Min_uint32 ((uint32) (delta >> tShift), tLimit); 2221 2222 mPtr [col] = table [index]; 2223 2224 deltaH += stepH; 2225 2226 } 2227 2228 offsetV += stepV; 2229 2230 mPtr += rowStep; 2231 2232 } 2233 2234 } 2235 2236 /*****************************************************************************/ 2237 2238 void RefVignette16 (int16 *sPtr, 2239 const uint16 *mPtr, 2240 uint32 rows, 2241 uint32 cols, 2242 uint32 planes, 2243 int32 sRowStep, 2244 int32 sPlaneStep, 2245 int32 mRowStep, 2246 uint32 mBits) 2247 { 2248 2249 const uint32 mRound = 1 << (mBits - 1); 2250 2251 switch (planes) 2252 { 2253 2254 case 1: 2255 { 2256 2257 for (uint32 row = 0; row < rows; row++) 2258 { 2259 2260 for (uint32 col = 0; col < cols; col++) 2261 { 2262 2263 uint32 s = sPtr [col] + 32768; 2264 2265 uint32 m = mPtr [col]; 2266 2267 s = (s * m + mRound) >> mBits; 2268 2269 s = Min_uint32 (s, 65535); 2270 2271 sPtr [col] = (int16) (s - 32768); 2272 2273 } 2274 2275 sPtr += sRowStep; 2276 2277 mPtr += mRowStep; 2278 2279 } 2280 2281 break; 2282 2283 } 2284 2285 case 3: 2286 { 2287 2288 int16 *rPtr = sPtr; 2289 int16 *gPtr = rPtr + sPlaneStep; 2290 int16 *bPtr = gPtr + sPlaneStep; 2291 2292 for (uint32 row = 0; row < rows; row++) 2293 { 2294 2295 for (uint32 col = 0; col < cols; col++) 2296 { 2297 2298 uint32 r = rPtr [col] + 32768; 2299 uint32 g = gPtr [col] + 32768; 2300 uint32 b = bPtr [col] + 32768; 2301 2302 uint32 m = mPtr [col]; 2303 2304 r = (r * m + mRound) >> mBits; 2305 g = (g * m + mRound) >> mBits; 2306 b = (b * m + mRound) >> mBits; 2307 2308 r = Min_uint32 (r, 65535); 2309 g = Min_uint32 (g, 65535); 2310 b = Min_uint32 (b, 65535); 2311 2312 rPtr [col] = (int16) (r - 32768); 2313 gPtr [col] = (int16) (g - 32768); 2314 bPtr [col] = (int16) (b - 32768); 2315 2316 } 2317 2318 rPtr += sRowStep; 2319 gPtr += sRowStep; 2320 bPtr += sRowStep; 2321 2322 mPtr += mRowStep; 2323 2324 } 2325 2326 break; 2327 2328 } 2329 2330 case 4: 2331 { 2332 2333 int16 *aPtr = sPtr; 2334 int16 *bPtr = aPtr + sPlaneStep; 2335 int16 *cPtr = bPtr + sPlaneStep; 2336 int16 *dPtr = cPtr + sPlaneStep; 2337 2338 for (uint32 row = 0; row < rows; row++) 2339 { 2340 2341 for (uint32 col = 0; col < cols; col++) 2342 { 2343 2344 uint32 a = aPtr [col] + 32768; 2345 uint32 b = bPtr [col] + 32768; 2346 uint32 c = cPtr [col] + 32768; 2347 uint32 d = dPtr [col] + 32768; 2348 2349 uint32 m = mPtr [col]; 2350 2351 a = (a * m + mRound) >> mBits; 2352 b = (b * m + mRound) >> mBits; 2353 c = (c * m + mRound) >> mBits; 2354 d = (d * m + mRound) >> mBits; 2355 2356 a = Min_uint32 (a, 65535); 2357 b = Min_uint32 (b, 65535); 2358 c = Min_uint32 (c, 65535); 2359 d = Min_uint32 (d, 65535); 2360 2361 aPtr [col] = (int16) (a - 32768); 2362 bPtr [col] = (int16) (b - 32768); 2363 cPtr [col] = (int16) (c - 32768); 2364 dPtr [col] = (int16) (d - 32768); 2365 2366 } 2367 2368 aPtr += sRowStep; 2369 bPtr += sRowStep; 2370 cPtr += sRowStep; 2371 dPtr += sRowStep; 2372 2373 mPtr += mRowStep; 2374 2375 } 2376 2377 break; 2378 2379 } 2380 2381 default: 2382 { 2383 2384 for (uint32 plane = 0; plane < planes; plane++) 2385 { 2386 2387 int16 *planePtr = sPtr; 2388 2389 const uint16 *maskPtr = mPtr; 2390 2391 for (uint32 row = 0; row < rows; row++) 2392 { 2393 2394 for (uint32 col = 0; col < cols; col++) 2395 { 2396 2397 uint32 s = planePtr [col] + 32768; 2398 2399 uint32 m = maskPtr [col]; 2400 2401 s = (s * m + mRound) >> mBits; 2402 2403 s = Min_uint32 (s, 65535); 2404 2405 planePtr [col] = (int16) (s - 32768); 2406 2407 } 2408 2409 planePtr += sRowStep; 2410 2411 maskPtr += mRowStep; 2412 2413 } 2414 2415 sPtr += sPlaneStep; 2416 2417 } 2418 2419 break; 2420 2421 } 2422 2423 } 2424 2425 } 2426 2427 /*****************************************************************************/ 2428 2429 void RefVignette32 (real32 *sPtr, 2430 const uint16 *mPtr, 2431 uint32 rows, 2432 uint32 cols, 2433 uint32 planes, 2434 int32 sRowStep, 2435 int32 sPlaneStep, 2436 int32 mRowStep, 2437 uint32 mBits) 2438 { 2439 2440 const real32 kNorm = 1.0f / (1 << mBits); 2441 2442 switch (planes) 2443 { 2444 2445 case 1: 2446 { 2447 2448 for (uint32 row = 0; row < rows; row++) 2449 { 2450 2451 for (uint32 col = 0; col < cols; col++) 2452 { 2453 2454 real32 s = sPtr [col]; 2455 2456 uint16 m = mPtr [col]; 2457 2458 real32 scale = m * kNorm; 2459 2460 s = Min_real32 (s * scale, 1.0f); 2461 2462 sPtr [col] = s; 2463 2464 } 2465 2466 sPtr += sRowStep; 2467 2468 mPtr += mRowStep; 2469 2470 } 2471 2472 break; 2473 2474 } 2475 2476 case 3: 2477 { 2478 2479 real32 *rPtr = sPtr; 2480 real32 *gPtr = rPtr + sPlaneStep; 2481 real32 *bPtr = gPtr + sPlaneStep; 2482 2483 for (uint32 row = 0; row < rows; row++) 2484 { 2485 2486 for (uint32 col = 0; col < cols; col++) 2487 { 2488 2489 real32 r = rPtr [col]; 2490 real32 g = gPtr [col]; 2491 real32 b = bPtr [col]; 2492 2493 uint16 m = mPtr [col]; 2494 2495 real32 scale = m * kNorm; 2496 2497 r = Min_real32 (r * scale, 1.0f); 2498 g = Min_real32 (g * scale, 1.0f); 2499 b = Min_real32 (b * scale, 1.0f); 2500 2501 rPtr [col] = r; 2502 gPtr [col] = g; 2503 bPtr [col] = b; 2504 2505 } 2506 2507 rPtr += sRowStep; 2508 gPtr += sRowStep; 2509 bPtr += sRowStep; 2510 2511 mPtr += mRowStep; 2512 2513 } 2514 2515 break; 2516 2517 } 2518 2519 case 4: 2520 { 2521 2522 real32 *aPtr = sPtr; 2523 real32 *bPtr = aPtr + sPlaneStep; 2524 real32 *cPtr = bPtr + sPlaneStep; 2525 real32 *dPtr = cPtr + sPlaneStep; 2526 2527 for (uint32 row = 0; row < rows; row++) 2528 { 2529 2530 for (uint32 col = 0; col < cols; col++) 2531 { 2532 2533 real32 a = aPtr [col]; 2534 real32 b = bPtr [col]; 2535 real32 c = cPtr [col]; 2536 real32 d = dPtr [col]; 2537 2538 uint16 m = mPtr [col]; 2539 2540 real32 scale = m * kNorm; 2541 2542 a = Min_real32 (a * scale, 1.0f); 2543 b = Min_real32 (b * scale, 1.0f); 2544 c = Min_real32 (c * scale, 1.0f); 2545 d = Min_real32 (d * scale, 1.0f); 2546 2547 aPtr [col] = a; 2548 bPtr [col] = b; 2549 cPtr [col] = c; 2550 dPtr [col] = d; 2551 2552 } 2553 2554 aPtr += sRowStep; 2555 bPtr += sRowStep; 2556 cPtr += sRowStep; 2557 dPtr += sRowStep; 2558 2559 mPtr += mRowStep; 2560 2561 } 2562 2563 break; 2564 2565 } 2566 2567 default: 2568 { 2569 2570 for (uint32 plane = 0; plane < planes; plane++) 2571 { 2572 2573 real32 *planePtr = sPtr; 2574 2575 const uint16 *maskPtr = mPtr; 2576 2577 for (uint32 row = 0; row < rows; row++) 2578 { 2579 2580 for (uint32 col = 0; col < cols; col++) 2581 { 2582 2583 real32 s = planePtr [col]; 2584 2585 uint16 m = maskPtr [col]; 2586 2587 real32 scale = m * kNorm; 2588 2589 s = Min_real32 (s * scale, 1.0f); 2590 2591 planePtr [col] = s; 2592 2593 } 2594 2595 planePtr += sRowStep; 2596 2597 maskPtr += mRowStep; 2598 2599 } 2600 2601 sPtr += sPlaneStep; 2602 2603 } 2604 2605 break; 2606 2607 } 2608 2609 } 2610 2611 } 2612 2613 /******************************************************************************/ 2614 2615 void RefMapArea16 (uint16 *dPtr, 2616 uint32 count0, 2617 uint32 count1, 2618 uint32 count2, 2619 int32 step0, 2620 int32 step1, 2621 int32 step2, 2622 const uint16 *map) 2623 { 2624 2625 if (step2 == 1 && count2 >= 32) 2626 { 2627 2628 for (uint32 index0 = 0; index0 < count0; index0++) 2629 { 2630 2631 uint16 *d1 = dPtr; 2632 2633 for (uint32 index1 = 0; index1 < count1; index1++) 2634 { 2635 2636 uint16 *d2 = d1; 2637 2638 uint32 count = count2; 2639 2640 // Get the data 32-bit aligned if it is not. 2641 2642 if (!IsAligned32 (dPtr)) 2643 { 2644 2645 d2 [0] = map [d2 [0]]; 2646 2647 count--; 2648 2649 d2++; 2650 2651 } 2652 2653 // Use 32-bit reads and writes for bulk processing. 2654 2655 uint32 *dPtr32 = (uint32 *) d2; 2656 2657 // Process in blocks of 16 pixels. 2658 2659 uint32 blocks = count >> 4; 2660 2661 count -= blocks << 4; 2662 d2 += blocks << 4; 2663 2664 while (blocks--) 2665 { 2666 2667 uint32 x0, x1, x2, x3, x4, x5, x6, x7; 2668 uint32 p0, p1, p2, p3, p4, p5, p6, p7; 2669 2670 // Use 32 bit reads & writes, and pack and unpack the 16-bit values. 2671 // This results in slightly higher performance. 2672 2673 // Note that this code runs on both little-endian and big-endian systems, 2674 // since the pixels are either never swapped or double swapped. 2675 2676 x0 = dPtr32 [0]; 2677 x1 = dPtr32 [1]; 2678 x2 = dPtr32 [2]; 2679 x3 = dPtr32 [3]; 2680 2681 p0 = map [x0 >> 16 ]; 2682 p1 = map [x0 & 0x0FFFF]; 2683 p2 = map [x1 >> 16 ]; 2684 p3 = map [x1 & 0x0FFFF]; 2685 p4 = map [x2 >> 16 ]; 2686 p5 = map [x2 & 0x0FFFF]; 2687 p6 = map [x3 >> 16 ]; 2688 p7 = map [x3 & 0x0FFFF]; 2689 2690 x0 = (p0 << 16) | p1; 2691 x1 = (p2 << 16) | p3; 2692 x2 = (p4 << 16) | p5; 2693 x3 = (p6 << 16) | p7; 2694 2695 x4 = dPtr32 [4]; 2696 x5 = dPtr32 [5]; 2697 x6 = dPtr32 [6]; 2698 x7 = dPtr32 [7]; 2699 2700 dPtr32 [0] = x0; 2701 dPtr32 [1] = x1; 2702 dPtr32 [2] = x2; 2703 dPtr32 [3] = x3; 2704 2705 p0 = map [x4 >> 16 ]; 2706 p1 = map [x4 & 0x0FFFF]; 2707 p2 = map [x5 >> 16 ]; 2708 p3 = map [x5 & 0x0FFFF]; 2709 p4 = map [x6 >> 16 ]; 2710 p5 = map [x6 & 0x0FFFF]; 2711 p6 = map [x7 >> 16 ]; 2712 p7 = map [x7 & 0x0FFFF]; 2713 2714 x4 = (p0 << 16) | p1; 2715 x5 = (p2 << 16) | p3; 2716 x6 = (p4 << 16) | p5; 2717 x7 = (p6 << 16) | p7; 2718 2719 dPtr32 [4] = x4; 2720 dPtr32 [5] = x5; 2721 dPtr32 [6] = x6; 2722 dPtr32 [7] = x7; 2723 2724 dPtr32 += 8; 2725 2726 } 2727 2728 // Process remaining columns. 2729 2730 for (uint32 j = 0; j < count; j++) 2731 { 2732 2733 d2 [j] = map [d2 [j]]; 2734 2735 } 2736 2737 d1 += step1; 2738 2739 } 2740 2741 dPtr += step0; 2742 2743 } 2744 2745 } 2746 2747 else 2748 { 2749 2750 for (uint32 index0 = 0; index0 < count0; index0++) 2751 { 2752 2753 uint16 *d1 = dPtr; 2754 2755 for (uint32 index1 = 0; index1 < count1; index1++) 2756 { 2757 2758 uint16 *d2 = d1; 2759 2760 for (uint32 index2 = 0; index2 < count2; index2++) 2761 { 2762 2763 d2 [0] = map [d2 [0]]; 2764 2765 d2 += step2; 2766 2767 } 2768 2769 d1 += step1; 2770 2771 } 2772 2773 dPtr += step0; 2774 2775 } 2776 2777 } 2778 2779 } 2780 2781 /*****************************************************************************/ 2782