Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/dng_sdk/source/dng_misc_opcodes.cpp
Line
Count
Source (jump to first uncovered line)
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
0
  {
39
  
40
0
  }
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
0
  {
53
  
54
0
  if (stream.Get_uint32 () != 16)
55
0
    {
56
0
    ThrowBadFormat ();
57
0
    }
58
    
59
0
  fBounds.t = stream.Get_int32 ();
60
0
  fBounds.l = stream.Get_int32 ();
61
0
  fBounds.b = stream.Get_int32 ();
62
0
  fBounds.r = stream.Get_int32 ();
63
  
64
0
  if (fBounds.IsEmpty ())
65
0
    {
66
0
    ThrowBadFormat ();
67
0
    }
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
0
  }
85
86
/*****************************************************************************/
87
88
void dng_opcode_TrimBounds::PutData (dng_stream &stream) const
89
0
  {
90
  
91
0
  stream.Put_uint32 (16);
92
  
93
0
  stream.Put_int32 (fBounds.t);
94
0
  stream.Put_int32 (fBounds.l);
95
0
  stream.Put_int32 (fBounds.b);
96
0
  stream.Put_int32 (fBounds.r);
97
  
98
0
  }
99
100
/*****************************************************************************/
101
102
void dng_opcode_TrimBounds::Apply (dng_host & /* host */,
103
                   dng_negative & /* negative */,
104
                   AutoPtr<dng_image> &image)
105
0
  {
106
  
107
0
  if (fBounds.IsEmpty () || (fBounds & image->Bounds ()) != fBounds)
108
0
    {
109
0
    ThrowBadFormat ();
110
0
    }
111
    
112
0
  image->Trim (fBounds);
113
  
114
0
  }
115
116
/*****************************************************************************/
117
118
void dng_area_spec::GetData (dng_stream &stream)
119
0
  {
120
  
121
0
  fArea.t = stream.Get_int32 ();
122
0
  fArea.l = stream.Get_int32 ();
123
0
  fArea.b = stream.Get_int32 ();
124
0
  fArea.r = stream.Get_int32 ();
125
  
126
0
  fPlane  = stream.Get_uint32 ();
127
0
  fPlanes = stream.Get_uint32 ();
128
  
129
0
  fRowPitch = stream.Get_uint32 ();
130
0
  fColPitch = stream.Get_uint32 ();
131
  
132
0
  if (fPlanes < 1)
133
0
    {
134
0
    ThrowBadFormat ();
135
0
    }
136
    
137
0
  if (fRowPitch < 1 || fColPitch < 1)
138
0
    {
139
0
    ThrowBadFormat ();
140
0
    }
141
    
142
0
  if (fArea.IsEmpty ())
143
0
    {
144
0
    if (fRowPitch != 1 || fColPitch != 1)
145
0
      {
146
0
      ThrowBadFormat ();
147
0
      }
148
0
    }
149
    
150
0
  else
151
0
    {
152
0
    int32 width = 0;
153
0
    int32 height = 0;
154
0
    if (!SafeInt32Sub (fArea.b, fArea.t, &height) ||
155
0
       !SafeInt32Sub (fArea.r, fArea.l, &width) ||
156
0
       fRowPitch > static_cast<uint32>(height) ||
157
0
       fColPitch > static_cast<uint32>(width))
158
0
      {
159
0
      ThrowBadFormat();
160
0
      }
161
0
    }
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
0
  }
183
184
/*****************************************************************************/
185
186
void dng_area_spec::PutData (dng_stream &stream) const
187
0
  {
188
  
189
0
  stream.Put_int32 (fArea.t);
190
0
  stream.Put_int32 (fArea.l);
191
0
  stream.Put_int32 (fArea.b);
192
0
  stream.Put_int32 (fArea.r);
193
  
194
0
  stream.Put_uint32 (fPlane);
195
0
  stream.Put_uint32 (fPlanes);
196
  
197
0
  stream.Put_uint32 (fRowPitch);
198
0
  stream.Put_uint32 (fColPitch);
199
  
200
0
  }
