Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/dng_sdk/source/dng_lens_correction.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
// Copyright 2008 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_lens_correction.h#2 $ */ 
10
/* $DateTime: 2012/08/02 06:09:06 $ */
11
/* $Change: 841096 $ */
12
/* $Author: erichan $ */
13
14
/** \file
15
 * Opcodes to fix lens aberrations such as geometric distortion, lateral chromatic
16
 * aberration, and vignetting (peripheral illumination falloff).
17
 */
18
19
/*****************************************************************************/
20
21
#ifndef __dng_lens_correction__
22
#define __dng_lens_correction__
23
24
/*****************************************************************************/
25
26
#include "dng_1d_function.h"
27
#include "dng_matrix.h"
28
#include "dng_memory.h"
29
#include "dng_opcodes.h"
30
#include "dng_pixel_buffer.h"
31
#include "dng_point.h"
32
#include "dng_resample.h"
33
#include "dng_sdk_limits.h"
34
35
#include <vector>
36
37
/*****************************************************************************/
38
39
/// \brief Abstract base class holding common warp opcode parameters (e.g.,
40
/// number of planes, optical center) and common warp routines.
41
42
class dng_warp_params
43
  {
44
45
  public:
46
47
    // Number of planes to be warped. Must be either 1 or equal to the
48
    // number of planes of the image to be processed. If set to 1, then a
49
    // single set of warp parameters applies to all planes of the image.
50
    // fPlanes must be at least 1 and no greater than kMaxColorPlanes (see
51
    // dng_sdk_limits.h).
52
53
    uint32 fPlanes;
54
55
    // The optical center of the lens in normalized [0,1] coordinates with
56
    // respect to the image's active area. For example, a value of (0.5,
57
    // 0.5) indicates that the optical center of the lens is at the center
58
    // of the image's active area. A normalized radius of 1.0 corresponds to
59
    // the distance from fCenter to the farthest corner of the image's
60
    // active area. Each component of fCenter must lie in the range [0,1].
61
62
    dng_point_real64 fCenter;
63
    
64
  public:
65
66
    /// Create empty (invalid) warp parameters.
67
68
    dng_warp_params ();
69
70
    /// Create warp parameters with specified number of planes and image
71
    /// center.
72
    ///
73
    /// \param planes The number of planes of parameters specified: It must
74
    /// be either 1 or equal to the number of planes of the image to be
75
    /// processed.
76
    ///
77
    /// \param fCenter The image center in relative coordinates.
78
79
    dng_warp_params (uint32 planes,
80
             const dng_point_real64 &fCenter);
81
82
    virtual ~dng_warp_params ();
83
84
    /// Is the entire correction a NOP for all planes?
85
86
    virtual bool IsNOPAll () const;
87
88
    /// Is the entire correction a NOP for the specified plane?
89
90
    virtual bool IsNOP (uint32 plane) const;
91
92
    /// Is the radial correction a NOP for all planes?
93
94
    virtual bool IsRadNOPAll () const;
95
96
    /// Is the radial correction a NOP for the specified plane?
97
98
    virtual bool IsRadNOP (uint32 plane) const;
99
100
    /// Is the tangential correction a NOP for all planes?
101
102
    virtual bool IsTanNOPAll () const;
103
104
    /// Is the tangential correction a NOP for the specified plane?
105
106
    virtual bool IsTanNOP (uint32 plane) const;
107
108
    /// Do these warp params appear valid?
109
110
    virtual bool IsValid () const;
111
112
    /// Are these warp params valid for the specified negative?
113
114
    virtual bool IsValidForNegative (const dng_negative &negative) const;
115
116
    /// Propagate warp parameters from first plane to all other planes.
117
118
    virtual void PropagateToAllPlanes (uint32 totalPlanes) = 0;
119
120
    /// Evaluate the 1D radial warp function for the specified plane.
121
    /// Parameter r is the destination (i.e., corrected) normalized radius,
122
    /// i.e., the normalized Euclidean distance between a corrected pixel
123
    /// position and the optical center in the image. r lies in the range
124
    /// [0,1]. The returned result is non-negative.
125
126
    virtual real64 Evaluate (uint32 plane,
127
                 real64 r) const = 0;
128
129
    /// Compute and return the inverse of Evaluate () above. The base
130
    /// implementation uses Newton's method to perform the inversion.
131
    /// Parameter r is the source (i.e., uncorrected) normalized radius,
132
    /// i.e., normalized Euclidean distance between a corrected pixel
133
    /// position and the optical center in the image. Both r and the
134
    /// computed result are non-negative.
135
136
    virtual real64 EvaluateInverse (uint32 plane,
137
                    real64 r) const;
138
139
    /// Evaluate the 1D radial warp ratio function for the specified plane.
140
    /// Parameter r2 is the square of the destination (i.e., corrected)
141
    /// normalized radius, i.e., the square of the normalized Euclidean
142
    /// distance between a corrected pixel position and the optical center
143
    /// in the image. r2 must lie in the range [0,1]. Note that this is
144
    /// different than the Evaluate () function, above, in that the argument
145
    /// to EvaluateRatio () is the square of the radius, not the radius
146
    /// itself. The returned result is non-negative. Mathematically,
147
    /// EvaluateRatio (r * r) is the same as Evaluate (r) / r.
148
149
    virtual real64 EvaluateRatio (uint32 plane,
150
                    real64 r2) const = 0;
151
152
    /// Evaluate the 2D tangential warp for the specified plane. Parameter
153
    /// r2 is the square of the destination (i.e., corrected) normalized
154
    /// radius, i.e., the square of the normalized Euclidean distance
155
    /// between a corrected pixel position P and the optical center in the
156
    /// image. r2 must lie in the range [0,1]. diff contains the vertical
157
    /// and horizontal Euclidean distances (in pixels) between P and the
158
    /// optical center. diff2 contains the squares of the vertical and
159
    /// horizontal Euclidean distances (in pixels) between P and the optical
160
    /// center. The returned result is the tangential warp offset, measured
161
    /// in pixels.
162
163
    virtual dng_point_real64 EvaluateTangential (uint32 plane,
164
                           real64 r2,
165
                           const dng_point_real64 &diff,
166
                           const dng_point_real64 &diff2) const = 0;
167
    
168
    /// Evaluate the 2D tangential warp for the specified plane. diff
169
    /// contains the vertical and horizontal Euclidean distances (in pixels)
170
    /// between the destination (i.e., corrected) pixel position and the
171
    /// optical center in the image. The returned result is the tangential
172
    /// warp offset, measured in pixels.
173
174
    dng_point_real64 EvaluateTangential2 (uint32 plane,
175
                        const dng_point_real64 &diff) const;
176
    
177
    /// Evaluate the 2D tangential warp for the specified plane. Parameter
178
    /// r2 is the square of the destination (i.e., corrected) normalized
179
    /// radius, i.e., the square of the normalized Euclidean distance
180
    /// between a corrected pixel position P and the optical center in the
181
    /// image. r2 must lie in the range [0,1]. diff contains the vertical
182
    /// and horizontal Euclidean distances (in pixels) between P and the
183
    /// optical center. The returned result is the tangential warp offset,
184
    /// measured in pixels.
185
186
    dng_point_real64 EvaluateTangential3 (uint32 plane,
187
                        real64 r2,
188
                        const dng_point_real64 &diff) const;
189
190
    /// Compute and return the maximum warped radius gap. Let D be a
191
    /// rectangle in a destination (corrected) image. Let rDstFar and
192
    /// rDstNear be the farthest and nearest points to the image center,
193
    /// respectively. Then the specified parameter maxDstGap is the
194
    /// Euclidean distance between rDstFar and rDstNear. Warp D through this
195
    /// warp function to a closed and bounded (generally not rectangular)
196
    /// region S. Let rSrcfar and rSrcNear be the farthest and nearest
197
    /// points to the image center, respectively. This routine returns a
198
    /// value that is at least (rSrcFar - rSrcNear).
199
200
    virtual real64 MaxSrcRadiusGap (real64 maxDstGap) const = 0;
201
202
    /// Compute and return the maximum warped tangential gap. minDst is the
203
    /// top-left pixel of the image in normalized pixel coordinates. maxDst
204
    /// is the bottom-right pixel of the image in normalized pixel
205
    /// coordinates. MaxSrcTanGap () computes the maximum absolute shift in
206
    /// normalized pixels in the horizontal and vertical directions that can
207
    /// occur as a result of the tangential warp.
208
209
    virtual dng_point_real64 MaxSrcTanGap (dng_point_real64 minDst,
210
                         dng_point_real64 maxDst) const = 0;
211
212
    /// Debug parameters.
213
214
    virtual void Dump () const;
215
216
  };
