1/*****************************************************************************/ 2// Copyright 2006-2011 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_linearization_info.cpp#1 $ */ 10/* $DateTime: 2012/05/30 13:28:51 $ */ 11/* $Change: 832332 $ */ 12/* $Author: tknoll $ */ 13 14/*****************************************************************************/ 15 16#include "dng_linearization_info.h" 17 18#include "dng_area_task.h" 19#include "dng_exceptions.h" 20#include "dng_host.h" 21#include "dng_image.h" 22#include "dng_info.h" 23#include "dng_negative.h" 24#include "dng_pixel_buffer.h" 25#include "dng_safe_arithmetic.h" 26#include "dng_tag_types.h" 27#include "dng_tile_iterator.h" 28#include "dng_utils.h" 29 30/*****************************************************************************/ 31 32class dng_linearize_plane 33 { 34 35 private: 36 37 const dng_image & fSrcImage; 38 dng_image & fDstImage; 39 40 uint32 fPlane; 41 42 dng_rect fActiveArea; 43 44 uint32 fSrcPixelType; 45 uint32 fDstPixelType; 46 47 bool fReal32; 48 49 real32 fScale; 50 51 AutoPtr<dng_memory_block> fScale_buffer; 52 53 uint32 fBlack_2D_rows; 54 uint32 fBlack_2D_cols; 55 56 AutoPtr<dng_memory_block> fBlack_2D_buffer; 57 58 uint32 fBlack_1D_rows; 59 60 AutoPtr<dng_memory_block> fBlack_1D_buffer; 61 62 public: 63 64 dng_linearize_plane (dng_host &host, 65 dng_linearization_info &info, 66 const dng_image &srcImage, 67 dng_image &dstImage, 68 uint32 plane); 69 70 ~dng_linearize_plane (); 71 72 void Process (const dng_rect &tile); 73 74 }; 75 76/*****************************************************************************/ 77 78dng_linearize_plane::dng_linearize_plane (dng_host &host, 79 dng_linearization_info &info, 80 const dng_image &srcImage, 81 dng_image &dstImage, 82 uint32 plane) 83 84 : fSrcImage (srcImage) 85 , fDstImage (dstImage) 86 , fPlane (plane) 87 , fActiveArea (info.fActiveArea) 88 , fSrcPixelType (srcImage.PixelType ()) 89 , fDstPixelType (dstImage.PixelType ()) 90 , fReal32 (false) 91 , fScale (0.0f) 92 , fScale_buffer () 93 , fBlack_2D_rows (0) 94 , fBlack_2D_cols (0) 95 , fBlack_2D_buffer () 96 , fBlack_1D_rows (0) 97 , fBlack_1D_buffer () 98 99 { 100 101 uint32 j; 102 uint32 k; 103 104 // Make sure the source pixel type is supported. 105 106 if (fSrcPixelType != ttByte && 107 fSrcPixelType != ttShort && 108 fSrcPixelType != ttLong && 109 fSrcPixelType != ttFloat) 110 { 111 112 DNG_REPORT ("Unsupported source pixel type"); 113 114 ThrowProgramError (); 115 116 } 117 118 if (fDstPixelType != ttShort && 119 fDstPixelType != ttFloat) 120 { 121 122 DNG_REPORT ("Unsupported destination pixel type"); 123 124 ThrowProgramError (); 125 126 } 127 128 if (fSrcPixelType == ttFloat && 129 fDstPixelType != ttFloat) 130 { 131 132 DNG_REPORT ("Cannot convert floating point stage1 to non-floating stage2"); 133 134 ThrowProgramError (); 135 136 } 137 138 // Are we using floating point math? 139 140 fReal32 = (fSrcPixelType == ttLong || 141 fDstPixelType == ttFloat); 142 143 // Find the scale for this plane. 144 145 real64 maxBlack = info.MaxBlackLevel (plane); 146 147 real64 minRange = info.fWhiteLevel [plane] - maxBlack; 148 149 if (minRange <= 0.0) 150 { 151 ThrowBadFormat (); 152 } 153 154 real64 scale = 1.0 / minRange; 155 156 fScale = (real32) scale; 157 158 // Calculate two-dimensional black pattern, if any. 159 160 if (info.fBlackDeltaH.Get ()) 161 { 162 163 fBlack_2D_rows = info.fBlackLevelRepeatRows; 164 fBlack_2D_cols = info.fActiveArea.W (); 165 166 } 167 168 else if (info.fBlackLevelRepeatCols > 1) 169 { 170 171 fBlack_2D_rows = info.fBlackLevelRepeatRows; 172 fBlack_2D_cols = info.fBlackLevelRepeatCols; 173 174 } 175 176 if (fBlack_2D_rows) 177 { 178 179 fBlack_2D_buffer.Reset (host.Allocate ( 180 SafeUint32Mult (fBlack_2D_rows, fBlack_2D_cols, 4))); 181 182 for (j = 0; j < fBlack_2D_rows; j++) 183 { 184 185 for (k = 0; k < fBlack_2D_cols; k++) 186 { 187 188 real64 x = info.fBlackLevel [j] 189 [k % info.fBlackLevelRepeatCols] 190 [plane]; 191 192 if (info.fBlackDeltaH.Get ()) 193 { 194 195 x += info.fBlackDeltaH->Buffer_real64 () [k]; 196 197 } 198 199 x *= scale; 200 201 uint32 index = j * fBlack_2D_cols + k; 202 203 if (fReal32) 204 { 205 206 fBlack_2D_buffer->Buffer_real32 () [index] = (real32) x; 207 208 } 209 210 else 211 { 212 213 x *= 0x0FFFF * 256.0; 214 215 int32 y = Round_int32 (x); 216 217 fBlack_2D_buffer->Buffer_int32 () [index] = y; 218 219 } 220 221 } 222 223 } 224 225 } 226 227 // Calculate one-dimensional (per row) black pattern, if any. 228 229 if (info.fBlackDeltaV.Get ()) 230 { 231 232 fBlack_1D_rows = info.fActiveArea.H (); 233 234 } 235 236 else if (fBlack_2D_rows == 0 && 237 (info.fBlackLevelRepeatRows > 1 || fSrcPixelType != ttShort)) 238 { 239 240 fBlack_1D_rows = info.fBlackLevelRepeatRows; 241 242 } 243 244 if (fBlack_1D_rows) 245 { 246 247 fBlack_1D_buffer.Reset (host.Allocate ( 248 SafeUint32Mult(fBlack_1D_rows, 4))); 249 250 bool allZero = true; 251 252 for (j = 0; j < fBlack_1D_rows; j++) 253 { 254 255 real64 x = 0.0; 256 257 if (fBlack_2D_rows == 0) 258 { 259 260 x = info.fBlackLevel [j % info.fBlackLevelRepeatRows] 261 [0] 262 [plane]; 263 264 } 265 266 if (info.fBlackDeltaV.Get ()) 267 { 268 269 x += info.fBlackDeltaV->Buffer_real64 () [j]; 270 271 } 272 273 allZero = allZero && (x == 0.0); 274 275 x *= scale; 276 277 if (fReal32) 278 { 279 280 fBlack_1D_buffer->Buffer_real32 () [j] = (real32) x; 281 282 } 283 284 else 285 { 286 287 x *= 0x0FFFF * 256.0; 288 289 int32 y = Round_int32 (x); 290 291 fBlack_1D_buffer->Buffer_int32 () [j] = y; 292 293 } 294 295 } 296 297 if (allZero) 298 { 299 300 fBlack_1D_rows = 0; 301 302 fBlack_1D_buffer.Reset (); 303 304 } 305 306 } 307 308 // Calculate scale table, if any. 309 310 if (fSrcPixelType != ttLong && 311 fSrcPixelType != ttFloat) 312 { 313 314 // Find linearization table, if any. 315 316 uint16 *lut = NULL; 317 318 uint32 lutEntries = 0; 319 320 if (info.fLinearizationTable.Get ()) 321 { 322 323 lut = info.fLinearizationTable->Buffer_uint16 (); 324 325 lutEntries = info.fLinearizationTable->LogicalSize () >> 1; 326 327 } 328 329 // If the black level does not vary from pixel to pixel, then 330 // the entire process can be a single LUT. 331 332 if (fBlack_1D_rows == 0 && 333 fBlack_2D_rows == 0) 334 { 335 336 fScale_buffer.Reset (host.Allocate (0x10000 * 337 TagTypeSize (fDstPixelType))); 338 339 for (j = 0; j < 0x10000; j++) 340 { 341 342 uint32 x = j; 343 344 // Apply linearization table, if any. 345 346 if (lut) 347 { 348 349 x = Min_uint32 (x, lutEntries - 1); 350 351 x = lut [x]; 352 353 } 354 355 // Subtract constant black level. 356 357 real64 y = x - info.fBlackLevel [0] [0] [plane]; 358 359 // Apply scale. 360 361 y *= scale; 362 363 // We can burn in the clipping also. 364 365 y = Pin_real64 (0.0, y, 1.0); 366 367 // Store output value in table. 368 369 if (fDstPixelType == ttShort) 370 { 371 372 uint16 z = (uint16) Round_uint32 (y * 0x0FFFF); 373 374 fScale_buffer->Buffer_uint16 () [j] = z; 375 376 } 377 378 else 379 { 380 381 fScale_buffer->Buffer_real32 () [j] = (real32) y; 382 383 } 384 385 } 386 387 } 388 389 // Else we only do the scaling operation in the scale table. 390 391 else 392 { 393 394 fScale_buffer.Reset (host.Allocate (0x10000 * 4)); 395 396 for (j = 0; j < 0x10000; j++) 397 { 398 399 uint32 x = j; 400 401 // Apply linearization table, if any. 402 403 if (lut) 404 { 405 406 x = Min_uint32 (x, lutEntries - 1); 407 408 x = lut [x]; 409 410 } 411 412 // Apply scale. 413 414 real64 y = x * scale; 415 416 // Store output value in table. 417 418 if (fReal32) 419 { 420 421 fScale_buffer->Buffer_real32 () [j] = (real32) y; 422 423 } 424 425 else 426 { 427 428 int32 z = Round_int32 (y * 0x0FFFF * 256.0); 429 430 fScale_buffer->Buffer_int32 () [j] = z; 431 432 } 433 434 } 435 436 } 437 438 } 439 440 } 441 442/*****************************************************************************/ 443 444dng_linearize_plane::~dng_linearize_plane () 445 { 446 447 } 448 449/*****************************************************************************/ 450 451void dng_linearize_plane::Process (const dng_rect &srcTile) 452 { 453 454 // Process tile. 455 456 dng_rect dstTile = srcTile - fActiveArea.TL (); 457 458 dng_const_tile_buffer srcBuffer (fSrcImage, srcTile); 459 dng_dirty_tile_buffer dstBuffer (fDstImage, dstTile); 460 461 int32 sStep = srcBuffer.fColStep; 462 int32 dStep = dstBuffer.fColStep; 463 464 uint32 count = srcTile.W (); 465 466 uint32 dstCol = dstTile.l; 467 468 uint32 rows = srcTile.H (); 469 470 for (uint32 row = 0; row < rows; row++) 471 { 472 473 uint32 dstRow = dstTile.t + row; 474 475 const void *sPtr = srcBuffer.ConstPixel (srcTile.t + row, 476 srcTile.l, 477 fPlane); 478 479 void *dPtr = dstBuffer.DirtyPixel (dstRow, 480 dstCol, 481 fPlane); 482 483 // Floating point source case. 484 485 if (fSrcPixelType == ttFloat) 486 { 487 488 real32 scale = fScale; 489 490 const real32 *srcPtr = (const real32 *) sPtr; 491 492 real32 *dstPtr = (real32 *) dPtr; 493 494 // Optimize scale only case, which is the most common. 495 496 if (fBlack_1D_rows == 0 && 497 fBlack_2D_cols == 0) 498 { 499 500 for (uint32 j = 0; j < count; j++) 501 { 502 503 *dstPtr = (*srcPtr) * scale; 504 505 srcPtr += sStep; 506 dstPtr += dStep; 507 508 } 509 510 } 511 512 else 513 { 514 515 real32 b1 = 0.0f; 516 517 if (fBlack_1D_rows) 518 { 519 b1 = fBlack_1D_buffer->Buffer_real32 () [dstRow % fBlack_1D_rows]; 520 } 521 522 const real32 *b2 = NULL; 523 524 uint32 b2_count = fBlack_2D_cols; 525 uint32 b2_phase = 0; 526 527 if (b2_count) 528 { 529 530 b2 = fBlack_2D_buffer->Buffer_real32 () + 531 b2_count * (dstRow % fBlack_2D_rows); 532 533 b2_phase = dstCol % b2_count; 534 535 } 536 537 for (uint32 j = 0; j < count; j++) 538 { 539 540 real32 x = (*srcPtr) * scale - b1; 541 542 if (b2_count) 543 { 544 545 x -= b2 [b2_phase]; 546 547 if (++b2_phase == b2_count) 548 { 549 b2_phase = 0; 550 } 551 552 } 553 554 *dstPtr = x; 555 556 srcPtr += sStep; 557 dstPtr += dStep; 558 559 } 560 561 } 562 563 } 564 565 // Simple LUT case. 566 567 else if (fBlack_1D_rows == 0 && 568 fBlack_2D_rows == 0 && fSrcPixelType != ttLong) 569 { 570 571 if (fDstPixelType == ttShort) 572 { 573 574 const uint16 *lut = fScale_buffer->Buffer_uint16 (); 575 576 uint16 *dstPtr = (uint16 *) dPtr; 577 578 if (fSrcPixelType == ttByte) 579 { 580 581 const uint8 *srcPtr = (const uint8 *) sPtr; 582 583 for (uint32 j = 0; j < count; j++) 584 { 585 586 *dstPtr = lut [*srcPtr]; 587 588 srcPtr += sStep; 589 dstPtr += dStep; 590 591 } 592 593 } 594 595 else 596 { 597 598 const uint16 *srcPtr = (const uint16 *) sPtr; 599 600 for (uint32 j = 0; j < count; j++) 601 { 602 603 *dstPtr = lut [*srcPtr]; 604 605 srcPtr += sStep; 606 dstPtr += dStep; 607 608 } 609 610 } 611 612 } 613 614 else 615 { 616 617 const real32 *lut = fScale_buffer->Buffer_real32 (); 618 619 real32 *dstPtr = (real32 *) dPtr; 620 621 if (fSrcPixelType == ttByte) 622 { 623 624 const uint8 *srcPtr = (const uint8 *) sPtr; 625 626 for (uint32 j = 0; j < count; j++) 627 { 628 629 *dstPtr = lut [*srcPtr]; 630 631 srcPtr += sStep; 632 dstPtr += dStep; 633 634 } 635 636 } 637 638 else 639 { 640 641 const uint16 *srcPtr = (const uint16 *) sPtr; 642 643 for (uint32 j = 0; j < count; j++) 644 { 645 646 *dstPtr = lut [*srcPtr]; 647 648 srcPtr += sStep; 649 dstPtr += dStep; 650 651 } 652 653 } 654 655 } 656 657 } 658 659 // Integer math case. 660 661 else if (!fReal32) 662 { 663 664 const int32 *lut = fScale_buffer->Buffer_int32 (); 665 666 int32 b1 = 0; 667 668 if (fBlack_1D_rows) 669 { 670 b1 = fBlack_1D_buffer->Buffer_int32 () [dstRow % fBlack_1D_rows]; 671 } 672 673 const int32 *b2 = NULL; 674 675 uint32 b2_count = fBlack_2D_cols; 676 uint32 b2_phase = 0; 677 678 if (b2_count) 679 { 680 681 b2 = fBlack_2D_buffer->Buffer_int32 () + 682 b2_count * (dstRow % fBlack_2D_rows); 683 684 b2_phase = dstCol % b2_count; 685 686 } 687 688 uint16 *dstPtr = (uint16 *) dPtr; 689 690 b1 -= 128; // Rounding for 8 bit shift 691 692 if (fSrcPixelType == ttByte) 693 { 694 695 const uint8 *srcPtr = (const uint8 *) sPtr; 696 697 for (uint32 j = 0; j < count; j++) 698 { 699 700 int32 x = lut [*srcPtr] - b1; 701 702 if (b2_count) 703 { 704 705 x -= b2 [b2_phase]; 706 707 if (++b2_phase == b2_count) 708 { 709 b2_phase = 0; 710 } 711 712 } 713 714 x >>= 8; 715 716 *dstPtr = Pin_uint16 (x); 717 718 srcPtr += sStep; 719 dstPtr += dStep; 720 721 } 722 723 } 724 725 else 726 { 727 728 const uint16 *srcPtr = (const uint16 *) sPtr; 729 730 for (uint32 j = 0; j < count; j++) 731 { 732 733 int32 x = lut [*srcPtr] - b1; 734 735 if (b2_count) 736 { 737 738 x -= b2 [b2_phase]; 739 740 if (++b2_phase == b2_count) 741 { 742 b2_phase = 0; 743 } 744 745 } 746 747 x >>= 8; 748 749 *dstPtr = Pin_uint16 (x); 750 751 srcPtr += sStep; 752 dstPtr += dStep; 753 754 } 755 756 } 757 758 } 759 760 // Floating point math cases. 761 762 else 763 { 764 765 real32 b1 = 0.0f; 766 767 if (fBlack_1D_rows) 768 { 769 b1 = fBlack_1D_buffer->Buffer_real32 () [dstRow % fBlack_1D_rows]; 770 } 771 772 const real32 *b2 = NULL; 773 774 uint32 b2_count = fBlack_2D_cols; 775 uint32 b2_phase = 0; 776 777 if (b2_count) 778 { 779 780 b2 = fBlack_2D_buffer->Buffer_real32 () + 781 b2_count * (dstRow % fBlack_2D_rows); 782 783 b2_phase = dstCol % b2_count; 784 785 } 786 787 // Case 1: uint8/uint16 -> real32 788 789 if (fSrcPixelType != ttLong) 790 { 791 792 const real32 *lut = fScale_buffer->Buffer_real32 (); 793 794 real32 *dstPtr = (real32 *) dPtr; 795 796 if (fSrcPixelType == ttByte) 797 { 798 799 const uint8 *srcPtr = (const uint8 *) sPtr; 800 801 for (uint32 j = 0; j < count; j++) 802 { 803 804 real32 x = lut [*srcPtr] - b1; 805 806 if (b2_count) 807 { 808 809 x -= b2 [b2_phase]; 810 811 if (++b2_phase == b2_count) 812 { 813 b2_phase = 0; 814 } 815 816 } 817 818 x = Pin_real32 (0.0f, x, 1.0f); 819 820 *dstPtr = x; 821 822 srcPtr += sStep; 823 dstPtr += dStep; 824 825 } 826 827 } 828 829 else 830 { 831 832 const uint16 *srcPtr = (const uint16 *) sPtr; 833 834 for (uint32 j = 0; j < count; j++) 835 { 836 837 real32 x = lut [*srcPtr] - b1; 838 839 if (b2_count) 840 { 841 842 x -= b2 [b2_phase]; 843 844 if (++b2_phase == b2_count) 845 { 846 b2_phase = 0; 847 } 848 849 } 850 851 x = Pin_real32 (0.0f, x, 1.0f); 852 853 *dstPtr = x; 854 855 srcPtr += sStep; 856 dstPtr += dStep; 857 858 } 859 860 } 861 862 } 863 864 // Otherwise source is uint32 865 866 else 867 { 868 869 real32 scale = fScale; 870 871 const uint32 *srcPtr = (const uint32 *) sPtr; 872 873 // Case 2: uint32 -> real32 874 875 if (fDstPixelType == ttFloat) 876 { 877 878 real32 *dstPtr = (real32 *) dPtr; 879 880 for (uint32 j = 0; j < count; j++) 881 { 882 883 real32 x = ((real32) *srcPtr) * scale - b1; 884 885 if (b2_count) 886 { 887 888 x -= b2 [b2_phase]; 889 890 if (++b2_phase == b2_count) 891 { 892 b2_phase = 0; 893 } 894 895 } 896 897 x = Pin_real32 (0.0f, x, 1.0f); 898 899 *dstPtr = x; 900 901 srcPtr += sStep; 902 dstPtr += dStep; 903 904 } 905 906 } 907 908 // Case 3: uint32 -> uint16 909 910 else 911 { 912 913 uint16 *dstPtr = (uint16 *) dPtr; 914 915 real32 dstScale = (real32) 0x0FFFF; 916 917 for (uint32 j = 0; j < count; j++) 918 { 919 920 real32 x = ((real32) *srcPtr) * scale - b1; 921 922 if (b2_count) 923 { 924 925 x -= b2 [b2_phase]; 926 927 if (++b2_phase == b2_count) 928 { 929 b2_phase = 0; 930 } 931 932 } 933 934 x = Pin_real32 (0.0f, x, 1.0f); 935 936 *dstPtr = (uint16) (x * dstScale + 0.5f); 937 938 srcPtr += sStep; 939 dstPtr += dStep; 940 941 } 942 943 } 944 945 } 946 947 } 948 949 } 950 951 } 952 953/*****************************************************************************/ 954 955class dng_linearize_image: public dng_area_task 956 { 957 958 private: 959 960 const dng_image & fSrcImage; 961 dng_image & fDstImage; 962 963 dng_rect fActiveArea; 964 965 AutoPtr<dng_linearize_plane> fPlaneTask [kMaxColorPlanes]; 966 967 public: 968 969 dng_linearize_image (dng_host &host, 970 dng_linearization_info &info, 971 const dng_image &srcImage, 972 dng_image &dstImage); 973 974 virtual ~dng_linearize_image (); 975 976 virtual dng_rect RepeatingTile1 () const; 977 978 virtual dng_rect RepeatingTile2 () const; 979 980 virtual void Process (uint32 threadIndex, 981 const dng_rect &tile, 982 dng_abort_sniffer *sniffer); 983 984 }; 985 986/*****************************************************************************/ 987 988dng_linearize_image::dng_linearize_image (dng_host &host, 989 dng_linearization_info &info, 990 const dng_image &srcImage, 991 dng_image &dstImage) 992 993 : fSrcImage (srcImage) 994 , fDstImage (dstImage) 995 , fActiveArea (info.fActiveArea) 996 997 { 998 999 // Build linearization table for each plane. 1000 1001 for (uint32 plane = 0; plane < srcImage.Planes (); plane++) 1002 { 1003 1004 fPlaneTask [plane].Reset (new dng_linearize_plane (host, 1005 info, 1006 srcImage, 1007 dstImage, 1008 plane)); 1009 1010 } 1011 1012 // Adjust maximum tile size. 1013 1014 fMaxTileSize = dng_point (1024, 1024); 1015 1016 } 1017 1018/*****************************************************************************/ 1019 1020dng_linearize_image::~dng_linearize_image () 1021 { 1022 1023 } 1024 1025/*****************************************************************************/ 1026 1027dng_rect dng_linearize_image::RepeatingTile1 () const 1028 { 1029 1030 return fSrcImage.RepeatingTile (); 1031 1032 } 1033 1034/*****************************************************************************/ 1035 1036dng_rect dng_linearize_image::RepeatingTile2 () const 1037 { 1038 1039 return fDstImage.RepeatingTile () + fActiveArea.TL (); 1040 1041 } 1042 1043/*****************************************************************************/ 1044 1045void dng_linearize_image::Process (uint32 /* threadIndex */, 1046 const dng_rect &srcTile, 1047 dng_abort_sniffer * /* sniffer */) 1048 { 1049 1050 // Process each plane. 1051 1052 for (uint32 plane = 0; plane < fSrcImage.Planes (); plane++) 1053 { 1054 1055 fPlaneTask [plane]->Process (srcTile); 1056 1057 } 1058 1059 } 1060 1061/*****************************************************************************/ 1062 1063dng_linearization_info::dng_linearization_info () 1064 1065 : fActiveArea () 1066 , fMaskedAreaCount (0) 1067 , fLinearizationTable () 1068 , fBlackLevelRepeatRows (1) 1069 , fBlackLevelRepeatCols (1) 1070 , fBlackDeltaH () 1071 , fBlackDeltaV () 1072 , fBlackDenom (256) 1073 1074 { 1075 1076 uint32 j; 1077 uint32 k; 1078 uint32 n; 1079 1080 for (j = 0; j < kMaxBlackPattern; j++) 1081 for (k = 0; k < kMaxBlackPattern; k++) 1082 for (n = 0; n < kMaxSamplesPerPixel; n++) 1083 { 1084 fBlackLevel [j] [k] [n] = 0.0; 1085 } 1086 1087 for (n = 0; n < kMaxSamplesPerPixel; n++) 1088 { 1089 fWhiteLevel [n] = 65535.0; 1090 } 1091 1092 } 1093 1094/*****************************************************************************/ 1095 1096dng_linearization_info::~dng_linearization_info () 1097 { 1098 1099 } 1100 1101/*****************************************************************************/ 1102 1103void dng_linearization_info::RoundBlacks () 1104 { 1105 1106 uint32 j; 1107 uint32 k; 1108 uint32 n; 1109 1110 real64 maxAbs = 0.0; 1111 1112 for (j = 0; j < fBlackLevelRepeatRows; j++) 1113 for (k = 0; k < fBlackLevelRepeatCols; k++) 1114 for (n = 0; n < kMaxSamplesPerPixel; n++) 1115 { 1116 1117 maxAbs = Max_real64 (maxAbs, 1118 Abs_real64 (fBlackLevel [j] [k] [n])); 1119 1120 } 1121 1122 uint32 count = RowBlackCount (); 1123 1124 for (j = 0; j < count; j++) 1125 { 1126 1127 maxAbs = Max_real64 (maxAbs, 1128 Abs_real64 (fBlackDeltaV->Buffer_real64 () [j])); 1129 1130 } 1131 1132 count = ColumnBlackCount (); 1133 1134 for (j = 0; j < count; j++) 1135 { 1136 1137 maxAbs = Max_real64 (maxAbs, 1138 Abs_real64 (fBlackDeltaH->Buffer_real64 () [j])); 1139 1140 1141 } 1142 1143 fBlackDenom = 256; 1144 1145 while (fBlackDenom > 1 && (maxAbs * fBlackDenom) >= 30000.0 * 65536.0) 1146 { 1147 fBlackDenom >>= 1; 1148 } 1149 1150 for (j = 0; j < fBlackLevelRepeatRows; j++) 1151 for (k = 0; k < fBlackLevelRepeatCols; k++) 1152 for (n = 0; n < kMaxSamplesPerPixel; n++) 1153 { 1154 1155 fBlackLevel [j] [k] [n] = BlackLevel (j, k, n).As_real64 (); 1156 1157 } 1158 1159 count = RowBlackCount (); 1160 1161 for (j = 0; j < count; j++) 1162 { 1163 1164 fBlackDeltaV->Buffer_real64 () [j] = RowBlack (j).As_real64 (); 1165 1166 } 1167 1168 count = ColumnBlackCount (); 1169 1170 for (j = 0; j < count; j++) 1171 { 1172 1173 fBlackDeltaH->Buffer_real64 () [j] = ColumnBlack (j).As_real64 (); 1174 1175 } 1176 1177 } 1178 1179/*****************************************************************************/ 1180 1181void dng_linearization_info::Parse (dng_host &host, 1182 dng_stream &stream, 1183 dng_info &info) 1184 { 1185 1186 uint32 j; 1187 uint32 k; 1188 uint32 n; 1189 1190 // Find main image IFD. 1191 1192 dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get (); 1193 1194 // Copy active area. 1195 1196 fActiveArea = rawIFD.fActiveArea; 1197 1198 // Copy masked areas. 1199 1200 fMaskedAreaCount = rawIFD.fMaskedAreaCount; 1201 1202 for (j = 0; j < fMaskedAreaCount; j++) 1203 { 1204 fMaskedArea [j] = rawIFD.fMaskedArea [j]; 1205 } 1206 1207 // Read linearization LUT. 1208 1209 if (rawIFD.fLinearizationTableCount) 1210 { 1211 1212 uint32 size = SafeUint32Mult (rawIFD.fLinearizationTableCount, 1213 static_cast<uint32> (sizeof (uint16))); 1214 1215 fLinearizationTable.Reset (host.Allocate (size)); 1216 1217 uint16 *table = fLinearizationTable->Buffer_uint16 (); 1218 1219 stream.SetReadPosition (rawIFD.fLinearizationTableOffset); 1220 1221 for (j = 0; j < rawIFD.fLinearizationTableCount; j++) 1222 { 1223 table [j] = stream.Get_uint16 (); 1224 } 1225 1226 } 1227 1228 // Copy black level pattern. 1229 1230 fBlackLevelRepeatRows = rawIFD.fBlackLevelRepeatRows; 1231 fBlackLevelRepeatCols = rawIFD.fBlackLevelRepeatCols; 1232 1233 for (j = 0; j < kMaxBlackPattern; j++) 1234 for (k = 0; k < kMaxBlackPattern; k++) 1235 for (n = 0; n < kMaxSamplesPerPixel; n++) 1236 { 1237 fBlackLevel [j] [k] [n] = rawIFD.fBlackLevel [j] [k] [n]; 1238 } 1239 1240 // Read BlackDeltaH. 1241 1242 if (rawIFD.fBlackLevelDeltaHCount) 1243 { 1244 1245 uint32 size = SafeUint32Mult (rawIFD.fBlackLevelDeltaHCount, 1246 static_cast<uint32> (sizeof (real64))); 1247 1248 fBlackDeltaH.Reset (host.Allocate (size)); 1249 1250 real64 *blacks = fBlackDeltaH->Buffer_real64 (); 1251 1252 stream.SetReadPosition (rawIFD.fBlackLevelDeltaHOffset); 1253 1254 for (j = 0; j < rawIFD.fBlackLevelDeltaHCount; j++) 1255 { 1256 blacks [j] = stream.TagValue_real64 (rawIFD.fBlackLevelDeltaHType); 1257 } 1258 1259 } 1260 1261 // Read BlackDeltaV. 1262 1263 if (rawIFD.fBlackLevelDeltaVCount) 1264 { 1265 1266 uint32 size = SafeUint32Mult (rawIFD.fBlackLevelDeltaVCount, 1267 static_cast<uint32> (sizeof (real64))); 1268 1269 fBlackDeltaV.Reset (host.Allocate (size)); 1270 1271 real64 *blacks = fBlackDeltaV->Buffer_real64 (); 1272 1273 stream.SetReadPosition (rawIFD.fBlackLevelDeltaVOffset); 1274 1275 for (j = 0; j < rawIFD.fBlackLevelDeltaVCount; j++) 1276 { 1277 blacks [j] = stream.TagValue_real64 (rawIFD.fBlackLevelDeltaVType); 1278 } 1279 1280 } 1281 1282 // Copy white level. 1283 1284 for (n = 0; n < kMaxSamplesPerPixel; n++) 1285 { 1286 fWhiteLevel [n] = rawIFD.fWhiteLevel [n]; 1287 } 1288 1289 // Round off black levels. 1290 1291 RoundBlacks (); 1292 1293 } 1294 1295/*****************************************************************************/ 1296 1297void dng_linearization_info::PostParse (dng_host & /* host */, 1298 dng_negative &negative) 1299 { 1300 1301 if (fActiveArea.IsEmpty ()) 1302 { 1303 1304 fActiveArea = negative.Stage1Image ()->Bounds (); 1305 1306 } 1307 1308 } 1309 1310/*****************************************************************************/ 1311 1312real64 dng_linearization_info::MaxBlackLevel (uint32 plane) const 1313 { 1314 1315 uint32 j; 1316 uint32 k; 1317 1318 // Find maximum value of fBlackDeltaH for each phase of black pattern. 1319 1320 real64 maxDeltaH [kMaxBlackPattern]; 1321 1322 for (j = 0; j < fBlackLevelRepeatCols; j++) 1323 { 1324 maxDeltaH [j] = 0.0; 1325 } 1326 1327 if (fBlackDeltaH.Get ()) 1328 { 1329 1330 real64 *table = fBlackDeltaH->Buffer_real64 (); 1331 1332 uint32 entries = fBlackDeltaH->LogicalSize () / (uint32) sizeof (table [0]); 1333 1334 for (j = 0; j < entries; j++) 1335 { 1336 1337 real64 &entry = maxDeltaH [j % fBlackLevelRepeatCols]; 1338 1339 if (j < fBlackLevelRepeatCols) 1340 { 1341 entry = table [j]; 1342 } 1343 else 1344 { 1345 entry = Max_real64 (entry, table [j]); 1346 } 1347 1348 } 1349 1350 } 1351 1352 // Find maximum value of fBlackDeltaV for each phase of black pattern. 1353 1354 real64 maxDeltaV [kMaxBlackPattern]; 1355 1356 for (j = 0; j < fBlackLevelRepeatRows; j++) 1357 { 1358 maxDeltaV [j] = 0.0; 1359 } 1360 1361 if (fBlackDeltaV.Get ()) 1362 { 1363 1364 real64 *table = fBlackDeltaV->Buffer_real64 (); 1365 1366 uint32 entries = fBlackDeltaV->LogicalSize () / (uint32) sizeof (table [0]); 1367 1368 for (j = 0; j < entries; j++) 1369 { 1370 1371 real64 &entry = maxDeltaV [j % fBlackLevelRepeatRows]; 1372 1373 if (j < fBlackLevelRepeatRows) 1374 { 1375 entry = table [j]; 1376 } 1377 else 1378 { 1379 entry = Max_real64 (entry, table [j]); 1380 } 1381 1382 } 1383 1384 } 1385 1386 // Now scan the pattern and find the maximum value after row and column 1387 // deltas. 1388 1389 real64 maxBlack = 0.0; 1390 1391 for (j = 0; j < fBlackLevelRepeatRows; j++) 1392 { 1393 1394 for (k = 0; k < fBlackLevelRepeatCols; k++) 1395 { 1396 1397 real64 black = fBlackLevel [j] [k] [plane]; 1398 1399 black += maxDeltaH [k]; 1400 black += maxDeltaV [j]; 1401 1402 if (j == 0 && k == 0) 1403 { 1404 maxBlack = black; 1405 } 1406 else 1407 { 1408 maxBlack = Max_real64 (maxBlack, black); 1409 } 1410 1411 } 1412 1413 } 1414 1415 return maxBlack; 1416 1417 } 1418 1419/*****************************************************************************/ 1420 1421void dng_linearization_info::Linearize (dng_host &host, 1422 const dng_image &srcImage, 1423 dng_image &dstImage) 1424 { 1425 1426 dng_linearize_image processor (host, 1427 *this, 1428 srcImage, 1429 dstImage); 1430 1431 host.PerformAreaTask (processor, 1432 fActiveArea); 1433 1434 } 1435 1436/*****************************************************************************/ 1437 1438dng_urational dng_linearization_info::BlackLevel (uint32 row, 1439 uint32 col, 1440 uint32 plane) const 1441 { 1442 1443 dng_urational r; 1444 1445 r.Set_real64 (fBlackLevel [row] [col] [plane], fBlackDenom); 1446 1447 return r; 1448 1449 } 1450 1451/*****************************************************************************/ 1452 1453uint32 dng_linearization_info::RowBlackCount () const 1454 { 1455 1456 if (fBlackDeltaV.Get ()) 1457 { 1458 1459 return fBlackDeltaV->LogicalSize () >> 3; 1460 1461 } 1462 1463 return 0; 1464 1465 } 1466 1467/*****************************************************************************/ 1468 1469dng_srational dng_linearization_info::RowBlack (uint32 row) const 1470 { 1471 1472 if (fBlackDeltaV.Get ()) 1473 { 1474 1475 dng_srational r; 1476 1477 r.Set_real64 (fBlackDeltaV->Buffer_real64 () [row], fBlackDenom); 1478 1479 return r; 1480 1481 } 1482 1483 return dng_srational (0, 1); 1484 1485 } 1486 1487/*****************************************************************************/ 1488 1489uint32 dng_linearization_info::ColumnBlackCount () const 1490 { 1491 1492 if (fBlackDeltaH.Get ()) 1493 { 1494 1495 return fBlackDeltaH->LogicalSize () >> 3; 1496 1497 } 1498 1499 return 0; 1500 1501 } 1502 1503/*****************************************************************************/ 1504 1505dng_srational dng_linearization_info::ColumnBlack (uint32 col) const 1506 { 1507 1508 if (fBlackDeltaH.Get ()) 1509 { 1510 1511 dng_srational r; 1512 1513 r.Set_real64 (fBlackDeltaH->Buffer_real64 () [col], fBlackDenom); 1514 1515 return r; 1516 1517 } 1518 1519 return dng_srational (0, 1); 1520 1521 } 1522 1523/*****************************************************************************/ 1524