201
202
/*****************************************************************************/
203
204
dng_rect dng_area_spec::Overlap (const dng_rect &tile) const
205
0
  {
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
0
  if (fArea.IsEmpty ())
211
0
    {
212
0
    return tile;
213
0
    }
214
  
215
0
  dng_rect overlap = fArea & tile;
216
  
217
0
  if (overlap.NotEmpty ())
218
0
    {
219
    
220
0
    overlap.t = fArea.t + ConvertUint32ToInt32(
221
0
      RoundUpUint32ToMultiple(static_cast<uint32>(overlap.t - fArea.t),
222
0
                  fRowPitch));
223
0
    overlap.l = fArea.l + ConvertUint32ToInt32(
224
0
      RoundUpUint32ToMultiple(static_cast<uint32>(overlap.l - fArea.l),
225
0
                  fColPitch));
226
    
227
0
    if (overlap.NotEmpty ())
228
0
      {
229
      
230
0
      overlap.b = overlap.t + ((overlap.H () - 1) / fRowPitch) * fRowPitch + 1;
231
0
      overlap.r = overlap.l + ((overlap.W () - 1) / fColPitch) * fColPitch + 1;
232
      
233
0
      return overlap;
234
      
235
0
      }
236
    
237
0
    }
238
    
239
0
  return dng_rect ();
240
  
241
0
  }
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
0
  {
259
  
260
0
  if (count == 0 || count > 0x10000)
261
0
    {
262
0
    ThrowProgramError ();
263
0
    }
264
  
265
0
  fTable.Reset (host.Allocate (0x10000 * sizeof (uint16)));
266
  
267
0
  DoCopyBytes (table,
268
0
         fTable->Buffer (),
269
0
         count * (uint32) sizeof (uint16));
270
         
271
0
  ReplicateLastEntry ();
272
  
273
0
  }
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
0
  {
289
  
290
0
  uint32 dataSize = stream.Get_uint32 ();
291
  
292
0
  fAreaSpec.GetData (stream);
293
  
294
0
  fCount = stream.Get_uint32 ();
295
  
296
0
  uint32 requiredSize = SafeUint32Mult(fCount, 2);
297
0
  requiredSize = SafeUint32Add(requiredSize, dng_area_spec::kDataSize);
298
0
  requiredSize = SafeUint32Add(requiredSize, 4);
299
0
  if (dataSize != requiredSize)
300
0
    {
301
0
    ThrowBadFormat ();
302
0
    }
303
    
304
0
  if (fCount == 0 || fCount > 0x10000)
305
0
    {
306
0
    ThrowBadFormat ();
307
0
    }
308
  
309
0
  fTable.Reset (host.Allocate (0x10000 * sizeof (uint16)));
310
  
311
0
  uint16 *table = fTable->Buffer_uint16 ();
312
  
313
0
  for (uint32 index = 0; index < fCount; index++)
314
0
    {
315
0
    table [index] = stream.Get_uint16 ();
316
0
    }
317
    
318
0
  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
0
  }
342
343
/*****************************************************************************/
344
345
void dng_opcode_MapTable::ReplicateLastEntry ()
346
0
  {
347
  
348
0
  uint16 *table = fTable->Buffer_uint16 ();
349
    
350
0
  uint16 lastEntry = table [fCount];
351
  
352
0
  for (uint32 index = fCount; index < 0x10000; index++)
353
0
    {
354
0
    table [index] = lastEntry;
355
0
    }
356
  
357
0
  }
358
359
/*****************************************************************************/
360
361
void dng_opcode_MapTable::PutData (dng_stream &stream) const
362
0
  {
363
  
364
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + fCount * 2);
365
  
366
0
  fAreaSpec.PutData (stream);
367
  
368
0
  stream.Put_uint32 (fCount);
369
  
370
0
  uint16 *table = fTable->Buffer_uint16 ();
371
    
372
0
  for (uint32 index = 0; index < fCount; index++)
373
0
    {
374
0
    stream.Put_uint16 (table [index]);
375
0
    }
376
  
377
0
  }
378
      
379
/*****************************************************************************/
380
381
uint32 dng_opcode_MapTable::BufferPixelType (uint32 /* imagePixelType */)
382
0
  {
383
  
384
0
  return ttShort;
385
  
386
0
  }
387
  