217
218
/*****************************************************************************/
219
220
/// \brief Warp parameters for pinhole perspective rectilinear (not fisheye)
221
/// camera model. Supports radial and tangential (decentering) distortion
222
/// correction parameters.
223
///
224
/// Note the restrictions described below.
225
226
class dng_warp_params_rectilinear: public dng_warp_params
227
  {
228
229
  public:
230
231
    // Radial and tangential polynomial coefficients. These define a warp
232
    // from corrected pixel coordinates (xDst, yDst) to uncorrected pixel
233
    // coordinates (xSrc, ySrc) for each plane P as follows:
234
    //
235
    // Let kr0 = fRadParams [P][0]
236
    //     kr1 = fRadParams [P][1]
237
    //     kr2 = fRadParams [P][2]
238
    //     kr3 = fRadParams [P][3]
239
    //
240
    //     kt0 = fTanParams [P][0]
241
    //     kt1 = fTanParams [P][1]
242
    //
243
    // Let (xCenter, yCenter) be the optical image center (see fCenter,
244
    // below) expressed in pixel coordinates. Let maxDist be the Euclidean
245
    // distance (in pixels) from (xCenter, yCenter) to the farthest image
246
    // corner.
247
    //
248
    // First, compute the normalized distance of the corrected pixel
249
    // position (xDst, yDst) from the image center:
250
    //
251
    //     dx = (xDst - xCenter) / maxDist
252
    //     dy = (yDst - yCenter) / maxDist
253
    //
254
    //     r^2 = dx^2 + dy^2
255
    //
256
    // Compute the radial correction term:
257
    //
258
    //     ratio = kr0 + (kr1 * r^2) + (kr2 * r^4) + (kr3 * r^6)
259
    //
260
    //     dxRad = dx * ratio
261
    //     dyRad = dy * ratio
262
    //
263
    // Compute the tangential correction term:
264
    //
265
    //     dxTan = (2 * kt0 * dx * dy) + kt1 * (r^2 + 2 * dx^2)
266
    //     dyTan = (2 * kt1 * dx * dy) + kt0 * (r^2 + 2 * dy^2)
267
    //
268
    // Compute the uncorrected pixel position (xSrc, ySrc):
269
    //
270
    //     xSrc = xCenter + (dxRad + dxTan) * maxDist
271
    //     ySrc = yCenter + (dyRad + dyTan) * maxDist
272
    //
273
    // Mathematical definitions and restrictions:
274
    //
275
    // Let { xSrc, ySrc } = f (xDst, yDst) be the warp function defined
276
    // above.
277
    //
278
    // Let xSrc = fx (xDst, yDst) be the x-component of the warp function.
279
    // Let ySrc = fy (xDst, yDst) be the y-component of the warp function.
280
    //
281
    // f (x, y) must be an invertible function.
282
    //
283
    // fx (x, y) must be an increasing function of x.
284
    // fy (x, y) must be an increasing function of x.
285
    //
286
    // The parameters kr0, kr1, kr2, and kr3 must define an increasing
287
    // radial warp function. Specifically, let w (r) be the radial warp
288
    // function:
289
    //
290
    //     w (r) = (kr0 * r) + (kr1 * r^3) + (kr2 * r^5) + (kr3 * r^7).
291
    //
292
    // w (r) must be an increasing function.
293
294
    dng_vector fRadParams [kMaxColorPlanes];
295
    dng_vector fTanParams [kMaxColorPlanes];
296
297
  public:
298
299
    /// Create empty (invalid) rectilinear warp parameters.
300
301
    dng_warp_params_rectilinear ();
302
303
    /// Create rectilinear warp parameters with the specified number of
304
    /// planes, radial component terms, tangential component terms, and
305
    /// image center in relative coordinates.
306
307
    dng_warp_params_rectilinear (uint32 planes,
308
                   const dng_vector radParams [],
309
                   const dng_vector tanParams [],
310
                   const dng_point_real64 &fCenter);
311
312
    virtual ~dng_warp_params_rectilinear ();
313
314
    // Overridden methods.
315
316
    virtual bool IsRadNOP (uint32 plane) const;
317
318
    virtual bool IsTanNOP (uint32 plane) const;
319
320
    virtual bool IsValid () const;
321
322
    virtual void PropagateToAllPlanes (uint32 totalPlanes);
323
324
    virtual real64 Evaluate (uint32 plane,
325
                 real64 r) const;
326
327
    virtual real64 EvaluateRatio (uint32 plane,
328
                    real64 r2) const;
329
330
    virtual dng_point_real64 EvaluateTangential (uint32 plane,
331
                           real64 r2,
332
                           const dng_point_real64 &diff,
333
                           const dng_point_real64 &diff2) const;
334
335
    virtual real64 MaxSrcRadiusGap (real64 maxDstGap) const;
336
337
    virtual dng_point_real64 MaxSrcTanGap (dng_point_real64 minDst,
338
                         dng_point_real64 maxDst) const;
339
340
    virtual void Dump () const;
341
342
  };
