Coverage Report

Created: 2025-07-23 06:38

/src/dng_sdk/source/dng_rect.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
// Copyright 2006-2007 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_rect.h#2 $ */ 
10
/* $DateTime: 2012/06/01 07:28:57 $ */
11
/* $Change: 832715 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#ifndef __dng_rect__
17
#define __dng_rect__
18
19
/*****************************************************************************/
20
21
#include "dng_exceptions.h"
22
#include "dng_point.h"
23
#include "dng_safe_arithmetic.h"
24
#include "dng_types.h"
25
#include "dng_utils.h"
26
27
/*****************************************************************************/
28
29
class dng_rect
30
  {
31
  
32
  public:
33
  
34
    int32 t;
35
    int32 l;
36
    int32 b;
37
    int32 r;
38
    
39
  public:
40
    
41
    dng_rect ()
42
60.4M
      : t (0)
43
60.4M
      , l (0)
44
60.4M
      , b (0)
45
60.4M
      , r (0)
46
60.4M
      {
47
60.4M
      }
48
      
49
    // Constructs a dng_rect from the top-left and bottom-right corner.
50
    // Throws an exception if the resulting height or width are too large to
51
    // be represented as an int32. The intent of this is to protect code
52
    // that may be computing the height or width directly from the member
53
    // variables (instead of going through H() or W()).
54
    dng_rect (int32 tt, int32 ll, int32 bb, int32 rr)
55
4.83M
      : t (tt)
56
4.83M
      , l (ll)
57
4.83M
      , b (bb)
58
4.83M
      , r (rr)
59
4.83M
      {
60
4.83M
      int32 dummy;
61
4.83M
      if (!SafeInt32Sub(r, l, &dummy) ||
62
4.83M
        !SafeInt32Sub(b, t, &dummy))
63
0
        {
64
0
        ThrowProgramError ("Overflow in dng_rect constructor");
65
0
        }
66
4.83M
      }
67
      
68
    dng_rect (uint32 h, uint32 w)
69
      : t (0)
70
      , l (0)
71
0
      {
72
0
        if (!ConvertUint32ToInt32(h, &b) ||
73
0
          !ConvertUint32ToInt32(w, &r))
74
0
          {
75
0
          ThrowProgramError ("Overflow in dng_rect constructor");
76
0
          }
77
0
      }
78
      
79
    dng_rect (const dng_point &size)
80
51.4k
      : t (0)
81
51.4k
      , l (0)
82
51.4k
      , b (size.v)
83
51.4k
      , r (size.h)
84
51.4k
      {
85
51.4k
      }
86
    
87
    void Clear ()
88
0
      {
89
0
      *this = dng_rect ();
90
0
      }
91
    
92
    bool operator== (const dng_rect &rect) const;
93
    
94
    bool operator!= (const dng_rect &rect) const
95
2.37M
      {
96
2.37M
      return !(*this == rect);
97
2.37M
      }
98
      
99
    bool IsZero () const;
100
      
101
    bool NotZero () const
102
0
      {
103
0
      return !IsZero ();
104
0
      }
105
      
106
    bool IsEmpty () const
107
48.4M
      {
108
48.4M
      return (t >= b) || (l >= r);
109
48.4M
      }
110
      
111
    bool NotEmpty () const
112
15.5M
      {
113
15.5M
      return !IsEmpty ();
114
15.5M
      }
115
      
116
    // Returns the width of the rectangle, or 0 if r is smaller than l.
117
    // Throws an exception if the width is too large to be represented as
118
    // a _signed_ int32 (even if it would fit in a uint32). This is
119
    // consciously conservative -- there are existing uses of W() where
120
    // the result is converted to an int32 without an overflow check, and
121
    // we want to make sure no overflow can occur in such cases. We provide
122
    // this check in addition to the check performed in the "two-corners"
123
    // constructor to protect client code that produes a dng_rect with
124
    // excessive size by initializing or modifying the member variables
125
    // directly.
126
    uint32 W () const
127
34.7M
      {
128
34.7M
      if (r >= l)
129
34.7M
        {
130
34.7M
        int32 width;
131
34.7M
        if (!SafeInt32Sub(r, l, &width))
132
67
          {
133
67
          ThrowProgramError ("Overflow computing rectangle width");
134
67
          }
135
34.7M
        return static_cast<uint32>(width);
136
34.7M
        }
137
6.83k
      else
138
6.83k
        {
139
6.83k
        return 0;
140
6.83k
        }
141
34.7M
      }
142
  
143
    // Returns the height of the rectangle, or 0 if b is smaller than t.
144
    // Throws an exception if the height is too large to be represented as
145
    // a _signed_ int32 (see W() for rationale).
146
    uint32 H () const
147
21.5M
      {
148
21.5M
      if (b >= t)
149
21.5M
        {
150
21.5M
        int32 height;
151
21.5M
        if (!SafeInt32Sub(b, t, &height))
152
50
          {
153
50
          ThrowProgramError ("Overflow computing rectangle height");
154
50
          }
155
21.5M
        return static_cast<uint32>(height);
156
21.5M
        }
157
11.6k
      else
158
11.6k
        {
159
11.6k
        return 0;
160
11.6k
        }
161
21.5M
      }
162
    
163
    dng_point TL () const
164
187k
      {
165
187k
      return dng_point (t, l);
166
187k
      }
167
      
168
    dng_point TR () const
169
0
      {
170
0
      return dng_point (t, r);
171
0
      }
172
      
173
    dng_point BL () const
174
0
      {
175
0
      return dng_point (b, l);
176
0
      }
177
      
178
    dng_point BR () const
179
0
      {
180
0
      return dng_point (b, r);
181
0
      }
182
      
183
    dng_point Size () const
184
3.28M
      {
185
3.28M
      return dng_point ((int32) H (), (int32) W ());
186
3.28M
      }
187
188
    real64 Diagonal () const
189
0
      {
190
0
      return hypot ((real64) W (),
191
0
              (real64) H ());
192
0
      }
193
  
194
  };