388
/*****************************************************************************/
389
390
dng_rect dng_opcode_MapTable::ModifiedBounds (const dng_rect &imageBounds)
391
0
  {
392
  
393
0
  return fAreaSpec.Overlap (imageBounds);
394
  
395
0
  }
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
0
  {
405
  
406
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
407
  
408
0
  if (overlap.NotEmpty ())
409
0
    {
410
    
411
0
    for (uint32 plane = fAreaSpec.Plane ();
412
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
413
0
       plane < buffer.Planes ();
414
0
       plane++)
415
0
      {
416
      
417
0
      DoMapArea16 (buffer.DirtyPixel_uint16 (overlap.t, overlap.l, plane),
418
0
             1,
419
0
             (overlap.H () + fAreaSpec.RowPitch () - 1) / fAreaSpec.RowPitch (),
420
0
             (overlap.W () + fAreaSpec.ColPitch () - 1) / fAreaSpec.ColPitch (),
421
0
             0,
422
0
             fAreaSpec.RowPitch () * buffer.RowStep (),
423
0
             fAreaSpec.ColPitch (),
424
0
             fTable->Buffer_uint16 ());
425
      
426
0
      }
427
    
428
0
    }
429
  
430
0
  }
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
0
  {
446
  
447
0
  for (uint32 j = 0; j <= kMaxDegree; j++)
448
0
    {
449
    
450
0
    if (j <= fDegree)
451
0
      {
452
0
      fCoefficient [j] = coefficient [j];
453
0
      }
454
      
455
0
    else
456
0
      {
457
0
      fCoefficient [j] = 0.0;
458
0
      }
459
460
0
    }
461
    
462
  // Reduce degree if possible.
463
    
464
0
  while (fDegree > 0 && fCoefficient [fDegree] == 0.0)
465
0
    {
466
0
    fDegree--;
467
0
    }
468
469
0
  }
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
0
  {
483
  
484
0
  uint32 dataSize = stream.Get_uint32 ();
485
  
486
0
  fAreaSpec.GetData (stream);
487
  
488
0
  fDegree = stream.Get_uint32 ();
489
  
490
0
  if (fDegree > kMaxDegree)
491
0
    {
492
0
    ThrowBadFormat ();
493
0
    }
494
      
495
0
  if (dataSize != dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8)
496
0
    {
497
0
    ThrowBadFormat ();
498
0
    }
499
    
500
0
  for (uint32 j = 0; j <= kMaxDegree; j++)
501
0
    {
502
    
503
0
    if (j <= fDegree)
504
0
      {
505
0
      fCoefficient [j] = stream.Get_real64 ();
506
0
      }
507
0
    else
508
0
      {
509
0
      fCoefficient [j] = 0.0;
510
0
      }
511
      
512
0
    }
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
0
  }
529
                  
530
/*****************************************************************************/
531
532
void dng_opcode_MapPolynomial::PutData (dng_stream &stream) const
533
0
  {
534
  
535
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + (fDegree + 1) * 8);
536
  
537
0
  fAreaSpec.PutData (stream);
538
  
539
0
  stream.Put_uint32 (fDegree);
540
  
541
0
  for (uint32 j = 0; j <= fDegree; j++)
542
0
    {
543
0
    stream.Put_real64 (fCoefficient [j]);
544
0
    }
545
  
546
0
  }
547
                  
548
/*****************************************************************************/
549
550
uint32 dng_opcode_MapPolynomial::BufferPixelType (uint32 imagePixelType)
551
0
  {
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
0
  real64 scale32 = 1.0;
563
  
564
0
  if (Stage () == 1)
565
0
    {
566
  
567
0
    switch (imagePixelType)
568
0
      {
569
      
570
0
      case ttFloat:
571
0
        break;
572
      
573
0
      case ttShort:
574
0
        {
575
0
        scale32 = (real64) 0xFFFF;
576
0
        break;
577
0
        }
578
        
579
0
      case ttLong:
580
0
        {
581
0
        scale32 = (real64) 0xFFFFFFFF;
582
0
        break;
583
0
        }
584
        
585
0
      default:
586
0
        ThrowBadFormat ();
587
        
588
0
      }
589
      
590
0
    }
591
    
592
0
  real64 factor32 = 1.0 / scale32;
593
    
594
0
  for (uint32 j = 0; j <= kMaxDegree; j++)
595
0
    {
596
    
597
0
    fCoefficient32 [j] = ConvertDoubleToFloat(fCoefficient [j] * factor32);
598
    
599
0
    factor32 *= scale32;
600
    
601
0
    }
602
603
0
  return ttFloat;
604
  
605
0
  }
606
                  