343
344
/*****************************************************************************/
345
346
/// \brief Warp parameters for fisheye camera model (radial component only).
347
/// Note the restrictions described below.
348
349
class dng_warp_params_fisheye: public dng_warp_params
350
  {
351
352
  public:
353
354
    // Radial warp coefficients. These define a warp from corrected pixel
355
    // coordinates (xDst, yDst) to uncorrected pixel coordinates (xSrc,
356
    // ySrc) for each plane P as follows:
357
    //
358
    // Let kr0 = fRadParams [P][0]
359
    //     kr1 = fRadParams [P][1]
360
    //     kr2 = fRadParams [P][2]
361
    //     kr3 = fRadParams [P][3]
362
    //
363
    // Let (xCenter, yCenter) be the optical image center (see fCenter,
364
    // below) expressed in pixel coordinates. Let maxDist be the Euclidean
365
    // distance (in pixels) from (xCenter, yCenter) to the farthest image
366
    // corner.
367
    //
368
    // First, compute the normalized distance of the corrected pixel
369
    // position (xDst, yDst) from the image center:
370
    //
371
    //     dx = (xDst - xCenter) / maxDist
372
    //     dy = (yDst - yCenter) / maxDist
373
    //
374
    //     r = sqrt (dx^2 + dy^2)
375
    //
376
    // Compute the radial correction term:
377
    //
378
    //     t = atan (r)
379
    //
380
    //     rWarp = (kr0 * t) + (kr1 * t^3) + (kr2 * t^5) + (kr3 * t^7)
381
    //
382
    //     ratio = rWarp / r
383
    //
384
    //     dxRad = dx * ratio
385
    //     dyRad = dy * ratio
386
    //
387
    // Compute the uncorrected pixel position (xSrc, ySrc):
388
    //
389
    //     xSrc = xCenter + (dxRad * maxDist)
390
    //     ySrc = yCenter + (dyRad * maxDist)
391
    //
392
    // The parameters kr0, kr1, kr2, and kr3 must define an increasing
393
    // radial warp function. Specifically, let w (r) be the radial warp
394
    // function:
395
    //
396
    //     t = atan (r)
397
    //
398
    //     w (r) = (kr0 * t) + (kr1 * t^3) + (kr2 * t^5) + (kr3 * t^7).
399
    //
400
    // w (r) must be an increasing function.
401
402
    dng_vector fRadParams [kMaxColorPlanes];
403
404
  public:
405
406
    /// Create empty (invalid) fisheye warp parameters.
407
408
    dng_warp_params_fisheye ();
409
410
    /// Create rectilinear warp parameters with the specified number of
411
    /// planes, radial component terms, and image center in relative
412
    /// coordinates.
413
414
    dng_warp_params_fisheye (uint32 planes,
415
                 const dng_vector radParams [],
416
                 const dng_point_real64 &fCenter);
417
418
    virtual ~dng_warp_params_fisheye ();
419
420
    // Overridden methods.
421
422
    virtual bool IsRadNOP (uint32 plane) const;
423
424
    virtual bool IsTanNOP (uint32 plane) const;
425
426
    virtual bool IsValid () const;
427
428
    virtual void PropagateToAllPlanes (uint32 totalPlanes);
429
430
    virtual real64 Evaluate (uint32 plane,
431
                 real64 r) const;
432
433
    virtual real64 EvaluateRatio (uint32 plane,
434
                    real64 r2) const;
435
436
    virtual dng_point_real64 EvaluateTangential (uint32 plane,
437
                           real64 r2,
438
                           const dng_point_real64 &diff,
439
                           const dng_point_real64 &diff2) const;
440
    
441
    virtual real64 MaxSrcRadiusGap (real64 maxDstGap) const;
442
443
    virtual dng_point_real64 MaxSrcTanGap (dng_point_real64 minDst,
444
                         dng_point_real64 maxDst) const;
445
446
    virtual void Dump () const;
447
448
  };
