diff options
Diffstat (limited to 'plugins/FreeImage/Source/Metadata/FIRational.cpp')
-rw-r--r-- | plugins/FreeImage/Source/Metadata/FIRational.cpp | 352 |
1 files changed, 176 insertions, 176 deletions
diff --git a/plugins/FreeImage/Source/Metadata/FIRational.cpp b/plugins/FreeImage/Source/Metadata/FIRational.cpp index 969c06489a..d383c8d38f 100644 --- a/plugins/FreeImage/Source/Metadata/FIRational.cpp +++ b/plugins/FreeImage/Source/Metadata/FIRational.cpp @@ -1,176 +1,176 @@ -// ==========================================================
-// Helper class for rational numbers
-//
-// Design and implementation by
-// - Hervé Drolon <drolon@infonie.fr>
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FIRational.h"
-
-/// Initialize and normalize a rational number
-void FIRational::initialize(LONG n, LONG d) {
- if(d) {
- _numerator = n;
- _denominator = d;
- // normalize rational
- normalize();
- } else {
- _numerator = 0;
- _denominator = 0;
- }
-}
-
-/// Default constructor
-FIRational::FIRational() {
- _numerator = 0;
- _denominator = 0;
-}
-
-/// Constructor with longs
-FIRational::FIRational(LONG n, LONG d) {
- initialize(n, d);
-}
-
-/// Constructor with FITAG
-FIRational::FIRational(const FITAG *tag) {
- switch(FreeImage_GetTagType((FITAG*)tag)) {
- case FIDT_RATIONAL: // 64-bit unsigned fraction
- {
- DWORD *pvalue = (DWORD*)FreeImage_GetTagValue((FITAG*)tag);
- initialize((LONG)pvalue[0], (LONG)pvalue[1]);
- break;
- }
-
- case FIDT_SRATIONAL: // 64-bit signed fraction
- {
- LONG *pvalue = (LONG*)FreeImage_GetTagValue((FITAG*)tag);
- initialize((LONG)pvalue[0], (LONG)pvalue[1]);
- break;
- }
- }
-}
-
-FIRational::FIRational(float value) {
- if (value == (float)((LONG)value)) {
- _numerator = (LONG)value;
- _denominator = 1L;
- } else {
- int k, count;
- LONG n[4];
-
- float x = fabs(value);
- int sign = (value > 0) ? 1 : -1;
-
- // make a continued-fraction expansion of x
- count = -1;
- for(k = 0; k < 4; k++) {
- n[k] = (LONG)floor(x);
- count++;
- x -= (float)n[k];
- if(x == 0) break;
- x = 1 / x;
- }
- // compute the rational
- _numerator = 1;
- _denominator = n[count];
-
- for(int i = count - 1; i >= 0; i--) {
- if(n[i] == 0) break;
- LONG _num = (n[i] * _numerator + _denominator);
- LONG _den = _numerator;
- _numerator = _num;
- _denominator = _den;
- }
- _numerator *= sign;
- }
-}
-
-/// Copy constructor
-FIRational::FIRational (const FIRational& r) {
- initialize(r._numerator, r._denominator);
-}
-
-/// Destructor
-FIRational::~FIRational() {
-}
-
-/// Assignement operator
-FIRational& FIRational::operator=(FIRational& r) {
- if(this != &r) {
- initialize(r._numerator, r._denominator);
- }
- return *this;
-}
-
-/// Get the numerator
-LONG FIRational::getNumerator() {
- return _numerator;
-}
-
-/// Get the denominator
-LONG FIRational::getDenominator() {
- return _denominator;
-}
-
-/// Calculate GCD
-LONG FIRational::gcd(LONG a, LONG b) {
- LONG temp;
- while (b) { // While non-zero value
- temp = b; // Save current value
- b = a % b; // Assign remainder of division
- a = temp; // Copy old value
- }
- return a; // Return GCD of numbers
-}
-
-/// Normalize numerator / denominator
-void FIRational::normalize() {
- if (_numerator != 1 && _denominator != 1) { // Is there something to do?
- // Calculate GCD
- LONG common = gcd(_numerator, _denominator);
- if (common != 1) { // If GCD is not one
- _numerator /= common; // Calculate new numerator
- _denominator /= common; // Calculate new denominator
- }
- }
- if(_denominator < 0) { // If sign is in denominator
- _numerator *= -1; // Multiply num and den by -1
- _denominator *= -1; // To keep sign in numerator
- }
-}
-
-/// Checks if this rational number is an Integer, either positive or negative
-BOOL FIRational::isInteger() {
- if(_denominator == 1 || (_denominator != 0 && (_numerator % _denominator == 0)) || (_denominator == 0 && _numerator == 0))
- return TRUE;
- return FALSE;
-}
-
-/// Convert as "numerator/denominator"
-std::string FIRational::toString() {
- std::ostringstream s;
- if(isInteger()) {
- s << intValue();
- } else {
- s << _numerator << "/" << _denominator;
- }
- return s.str();
-}
-
-
+// ========================================================== +// Helper class for rational numbers +// +// Design and implementation by +// - Hervé Drolon <drolon@infonie.fr> +// +// This file is part of FreeImage 3 +// +// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE +// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT +// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY +// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL +// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER +// THIS DISCLAIMER. +// +// Use at your own risk! +// ========================================================== + +#include "FreeImage.h" +#include "Utilities.h" +#include "FIRational.h" + +/// Initialize and normalize a rational number +void FIRational::initialize(LONG n, LONG d) { + if(d) { + _numerator = n; + _denominator = d; + // normalize rational + normalize(); + } else { + _numerator = 0; + _denominator = 0; + } +} + +/// Default constructor +FIRational::FIRational() { + _numerator = 0; + _denominator = 0; +} + +/// Constructor with longs +FIRational::FIRational(LONG n, LONG d) { + initialize(n, d); +} + +/// Constructor with FITAG +FIRational::FIRational(const FITAG *tag) { + switch(FreeImage_GetTagType((FITAG*)tag)) { + case FIDT_RATIONAL: // 64-bit unsigned fraction + { + DWORD *pvalue = (DWORD*)FreeImage_GetTagValue((FITAG*)tag); + initialize((LONG)pvalue[0], (LONG)pvalue[1]); + break; + } + + case FIDT_SRATIONAL: // 64-bit signed fraction + { + LONG *pvalue = (LONG*)FreeImage_GetTagValue((FITAG*)tag); + initialize((LONG)pvalue[0], (LONG)pvalue[1]); + break; + } + } +} + +FIRational::FIRational(float value) { + if (value == (float)((LONG)value)) { + _numerator = (LONG)value; + _denominator = 1L; + } else { + int k, count; + LONG n[4]; + + float x = fabs(value); + int sign = (value > 0) ? 1 : -1; + + // make a continued-fraction expansion of x + count = -1; + for(k = 0; k < 4; k++) { + n[k] = (LONG)floor(x); + count++; + x -= (float)n[k]; + if(x == 0) break; + x = 1 / x; + } + // compute the rational + _numerator = 1; + _denominator = n[count]; + + for(int i = count - 1; i >= 0; i--) { + if(n[i] == 0) break; + LONG _num = (n[i] * _numerator + _denominator); + LONG _den = _numerator; + _numerator = _num; + _denominator = _den; + } + _numerator *= sign; + } +} + +/// Copy constructor +FIRational::FIRational (const FIRational& r) { + initialize(r._numerator, r._denominator); +} + +/// Destructor +FIRational::~FIRational() { +} + +/// Assignement operator +FIRational& FIRational::operator=(FIRational& r) { + if(this != &r) { + initialize(r._numerator, r._denominator); + } + return *this; +} + +/// Get the numerator +LONG FIRational::getNumerator() { + return _numerator; +} + +/// Get the denominator +LONG FIRational::getDenominator() { + return _denominator; +} + +/// Calculate GCD +LONG FIRational::gcd(LONG a, LONG b) { + LONG temp; + while (b) { // While non-zero value + temp = b; // Save current value + b = a % b; // Assign remainder of division + a = temp; // Copy old value + } + return a; // Return GCD of numbers +} + +/// Normalize numerator / denominator +void FIRational::normalize() { + if (_numerator != 1 && _denominator != 1) { // Is there something to do? + // Calculate GCD + LONG common = gcd(_numerator, _denominator); + if (common != 1) { // If GCD is not one + _numerator /= common; // Calculate new numerator + _denominator /= common; // Calculate new denominator + } + } + if(_denominator < 0) { // If sign is in denominator + _numerator *= -1; // Multiply num and den by -1 + _denominator *= -1; // To keep sign in numerator + } +} + +/// Checks if this rational number is an Integer, either positive or negative +BOOL FIRational::isInteger() { + if(_denominator == 1 || (_denominator != 0 && (_numerator % _denominator == 0)) || (_denominator == 0 && _numerator == 0)) + return TRUE; + return FALSE; +} + +/// Convert as "numerator/denominator" +std::string FIRational::toString() { + std::ostringstream s; + if(isInteger()) { + s << intValue(); + } else { + s << _numerator << "/" << _denominator; + } + return s.str(); +} + + |