195
196
/*****************************************************************************/
197
198
class dng_rect_real64
199
  {
200
  
201
  public:
202
  
203
    real64 t;
204
    real64 l;
205
    real64 b;
206
    real64 r;
207
    
208
  public:
209
    
210
    dng_rect_real64 ()
211
0
      : t (0.0)
212
0
      , l (0.0)
213
0
      , b (0.0)
214
0
      , r (0.0)
215
0
      {
216
0
      }
217
      
218
    dng_rect_real64 (real64 tt, real64 ll, real64 bb, real64 rr)
219
      : t (tt)
220
      , l (ll)
221
      , b (bb)
222
      , r (rr)
223
0
      {
224
0
      }
225
      
226
    dng_rect_real64 (real64 h, real64 w)
227
      : t (0)
228
      , l (0)
229
      , b (h)
230
      , r (w)
231
0
      {
232
0
      }
233
      
234
    dng_rect_real64 (const dng_point_real64 &size)
235
      : t (0)
236
      , l (0)
237
      , b (size.v)
238
      , r (size.h)
239
0
      {
240
0
      }
241
      
242
    dng_rect_real64 (const dng_point_real64 &pt1,
243
             const dng_point_real64 &pt2)
244
      : t (Min_real64 (pt1.v, pt2.v))
245
      , l (Min_real64 (pt1.h, pt2.h))
246
      , b (Max_real64 (pt1.v, pt2.v))
247
      , r (Max_real64 (pt1.h, pt2.h))
248
0
      {
249
0
      }
250
      
251
    dng_rect_real64 (const dng_rect &rect)
252
0
      : t ((real64) rect.t)
253
0
      , l ((real64) rect.l)
254
0
      , b ((real64) rect.b)
255
0
      , r ((real64) rect.r)
256
0
      {
257
0
      }
258
    
259
    void Clear ()
260
0
      {
261
0
      *this = dng_point_real64 ();
262
0
      }
263
    
264
    bool operator== (const dng_rect_real64 &rect) const;
265
    
266
    bool operator!= (const dng_rect_real64 &rect) const
267
0
      {
268
0
      return !(*this == rect);
269
0
      }
270
      
271
    bool IsZero () const;
272
      
273
    bool NotZero () const
274
0
      {
275
0
      return !IsZero ();
276
0
      }
277
      
278
    bool IsEmpty () const
279
0
      {
280
0
      return (t >= b) || (l >= r);
281
0
      }
282
      
283
    bool NotEmpty () const
284
0
      {
285
0
      return !IsEmpty ();
286
0
      }
287
      
288
    real64 W () const
289
0
      {
290
0
      return Max_real64 (r - l, 0.0);
291
0
      }
292
  
293
    real64 H () const
294
0
      {
295
0
      return Max_real64 (b - t, 0.0);
296
0
      }
297
    
298
    dng_point_real64 TL () const
299
0
      {
300
0
      return dng_point_real64 (t, l);
301
0
      }
302
      
303
    dng_point_real64 TR () const
304
0
      {
305
0
      return dng_point_real64 (t, r);
306
0
      }
307
      
308
    dng_point_real64 BL () const
309
0
      {
310
0
      return dng_point_real64 (b, l);
311
0
      }
312
      
313
    dng_point_real64 BR () const
314
0
      {
315
0
      return dng_point_real64 (b, r);
316
0
      }
317
      
318
    dng_point_real64 Size () const
319
0
      {
320
0
      return dng_point_real64 (H (), W ());
321
0
      }
322
      
323
    dng_rect Round () const
324
0
      {
325
0
      return dng_rect (Round_int32 (t),
326
0
               Round_int32 (l),
327
0
               Round_int32 (b),
328
0
               Round_int32 (r));
329
0
      }
330
  
331
    real64 Diagonal () const
332
0
      {
333
0
      return hypot (W (), H ());
334
0
      }
335
  
336
  };