449
450
/*****************************************************************************/
451
452
/// \brief Warp opcode for pinhole perspective (rectilinear) camera model.
453
454
class dng_opcode_WarpRectilinear: public dng_opcode
455
  {
456
    
457
  protected:
458
459
    dng_warp_params_rectilinear fWarpParams;
460
461
  public:
462
  
463
    dng_opcode_WarpRectilinear (const dng_warp_params_rectilinear &params,
464
                  uint32 flags);
465
    
466
    explicit dng_opcode_WarpRectilinear (dng_stream &stream);
467
  
468
    // Overridden methods.
469
470
    virtual bool IsNOP () const;
471
    
472
    virtual bool IsValidForNegative (const dng_negative &negative) const;
473
  
474
    virtual void PutData (dng_stream &stream) const;
475
476
    virtual void Apply (dng_host &host,
477
              dng_negative &negative,
478
              AutoPtr<dng_image> &image);
479
480
  protected:
481
482
    static uint32 ParamBytes (uint32 planes);
483
484
  };
485
486
/*****************************************************************************/
487
488
/// \brief Warp opcode for fisheye camera model.
489
490
class dng_opcode_WarpFisheye: public dng_opcode
491
  {
492
    
493
  protected:
494
495
    dng_warp_params_fisheye fWarpParams;
496
497
  public:
498
  
499
    dng_opcode_WarpFisheye (const dng_warp_params_fisheye &params,
500
                uint32 flags);
501
    
502
    explicit dng_opcode_WarpFisheye (dng_stream &stream);
503
  
504
    // Overridden methods.
505
506
    virtual bool IsNOP () const;
507
    
508
    virtual bool IsValidForNegative (const dng_negative &negative) const;
509
  
510
    virtual void PutData (dng_stream &stream) const;
511
512
    virtual void Apply (dng_host &host,
513
              dng_negative &negative,
514
              AutoPtr<dng_image> &image);
515
516
  protected:
517
518
    static uint32 ParamBytes (uint32 planes);
519
520
  };