607
/*****************************************************************************/
608
609
dng_rect dng_opcode_MapPolynomial::ModifiedBounds (const dng_rect &imageBounds)
610
0
  {
611
  
612
0
  return fAreaSpec.Overlap (imageBounds);
613
  
614
0
  }
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
0
  {
624
  
625
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
626
  
627
0
  if (overlap.NotEmpty ())
628
0
    {
629
    
630
0
    uint32 cols = overlap.W ();
631
    
632
0
    uint32 colPitch = fAreaSpec.ColPitch ();
633
    
634
0
    for (uint32 plane = fAreaSpec.Plane ();
635
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
636
0
       plane < buffer.Planes ();
637
0
       plane++)
638
0
      {
639
      
640
0
      for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
641
0
        {
642
        
643
0
        real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
644
        
645
0
        switch (fDegree)
646
0
          {
647
          
648
0
          case 0:
649
0
            {
650
            
651
0
            real32 y = Pin_real32 (0.0f,
652
0
                         fCoefficient32 [0],
653
0
                         1.0f);
654
            
655
0
            for (uint32 col = 0; col < cols; col += colPitch)
656
0
              {
657
              
658
0
              dPtr [col] = y;
659
              
660
0
              }
661
              
662
0
            break;
663
          
664
0
            }
665
666
0
          case 1:
667
0
            {
668
            
669
0
            real32 c0 = fCoefficient32 [0];
670
0
            real32 c1 = fCoefficient32 [1];
671
            
672
0
            if (c0 == 0.0f)
673
0
              {
674
              
675
0
              if (c1 > 0.0f)
676
0
                {
677
            
678
0
                for (uint32 col = 0; col < cols; col += colPitch)
679
0
                  {
680
                  
681
0
                  real32 x = dPtr [col];
682
                  
683
0
                  real32 y = c1 * x;
684
                         
685
0
                  dPtr [col] = Min_real32 (y, 1.0f);
686
                  
687
0
                  }
688
                
689
0
                }
690
                
691
0
              else
692
0
                {
693
            
694
0
                for (uint32 col = 0; col < cols; col += colPitch)
695
0
                  {
696
                  
697
0
                  dPtr [col] = 0.0f;
698
                  
699
0
                  }
700
                
701
0
                }
702
              
703
0
              }
704
              
705
0
            else
706
0
              {
707
            
708
0
              for (uint32 col = 0; col < cols; col += colPitch)
709
0
                {
710
                
711
0
                real32 x = dPtr [col];
712
                
713
0
                real32 y = c0 +
714
0
                       c1 * x;
715
                       
716
0
                dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
717
                
718
0
                }
719
                
720
0
              }
721
              
722
0
            break;
723
          
724
0
            }
725
          
726
0
          case 2:
727
0
            {
728
            
729
0
            for (uint32 col = 0; col < cols; col += colPitch)
730
0
              {
731
              
732
0
              real32 x = dPtr [col];
733
              
734
0
              real32 y =  fCoefficient32 [0] + x *
735
0
                     (fCoefficient32 [1] + x *
736
0
                     (fCoefficient32 [2]));
737
                     
738
0
              dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
739
              
740
0
              }
741
              
742
0
            break;
743
          
744
0
            }
745
          
746
0
          case 3:
747
0
            {
748
            
749
0
            for (uint32 col = 0; col < cols; col += colPitch)
750
0
              {
751
              
752
0
              real32 x = dPtr [col];
753
              
754
0
              real32 y =  fCoefficient32 [0] + x *
755
0
                     (fCoefficient32 [1] + x *
756
0
                     (fCoefficient32 [2] + x *
757
0
                     (fCoefficient32 [3])));
758
                     
759
0
              dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
760
              
761
0
              }
762
              
763
0
            break;
764
          
765
0
            }
766
          
767
0
          case 4:
768
0
            {
769
            
770
0
            for (uint32 col = 0; col < cols; col += colPitch)
771
0
              {
772
              
773
0
              real32 x = dPtr [col];
774
              
775
0
              real32 y =  fCoefficient32 [0] + x *
776
0
                     (fCoefficient32 [1] + x *
777
0
                     (fCoefficient32 [2] + x *
778
0
                     (fCoefficient32 [3] + x *
779
0
                     (fCoefficient32 [4]))));
780
                     
781
0
              dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
782
              
783
0
              }
784
              
785
0
            break;
786
          
787
0
            }
788
                                            
789
0
          default:
790
0
            {
791
            
792
0
            for (uint32 col = 0; col < cols; col += colPitch)
793
0
              {
794
              
795
0
              real32 x = dPtr [col];
796
              
797
0
              real32 y = fCoefficient32 [0];
798
              
799
0
              real32 xx = x;
800
              
801
0
              for (uint32 j = 1; j <= fDegree; j++)
802
0
                {
803
                
804
0
                y += fCoefficient32 [j] * xx;
805
                
806
0
                xx *= x;
807
                
808
0
                }
809
                                   
810
0
              dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
811
              
812
0
              }
813
              
814
0
            }
815
                      
816
0
          }
817
        
818
0
        }
819
      
820
0
      }
821
    
822
0
    }
823
  
824
0
  }
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
0
  {
840
  
841
0
  fTable.Reset (table.Release ());
842
  
843
0
  }
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
0
  {
859
  
860
0
  uint32 dataSize = stream.Get_uint32 ();
861
  
862
0
  fAreaSpec.GetData (stream);
863
  
864
0
  uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().H (),
865
0
                    fAreaSpec.RowPitch ());