337
338
/*****************************************************************************/
339
340
dng_rect operator& (const dng_rect &a,
341
          const dng_rect &b);
342
343
dng_rect operator| (const dng_rect &a,
344
          const dng_rect &b);
345
346
/*****************************************************************************/
347
348
dng_rect_real64 operator& (const dng_rect_real64 &a,
349
               const dng_rect_real64 &b);
350
351
dng_rect_real64 operator| (const dng_rect_real64 &a,
352
               const dng_rect_real64 &b);
353
354
/*****************************************************************************/
355
356
inline dng_rect operator+ (const dng_rect &a,
357
                 const dng_point &b)
358
923k
  {
359
  
360
923k
  return dng_rect (a.t + b.v,
361
923k
           a.l + b.h,
362
923k
           a.b + b.v,
363
923k
           a.r + b.h);
364
  
365
923k
  }
366
367
/*****************************************************************************/
368
369
inline dng_rect_real64 operator+ (const dng_rect_real64 &a,
370
                      const dng_point_real64 &b)
371
0
  {
372
0
  
373
0
  return dng_rect_real64 (a.t + b.v,
374
0
              a.l + b.h,
375
0
              a.b + b.v,
376
0
              a.r + b.h);
377
0
  
378
0
  }
379
380
/*****************************************************************************/
381
382
inline dng_rect operator- (const dng_rect &a,
383
                 const dng_point &b)
384
123k
  {
385
  
386
123k
  return dng_rect (a.t - b.v,
387
123k
           a.l - b.h,
388
123k
           a.b - b.v,
389
123k
           a.r - b.h);
390
  
391
123k
  }
392
393
/*****************************************************************************/
394
395
inline dng_rect_real64 operator- (const dng_rect_real64 &a,
396
                      const dng_point_real64 &b)