521
522
/*****************************************************************************/
523
524
/// \brief Radially-symmetric vignette (peripheral illuminational falloff)
525
/// correction parameters.
526
527
class dng_vignette_radial_params
528
  {
529
530
  public:
531
532
    static const uint32 kNumTerms = 5;
533
534
  public:
535
536
    // Let v be an uncorrected pixel value of a pixel p in linear space.
537
    //
538
    // Let r be the Euclidean distance between p and the optical center.
539
    //
540
    // Compute corrected pixel value v' = v * g, where g is the gain.
541
    //
542
    // Let k0 = fParams [0]
543
    // Let k1 = fParams [1]
544
    // Let k2 = fParams [2]
545
    // Let k3 = fParams [3]
546
    // Let k4 = fParams [4]
547
    //
548
    // Gain g = 1 + (k0 * r^2) + (k1 * r^4) + (k2 * r^6) + (k3 * r^8) + (k4 * r^10)
549
550
    dng_std_vector<real64> fParams;
551
552
    dng_point_real64 fCenter;
553
554
  public:
555
556
    dng_vignette_radial_params ();
557
558
    dng_vignette_radial_params (const dng_std_vector<real64> &params,
559
                  const dng_point_real64 &center);
560
561
    bool IsNOP () const;
562
563
    bool IsValid () const;
564
565
    // For debugging.
566
567
    void Dump () const;
568
569
  };