866
           
867
0
  if (deltas != stream.Get_uint32 ())
868
0
    {
869
0
    ThrowBadFormat ();
870
0
    }
871
    
872
0
  if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4)
873
0
    {
874
0
    ThrowBadFormat ();
875
0
    }
876
    
877
0
  fTable.Reset (host.Allocate (SafeUint32Mult (deltas,
878
0
    static_cast<uint32> (sizeof (real32)))));
879
  
880
0
  real32 *table = fTable->Buffer_real32 ();
881
  
882
0
  for (uint32 j = 0; j < deltas; j++)
883
0
    {
884
0
    table [j] = stream.Get_real32 ();
885
0
    }
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
0
  }
909
910
/*****************************************************************************/
911
912
void dng_opcode_DeltaPerRow::PutData (dng_stream &stream) const
913
0
  {
914
  
915
0
  uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().H (),
916
0
                    fAreaSpec.RowPitch ());
917
  
918
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4);
919
  
920
0
  fAreaSpec.PutData (stream);
921
  
922
0
  stream.Put_uint32 (deltas);
923
  
924
0
  real32 *table = fTable->Buffer_real32 ();
925
  
926
0
  for (uint32 j = 0; j < deltas; j++)
927
0
    {
928
0
    stream.Put_real32 (table [j]);
929
0
    }
930
  
931
0
  }
932
933
/*****************************************************************************/
934
935
uint32 dng_opcode_DeltaPerRow::BufferPixelType (uint32 imagePixelType)
936
0
  {
937
  
938
0
  real64 scale32 = 1.0;
939
  
940
0
  switch (imagePixelType)
941
0
    {
942
    
943
0
    case ttFloat:
944
0
      break;
945
    
946
0
    case ttShort:
947
0
      {
948
0
      scale32 = (real64) 0xFFFF;
949
0
      break;
950
0
      }
951
      
952
0
    case ttLong:
953
0
      {
954
0
      scale32 = (real64) 0xFFFFFFFF;
955
0
      break;
956
0
      }
957
      
958
0
    default:
959
0
      ThrowBadFormat ();
960
      
961
0
    }
962
    
963
0
  fScale = (real32) (1.0 / scale32);
964
    
965
0
  return ttFloat;
966
  
967
0
  }
968
969
/*****************************************************************************/
970
971
dng_rect dng_opcode_DeltaPerRow::ModifiedBounds (const dng_rect &imageBounds)
972
0
  {
973
  
974
0
  return fAreaSpec.Overlap (imageBounds);
975
  
976
0
  }
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
0
  {
986
  
987
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
988
  
989
0
  if (overlap.NotEmpty ())
990
0
    {
991
    
992
0
    uint32 cols = overlap.W ();
993
    
994
0
    uint32 colPitch = fAreaSpec.ColPitch ();
995
    
996
0
    for (uint32 plane = fAreaSpec.Plane ();
997
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
998
0
       plane < buffer.Planes ();
999
0
       plane++)
1000
0
      {
1001
      
1002
0
      const real32 *table = fTable->Buffer_real32 () +
1003
0
                  ((overlap.t - fAreaSpec.Area ().t) /
1004
0
                   fAreaSpec.RowPitch ());
1005
      
1006
0
      for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
1007
0
        {
1008
        
1009
0
        real32 rowDelta = *(table++) * fScale;
1010
        
1011
0
        real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
1012
        
1013
0
        for (uint32 col = 0; col < cols; col += colPitch)
1014
0
          {
1015
          
1016
0
          real32 x = dPtr [col];
1017
          
1018
0
          real32 y = x + rowDelta;
1019
                 
1020
0
          dPtr [col] = Pin_real32 (0.0f, y, 1.0f);
1021
          
1022
0
          }
1023
        
1024
0
        }
1025
      
1026
0
      }
1027
    
1028
0
    }
1029
  
1030
0
  }
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
0
  {
1046
  
1047
0
  fTable.Reset (table.Release ());
1048
  
1049
0
  }
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
0
  {
1065
  
1066
0
  uint32 dataSize = stream.Get_uint32 ();
1067
  
1068
0
  fAreaSpec.GetData (stream);
1069
  
1070
0
  uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().W (),
1071
0
                    fAreaSpec.ColPitch ());