397
0
  {
398
0
  
399
0
  return dng_rect_real64 (a.t - b.v,
400
0
              a.l - b.h,
401
0
              a.b - b.v,
402
0
              a.r - b.h);
403
0
  
404
0
  }
405
406
/*****************************************************************************/
407
408
inline dng_rect Transpose (const dng_rect &a)
409
0
  {
410
  
411
0
  return dng_rect (a.l, a.t, a.r, a.b);
412
  
413
0
  }
414
415
/*****************************************************************************/
416
417
inline dng_rect_real64 Transpose (const dng_rect_real64 &a)
418
0
  {
419
0
  
420
0
  return dng_rect_real64 (a.l, a.t, a.r, a.b);
421
0
  
422
0
  }
423
424
/*****************************************************************************/
425
426
inline void HalfRect (dng_rect &rect)
427
0
  {
428
0
429
0
  rect.r = rect.l + (int32) (rect.W () >> 1);
430
0
  rect.b = rect.t + (int32) (rect.H () >> 1);
431
0
432
0
  }
433
434
/*****************************************************************************/
435
436
inline void DoubleRect (dng_rect &rect)
437
0
  {
438
0
439
0
  rect.r = rect.l + (int32) (rect.W () << 1);
440
0
  rect.b = rect.t + (int32) (rect.H () << 1);
441
0
442
0
  }
443
444
/*****************************************************************************/
445
446
inline void InnerPadRect (dng_rect &rect,
447
              int32 pad)
448
0
  {
449
0
450
0
  rect.l += pad;
451
0
  rect.r -= pad;
452
0
  rect.t += pad;
453
0
  rect.b -= pad;
454
0
455
0
  }
456
457
/*****************************************************************************/
458
459
inline void OuterPadRect (dng_rect &rect,
460
              int32 pad)
461
0
  {
462
0
463
0
  InnerPadRect (rect, -pad);
464
0
465
0
  }
466
467
/*****************************************************************************/
468
469
inline void InnerPadRectH (dng_rect &rect,
470
               int32 pad)
471
0
  {
472
0
473
0
  rect.l += pad;
474
0
  rect.r -= pad;
475
0
476
0
  }
477
478
/*****************************************************************************/
479
480
inline void InnerPadRectV (dng_rect &rect,
481
               int32 pad)
482
0
  {
483
0
484
0
  rect.t += pad;
485
0
  rect.b -= pad;
486
0
487
0
  }
488
489
/*****************************************************************************/
490
491
inline dng_rect MakeHalfRect (const dng_rect &rect)
492
0
  {
493
0
  
494
0
  dng_rect out = rect;
495
0
496
0
  HalfRect (out);
497
0
498
0
  return out;
499
0
  
500
0
  }
501
502
/*****************************************************************************/
503
504
inline dng_rect MakeDoubleRect (const dng_rect &rect)
505
0
  {
506
0
  
507
0
  dng_rect out = rect;
508
0
509
0
  DoubleRect (out);
510
0
511
0
  return out;
512
0
  
513
0
  }
514
515
/*****************************************************************************/
516
517
inline dng_rect MakeInnerPadRect (const dng_rect &rect,
518
                  int32 pad)
519
0
  {
520
0
  
521
0
  dng_rect out = rect;
522
0
523
0
  InnerPadRect (out, pad);
524
0
525
0
  return out;
526
0
  
527
0
  }
528
529
/*****************************************************************************/
530
531
inline dng_rect MakeOuterPadRect (const dng_rect &rect,
532
                  int32 pad)
533
0
  {
534
0
  
535
0
  dng_rect out = rect;
536
0
537
0
  OuterPadRect (out, pad);
538
0
539
0
  return out;
540
0
  
541
0
  }
542
543
/*****************************************************************************/
544
545
#endif
546
  
547
/*****************************************************************************/