Merge branch 'Rational2DoublePrecision_correction' into 'master'

tif_dirwrite.c: bugfix DoubleToSrational() for plain signed integers

See merge request libtiff/libtiff!109
This commit is contained in:
Even Rouault 2020-02-29 18:04:50 +00:00
commit c8c5309b76
2 changed files with 12 additions and 11 deletions

View File

@ -162,8 +162,8 @@ static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32* ndir, TIF
static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value); static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
static void DoubleToRational(double f, uint32 *num, uint32 *denom); static void DoubleToRational(double value, uint32 *num, uint32 *denom);
static void DoubleToSrational(double f, int32 *num, int32 *denom); static void DoubleToSrational(double value, int32 *num, int32 *denom);
#if 0 #if 0
static void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom); static void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom);
static void DoubleToSrational_direct(double value, long *num, long *denom); static void DoubleToSrational_direct(double value, long *num, long *denom);
@ -2893,7 +2893,7 @@ void DoubleToSrational(double value, int32 *num, int32 *denom)
double dblDiff, dblDiff2; double dblDiff, dblDiff2;
unsigned long long ullNum, ullDenom, ullNum2, ullDenom2; unsigned long long ullNum, ullDenom, ullNum2, ullDenom2;
/*-- Check for negative values and use then the positive one for internal calculations. */ /*-- Check for negative values and use then the positive one for internal calculations, but take the sign into account before returning. */
if (value < 0) { neg = -1; value = -value; } if (value < 0) { neg = -1; value = -value; }
/*-- Check for too big numbers (> LONG_MAX) -- */ /*-- Check for too big numbers (> LONG_MAX) -- */
@ -2903,8 +2903,8 @@ void DoubleToSrational(double value, int32 *num, int32 *denom)
return; return;
} }
/*-- Check for easy numbers -- */ /*-- Check for easy numbers -- */
if (value == (uint32)(value)) { if (value == (int32)(value)) {
*num = (uint32)value; *num = (int32)(neg * value);
*denom = 1; *denom = 1;
return; return;
} }
@ -2936,12 +2936,12 @@ void DoubleToSrational(double value, int32 *num, int32 *denom)
dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
if (dblDiff < dblDiff2) { if (dblDiff < dblDiff2) {
*num = (uint32)(neg * (long)ullNum); *num = (int32)(neg * (long)ullNum);
*denom = (uint32)ullDenom; *denom = (int32)ullDenom;
} }
else { else {
*num = (uint32)(neg * (long)ullNum2); *num = (int32)(neg * (long)ullNum2);
*denom = (uint32)ullDenom2; *denom = (int32)ullDenom2;
} }
} /*-- DoubleToSrational() --------------*/ } /*-- DoubleToSrational() --------------*/

View File

@ -498,7 +498,8 @@ write_test_tiff(TIFF* tif, const char* filenameRead, int blnAllCustomTags) {
fprintf(stderr, "Can't set TIFFTAG_RATIONAL_DOUBLE tag.\n"); fprintf(stderr, "Can't set TIFFTAG_RATIONAL_DOUBLE tag.\n");
goto failure; goto failure;
} }
if (!TIFFSetField(tif, TIFFTAG_SRATIONAL_DOUBLE, (-1.0 * auxDoubleArrayW[101]))) { /* test for plain integers */
if (!TIFFSetField(tif, TIFFTAG_SRATIONAL_DOUBLE, (-1.0 ))) {
fprintf(stderr, "Can't set TIFFTAG_SRATIONAL_DOUBLE tag.\n"); fprintf(stderr, "Can't set TIFFTAG_SRATIONAL_DOUBLE tag.\n");
goto failure; goto failure;
} }
@ -764,7 +765,7 @@ write_test_tiff(TIFF* tif, const char* filenameRead, int blnAllCustomTags) {
auxDblUnion.dbl = 0; auxDblUnion.dbl = 0;
retCode = TIFFGetField(tif, TIFFTAG_SRATIONAL_DOUBLE, &auxDblUnion.dbl); retCode = TIFFGetField(tif, TIFFTAG_SRATIONAL_DOUBLE, &auxDblUnion.dbl);
if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_SRATIONAL_DOUBLE"); GOTOFAILURE } if (!retCode) { fprintf(stderr, "Can't read %s\n", "TIFFTAG_SRATIONAL_DOUBLE"); GOTOFAILURE }
auxDouble = -1.0 * auxDoubleArrayW[101]; auxDouble = -1.0;
dblDiffLimit = RATIONAL_EPS * auxDouble; dblDiffLimit = RATIONAL_EPS * auxDouble;
dblDiff = auxDblUnion.dbl - auxDouble; dblDiff = auxDblUnion.dbl - auxDouble;
if (fabs(dblDiff) > fabs(dblDiffLimit)) { if (fabs(dblDiff) > fabs(dblDiffLimit)) {