1072
           
1073
0
  if (deltas != stream.Get_uint32 ())
1074
0
    {
1075
0
    ThrowBadFormat ();
1076
0
    }
1077
    
1078
0
  if (dataSize != dng_area_spec::kDataSize + 4 + deltas * 4)
1079
0
    {
1080
0
    ThrowBadFormat ();
1081
0
    }
1082
    
1083
0
  fTable.Reset (host.Allocate (SafeUint32Mult (deltas,
1084
0
    static_cast<uint32> (sizeof (real32)))));
1085
  
1086
0
  real32 *table = fTable->Buffer_real32 ();
1087
  
1088
0
  for (uint32 j = 0; j < deltas; j++)
1089
0
    {
1090
0
    table [j] = stream.Get_real32 ();
1091
0
    }
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
0
  }
1115
1116
/*****************************************************************************/
1117
1118
void dng_opcode_DeltaPerColumn::PutData (dng_stream &stream) const
1119
0
  {
1120
  
1121
0
  uint32 deltas = SafeUint32DivideUp (fAreaSpec.Area ().W (),
1122
0
                    fAreaSpec.ColPitch ());
1123
  
1124
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + deltas * 4);
1125
  
1126
0
  fAreaSpec.PutData (stream);
1127
  
1128
0
  stream.Put_uint32 (deltas);
1129
  
1130
0
  real32 *table = fTable->Buffer_real32 ();
1131
  
1132
0
  for (uint32 j = 0; j < deltas; j++)
1133
0
    {
1134
0
    stream.Put_real32 (table [j]);
1135
0
    }
1136
  
1137
0
  }
1138
1139
/*****************************************************************************/
1140
1141
uint32 dng_opcode_DeltaPerColumn::BufferPixelType (uint32 imagePixelType)
1142
0
  {
1143
  
1144
0
  real64 scale32 = 1.0;
1145
  
1146
0
  switch (imagePixelType)
1147
0
    {
1148
    
1149
0
    case ttFloat:
1150
0
      break;
1151
    
1152
0
    case ttShort:
1153
0
      {
1154
0
      scale32 = (real64) 0xFFFF;
1155
0
      break;
1156
0
      }
1157
      
1158
0
    case ttLong:
1159
0
      {
1160
0
      scale32 = (real64) 0xFFFFFFFF;
1161
0
      break;
1162
0
      }
1163
      
1164
0
    default:
1165
0
      ThrowBadFormat ();
1166
      
1167
0
    }
1168
    
1169
0
  fScale = (real32) (1.0 / scale32);
1170
    
1171
0
  return ttFloat;
1172
  
1173
0
  }
1174
1175
/*****************************************************************************/
1176
1177
dng_rect dng_opcode_DeltaPerColumn::ModifiedBounds (const dng_rect &imageBounds)
1178
0
  {
1179
  
1180
0
  return fAreaSpec.Overlap (imageBounds);
1181
  
1182
0
  }
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
0
  {
1192
  
1193
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
1194
  
1195
0
  if (overlap.NotEmpty ())
1196
0
    {
1197
    
1198
0
    uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) /
1199
0
            fAreaSpec.RowPitch ();
1200
    
1201
0
    int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch ();
1202
    
1203
0
    for (uint32 plane = fAreaSpec.Plane ();
1204
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
1205
0
       plane < buffer.Planes ();
1206
0
       plane++)
1207
0
      {
1208
      
1209
0
      const real32 *table = fTable->Buffer_real32 () +
1210
0
                  ((overlap.l - fAreaSpec.Area ().l) /
1211
0
                   fAreaSpec.ColPitch ());
1212
      
1213
0
      for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ())
1214
0
        {
1215
        
1216
0
        real32 colDelta = *(table++) * fScale;
1217
        
1218
0
        real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane);
1219
        
1220
0
        for (uint32 row = 0; row < rows; row++)
1221
0
          {
1222
          
1223
0
          real32 x = dPtr [0];
1224
          
1225
0
          real32 y = x + colDelta;
1226
                 
1227
0
          dPtr [0] = Pin_real32 (0.0f, y, 1.0f);
1228
          
1229
0
          dPtr += rowStep;
1230
          
1231
0
          }
1232
        
1233
0
        }
