diff --git a/panda/src/chan/animChannelScalarTable.cxx b/panda/src/chan/animChannelScalarTable.cxx index 323119526c..21b8fb5468 100644 --- a/panda/src/chan/animChannelScalarTable.cxx +++ b/panda/src/chan/animChannelScalarTable.cxx @@ -163,7 +163,7 @@ write_datagram(BamWriter *manager, Datagram &me) for (i = 0; i < (int)_table.size() && (int)index.size() <= max_values; i++) { - int value = (int)floor(_table[i] * scale + 0.5f); + int value = (int)cfloor(_table[i] * scale + 0.5f); index.insert(pmap::value_type(value, index.size())); } int index_length = index.size(); @@ -200,8 +200,8 @@ write_datagram(BamWriter *manager, Datagram &me) } else { 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 i2 = index[value2]; @@ -210,7 +210,7 @@ write_datagram(BamWriter *manager, Datagram &me) // There might be one odd value. 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]; me.add_uint8(i1 << 4); diff --git a/panda/src/chan/animControl.I b/panda/src/chan/animControl.I index 3c333f3199..57db0b55f3 100644 --- a/panda/src/chan/animControl.I +++ b/panda/src/chan/animControl.I @@ -75,7 +75,7 @@ get_frame() const { // We have to use floor() here instead of simply casting the number // to an integer, becase the frame number might have become // negative. - return (int)floor(_frame + 0.0001); + return (int)cfloor(_frame + 0.0001); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/chan/animControl.cxx b/panda/src/chan/animControl.cxx index fc1cad45eb..7fc102c113 100644 --- a/panda/src/chan/animControl.cxx +++ b/panda/src/chan/animControl.cxx @@ -387,7 +387,7 @@ advance_time(double time) { // anyway (no need to convert to integer format and back // again), and because we need correct behavior when the // frame number is negative. - _frame = _frame - floor(_frame / num_frames) * num_frames; + _frame = _frame - cfloor(_frame / num_frames) * num_frames; new_frame = get_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 // again), and because we need correct behavior when the // frame number is negative. - _frame = _frame - floor(_frame / num_frames) * num_frames; + _frame = _frame - cfloor(_frame / num_frames) * num_frames; new_frame = get_frame(); do_actions_forward(0, new_frame); } diff --git a/panda/src/chan/animControl.h b/panda/src/chan/animControl.h index e5f5d6418f..0692f7f0c7 100644 --- a/panda/src/chan/animControl.h +++ b/panda/src/chan/animControl.h @@ -29,7 +29,7 @@ #include #include #include - +#include #include #include "pmap.h" diff --git a/panda/src/linmath/cmath.I b/panda/src/linmath/cmath.I index 8790b5e454..7437546b5a 100644 --- a/panda/src/linmath/cmath.I +++ b/panda/src/linmath/cmath.I @@ -96,6 +96,38 @@ INLINE_LINMATH float catan2(float y, float 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) { return sqrt(v); } diff --git a/panda/src/linmath/cmath.h b/panda/src/linmath/cmath.h index c9d088551a..4e9ab2a148 100644 --- a/panda/src/linmath/cmath.h +++ b/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 catan(float v); 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 csin(double v); INLINE_LINMATH double ccos(double v); diff --git a/panda/src/mathutil/fftCompressor.cxx b/panda/src/mathutil/fftCompressor.cxx index 376c00337a..0b138c6e48 100644 --- a/panda/src/mathutil/fftCompressor.cxx +++ b/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; 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? double a = fabs(num); diff --git a/panda/src/parametrics/parametricCurve.cxx b/panda/src/parametrics/parametricCurve.cxx index 8799559263..8015bc3fe0 100644 --- a/panda/src/parametrics/parametricCurve.cxx +++ b/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. 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; get_point(t2, p2); float net = 0.0f; diff --git a/panda/src/parametrics/parametricCurveCollection.cxx b/panda/src/parametrics/parametricCurveCollection.cxx index 220bb8621a..721f2a19fe 100644 --- a/panda/src/parametrics/parametricCurveCollection.cxx +++ b/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. 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()) { parametrics_cat.debug() @@ -426,7 +426,7 @@ face_forward(float segments_per_unit) { CurveFitter fitter; 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); diff --git a/panda/src/parametrics/parametricCurveDrawer.cxx b/panda/src/parametrics/parametricCurveDrawer.cxx index 9303549b74..99effae8b4 100644 --- a/panda/src/parametrics/parametricCurveDrawer.cxx +++ b/panda/src/parametrics/parametricCurveDrawer.cxx @@ -327,7 +327,7 @@ draw() { // Make sure the curve(s) are fresh. _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 scale = max_t / (float)(total_segs-1); @@ -358,7 +358,7 @@ draw() { // Now draw the time tick marks. 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 *hpr_curve = _curves->get_hpr_curve(); diff --git a/panda/src/pnmimage/pnm-image-filter.cxx b/panda/src/pnmimage/pnm-image-filter.cxx index 0ec71e5029..15ca922792 100644 --- a/panda/src/pnmimage/pnm-image-filter.cxx +++ b/panda/src/pnmimage/pnm-image-filter.cxx @@ -37,8 +37,8 @@ // each channel in the image. #include - #include +#include #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 // the far left edge of the original pixel, not in the center. So we will // 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 @@ -37,33 +38,33 @@ static void TIFFDefaultTransferFunction(TIFFDirectory* td) { - uint16 **tf = td->td_transferfunction; - long i, n = 1<td_bitspersample; + uint16 **tf = td->td_transferfunction; + long i, n = 1<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 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_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_bitspersample)-1L); + } } #endif @@ -71,122 +72,122 @@ TIFFDefaultRefBlackWhite(TIFFDirectory* td) * 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. + * 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; + 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 - case TIFFTAG_DOTRANGE: - *va_arg(ap, uint16 *) = 0; - *va_arg(ap, uint16 *) = (1<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_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; + 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); + 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); + 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); + 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); + } + return (0); } /* @@ -196,11 +197,11 @@ TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap) int 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); } diff --git a/panda/src/tiff/tif_aux.cxx b/panda/src/tiff/tif_aux.cxx new file mode 100644 index 0000000000..9a934f08b9 --- /dev/null +++ b/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 + +static void +TIFFDefaultTransferFunction(TIFFDirectory* td) +{ + uint16 **tf = td->td_transferfunction; + long i, n = 1<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_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_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); +}