1 /*****************************************************************************/ 2 // Copyright 2008-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_misc_opcodes.cpp#1 $ */ 10 /* $DateTime: 2012/05/30 13:28:51 $ */ 11 /* $Change: 832332 $ */ 12 /* $Author: tknoll $ */ 13 14 /*****************************************************************************/ 15 16 #include "dng_misc_opcodes.h" 17 18 #include "dng_bottlenecks.h" 19 #include "dng_exceptions.h" 20 #include "dng_globals.h" 21 #include "dng_host.h" 22 #include "dng_image.h" 23 #include "dng_rect.h" 24 #include "dng_safe_arithmetic.h" 25 #include "dng_stream.h" 26 #include "dng_tag_values.h" 27 28 /*****************************************************************************/ 29 30 dng_opcode_TrimBounds::dng_opcode_TrimBounds (const dng_rect &bounds) 31 32 : dng_opcode (dngOpcode_TrimBounds, 33 dngVersion_1_3_0_0, 34 kFlag_None) 35 36 , fBounds (bounds) 37 38 { 39 40 } 41 42 /*****************************************************************************/ 43 44 dng_opcode_TrimBounds::dng_opcode_TrimBounds (dng_stream &stream) 45 46 : dng_opcode (dngOpcode_TrimBounds, 47 stream, 48 "TrimBounds") 49 50 , fBounds () 51 52 { 53 54 if (stream.Get_uint32 () != 16) 55 { 56 ThrowBadFormat (); 57 } 58 59 fBounds.t = stream.Get_int32 (); 60 fBounds.l = stream.Get_int32 (); 61 fBounds.b = stream.Get_int32 (); 62 fBounds.r = stream.Get_int32 (); 63 64 if (fBounds.IsEmpty ()) 65 { 66 ThrowBadFormat (); 67 } 68 69 #if qDNGValidate 70 71 if (gVerbose) 72 { 73 74 printf ("Bounds: t=%d, l=%d, b=%d, r=%d\n", 75 (int) fBounds.t, 76 (int) fBounds.l, 77 (int) fBounds.b, 78 (int) fBounds.r); 79 80 } 81 82 #endif 83 84 } 85 86 /*****************************************************************************/ 87 88 void dng_opcode_TrimBounds::PutData (dng_stream &stream) const 89 { 90 91 stream.Put_uint32 (16); 92 93 stream.Put_int32 (fBounds.t); 94 stream.Put_int32 (fBounds.l); 95 stream.Put_int32 (fBounds.b); 96 stream.Put_int32 (fBounds.r); 97 98 } 99 100 /*****************************************************************************/ 101 102 void dng_opcode_TrimBounds::Apply (dng_host & /* host */, 103 dng_negative & /* negative */, 104 AutoPtr<dng_image> &image) 105 { 106 107 if (fBounds.IsEmpty () || (fBounds & image->Bounds ()) != fBounds) 108 { 109 ThrowBadFormat (); 110 } 111 112 image->Trim (fBounds); 113 114 } 115 116 /*****************************************************************************/ 117 118 void dng_area_spec::GetData (dng_stream &stream) 119 { 120 121 fArea.t = stream.Get_int32 (); 122 fArea.l = stream.Get_int32 (); 123 fArea.b = stream.Get_int32 (); 124 fArea.r = stream.Get_int32 (); 125 126 fPlane = stream.Get_uint32 (); 127 fPlanes = stream.Get_uint32 (); 128 129 fRowPitch = stream.Get_uint32 (); 130 fColPitch = stream.Get_uint32 (); 131 132 if (fPlanes < 1) 133 { 134 ThrowBadFormat (); 135 } 136 137 if (fRowPitch < 1 || fColPitch < 1) 138 { 139 ThrowBadFormat (); 140 } 141 142 if (fArea.IsEmpty ()) 143 { 144 if (fRowPitch != 1 || fColPitch != 1) 145 { 146 ThrowBadFormat (); 147 } 148 } 149 150 else 151 { 152 int32 width = 0; 153 int32 height = 0; 154 if (!SafeInt32Sub (fArea.b, fArea.t, &height) || 155 !SafeInt32Sub (fArea.r, fArea.l, &width) || 156 fRowPitch > static_cast<uint32>(height) || 157 fColPitch > static_cast<uint32>(width)) 158 { 159 ThrowBadFormat(); 160 } 161 } 162 163 #if qDNGValidate 164 165 if (gVerbose) 166 { 167 168 printf ("AreaSpec: t=%d, l=%d, b=%d, r=%d, p=%u:%u, rp=%u, cp=%u\n", 169 (int) fArea.t, 170 (int) fArea.l, 171 (int) fArea.b, 172 (int) fArea.r, 173 (unsigned) fPlane, 174 (unsigned) fPlanes, 175 (unsigned) fRowPitch, 176 (unsigned) fColPitch); 177 178 } 179 180 #endif 181 182 } 183 184 /*****************************************************************************/ 185 186 void dng_area_spec::PutData (dng_stream &stream) const 187 { 188 189 stream.Put_int32 (fArea.t); 190 stream.Put_int32 (fArea.l); 191 stream.Put_int32 (fArea.b); 192 stream.Put_int32 (fArea.r); 193 194 stream.Put_uint32 (fPlane); 195 stream.Put_uint32 (fPlanes); 196 197 stream.Put_uint32 (fRowPitch); 198 stream.Put_uint32 (fColPitch); 199 200 } 201 202 /*****************************************************************************/ 203 204 dng_rect dng_area_spec::Overlap (const dng_rect &tile) const 205 { 206 207 // Special case - if the fArea is empty, then dng_area_spec covers 208 // the entire image, no matter how large it is. 209 210 if (fArea.IsEmpty ()) 211 { 212 return tile; 213 } 214 215 dng_rect overlap = fArea & tile; 216 217 if (overlap.NotEmpty ()) 218 { 219 220 overlap.t = fArea.t + ConvertUint32ToInt32( 221 RoundUpUint32ToMultiple(static_cast<uint32>(overlap.t - fArea.t), 222 fRowPitch)); 223 overlap.l = fArea.l + ConvertUint32ToInt32( 224 RoundUpUint32ToMultiple(static_cast<uint32>(overlap.l - fArea.l), 225 fColPitch)); 226 227 if (overlap.NotEmpty ()) 228 { 229 230 overlap.b = overlap.t + ((overlap.H () - 1) / fRowPitch) * fRowPitch + 1; 231 overlap.r = overlap.l + ((overlap.W () - 1) / fColPitch) * fColPitch + 1; 232 233 return overlap; 234 235 } 236 237 } 238 239 return dng_rect (); 240 241 } 242 243 /*****************************************************************************/ 244 245 dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host, 246 const dng_area_spec &areaSpec, 247 const uint16 *table, 248 uint32 count) 249 250 : dng_inplace_opcode (dngOpcode_MapTable, 251 dngVersion_1_3_0_0, 252 kFlag_None) 253 254 , fAreaSpec (areaSpec) 255 , fTable () 256 , fCount (count) 257 258 { 259 260 if (count == 0 || count > 0x10000) 261 { 262 ThrowProgramError (); 263 } 264 265 fTable.Reset (host.Allocate (0x10000 * sizeof (uint16))); 266 267 DoCopyBytes (table, 268 fTable->Buffer (), 269 count * (uint32) sizeof (uint16)); 270 271 ReplicateLastEntry (); 272 273 } 274 275 /*****************************************************************************/ 276 277 dng_opcode_MapTable::dng_opcode_MapTable (dng_host &host, 278 dng_stream &stream) 279 280 : dng_inplace_opcode (dngOpcode_MapTable, 281 stream, 282 "MapTable") 283 284 , fAreaSpec () 285 , fTable () 286 , fCount (0) 287 288 { 289 290 uint32 dataSize = stream.Get_uint32 (); 291 292 fAreaSpec.GetData (stream); 293 294 fCount = stream.Get_uint32 (); 295 296 uint32 requiredSize = SafeUint32Mult(fCount, 2); 297 requiredSize = SafeUint32Add(requiredSize, dng_area_spec::kDataSize); 298 requiredSize = SafeUint32Add(requiredSize, 4); 299 if (dataSize != requiredSize) 300 { 301 ThrowBadFormat (); 302 } 303 304 if (fCount == 0 || fCount > 0x10000) 305 { 306 ThrowBadFormat (); 307 } 308 309 fTable.Reset (host.Allocate (0x10000 * sizeof (uint16))); 310 311 uint16 *table = fTable->Buffer_uint16 (); 312 313 for (uint32 index = 0; index < fCount; index++) 314 { 315 table [index] = stream.Get_uint16 (); 316 } 317 318 ReplicateLastEntry (); 319 320 #if qDNGValidate 321 322 if (gVerbose) 323 { 324 325 printf ("Count: %u\n", (unsigned) fCount); 326 327 for (uint32 j = 0; j < fCount && j < gDumpLineLimit; j++) 328 { 329 printf (" Table [%5u] = %5u\n", (unsigned) j, (unsigned) table [j]); 330 } 331 332 if (fCount > gDumpLineLimit) 333 { 334 printf (" ... %u table entries skipped\n", (unsigned) (fCount - gDumpLineLimit)); 335 } 336 337 } 338 339 #endif 340 341 } 342 343 /*****************************************************************************/ 344 345 void dng_opcode_MapTable::ReplicateLastEntry () 346 { 347 348 uint16 *table = fTable->Buffer_uint16 (); 349 350 uint16 lastEntry = table [fCount]; 351 352 for (uint32 index = fCount; index < 0x10000; index++) 353 { 354 table [index] = lastEntry; 355 } 356 357 } 358 359 /*****************************************************************************/ 360 361 void dng_opcode_MapTable::PutData (dng_stream &stream) const 362 { 363 364 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + fCount * 2); 365 366 fAreaSpec.PutData (stream); 367 368 stream.Put_uint32 (fCount); 369 370 uint16 *table = fTable->Buffer_uint16 (); 371 372 for (uint32 index = 0; index < fCount; index++) 373 { 374 stream.Put_uint16 (table [index]); 375 } 376 377 } 378 379 /*****************************************************************************/ 380 381 uint32 dng_opcode_MapTable::BufferPixelType (uint32 /* imagePixelType */) 382 { 383 384 return ttShort; 385 386 } 387 388 /*****************************************************************************/ 389 390 dng_rect dng_opcode_MapTable::ModifiedBounds (const dng_rect &imageBounds) 391 { 392 393 return fAreaSpec.Overlap (imageBounds); 394 395 } 396 397 /*****************************************************************************/ 398 399 void dng_opcode_MapTable::ProcessArea (dng_negative & /* negative */, 400 uint32 /* threadIndex */, 401 dng_pixel_buffer &buffer, 402 const dng_rect &dstArea, 403 const dng_rect & /* imageBounds */) 404 { 405 406 dng_rect overlap = fAreaSpec.Overlap (dstArea); 407 408 if (overlap.NotEmpty ()) 409 { 410 411 for (uint32 plane = fAreaSpec.Plane (); 412 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 413 plane < buffer.Planes (); 414 plane++) 415 { 416 417 DoMapArea16 (buffer.DirtyPixel_uint16 (overlap.t, overlap.l, plane), 418 1, 419 (overlap.H () + fAreaSpec.RowPitch () - 1) / fAreaSpec.RowPitch (), 420 (overlap.W () + fAreaSpec.ColPitch () - 1) / fAreaSpec.ColPitch (), 421 0, 422 fAreaSpec.RowPitch () * buffer.RowStep (), 423 fAreaSpec.ColPitch (), 424 fTable->Buffer_uint16 ()); 425 426 } 427 428 } 429 430 } 431 432 /*****************************************************************************/ 433 434 dng_opcode_MapPolynomial::dng_opcode_MapPolynomial (const dng_area_spec &areaSpec, 435 uint32 degree, 436 const real64 *coefficient) 437 438 : dng_inplace_opcode (dngOpcode_MapPolynomial, 439 dngVersion_1_3_0_0, 440 kFlag_None) 441 442 , fAreaSpec (areaSpec) 443 , fDegree (degree) 444 445 { 446 447 for (uint32 j = 0; j <= kMaxDegree; j++) 448 { 449 450 if (j <= fDegree) 451 { 452 fCoefficient [j] = coefficient [j]; 453 } 454 455 else 456 { 457 fCoefficient [j] = 0.0; 458 } 459 460 } 461 462 // Reduce degree if possible. 463 464 while (fDegree > 0 && fCoefficient [fDegree] == 0.0) 465 { 466 fDegree--; 467 } 468 469 } 470 471 /*****************************************************************************/ 472 473 dng_opcode_MapPolynomial::dng_opcode_MapPolynomial (dng_stream &stream) 474 475 : dng_inplace_opcode (dngOpcode_MapPolynomial, 476 stream, 477 "MapPolynomial") 478 479 , fAreaSpec () 480 , fDegree (0) 481 482 { 483 484 uint32 dataSize = stream.Get_uint32 (); 485 486 fAreaSpec.GetData (stream); 487 488 fDegree = stream.Get_uint32 (); 489 490 if (fDegree > kMaxDegree) 491 { 492 ThrowBadFormat (); 493 } 494 495 if (dataSize != dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8) 496 { 497 ThrowBadFormat (); 498 } 499 500 for (uint32 j = 0; j <= kMaxDegree; j++) 501 { 502 503 if (j <= fDegree) 504 { 505 fCoefficient [j] = stream.Get_real64 (); 506 } 507 else 508 { 509 fCoefficient [j] = 0.0; 510 } 511 512 } 513 514 #if qDNGValidate 515 516 if (gVerbose) 517 { 518 519 for (uint32 k = 0; k <= fDegree; k++) 520 { 521 printf (" Coefficient [%u] = %f\n", (unsigned) k, fCoefficient [k]); 522 } 523 524 } 525 526 #endif 527 528 } 529 530 /*****************************************************************************/ 531 532 void dng_opcode_MapPolynomial::PutData (dng_stream &stream) const 533 { 534 535 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8); 536 537 fAreaSpec.PutData (stream); 538 539 stream.Put_uint32 (fDegree); 540 541 for (uint32 j = 0; j <= fDegree; j++) 542 { 543 stream.Put_real64 (fCoefficient [j]); 544 } 545 546 } 547 548 /*****************************************************************************/ 549 550 uint32 dng_opcode_MapPolynomial::BufferPixelType (uint32 imagePixelType) 551 { 552 553 // If we are operating on the stage 1 image, then we need 554 // to adjust the coefficients to convert from the image 555 // values to the 32-bit floating point values that this 556 // opcode operates on. 557 558 // If we are operating on the stage 2 or 3 image, the logical 559 // range of the image is already 0.0 to 1.0, so we don't 560 // need to adjust the values. 561 562 real64 scale32 = 1.0; 563 564 if (Stage () == 1) 565 { 566 567 switch (imagePixelType) 568 { 569 570 case ttFloat: 571 break; 572 573 case ttShort: 574 { 575 scale32 = (real64) 0xFFFF; 576 break; 577 } 578 579 case ttLong: 580 { 581 scale32 = (real64) 0xFFFFFFFF; 582 break; 583 } 584 585 default: 586 ThrowBadFormat (); 587 588 } 589 590 } 591 592 real64 factor32 = 1.0 / scale32; 593 594 for (uint32 j = 0; j <= kMaxDegree; j++) 595 { 596 597 fCoefficient32 [j] = ConvertDoubleToFloat(fCoefficient [j] * factor32); 598 599 factor32 *= scale32; 600 601 } 602 603 return ttFloat; 604 605 } 606 607 /*****************************************************************************/ 608 609 dng_rect dng_opcode_MapPolynomial::ModifiedBounds (const dng_rect &imageBounds) 610 { 611 612 return fAreaSpec.Overlap (imageBounds); 613 614 } 615 616 /*****************************************************************************/ 617 618 void dng_opcode_MapPolynomial::ProcessArea (dng_negative & /* negative */, 619 uint32 /* threadIndex */, 620 dng_pixel_buffer &buffer, 621 const dng_rect &dstArea, 622 const dng_rect & /* imageBounds */) 623 { 624 625 dng_rect overlap = fAreaSpec.Overlap (dstArea); 626 627 if (overlap.NotEmpty ()) 628 { 629 630 uint32 cols = overlap.W (); 631 632 uint32 colPitch = fAreaSpec.ColPitch (); 633 634 for (uint32 plane = fAreaSpec.Plane (); 635 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 636 plane < buffer.Planes (); 637 plane++) 638 { 639 640 for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) 641 { 642 643 real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); 644 645 switch (fDegree) 646 { 647 648 case 0: 649 { 650 651 real32 y = Pin_real32 (0.0f, 652 fCoefficient32 [0], 653 1.0f); 654 655 for (uint32 col = 0; col < cols; col += colPitch) 656 { 657 658 dPtr [col] = y; 659 660 } 661 662 break; 663 664 } 665 666 case 1: 667 { 668 669 real32 c0 = fCoefficient32 [0]; 670 real32 c1 = fCoefficient32 [1]; 671 672 if (c0 == 0.0f) 673 { 674 675 if (c1 > 0.0f) 676 { 677 678 for (uint32 col = 0; col < cols; col += colPitch) 679 { 680 681 real32 x = dPtr [col]; 682 683 real32 y = c1 * x; 684 685 dPtr [col] = Min_real32 (y, 1.0f); 686 687 } 688 689 } 690 691 else 692 { 693 694 for (uint32 col = 0; col < cols; col += colPitch) 695 { 696 697 dPtr [col] = 0.0f; 698 699 } 700 701 } 702 703 } 704 705 else 706 { 707 708 for (uint32 col = 0; col < cols; col += colPitch) 709 { 710 711 real32 x = dPtr [col]; 712 713 real32 y = c0 + 714 c1 * x; 715 716 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 717 718 } 719 720 } 721 722 break; 723 724 } 725 726 case 2: 727 { 728 729 for (uint32 col = 0; col < cols; col += colPitch) 730 { 731 732 real32 x = dPtr [col]; 733 734 real32 y = fCoefficient32 [0] + x * 735 (fCoefficient32 [1] + x * 736 (fCoefficient32 [2])); 737 738 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 739 740 } 741 742 break; 743 744 } 745 746 case 3: 747 { 748 749 for (uint32 col = 0; col < cols; col += colPitch) 750 { 751 752 real32 x = dPtr [col]; 753 754 real32 y = fCoefficient32 [0] + x * 755 (fCoefficient32 [1] + x * 756 (fCoefficient32 [2] + x * 757 (fCoefficient32 [3]))); 758 759 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 760 761 } 762 763 break; 764 765 } 766 767 case 4: 768 { 769 770 for (uint32 col = 0; col < cols; col += colPitch) 771 { 772 773 real32 x = dPtr [col]; 774 775 real32 y = fCoefficient32 [0] + x * 776 (fCoefficient32 [1] + x * 777 (fCoefficient32 [2] + x * 778 (fCoefficient32 [3] + x * 779 (fCoefficient32 [4])))); 780 781 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 782 783 } 784 785 break; 786 787 } 788 789 default: 790 { 791 792 for (uint32 col = 0; col < cols; col += colPitch) 793 { 794 795 real32 x = dPtr [col]; 796 797 real32 y = fCoefficient32 [0]; 798 799 real32 xx = x; 800 801 for (uint32 j = 1; j <= fDegree; j++) 802 { 803 804 y += fCoefficient32 [j] * xx; 805 806 xx *= x; 807 808 } 809 810 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 811 812 } 813 814 } 815 816 } 817 818 } 819 820 } 821 822 } 823 824 } 825 826 /*****************************************************************************/ 827 828 dng_opcode_DeltaPerRow::dng_opcode_DeltaPerRow (const dng_area_spec &areaSpec, 829 AutoPtr<dng_memory_block> &table) 830 831 : dng_inplace_opcode (dngOpcode_DeltaPerRow, 832 dngVersion_1_3_0_0, 833 kFlag_None) 834 835 , fAreaSpec (areaSpec) 836 , fTable () 837 , fScale (1.0f) 838 839 { 840 841 fTable.Reset (table.Release ()); 842 843 } 844 845 /*****************************************************************************/ 846 847 dng_opcode_DeltaPerRow::dng_opcode_DeltaPerRow (dng_host &host, 848 dng_stream &stream) 849 850 : dng_inplace_opcode (dngOpcode_DeltaPerRow, 851 stream, 852 "DeltaPerRow") 853 854 , fAreaSpec () 855 , fTable () 856 , fScale (1.0f) 857 858 { 859 860 uint32 dataSize = stream.Get_uint32 (); 861 862 fAreaSpec.GetData (stream); 863 864 uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().H (), 865 fAreaSpec.RowPitch ()); 866 867 if (deltas != stream.Get_uint32 ()) 868 { 869 ThrowBadFormat (); 870 } 871 872 if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4) 873 { 874 ThrowBadFormat (); 875 } 876 877 fTable.Reset (host.Allocate (SafeUint32Mult (deltas, 878 static_cast<uint32> (sizeof (real32))))); 879 880 real32 *table = fTable->Buffer_real32 (); 881 882 for (uint32 j = 0; j < deltas; j++) 883 { 884 table [j] = stream.Get_real32 (); 885 } 886 887 #if qDNGValidate 888 889 if (gVerbose) 890 { 891 892 printf ("Count: %u\n", (unsigned) deltas); 893 894 for (uint32 k = 0; k < deltas && k < gDumpLineLimit; k++) 895 { 896 printf (" Delta [%u] = %f\n", (unsigned) k, table [k]); 897 } 898 899 if (deltas > gDumpLineLimit) 900 { 901 printf (" ... %u deltas skipped\n", (unsigned) (deltas - gDumpLineLimit)); 902 } 903 904 } 905 906 #endif 907 908 } 909 910 /*****************************************************************************/ 911 912 void dng_opcode_DeltaPerRow::PutData (dng_stream &stream) const 913 { 914 915 uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().H (), 916 fAreaSpec.RowPitch ()); 917 918 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4); 919 920 fAreaSpec.PutData (stream); 921 922 stream.Put_uint32 (deltas); 923 924 real32 *table = fTable->Buffer_real32 (); 925 926 for (uint32 j = 0; j < deltas; j++) 927 { 928 stream.Put_real32 (table [j]); 929 } 930 931 } 932 933 /*****************************************************************************/ 934 935 uint32 dng_opcode_DeltaPerRow::BufferPixelType (uint32 imagePixelType) 936 { 937 938 real64 scale32 = 1.0; 939 940 switch (imagePixelType) 941 { 942 943 case ttFloat: 944 break; 945 946 case ttShort: 947 { 948 scale32 = (real64) 0xFFFF; 949 break; 950 } 951 952 case ttLong: 953 { 954 scale32 = (real64) 0xFFFFFFFF; 955 break; 956 } 957 958 default: 959 ThrowBadFormat (); 960 961 } 962 963 fScale = (real32) (1.0 / scale32); 964 965 return ttFloat; 966 967 } 968 969 /*****************************************************************************/ 970 971 dng_rect dng_opcode_DeltaPerRow::ModifiedBounds (const dng_rect &imageBounds) 972 { 973 974 return fAreaSpec.Overlap (imageBounds); 975 976 } 977 978 /*****************************************************************************/ 979 980 void dng_opcode_DeltaPerRow::ProcessArea (dng_negative & /* negative */, 981 uint32 /* threadIndex */, 982 dng_pixel_buffer &buffer, 983 const dng_rect &dstArea, 984 const dng_rect & /* imageBounds */) 985 { 986 987 dng_rect overlap = fAreaSpec.Overlap (dstArea); 988 989 if (overlap.NotEmpty ()) 990 { 991 992 uint32 cols = overlap.W (); 993 994 uint32 colPitch = fAreaSpec.ColPitch (); 995 996 for (uint32 plane = fAreaSpec.Plane (); 997 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 998 plane < buffer.Planes (); 999 plane++) 1000 { 1001 1002 const real32 *table = fTable->Buffer_real32 () + 1003 ((overlap.t - fAreaSpec.Area ().t) / 1004 fAreaSpec.RowPitch ()); 1005 1006 for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) 1007 { 1008 1009 real32 rowDelta = *(table++) * fScale; 1010 1011 real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); 1012 1013 for (uint32 col = 0; col < cols; col += colPitch) 1014 { 1015 1016 real32 x = dPtr [col]; 1017 1018 real32 y = x + rowDelta; 1019 1020 dPtr [col] = Pin_real32 (0.0f, y, 1.0f); 1021 1022 } 1023 1024 } 1025 1026 } 1027 1028 } 1029 1030 } 1031 1032 /*****************************************************************************/ 1033 1034 dng_opcode_DeltaPerColumn::dng_opcode_DeltaPerColumn (const dng_area_spec &areaSpec, 1035 AutoPtr<dng_memory_block> &table) 1036 1037 : dng_inplace_opcode (dngOpcode_DeltaPerColumn, 1038 dngVersion_1_3_0_0, 1039 kFlag_None) 1040 1041 , fAreaSpec (areaSpec) 1042 , fTable () 1043 , fScale (1.0f) 1044 1045 { 1046 1047 fTable.Reset (table.Release ()); 1048 1049 } 1050 1051 /*****************************************************************************/ 1052 1053 dng_opcode_DeltaPerColumn::dng_opcode_DeltaPerColumn (dng_host &host, 1054 dng_stream &stream) 1055 1056 : dng_inplace_opcode (dngOpcode_DeltaPerColumn, 1057 stream, 1058 "DeltaPerColumn") 1059 1060 , fAreaSpec () 1061 , fTable () 1062 , fScale (1.0f) 1063 1064 { 1065 1066 uint32 dataSize = stream.Get_uint32 (); 1067 1068 fAreaSpec.GetData (stream); 1069 1070 uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().W (), 1071 fAreaSpec.ColPitch ()); 1072 1073 if (deltas != stream.Get_uint32 ()) 1074 { 1075 ThrowBadFormat (); 1076 } 1077 1078 if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4) 1079 { 1080 ThrowBadFormat (); 1081 } 1082 1083 fTable.Reset (host.Allocate (SafeUint32Mult (deltas, 1084 static_cast<uint32> (sizeof (real32))))); 1085 1086 real32 *table = fTable->Buffer_real32 (); 1087 1088 for (uint32 j = 0; j < deltas; j++) 1089 { 1090 table [j] = stream.Get_real32 (); 1091 } 1092 1093 #if qDNGValidate 1094 1095 if (gVerbose) 1096 { 1097 1098 printf ("Count: %u\n", (unsigned) deltas); 1099 1100 for (uint32 k = 0; k < deltas && k < gDumpLineLimit; k++) 1101 { 1102 printf (" Delta [%u] = %f\n", (unsigned) k, table [k]); 1103 } 1104 1105 if (deltas > gDumpLineLimit) 1106 { 1107 printf (" ... %u deltas skipped\n", (unsigned) (deltas - gDumpLineLimit)); 1108 } 1109 1110 } 1111 1112 #endif 1113 1114 } 1115 1116 /*****************************************************************************/ 1117 1118 void dng_opcode_DeltaPerColumn::PutData (dng_stream &stream) const 1119 { 1120 1121 uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().W (), 1122 fAreaSpec.ColPitch ()); 1123 1124 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4); 1125 1126 fAreaSpec.PutData (stream); 1127 1128 stream.Put_uint32 (deltas); 1129 1130 real32 *table = fTable->Buffer_real32 (); 1131 1132 for (uint32 j = 0; j < deltas; j++) 1133 { 1134 stream.Put_real32 (table [j]); 1135 } 1136 1137 } 1138 1139 /*****************************************************************************/ 1140 1141 uint32 dng_opcode_DeltaPerColumn::BufferPixelType (uint32 imagePixelType) 1142 { 1143 1144 real64 scale32 = 1.0; 1145 1146 switch (imagePixelType) 1147 { 1148 1149 case ttFloat: 1150 break; 1151 1152 case ttShort: 1153 { 1154 scale32 = (real64) 0xFFFF; 1155 break; 1156 } 1157 1158 case ttLong: 1159 { 1160 scale32 = (real64) 0xFFFFFFFF; 1161 break; 1162 } 1163 1164 default: 1165 ThrowBadFormat (); 1166 1167 } 1168 1169 fScale = (real32) (1.0 / scale32); 1170 1171 return ttFloat; 1172 1173 } 1174 1175 /*****************************************************************************/ 1176 1177 dng_rect dng_opcode_DeltaPerColumn::ModifiedBounds (const dng_rect &imageBounds) 1178 { 1179 1180 return fAreaSpec.Overlap (imageBounds); 1181 1182 } 1183 1184 /*****************************************************************************/ 1185 1186 void dng_opcode_DeltaPerColumn::ProcessArea (dng_negative & /* negative */, 1187 uint32 /* threadIndex */, 1188 dng_pixel_buffer &buffer, 1189 const dng_rect &dstArea, 1190 const dng_rect & /* imageBounds */) 1191 { 1192 1193 dng_rect overlap = fAreaSpec.Overlap (dstArea); 1194 1195 if (overlap.NotEmpty ()) 1196 { 1197 1198 uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) / 1199 fAreaSpec.RowPitch (); 1200 1201 int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch (); 1202 1203 for (uint32 plane = fAreaSpec.Plane (); 1204 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 1205 plane < buffer.Planes (); 1206 plane++) 1207 { 1208 1209 const real32 *table = fTable->Buffer_real32 () + 1210 ((overlap.l - fAreaSpec.Area ().l) / 1211 fAreaSpec.ColPitch ()); 1212 1213 for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ()) 1214 { 1215 1216 real32 colDelta = *(table++) * fScale; 1217 1218 real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane); 1219 1220 for (uint32 row = 0; row < rows; row++) 1221 { 1222 1223 real32 x = dPtr [0]; 1224 1225 real32 y = x + colDelta; 1226 1227 dPtr [0] = Pin_real32 (0.0f, y, 1.0f); 1228 1229 dPtr += rowStep; 1230 1231 } 1232 1233 } 1234 1235 } 1236 1237 } 1238 1239 } 1240 1241 /*****************************************************************************/ 1242 1243 dng_opcode_ScalePerRow::dng_opcode_ScalePerRow (const dng_area_spec &areaSpec, 1244 AutoPtr<dng_memory_block> &table) 1245 1246 : dng_inplace_opcode (dngOpcode_ScalePerRow, 1247 dngVersion_1_3_0_0, 1248 kFlag_None) 1249 1250 , fAreaSpec (areaSpec) 1251 , fTable () 1252 1253 { 1254 1255 fTable.Reset (table.Release ()); 1256 1257 } 1258 1259 /*****************************************************************************/ 1260 1261 dng_opcode_ScalePerRow::dng_opcode_ScalePerRow (dng_host &host, 1262 dng_stream &stream) 1263 1264 : dng_inplace_opcode (dngOpcode_ScalePerRow, 1265 stream, 1266 "ScalePerRow") 1267 1268 , fAreaSpec () 1269 , fTable () 1270 1271 { 1272 1273 uint32 dataSize = stream.Get_uint32 (); 1274 1275 fAreaSpec.GetData (stream); 1276 1277 uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().H (), 1278 fAreaSpec.RowPitch ()); 1279 1280 if (scales != stream.Get_uint32 ()) 1281 { 1282 ThrowBadFormat (); 1283 } 1284 1285 if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4) 1286 { 1287 ThrowBadFormat (); 1288 } 1289 1290 fTable.Reset (host.Allocate (SafeUint32Mult (scales, 1291 static_cast<uint32> (sizeof (real32))))); 1292 1293 real32 *table = fTable->Buffer_real32 (); 1294 1295 for (uint32 j = 0; j < scales; j++) 1296 { 1297 table [j] = stream.Get_real32 (); 1298 } 1299 1300 #if qDNGValidate 1301 1302 if (gVerbose) 1303 { 1304 1305 printf ("Count: %u\n", (unsigned) scales); 1306 1307 for (uint32 k = 0; k < scales && k < gDumpLineLimit; k++) 1308 { 1309 printf (" Scale [%u] = %f\n", (unsigned) k, table [k]); 1310 } 1311 1312 if (scales > gDumpLineLimit) 1313 { 1314 printf (" ... %u scales skipped\n", (unsigned) (scales - gDumpLineLimit)); 1315 } 1316 1317 } 1318 1319 #endif 1320 1321 } 1322 1323 /*****************************************************************************/ 1324 1325 void dng_opcode_ScalePerRow::PutData (dng_stream &stream) const 1326 { 1327 1328 uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().H (), 1329 fAreaSpec.RowPitch ()); 1330 1331 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4); 1332 1333 fAreaSpec.PutData (stream); 1334 1335 stream.Put_uint32 (scales); 1336 1337 real32 *table = fTable->Buffer_real32 (); 1338 1339 for (uint32 j = 0; j < scales; j++) 1340 { 1341 stream.Put_real32 (table [j]); 1342 } 1343 1344 } 1345 1346 /*****************************************************************************/ 1347 1348 uint32 dng_opcode_ScalePerRow::BufferPixelType (uint32 /* imagePixelType */) 1349 { 1350 1351 return ttFloat; 1352 1353 } 1354 1355 /*****************************************************************************/ 1356 1357 dng_rect dng_opcode_ScalePerRow::ModifiedBounds (const dng_rect &imageBounds) 1358 { 1359 1360 return fAreaSpec.Overlap (imageBounds); 1361 1362 } 1363 1364 /*****************************************************************************/ 1365 1366 void dng_opcode_ScalePerRow::ProcessArea (dng_negative & /* negative */, 1367 uint32 /* threadIndex */, 1368 dng_pixel_buffer &buffer, 1369 const dng_rect &dstArea, 1370 const dng_rect & /* imageBounds */) 1371 { 1372 1373 dng_rect overlap = fAreaSpec.Overlap (dstArea); 1374 1375 if (overlap.NotEmpty ()) 1376 { 1377 1378 uint32 cols = overlap.W (); 1379 1380 uint32 colPitch = fAreaSpec.ColPitch (); 1381 1382 for (uint32 plane = fAreaSpec.Plane (); 1383 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 1384 plane < buffer.Planes (); 1385 plane++) 1386 { 1387 1388 const real32 *table = fTable->Buffer_real32 () + 1389 ((overlap.t - fAreaSpec.Area ().t) / 1390 fAreaSpec.RowPitch ()); 1391 1392 for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ()) 1393 { 1394 1395 real32 rowScale = *(table++); 1396 1397 real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane); 1398 1399 for (uint32 col = 0; col < cols; col += colPitch) 1400 { 1401 1402 real32 x = dPtr [col]; 1403 1404 real32 y = x * rowScale; 1405 1406 dPtr [col] = Min_real32 (y, 1.0f); 1407 1408 } 1409 1410 } 1411 1412 } 1413 1414 } 1415 1416 } 1417 1418 /*****************************************************************************/ 1419 1420 dng_opcode_ScalePerColumn::dng_opcode_ScalePerColumn (const dng_area_spec &areaSpec, 1421 AutoPtr<dng_memory_block> &table) 1422 1423 : dng_inplace_opcode (dngOpcode_ScalePerColumn, 1424 dngVersion_1_3_0_0, 1425 kFlag_None) 1426 1427 , fAreaSpec (areaSpec) 1428 , fTable () 1429 1430 { 1431 1432 fTable.Reset (table.Release ()); 1433 1434 } 1435 1436 /*****************************************************************************/ 1437 1438 dng_opcode_ScalePerColumn::dng_opcode_ScalePerColumn (dng_host &host, 1439 dng_stream &stream) 1440 1441 : dng_inplace_opcode (dngOpcode_ScalePerColumn, 1442 stream, 1443 "ScalePerColumn") 1444 1445 , fAreaSpec () 1446 , fTable () 1447 1448 { 1449 1450 uint32 dataSize = stream.Get_uint32 (); 1451 1452 fAreaSpec.GetData (stream); 1453 1454 uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().W (), 1455 fAreaSpec.ColPitch()); 1456 1457 if (scales != stream.Get_uint32 ()) 1458 { 1459 ThrowBadFormat (); 1460 } 1461 1462 if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4) 1463 { 1464 ThrowBadFormat (); 1465 } 1466 1467 fTable.Reset (host.Allocate (SafeUint32Mult (scales, 1468 static_cast<uint32> (sizeof (real32))))); 1469 1470 real32 *table = fTable->Buffer_real32 (); 1471 1472 for (uint32 j = 0; j < scales; j++) 1473 { 1474 table [j] = stream.Get_real32 (); 1475 } 1476 1477 #if qDNGValidate 1478 1479 if (gVerbose) 1480 { 1481 1482 printf ("Count: %u\n", (unsigned) scales); 1483 1484 for (uint32 k = 0; k < scales && k < gDumpLineLimit; k++) 1485 { 1486 printf (" Scale [%u] = %f\n", (unsigned) k, table [k]); 1487 } 1488 1489 if (scales > gDumpLineLimit) 1490 { 1491 printf (" ... %u deltas skipped\n", (unsigned) (scales - gDumpLineLimit)); 1492 } 1493 1494 } 1495 1496 #endif 1497 1498 } 1499 1500 /*****************************************************************************/ 1501 1502 void dng_opcode_ScalePerColumn::PutData (dng_stream &stream) const 1503 { 1504 1505 uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().W (), 1506 fAreaSpec.ColPitch ()); 1507 1508 stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4); 1509 1510 fAreaSpec.PutData (stream); 1511 1512 stream.Put_uint32 (scales); 1513 1514 real32 *table = fTable->Buffer_real32 (); 1515 1516 for (uint32 j = 0; j < scales; j++) 1517 { 1518 stream.Put_real32 (table [j]); 1519 } 1520 1521 } 1522 1523 /*****************************************************************************/ 1524 1525 uint32 dng_opcode_ScalePerColumn::BufferPixelType (uint32 /* imagePixelType */) 1526 { 1527 1528 return ttFloat; 1529 1530 } 1531 1532 /*****************************************************************************/ 1533 1534 dng_rect dng_opcode_ScalePerColumn::ModifiedBounds (const dng_rect &imageBounds) 1535 { 1536 1537 return fAreaSpec.Overlap (imageBounds); 1538 1539 } 1540 1541 /*****************************************************************************/ 1542 1543 void dng_opcode_ScalePerColumn::ProcessArea (dng_negative & /* negative */, 1544 uint32 /* threadIndex */, 1545 dng_pixel_buffer &buffer, 1546 const dng_rect &dstArea, 1547 const dng_rect & /* imageBounds */) 1548 { 1549 1550 dng_rect overlap = fAreaSpec.Overlap (dstArea); 1551 1552 if (overlap.NotEmpty ()) 1553 { 1554 1555 uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) / 1556 fAreaSpec.RowPitch (); 1557 1558 int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch (); 1559 1560 for (uint32 plane = fAreaSpec.Plane (); 1561 plane < fAreaSpec.Plane () + fAreaSpec.Planes () && 1562 plane < buffer.Planes (); 1563 plane++) 1564 { 1565 1566 const real32 *table = fTable->Buffer_real32 () + 1567 ((overlap.l - fAreaSpec.Area ().l) / 1568 fAreaSpec.ColPitch ()); 1569 1570 for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ()) 1571 { 1572 1573 real32 colScale = *(table++); 1574 1575 real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane); 1576 1577 for (uint32 row = 0; row < rows; row++) 1578 { 1579 1580 real32 x = dPtr [0]; 1581 1582 real32 y = x * colScale; 1583 1584 dPtr [0] = Min_real32 (y, 1.0f); 1585 1586 dPtr += rowStep; 1587 1588 } 1589 1590 } 1591 1592 } 1593 1594 } 1595 1596 } 1597 1598 /*****************************************************************************/ 1599