1234
      
1235
0
      }
1236
    
1237
0
    }
1238
  
1239
0
  }
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
0
  {
1254
  
1255
0
  fTable.Reset (table.Release ());
1256
  
1257
0
  }
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
0
  {
1272
  
1273
0
  uint32 dataSize = stream.Get_uint32 ();
1274
  
1275
0
  fAreaSpec.GetData (stream);
1276
  
1277
0
  uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().H (),
1278
0
                    fAreaSpec.RowPitch ());
1279
           
1280
0
  if (scales != stream.Get_uint32 ())
1281
0
    {
1282
0
    ThrowBadFormat ();
1283
0
    }
1284
    
1285
0
  if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4)
1286
0
    {
1287
0
    ThrowBadFormat ();
1288
0
    }
1289
    
1290
0
  fTable.Reset (host.Allocate (SafeUint32Mult (scales,
1291
0
    static_cast<uint32> (sizeof (real32)))));
1292
  
1293
0
  real32 *table = fTable->Buffer_real32 ();
1294
  
1295
0
  for (uint32 j = 0; j < scales; j++)
1296
0
    {
1297
0
    table [j] = stream.Get_real32 ();
1298
0
    }
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
0
  }
1322
1323
/*****************************************************************************/
1324
1325
void dng_opcode_ScalePerRow::PutData (dng_stream &stream) const
1326
0
  {
1327
  
1328
0
  uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().H (),
1329
0
                    fAreaSpec.RowPitch ());
1330
  
1331
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4);
1332
  
1333
0
  fAreaSpec.PutData (stream);
1334
  
1335
0
  stream.Put_uint32 (scales);
1336
  
1337
0
  real32 *table = fTable->Buffer_real32 ();
1338
  
1339
0
  for (uint32 j = 0; j < scales; j++)
1340
0
    {
1341
0
    stream.Put_real32 (table [j]);
1342
0
    }
1343
  
1344
0
  }
1345
1346
/*****************************************************************************/
1347
1348
uint32 dng_opcode_ScalePerRow::BufferPixelType (uint32 /* imagePixelType */)
1349
0
  {
1350
      
1351
0
  return ttFloat;
1352
  
1353
0
  }
1354
1355
/*****************************************************************************/
1356
1357
dng_rect dng_opcode_ScalePerRow::ModifiedBounds (const dng_rect &imageBounds)
1358
0
  {
1359
  
1360
0
  return fAreaSpec.Overlap (imageBounds);
1361
  
1362
0
  }
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
0
  {
1372
  
1373
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
1374
  
1375
0
  if (overlap.NotEmpty ())
1376
0
    {
1377
    
1378
0
    uint32 cols = overlap.W ();
1379
    
1380
0
    uint32 colPitch = fAreaSpec.ColPitch ();
1381
    
1382
0
    for (uint32 plane = fAreaSpec.Plane ();
1383
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
1384
0
       plane < buffer.Planes ();
1385
0
       plane++)
1386
0
      {
1387
      
1388
0
      const real32 *table = fTable->Buffer_real32 () +
1389
0
                  ((overlap.t - fAreaSpec.Area ().t) /
1390
0
                   fAreaSpec.RowPitch ());
1391
      
1392
0
      for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
1393
0
        {
1394
        
1395
0
        real32 rowScale = *(table++);
1396
        
1397
0
        real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
1398
        
1399
0
        for (uint32 col = 0; col < cols; col += colPitch)
1400
0
          {
1401
          
1402
0
          real32 x = dPtr [col];
1403
          
1404
0
          real32 y = x * rowScale;
1405
                 
1406
0
          dPtr [col] = Min_real32 (y, 1.0f);
1407
          
1408
0
          }
1409
        
1410
0
        }
1411
      
1412
0
      }
1413
    
1414
0
    }
1415
  
1416
0
  }
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
0
  {
1431
  
1432
0
  fTable.Reset (table.Release ());
1433
  
1434
0
  }
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
0
  {
1449
  
1450
0
  uint32 dataSize = stream.Get_uint32 ();
1451
  
1452
0
  fAreaSpec.GetData (stream);
1453
  
1454
0
  uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().W (),
1455
0
                    fAreaSpec.ColPitch());
