| /*****************************************************************************/ |
| // Copyright 2006-2007 Adobe Systems Incorporated |
| // All Rights Reserved. |
| // |
| // NOTICE: Adobe permits you to use, modify, and distribute this file in |
| // accordance with the terms of the Adobe license agreement accompanying it. |
| /*****************************************************************************/ |
| |
| /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_rect.h#2 $ */ |
| /* $DateTime: 2012/06/01 07:28:57 $ */ |
| /* $Change: 832715 $ */ |
| /* $Author: tknoll $ */ |
| |
| /*****************************************************************************/ |
| |
| #ifndef __dng_rect__ |
| #define __dng_rect__ |
| |
| /*****************************************************************************/ |
| |
| #include "dng_exceptions.h" |
| #include "dng_point.h" |
| #include "dng_safe_arithmetic.h" |
| #include "dng_types.h" |
| #include "dng_utils.h" |
| |
| /*****************************************************************************/ |
| |
| class dng_rect |
| { |
| |
| public: |
| |
| int32 t; |
| int32 l; |
| int32 b; |
| int32 r; |
| |
| public: |
| |
| dng_rect () |
| : t (0) |
| , l (0) |
| , b (0) |
| , r (0) |
| { |
| } |
| |
| // Constructs a dng_rect from the top-left and bottom-right corner. |
| // Throws an exception if the resulting height or width are too large to |
| // be represented as an int32. The intent of this is to protect code |
| // that may be computing the height or width directly from the member |
| // variables (instead of going through H() or W()). |
| dng_rect (int32 tt, int32 ll, int32 bb, int32 rr) |
| : t (tt) |
| , l (ll) |
| , b (bb) |
| , r (rr) |
| { |
| int32 dummy; |
| if (!SafeInt32Sub(r, l, &dummy) || |
| !SafeInt32Sub(b, t, &dummy)) |
| { |
| ThrowProgramError ("Overflow in dng_rect constructor"); |
| } |
| } |
| |
| dng_rect (uint32 h, uint32 w) |
| : t (0) |
| , l (0) |
| { |
| if (!ConvertUint32ToInt32(h, &b) || |
| !ConvertUint32ToInt32(w, &r)) |
| { |
| ThrowProgramError ("Overflow in dng_rect constructor"); |
| } |
| } |
| |
| dng_rect (const dng_point &size) |
| : t (0) |
| , l (0) |
| , b (size.v) |
| , r (size.h) |
| { |
| } |
| |
| void Clear () |
| { |
| *this = dng_rect (); |
| } |
| |
| bool operator== (const dng_rect &rect) const; |
| |
| bool operator!= (const dng_rect &rect) const |
| { |
| return !(*this == rect); |
| } |
| |
| bool IsZero () const; |
| |
| bool NotZero () const |
| { |
| return !IsZero (); |
| } |
| |
| bool IsEmpty () const |
| { |
| return (t >= b) || (l >= r); |
| } |
| |
| bool NotEmpty () const |
| { |
| return !IsEmpty (); |
| } |
| |
| // Returns the width of the rectangle, or 0 if r is smaller than l. |
| // Throws an exception if the width is too large to be represented as |
| // a _signed_ int32 (even if it would fit in a uint32). This is |
| // consciously conservative -- there are existing uses of W() where |
| // the result is converted to an int32 without an overflow check, and |
| // we want to make sure no overflow can occur in such cases. We provide |
| // this check in addition to the check performed in the "two-corners" |
| // constructor to protect client code that produes a dng_rect with |
| // excessive size by initializing or modifying the member variables |
| // directly. |
| uint32 W () const |
| { |
| if (r >= l) |
| { |
| int32 width; |
| if (!SafeInt32Sub(r, l, &width)) |
| { |
| ThrowProgramError ("Overflow computing rectangle width"); |
| } |
| return static_cast<uint32>(width); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| // Returns the height of the rectangle, or 0 if b is smaller than t. |
| // Throws an exception if the height is too large to be represented as |
| // a _signed_ int32 (see W() for rationale). |
| uint32 H () const |
| { |
| if (b >= t) |
| { |
| int32 height; |
| if (!SafeInt32Sub(b, t, &height)) |
| { |
| ThrowProgramError ("Overflow computing rectangle height"); |
| } |
| return static_cast<uint32>(height); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| dng_point TL () const |
| { |
| return dng_point (t, l); |
| } |
| |
| dng_point TR () const |
| { |
| return dng_point (t, r); |
| } |
| |
| dng_point BL () const |
| { |
| return dng_point (b, l); |
| } |
| |
| dng_point BR () const |
| { |
| return dng_point (b, r); |
| } |
| |
| dng_point Size () const |
| { |
| return dng_point ((int32) H (), (int32) W ()); |
| } |
| |
| real64 Diagonal () const |
| { |
| return hypot ((real64) W (), |
| (real64) H ()); |
| } |
| |
| }; |
| |
| /*****************************************************************************/ |
| |
| class dng_rect_real64 |
| { |
| |
| public: |
| |
| real64 t; |
| real64 l; |
| real64 b; |
| real64 r; |
| |
| public: |
| |
| dng_rect_real64 () |
| : t (0.0) |
| , l (0.0) |
| , b (0.0) |
| , r (0.0) |
| { |
| } |
| |
| dng_rect_real64 (real64 tt, real64 ll, real64 bb, real64 rr) |
| : t (tt) |
| , l (ll) |
| , b (bb) |
| , r (rr) |
| { |
| } |
| |
| dng_rect_real64 (real64 h, real64 w) |
| : t (0) |
| , l (0) |
| , b (h) |
| , r (w) |
| { |
| } |
| |
| dng_rect_real64 (const dng_point_real64 &size) |
| : t (0) |
| , l (0) |
| , b (size.v) |
| , r (size.h) |
| { |
| } |
| |
| dng_rect_real64 (const dng_point_real64 &pt1, |
| const dng_point_real64 &pt2) |
| : t (Min_real64 (pt1.v, pt2.v)) |
| , l (Min_real64 (pt1.h, pt2.h)) |
| , b (Max_real64 (pt1.v, pt2.v)) |
| , r (Max_real64 (pt1.h, pt2.h)) |
| { |
| } |
| |
| dng_rect_real64 (const dng_rect &rect) |
| : t ((real64) rect.t) |
| , l ((real64) rect.l) |
| , b ((real64) rect.b) |
| , r ((real64) rect.r) |
| { |
| } |
| |
| void Clear () |
| { |
| *this = dng_point_real64 (); |
| } |
| |
| bool operator== (const dng_rect_real64 &rect) const; |
| |
| bool operator!= (const dng_rect_real64 &rect) const |
| { |
| return !(*this == rect); |
| } |
| |
| bool IsZero () const; |
| |
| bool NotZero () const |
| { |
| return !IsZero (); |
| } |
| |
| bool IsEmpty () const |
| { |
| return (t >= b) || (l >= r); |
| } |
| |
| bool NotEmpty () const |
| { |
| return !IsEmpty (); |
| } |
| |
| real64 W () const |
| { |
| return Max_real64 (r - l, 0.0); |
| } |
| |
| real64 H () const |
| { |
| return Max_real64 (b - t, 0.0); |
| } |
| |
| dng_point_real64 TL () const |
| { |
| return dng_point_real64 (t, l); |
| } |
| |
| dng_point_real64 TR () const |
| { |
| return dng_point_real64 (t, r); |
| } |
| |
| dng_point_real64 BL () const |
| { |
| return dng_point_real64 (b, l); |
| } |
| |
| dng_point_real64 BR () const |
| { |
| return dng_point_real64 (b, r); |
| } |
| |
| dng_point_real64 Size () const |
| { |
| return dng_point_real64 (H (), W ()); |
| } |
| |
| dng_rect Round () const |
| { |
| return dng_rect (Round_int32 (t), |
| Round_int32 (l), |
| Round_int32 (b), |
| Round_int32 (r)); |
| } |
| |
| real64 Diagonal () const |
| { |
| return hypot (W (), H ()); |
| } |
| |
| }; |
| |
| /*****************************************************************************/ |
| |
| dng_rect operator& (const dng_rect &a, |
| const dng_rect &b); |
| |
| dng_rect operator| (const dng_rect &a, |
| const dng_rect &b); |
| |
| /*****************************************************************************/ |
| |
| dng_rect_real64 operator& (const dng_rect_real64 &a, |
| const dng_rect_real64 &b); |
| |
| dng_rect_real64 operator| (const dng_rect_real64 &a, |
| const dng_rect_real64 &b); |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect operator+ (const dng_rect &a, |
| const dng_point &b) |
| { |
| |
| return dng_rect (a.t + b.v, |
| a.l + b.h, |
| a.b + b.v, |
| a.r + b.h); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect_real64 operator+ (const dng_rect_real64 &a, |
| const dng_point_real64 &b) |
| { |
| |
| return dng_rect_real64 (a.t + b.v, |
| a.l + b.h, |
| a.b + b.v, |
| a.r + b.h); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect operator- (const dng_rect &a, |
| const dng_point &b) |
| { |
| |
| return dng_rect (a.t - b.v, |
| a.l - b.h, |
| a.b - b.v, |
| a.r - b.h); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect_real64 operator- (const dng_rect_real64 &a, |
| const dng_point_real64 &b) |
| { |
| |
| return dng_rect_real64 (a.t - b.v, |
| a.l - b.h, |
| a.b - b.v, |
| a.r - b.h); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect Transpose (const dng_rect &a) |
| { |
| |
| return dng_rect (a.l, a.t, a.r, a.b); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect_real64 Transpose (const dng_rect_real64 &a) |
| { |
| |
| return dng_rect_real64 (a.l, a.t, a.r, a.b); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void HalfRect (dng_rect &rect) |
| { |
| |
| rect.r = rect.l + (int32) (rect.W () >> 1); |
| rect.b = rect.t + (int32) (rect.H () >> 1); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void DoubleRect (dng_rect &rect) |
| { |
| |
| rect.r = rect.l + (int32) (rect.W () << 1); |
| rect.b = rect.t + (int32) (rect.H () << 1); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void InnerPadRect (dng_rect &rect, |
| int32 pad) |
| { |
| |
| rect.l += pad; |
| rect.r -= pad; |
| rect.t += pad; |
| rect.b -= pad; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void OuterPadRect (dng_rect &rect, |
| int32 pad) |
| { |
| |
| InnerPadRect (rect, -pad); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void InnerPadRectH (dng_rect &rect, |
| int32 pad) |
| { |
| |
| rect.l += pad; |
| rect.r -= pad; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline void InnerPadRectV (dng_rect &rect, |
| int32 pad) |
| { |
| |
| rect.t += pad; |
| rect.b -= pad; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect MakeHalfRect (const dng_rect &rect) |
| { |
| |
| dng_rect out = rect; |
| |
| HalfRect (out); |
| |
| return out; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect MakeDoubleRect (const dng_rect &rect) |
| { |
| |
| dng_rect out = rect; |
| |
| DoubleRect (out); |
| |
| return out; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect MakeInnerPadRect (const dng_rect &rect, |
| int32 pad) |
| { |
| |
| dng_rect out = rect; |
| |
| InnerPadRect (out, pad); |
| |
| return out; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| inline dng_rect MakeOuterPadRect (const dng_rect &rect, |
| int32 pad) |
| { |
| |
| dng_rect out = rect; |
| |
| OuterPadRect (out, pad); |
| |
| return out; |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| #endif |
| |
| /*****************************************************************************/ |