You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
10 KiB
547 lines
10 KiB
/*****************************************************************************/ |
|
// 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 |
|
|
|
/*****************************************************************************/
|
|
|