1456
           
1457
0
  if (scales != stream.Get_uint32 ())
1458
0
    {
1459
0
    ThrowBadFormat ();
1460
0
    }
1461
    
1462
0
  if (dataSize != dng_area_spec::kDataSize + 4 + scales * 4)
1463
0
    {
1464
0
    ThrowBadFormat ();
1465
0
    }
1466
    
1467
0
  fTable.Reset (host.Allocate (SafeUint32Mult (scales,
1468
0
    static_cast<uint32> (sizeof (real32)))));
1469
  
1470
0
  real32 *table = fTable->Buffer_real32 ();
1471
  
1472
0
  for (uint32 j = 0; j < scales; j++)
1473
0
    {
1474
0
    table [j] = stream.Get_real32 ();
1475
0
    }
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
0
  }
1499
1500
/*****************************************************************************/
1501
1502
void dng_opcode_ScalePerColumn::PutData (dng_stream &stream) const
1503
0
  {
1504
  
1505
0
  uint32 scales = SafeUint32DivideUp (fAreaSpec.Area ().W (),
1506
0
                    fAreaSpec.ColPitch ());
1507
  
1508
0
  stream.Put_uint32 (dng_area_spec::kDataSize + 4 + scales * 4);
1509
  
1510
0
  fAreaSpec.PutData (stream);
1511
  
1512
0
  stream.Put_uint32 (scales);
1513
  
1514
0
  real32 *table = fTable->Buffer_real32 ();
1515
  
1516
0
  for (uint32 j = 0; j < scales; j++)
1517
0
    {
1518
0
    stream.Put_real32 (table [j]);
1519
0
    }
1520
  
1521
0
  }
1522
1523
/*****************************************************************************/
1524
1525
uint32 dng_opcode_ScalePerColumn::BufferPixelType (uint32 /* imagePixelType */)
1526
0
  {
1527
  
1528
0
  return ttFloat;
1529
  
1530
0
  }
1531
1532
/*****************************************************************************/
1533
1534
dng_rect dng_opcode_ScalePerColumn::ModifiedBounds (const dng_rect &imageBounds)
1535
0
  {
1536
  
1537
0
  return fAreaSpec.Overlap (imageBounds);
1538
  
1539
0
  }
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
0
  {
1549
  
1550
0
  dng_rect overlap = fAreaSpec.Overlap (dstArea);
1551
  
1552
0
  if (overlap.NotEmpty ())
1553
0
    {
1554
    
1555
0
    uint32 rows = (overlap.H () + fAreaSpec.RowPitch () - 1) /
1556
0
            fAreaSpec.RowPitch ();
1557
    
1558
0
    int32 rowStep = buffer.RowStep () * fAreaSpec.RowPitch ();
1559
    
1560
0
    for (uint32 plane = fAreaSpec.Plane ();
1561
0
       plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
1562
0
       plane < buffer.Planes ();
1563
0
       plane++)
1564
0
      {
1565
      
1566
0
      const real32 *table = fTable->Buffer_real32 () +
1567
0
                  ((overlap.l - fAreaSpec.Area ().l) /
1568
0
                   fAreaSpec.ColPitch ());
1569
      
1570
0
      for (int32 col = overlap.l; col < overlap.r; col += fAreaSpec.ColPitch ())
1571
0
        {
1572
        
1573
0
        real32 colScale = *(table++);
1574
        
1575
0
        real32 *dPtr = buffer.DirtyPixel_real32 (overlap.t, col, plane);
1576
        
1577
0
        for (uint32 row = 0; row < rows; row++)
1578
0
          {
1579
          
1580
0
          real32 x = dPtr [0];
1581
          
1582
0
          real32 y = x * colScale;
1583
                 
1584
0
          dPtr [0] = Min_real32 (y, 1.0f);
1585
          
1586
0
          dPtr += rowStep;
1587
          
1588
0
          }
1589
        
1590
0
        }
1591
      
1592
0
      }
1593
    
1594
0
    }
1595
  
1596
0
  }
1597
1598
/*****************************************************************************/