Просмотр исходного кода

use cfloor/cceil instead of floor/ceil

cxgeorge 24 лет назад
Родитель
Сommit
2d54f59f54

+ 4 - 4
panda/src/chan/animChannelScalarTable.cxx

@@ -163,7 +163,7 @@ write_datagram(BamWriter *manager, Datagram &me)
     for (i = 0;
     for (i = 0;
          i < (int)_table.size() && (int)index.size() <= max_values;
          i < (int)_table.size() && (int)index.size() <= max_values;
          i++) {
          i++) {
-      int value = (int)floor(_table[i] * scale + 0.5f);
+      int value = (int)cfloor(_table[i] * scale + 0.5f);
       index.insert(pmap<int, int>::value_type(value, index.size()));
       index.insert(pmap<int, int>::value_type(value, index.size()));
     }
     }
     int index_length = index.size();
     int index_length = index.size();
@@ -200,8 +200,8 @@ write_datagram(BamWriter *manager, Datagram &me)
 
 
         } else {
         } else {
           for (i = 0; i < table_length - 1; i+= 2) {
           for (i = 0; i < table_length - 1; i+= 2) {
-            int value1 = (int)floor(_table[i] * scale + 0.5f);
-            int value2 = (int)floor(_table[i + 1] * scale + 0.5f);
+            int value1 = (int)cfloor(_table[i] * scale + 0.5f);
+            int value2 = (int)cfloor(_table[i + 1] * scale + 0.5f);
             int i1 = index[value1];
             int i1 = index[value1];
             int i2 = index[value2];
             int i2 = index[value2];
 
 
@@ -210,7 +210,7 @@ write_datagram(BamWriter *manager, Datagram &me)
 
 
           // There might be one odd value.
           // There might be one odd value.
           if (i < table_length) {
           if (i < table_length) {
-            int value1 = (int)floor(_table[i] * scale + 0.5f);
+            int value1 = (int)cfloor(_table[i] * scale + 0.5f);
             int i1 = index[value1];
             int i1 = index[value1];
 
 
             me.add_uint8(i1 << 4);
             me.add_uint8(i1 << 4);

+ 1 - 1
panda/src/chan/animControl.I

@@ -75,7 +75,7 @@ get_frame() const {
   // We have to use floor() here instead of simply casting the number
   // We have to use floor() here instead of simply casting the number
   // to an integer, becase the frame number might have become
   // to an integer, becase the frame number might have become
   // negative.
   // negative.
-  return (int)floor(_frame + 0.0001);
+  return (int)cfloor(_frame + 0.0001);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
panda/src/chan/animControl.cxx

@@ -387,7 +387,7 @@ advance_time(double time) {
           // anyway (no need to convert to integer format and back
           // anyway (no need to convert to integer format and back
           // again), and because we need correct behavior when the
           // again), and because we need correct behavior when the
           // frame number is negative.
           // frame number is negative.
-          _frame = _frame - floor(_frame / num_frames) * num_frames;
+          _frame = _frame - cfloor(_frame / num_frames) * num_frames;
           new_frame = get_frame();
           new_frame = get_frame();
           do_actions_backward(get_num_frames(), new_frame);
           do_actions_backward(get_num_frames(), new_frame);
         }
         }
@@ -404,7 +404,7 @@ advance_time(double time) {
           // anyway (no need to convert to integer format and back
           // anyway (no need to convert to integer format and back
           // again), and because we need correct behavior when the
           // again), and because we need correct behavior when the
           // frame number is negative.
           // frame number is negative.
-          _frame = _frame - floor(_frame / num_frames) * num_frames;
+          _frame = _frame - cfloor(_frame / num_frames) * num_frames;
           new_frame = get_frame();
           new_frame = get_frame();
           do_actions_forward(0, new_frame);
           do_actions_forward(0, new_frame);
         }
         }

+ 1 - 1
panda/src/chan/animControl.h

@@ -29,7 +29,7 @@
 #include <referenceCount.h>
 #include <referenceCount.h>
 #include <event.h>
 #include <event.h>
 #include <pt_Event.h>
 #include <pt_Event.h>
-
+#include <cmath.h>
 #include <string>
 #include <string>
 #include "pmap.h"
 #include "pmap.h"
 
 

+ 32 - 0
panda/src/linmath/cmath.I

@@ -96,6 +96,38 @@ INLINE_LINMATH float catan2(float y, float x) {
   return atan2f(y, x);
   return atan2f(y, x);
 }
 }
 
 
+#ifdef __INTEL_COMPILER
+// see float.h
+#define FPU_CONTROLWORD_WRITEMASK    0xFFFFF        // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF
+#define FPU_CONTROLWORD_NEW_SETTING  _CW_DEFAULT
+#endif  
+
+INLINE_LINMATH double cfloor(double f) {
+  #ifdef __INTEL_COMPILER
+    // intel floor doesnt work right if fpu mode is not double, so make double-prec mode is on
+    unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
+    _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK);
+    double retval=floor(f);
+    _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
+    return retval;
+  #else
+    return floor(f);  
+  #endif
+}
+
+INLINE_LINMATH double cceil(double f) {
+  #ifdef __INTEL_COMPILER
+    // intel ceil doesnt work right if fpu mode is not double, so make double-prec mode is on
+    unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
+    _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK);
+    double retval=ceil(f);
+    _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
+    return retval;
+  #else
+    return ceil(f);  
+  #endif
+}
+
 INLINE_LINMATH double csqrt(double v) {
 INLINE_LINMATH double csqrt(double v) {
   return sqrt(v);
   return sqrt(v);
 }
 }

+ 4 - 0
panda/src/linmath/cmath.h

@@ -37,7 +37,11 @@ INLINE_LINMATH void  csincos(float v, float *pSinResult, float *pCosResult);  //
 INLINE_LINMATH float cabs(float v);
 INLINE_LINMATH float cabs(float v);
 INLINE_LINMATH float catan(float v);
 INLINE_LINMATH float catan(float v);
 INLINE_LINMATH float catan2(float y, float x);
 INLINE_LINMATH float catan2(float y, float x);
+//INLINE_LINMATH float cfloor(float f);
+//INLINE_LINMATH float cceil(float f);
 
 
+INLINE_LINMATH double cfloor(double f);
+INLINE_LINMATH double cceil(double f);
 INLINE_LINMATH double csqrt(double v);
 INLINE_LINMATH double csqrt(double v);
 INLINE_LINMATH double csin(double v);
 INLINE_LINMATH double csin(double v);
 INLINE_LINMATH double ccos(double v);
 INLINE_LINMATH double ccos(double v);

+ 1 - 1
panda/src/mathutil/fftCompressor.cxx

@@ -264,7 +264,7 @@ write_reals(Datagram &datagram, const float *array, int length) {
     static const double max_range_8 = 127.0;
     static const double max_range_8 = 127.0;
 
 
     double scale_factor = get_scale_factor(i, length);
     double scale_factor = get_scale_factor(i, length);
-    double num = floor(half_complex[i] / scale_factor + 0.5);
+    double num = cfloor(half_complex[i] / scale_factor + 0.5);
 
 
     // How many bits do we need to encode this integer?
     // How many bits do we need to encode this integer?
     double a = fabs(num);
     double a = fabs(num);

+ 1 - 1
panda/src/parametrics/parametricCurve.cxx

@@ -251,7 +251,7 @@ find_length(float start_t, float length_offset) const {
 
 
   // Start with a segment for each unit of t.
   // Start with a segment for each unit of t.
   float max_t = get_max_t();
   float max_t = get_max_t();
-  int num_segs = (int)floor(max_t - start_t + 1);
+  int num_segs = (int)cfloor(max_t - start_t + 1);
   t2 = start_t;
   t2 = start_t;
   get_point(t2, p2);
   get_point(t2, p2);
   float net = 0.0f;
   float net = 0.0f;

+ 2 - 2
panda/src/parametrics/parametricCurveCollection.cxx

@@ -337,7 +337,7 @@ make_even(float max_t, float segments_per_unit) {
   // approximately the same length as all the others.
   // approximately the same length as all the others.
   CurveFitter fitter;
   CurveFitter fitter;
 
 
-  int num_segments = max(1, (int)floor(segments_per_unit * xyz_curve->get_max_t() + 0.5f));
+  int num_segments = max(1, (int)cfloor(segments_per_unit * xyz_curve->get_max_t() + 0.5f));
 
 
   if (parametrics_cat.is_debug()) {
   if (parametrics_cat.is_debug()) {
     parametrics_cat.debug()
     parametrics_cat.debug()
@@ -426,7 +426,7 @@ face_forward(float segments_per_unit) {
   CurveFitter fitter;
   CurveFitter fitter;
 
 
   float max_t = get_max_t();
   float max_t = get_max_t();
-  int num_segments = (int)floor(segments_per_unit * max_t + 0.5);
+  int num_segments = (int)cfloor(segments_per_unit * max_t + 0.5);
 
 
   LVecBase3f hpr(0.0f, 0.0f, 0.0f);
   LVecBase3f hpr(0.0f, 0.0f, 0.0f);
 
 

+ 2 - 2
panda/src/parametrics/parametricCurveDrawer.cxx

@@ -327,7 +327,7 @@ draw() {
   // Make sure the curve(s) are fresh.
   // Make sure the curve(s) are fresh.
   _curves->recompute();
   _curves->recompute();
 
 
-  int total_segs = (int)floor(_curves->get_max_t() * _num_segs + 0.5);
+  int total_segs = (int)cfloor(_curves->get_max_t() * _num_segs + 0.5);
 
 
   float max_t = xyz_curve->get_max_t();
   float max_t = xyz_curve->get_max_t();
   float scale = max_t / (float)(total_segs-1);
   float scale = max_t / (float)(total_segs-1);
@@ -358,7 +358,7 @@ draw() {
 
 
   // Now draw the time tick marks.
   // Now draw the time tick marks.
   if (_num_ticks > 0.0f) {
   if (_num_ticks > 0.0f) {
-    int total_ticks = (int)floor(max_t * _num_ticks + 0.5);
+    int total_ticks = (int)cfloor(max_t * _num_ticks + 0.5);
     ParametricCurve *xyz_curve = _curves->get_default_curve();
     ParametricCurve *xyz_curve = _curves->get_default_curve();
     ParametricCurve *hpr_curve = _curves->get_hpr_curve();
     ParametricCurve *hpr_curve = _curves->get_hpr_curve();
 
 

+ 7 - 7
panda/src/pnmimage/pnm-image-filter.cxx

@@ -37,8 +37,8 @@
 // each channel in the image.
 // each channel in the image.
 
 
 #include <pandabase.h>
 #include <pandabase.h>
-
 #include <math.h>
 #include <math.h>
+#include <cmath.h>
 
 
 #include "pnmImage.h"
 #include "pnmImage.h"
 
 
@@ -123,7 +123,7 @@ filter_row(StoreType dest[], int dest_len,
   // Similarly, if we are expanding the row, we want to start the new row at
   // Similarly, if we are expanding the row, we want to start the new row at
   // the far left edge of the original pixel, not in the center.  So we will
   // the far left edge of the original pixel, not in the center.  So we will
   // have a non-zero offset.
   // have a non-zero offset.
-  int offset = (int)floor(iscale*0.5);
+  int offset = (int)cfloor(iscale*0.5);
 
 
   for (int dest_x=0; dest_x<dest_len; dest_x++) {
   for (int dest_x=0; dest_x<dest_len; dest_x++) {
     double center = (dest_x-offset)/scale;
     double center = (dest_x-offset)/scale;
@@ -131,12 +131,12 @@ filter_row(StoreType dest[], int dest_len,
     // left and right are the starting and ending ranges of the radius of
     // left and right are the starting and ending ranges of the radius of
     // interest of the filter function.  We need to apply the filter to each
     // interest of the filter function.  We need to apply the filter to each
     // value in this range.
     // value in this range.
-    int left = max((int)floor(center - filter_width), 0);
-    int right = min((int)ceil(center + filter_width), source_len-1);
+    int left = max((int)cfloor(center - filter_width), 0);
+    int right = min((int)cceil(center + filter_width), source_len-1);
 
 
     // right_center is the point just to the right of the center.  This
     // right_center is the point just to the right of the center.  This
     // allows us to flip the sign of the offset when we cross the center point.
     // allows us to flip the sign of the offset when we cross the center point.
-    int right_center = (int)ceil(center);
+    int right_center = (int)cceil(center);
 
 
     WorkType net_weight = 0;
     WorkType net_weight = 0;
     WorkType net_value = 0;
     WorkType net_value = 0;
@@ -197,7 +197,7 @@ box_filter_impl(double scale, double width,
     fscale = scale;
     fscale = scale;
   }
   }
   filter_width = width;
   filter_width = width;
-  int actual_width = (int)ceil((filter_width+1) * fscale);
+  int actual_width = (int)cceil((filter_width+1) * fscale);
 
 
   filter = new WorkType[actual_width];
   filter = new WorkType[actual_width];
 
 
@@ -224,7 +224,7 @@ gaussian_filter_impl(double scale, double width,
   }
   }
   double sigma = width/2;
   double sigma = width/2;
   filter_width = 3.0 * sigma;
   filter_width = 3.0 * sigma;
-  int actual_width = (int)ceil((filter_width+1) * fscale);
+  int actual_width = (int)cceil((filter_width+1) * fscale);
 
 
   // G(x, y) = (1/(2 pi sigma^2)) * exp( - (x^2 + y^2) / (2 sigma^2))
   // G(x, y) = (1/(2 pi sigma^2)) * exp( - (x^2 + y^2) / (2 sigma^2))
 
 

+ 4 - 2
panda/src/tiff/Sources.pp

@@ -1,11 +1,13 @@
 #define OTHER_LIBS dtoolconfig dtool
 #define OTHER_LIBS dtoolconfig dtool
-#define LOCAL_LIBS pandabase
+#define LOCAL_LIBS pandabase linmath
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET tiff
   #define TARGET tiff
+  
+   // Note: tif_aux.c switched to tif_aux.cxx, so cmath.h can be included for our fixed floor()
 
 
    #define SHARED_SRCS \
    #define SHARED_SRCS \
-     tif_aux.c tif_close.c tif_codec.c tif_compress.c tif_dir.c  \
+     tif_aux.cxx tif_close.c tif_codec.c tif_compress.c tif_dir.c  \
      tif_dirinfo.c tif_dirread.c tif_dirwrite.c tif_dumpmode.c  \
      tif_dirinfo.c tif_dirread.c tif_dirwrite.c tif_dumpmode.c  \
      tif_error.c tif_fax3.c tif_flush.c tif_jpeg.c tif_luv.c  \
      tif_error.c tif_fax3.c tif_flush.c tif_jpeg.c tif_luv.c  \
      tif_lzw.c tif_next.c tif_open.c tif_packbits.c  \
      tif_lzw.c tif_next.c tif_open.c tif_packbits.c  \

+ 131 - 130
panda/src/tiff/tif_aux.c

@@ -30,6 +30,7 @@
  * Auxiliary Support Routines.
  * Auxiliary Support Routines.
  */
  */
 #include "tiffiop.h"
 #include "tiffiop.h"
+#include "cmath.h"
 
 
 #ifdef COLORIMETRY_SUPPORT
 #ifdef COLORIMETRY_SUPPORT
 #include <math.h>
 #include <math.h>
@@ -37,33 +38,33 @@
 static void
 static void
 TIFFDefaultTransferFunction(TIFFDirectory* td)
 TIFFDefaultTransferFunction(TIFFDirectory* td)
 {
 {
-	uint16 **tf = td->td_transferfunction;
-	long i, n = 1<<td->td_bitspersample;
+    uint16 **tf = td->td_transferfunction;
+    long i, n = 1<<td->td_bitspersample;
 
 
-	tf[0] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
-	tf[0][0] = 0;
-	for (i = 1; i < n; i++) {
-		double t = (double)i/((double) n-1.);
-		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
-	}
-	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-		tf[1] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
-		_TIFFmemcpy(tf[1], tf[0], n * sizeof (uint16));
-		tf[2] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
-		_TIFFmemcpy(tf[2], tf[0], n * sizeof (uint16));
-	}
+    tf[0] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+    tf[0][0] = 0;
+    for (i = 1; i < n; i++) {
+        double t = (double)i/((double) n-1.);
+        tf[0][i] = (uint16)cfloor(65535.*pow(t, 2.2) + .5);
+    }
+    if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+        tf[1] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+        _TIFFmemcpy(tf[1], tf[0], n * sizeof (uint16));
+        tf[2] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+        _TIFFmemcpy(tf[2], tf[0], n * sizeof (uint16));
+    }
 }
 }
 
 
 static void
 static void
 TIFFDefaultRefBlackWhite(TIFFDirectory* td)
 TIFFDefaultRefBlackWhite(TIFFDirectory* td)
 {
 {
-	int i;
+    int i;
 
 
-	td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float));
-	for (i = 0; i < 3; i++) {
-	    td->td_refblackwhite[2*i+0] = 0;
-	    td->td_refblackwhite[2*i+1] = (float)((1L<<td->td_bitspersample)-1L);
-	}
+    td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float));
+    for (i = 0; i < 3; i++) {
+        td->td_refblackwhite[2*i+0] = 0;
+        td->td_refblackwhite[2*i+1] = (float)((1L<<td->td_bitspersample)-1L);
+    }
 }
 }
 #endif
 #endif
 
 
@@ -71,122 +72,122 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td)
  * Like TIFFGetField, but return any default
  * Like TIFFGetField, but return any default
  * value if the tag is not present in the directory.
  * value if the tag is not present in the directory.
  *
  *
- * NB:	We use the value in the directory, rather than
- *	explcit values so that defaults exist only one
- *	place in the library -- in TIFFDefaultDirectory.
+ * NB:  We use the value in the directory, rather than
+ *  explcit values so that defaults exist only one
+ *  place in the library -- in TIFFDefaultDirectory.
  */
  */
 int
 int
 TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
 TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
 {
 {
-	TIFFDirectory *td = &tif->tif_dir;
+    TIFFDirectory *td = &tif->tif_dir;
 
 
-	if (TIFFVGetField(tif, tag, ap))
-		return (1);
-	switch (tag) {
-	case TIFFTAG_SUBFILETYPE:
-		*va_arg(ap, uint32 *) = td->td_subfiletype;
-		return (1);
-	case TIFFTAG_BITSPERSAMPLE:
-		*va_arg(ap, uint16 *) = td->td_bitspersample;
-		return (1);
-	case TIFFTAG_THRESHHOLDING:
-		*va_arg(ap, uint16 *) = td->td_threshholding;
-		return (1);
-	case TIFFTAG_FILLORDER:
-		*va_arg(ap, uint16 *) = td->td_fillorder;
-		return (1);
-	case TIFFTAG_ORIENTATION:
-		*va_arg(ap, uint16 *) = td->td_orientation;
-		return (1);
-	case TIFFTAG_SAMPLESPERPIXEL:
-		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
-		return (1);
-	case TIFFTAG_ROWSPERSTRIP:
-		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
-		return (1);
-	case TIFFTAG_MINSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
-		return (1);
-	case TIFFTAG_MAXSAMPLEVALUE:
-		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
-		return (1);
-	case TIFFTAG_PLANARCONFIG:
-		*va_arg(ap, uint16 *) = td->td_planarconfig;
-		return (1);
-	case TIFFTAG_RESOLUTIONUNIT:
-		*va_arg(ap, uint16 *) = td->td_resolutionunit;
-		return (1);
+    if (TIFFVGetField(tif, tag, ap))
+        return (1);
+    switch (tag) {
+    case TIFFTAG_SUBFILETYPE:
+        *va_arg(ap, uint32 *) = td->td_subfiletype;
+        return (1);
+    case TIFFTAG_BITSPERSAMPLE:
+        *va_arg(ap, uint16 *) = td->td_bitspersample;
+        return (1);
+    case TIFFTAG_THRESHHOLDING:
+        *va_arg(ap, uint16 *) = td->td_threshholding;
+        return (1);
+    case TIFFTAG_FILLORDER:
+        *va_arg(ap, uint16 *) = td->td_fillorder;
+        return (1);
+    case TIFFTAG_ORIENTATION:
+        *va_arg(ap, uint16 *) = td->td_orientation;
+        return (1);
+    case TIFFTAG_SAMPLESPERPIXEL:
+        *va_arg(ap, uint16 *) = td->td_samplesperpixel;
+        return (1);
+    case TIFFTAG_ROWSPERSTRIP:
+        *va_arg(ap, uint32 *) = td->td_rowsperstrip;
+        return (1);
+    case TIFFTAG_MINSAMPLEVALUE:
+        *va_arg(ap, uint16 *) = td->td_minsamplevalue;
+        return (1);
+    case TIFFTAG_MAXSAMPLEVALUE:
+        *va_arg(ap, uint16 *) = td->td_maxsamplevalue;
+        return (1);
+    case TIFFTAG_PLANARCONFIG:
+        *va_arg(ap, uint16 *) = td->td_planarconfig;
+        return (1);
+    case TIFFTAG_RESOLUTIONUNIT:
+        *va_arg(ap, uint16 *) = td->td_resolutionunit;
+        return (1);
 #ifdef CMYK_SUPPORT
 #ifdef CMYK_SUPPORT
-	case TIFFTAG_DOTRANGE:
-		*va_arg(ap, uint16 *) = 0;
-		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
-		return (1);
-	case TIFFTAG_INKSET:
-		*va_arg(ap, uint16 *) = td->td_inkset;
-		return (1);
-	case TIFFTAG_NUMBEROFINKS:
-		*va_arg(ap, uint16 *) = td->td_ninks;
-		return (1);
+    case TIFFTAG_DOTRANGE:
+        *va_arg(ap, uint16 *) = 0;
+        *va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
+        return (1);
+    case TIFFTAG_INKSET:
+        *va_arg(ap, uint16 *) = td->td_inkset;
+        return (1);
+    case TIFFTAG_NUMBEROFINKS:
+        *va_arg(ap, uint16 *) = td->td_ninks;
+        return (1);
 #endif
 #endif
-	case TIFFTAG_EXTRASAMPLES:
-		*va_arg(ap, uint16 *) = td->td_extrasamples;
-		*va_arg(ap, uint16 **) = td->td_sampleinfo;
-		return (1);
-	case TIFFTAG_MATTEING:
-		*va_arg(ap, uint16 *) =
-		    (td->td_extrasamples == 1 &&
-		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
-		return (1);
-	case TIFFTAG_TILEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_tiledepth;
-		return (1);
-	case TIFFTAG_DATATYPE:
-		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
-		return (1);
-	case TIFFTAG_SAMPLEFORMAT:
-		*va_arg(ap, uint16 *) = td->td_sampleformat;
+    case TIFFTAG_EXTRASAMPLES:
+        *va_arg(ap, uint16 *) = td->td_extrasamples;
+        *va_arg(ap, uint16 **) = td->td_sampleinfo;
+        return (1);
+    case TIFFTAG_MATTEING:
+        *va_arg(ap, uint16 *) =
+            (td->td_extrasamples == 1 &&
+             td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+        return (1);
+    case TIFFTAG_TILEDEPTH:
+        *va_arg(ap, uint32 *) = td->td_tiledepth;
+        return (1);
+    case TIFFTAG_DATATYPE:
+        *va_arg(ap, uint16 *) = td->td_sampleformat-1;
+        return (1);
+    case TIFFTAG_SAMPLEFORMAT:
+        *va_arg(ap, uint16 *) = td->td_sampleformat;
                 return(1);
                 return(1);
-	case TIFFTAG_IMAGEDEPTH:
-		*va_arg(ap, uint32 *) = td->td_imagedepth;
-		return (1);
+    case TIFFTAG_IMAGEDEPTH:
+        *va_arg(ap, uint32 *) = td->td_imagedepth;
+        return (1);
 #ifdef YCBCR_SUPPORT
 #ifdef YCBCR_SUPPORT
-	case TIFFTAG_YCBCRCOEFFICIENTS:
-		if (!td->td_ycbcrcoeffs) {
-			td->td_ycbcrcoeffs = (float *)
-			    _TIFFmalloc(3*sizeof (float));
-			/* defaults are from CCIR Recommendation 601-1 */
-			td->td_ycbcrcoeffs[0] = 0.299f;
-			td->td_ycbcrcoeffs[1] = 0.587f;
-			td->td_ycbcrcoeffs[2] = 0.114f;
-		}
-		*va_arg(ap, float **) = td->td_ycbcrcoeffs;
-		return (1);
-	case TIFFTAG_YCBCRSUBSAMPLING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
-		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
-		return (1);
-	case TIFFTAG_YCBCRPOSITIONING:
-		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
-		return (1);
+    case TIFFTAG_YCBCRCOEFFICIENTS:
+        if (!td->td_ycbcrcoeffs) {
+            td->td_ycbcrcoeffs = (float *)
+                _TIFFmalloc(3*sizeof (float));
+            /* defaults are from CCIR Recommendation 601-1 */
+            td->td_ycbcrcoeffs[0] = 0.299f;
+            td->td_ycbcrcoeffs[1] = 0.587f;
+            td->td_ycbcrcoeffs[2] = 0.114f;
+        }
+        *va_arg(ap, float **) = td->td_ycbcrcoeffs;
+        return (1);
+    case TIFFTAG_YCBCRSUBSAMPLING:
+        *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
+        *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
+        return (1);
+    case TIFFTAG_YCBCRPOSITIONING:
+        *va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
+        return (1);
 #endif
 #endif
 #ifdef COLORIMETRY_SUPPORT
 #ifdef COLORIMETRY_SUPPORT
-	case TIFFTAG_TRANSFERFUNCTION:
-		if (!td->td_transferfunction[0])
-			TIFFDefaultTransferFunction(td);
-		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
-		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
-			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
-			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
-		}
-		return (1);
-	case TIFFTAG_REFERENCEBLACKWHITE:
-		if (!td->td_refblackwhite)
-			TIFFDefaultRefBlackWhite(td);
-		*va_arg(ap, float **) = td->td_refblackwhite;
-		return (1);
+    case TIFFTAG_TRANSFERFUNCTION:
+        if (!td->td_transferfunction[0])
+            TIFFDefaultTransferFunction(td);
+        *va_arg(ap, uint16 **) = td->td_transferfunction[0];
+        if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+            *va_arg(ap, uint16 **) = td->td_transferfunction[1];
+            *va_arg(ap, uint16 **) = td->td_transferfunction[2];
+        }
+        return (1);
+    case TIFFTAG_REFERENCEBLACKWHITE:
+        if (!td->td_refblackwhite)
+            TIFFDefaultRefBlackWhite(td);
+        *va_arg(ap, float **) = td->td_refblackwhite;
+        return (1);
 #endif
 #endif
-	}
-	return (0);
+    }
+    return (0);
 }
 }
 
 
 /*
 /*
@@ -196,11 +197,11 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
 int
 int
 TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)
 TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)
 {
 {
-	int ok;
-	va_list ap;
+    int ok;
+    va_list ap;
 
 
-	va_start(ap, tag);
-	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
-	va_end(ap);
-	return (ok);
+    va_start(ap, tag);
+    ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
+    va_end(ap);
+    return (ok);
 }
 }

+ 207 - 0
panda/src/tiff/tif_aux.cxx

@@ -0,0 +1,207 @@
+/* $Header$ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Auxiliary Support Routines.
+ */
+#include "tiffiop.h"
+#include "cmath.h"
+
+#ifdef COLORIMETRY_SUPPORT
+#include <math.h>
+
+static void
+TIFFDefaultTransferFunction(TIFFDirectory* td)
+{
+    uint16 **tf = td->td_transferfunction;
+    long i, n = 1<<td->td_bitspersample;
+
+    tf[0] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+    tf[0][0] = 0;
+    for (i = 1; i < n; i++) {
+        double t = (double)i/((double) n-1.);
+        tf[0][i] = (uint16)cfloor(65535.*pow(t, 2.2) + .5);
+    }
+    if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+        tf[1] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+        _TIFFmemcpy(tf[1], tf[0], n * sizeof (uint16));
+        tf[2] = (uint16 *)_TIFFmalloc(n * sizeof (uint16));
+        _TIFFmemcpy(tf[2], tf[0], n * sizeof (uint16));
+    }
+}
+
+static void
+TIFFDefaultRefBlackWhite(TIFFDirectory* td)
+{
+    int i;
+
+    td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float));
+    for (i = 0; i < 3; i++) {
+        td->td_refblackwhite[2*i+0] = 0;
+        td->td_refblackwhite[2*i+1] = (float)((1L<<td->td_bitspersample)-1L);
+    }
+}
+#endif
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ *
+ * NB:  We use the value in the directory, rather than
+ *  explcit values so that defaults exist only one
+ *  place in the library -- in TIFFDefaultDirectory.
+ */
+int
+TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
+{
+    TIFFDirectory *td = &tif->tif_dir;
+
+    if (TIFFVGetField(tif, tag, ap))
+        return (1);
+    switch (tag) {
+    case TIFFTAG_SUBFILETYPE:
+        *va_arg(ap, uint32 *) = td->td_subfiletype;
+        return (1);
+    case TIFFTAG_BITSPERSAMPLE:
+        *va_arg(ap, uint16 *) = td->td_bitspersample;
+        return (1);
+    case TIFFTAG_THRESHHOLDING:
+        *va_arg(ap, uint16 *) = td->td_threshholding;
+        return (1);
+    case TIFFTAG_FILLORDER:
+        *va_arg(ap, uint16 *) = td->td_fillorder;
+        return (1);
+    case TIFFTAG_ORIENTATION:
+        *va_arg(ap, uint16 *) = td->td_orientation;
+        return (1);
+    case TIFFTAG_SAMPLESPERPIXEL:
+        *va_arg(ap, uint16 *) = td->td_samplesperpixel;
+        return (1);
+    case TIFFTAG_ROWSPERSTRIP:
+        *va_arg(ap, uint32 *) = td->td_rowsperstrip;
+        return (1);
+    case TIFFTAG_MINSAMPLEVALUE:
+        *va_arg(ap, uint16 *) = td->td_minsamplevalue;
+        return (1);
+    case TIFFTAG_MAXSAMPLEVALUE:
+        *va_arg(ap, uint16 *) = td->td_maxsamplevalue;
+        return (1);
+    case TIFFTAG_PLANARCONFIG:
+        *va_arg(ap, uint16 *) = td->td_planarconfig;
+        return (1);
+    case TIFFTAG_RESOLUTIONUNIT:
+        *va_arg(ap, uint16 *) = td->td_resolutionunit;
+        return (1);
+#ifdef CMYK_SUPPORT
+    case TIFFTAG_DOTRANGE:
+        *va_arg(ap, uint16 *) = 0;
+        *va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
+        return (1);
+    case TIFFTAG_INKSET:
+        *va_arg(ap, uint16 *) = td->td_inkset;
+        return (1);
+    case TIFFTAG_NUMBEROFINKS:
+        *va_arg(ap, uint16 *) = td->td_ninks;
+        return (1);
+#endif
+    case TIFFTAG_EXTRASAMPLES:
+        *va_arg(ap, uint16 *) = td->td_extrasamples;
+        *va_arg(ap, uint16 **) = td->td_sampleinfo;
+        return (1);
+    case TIFFTAG_MATTEING:
+        *va_arg(ap, uint16 *) =
+            (td->td_extrasamples == 1 &&
+             td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+        return (1);
+    case TIFFTAG_TILEDEPTH:
+        *va_arg(ap, uint32 *) = td->td_tiledepth;
+        return (1);
+    case TIFFTAG_DATATYPE:
+        *va_arg(ap, uint16 *) = td->td_sampleformat-1;
+        return (1);
+    case TIFFTAG_SAMPLEFORMAT:
+        *va_arg(ap, uint16 *) = td->td_sampleformat;
+                return(1);
+    case TIFFTAG_IMAGEDEPTH:
+        *va_arg(ap, uint32 *) = td->td_imagedepth;
+        return (1);
+#ifdef YCBCR_SUPPORT
+    case TIFFTAG_YCBCRCOEFFICIENTS:
+        if (!td->td_ycbcrcoeffs) {
+            td->td_ycbcrcoeffs = (float *)
+                _TIFFmalloc(3*sizeof (float));
+            /* defaults are from CCIR Recommendation 601-1 */
+            td->td_ycbcrcoeffs[0] = 0.299f;
+            td->td_ycbcrcoeffs[1] = 0.587f;
+            td->td_ycbcrcoeffs[2] = 0.114f;
+        }
+        *va_arg(ap, float **) = td->td_ycbcrcoeffs;
+        return (1);
+    case TIFFTAG_YCBCRSUBSAMPLING:
+        *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
+        *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
+        return (1);
+    case TIFFTAG_YCBCRPOSITIONING:
+        *va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
+        return (1);
+#endif
+#ifdef COLORIMETRY_SUPPORT
+    case TIFFTAG_TRANSFERFUNCTION:
+        if (!td->td_transferfunction[0])
+            TIFFDefaultTransferFunction(td);
+        *va_arg(ap, uint16 **) = td->td_transferfunction[0];
+        if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+            *va_arg(ap, uint16 **) = td->td_transferfunction[1];
+            *va_arg(ap, uint16 **) = td->td_transferfunction[2];
+        }
+        return (1);
+    case TIFFTAG_REFERENCEBLACKWHITE:
+        if (!td->td_refblackwhite)
+            TIFFDefaultRefBlackWhite(td);
+        *va_arg(ap, float **) = td->td_refblackwhite;
+        return (1);
+#endif
+    }
+    return (0);
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ */
+int
+TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)
+{
+    int ok;
+    va_list ap;
+
+    va_start(ap, tag);
+    ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
+    va_end(ap);
+    return (ok);
+}