Home | History | Annotate | Download | only in source
      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