570
571
/*****************************************************************************/
572
573
/// \brief Radially-symmetric lens vignette correction opcode.
574
575
class dng_opcode_FixVignetteRadial: public dng_inplace_opcode
576
  {
577
    
578
  protected:
579
580
    dng_vignette_radial_params fParams;
581
582
    uint32 fImagePlanes;
583
584
    int64 fSrcOriginH;
585
    int64 fSrcOriginV;
586
    
587
    int64 fSrcStepH;
588
    int64 fSrcStepV;
589
    
590
    uint32 fTableInputBits;
591
    uint32 fTableOutputBits;
592
593
    AutoPtr<dng_memory_block> fGainTable;
594
595
    AutoPtr<dng_memory_block> fMaskBuffers [kMaxMPThreads];
596
597
  public:
598
  
599
    dng_opcode_FixVignetteRadial (const dng_vignette_radial_params &params,
600
                    uint32 flags);
601
    
602
    explicit dng_opcode_FixVignetteRadial (dng_stream &stream);
603
  
604
    virtual bool IsNOP () const;
605
    
606
    virtual bool IsValidForNegative (const dng_negative &) const;
607
  
608
    virtual void PutData (dng_stream &stream) const;
609
610
    virtual uint32 BufferPixelType (uint32 /* imagePixelType */)
611
0
      {
612
0
      return ttFloat;
613
0
      }
614
      
615
    virtual void Prepare (dng_negative &negative,
616
                uint32 threadCount,
617
                const dng_point &tileSize,
618
                const dng_rect &imageBounds,
619
                uint32 imagePlanes,
620
                uint32 bufferPixelType,
621
                dng_memory_allocator &allocator);
622
623
    virtual void ProcessArea (dng_negative &negative,
624
                  uint32 threadIndex,
625
                  dng_pixel_buffer &buffer,
626
                  const dng_rect &dstArea,
627
                  const dng_rect &imageBounds);
628
629
  protected:
630
631
    static uint32 ParamBytes ();
632
633
  };
634
635
/*****************************************************************************/
636
637
#endif
638
  
639
/*****************************************************************************/