From: Pablo d'A. <da...@us...> - 2006-03-04 23:30:12
|
Update of /cvsroot/hugin/hugin/src/include/vigra_ext In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32125/src/include/vigra_ext Modified Files: FunctorAccessor.h ImageTransforms.h tiffUtils.h utils.h Added Files: impexalpha.hxx Log Message: merged vigra 1.4 version back into HEAD. Everything seems to work well. Index: tiffUtils.h =================================================================== RCS file: /cvsroot/hugin/hugin/src/include/vigra_ext/tiffUtils.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- tiffUtils.h 15 Aug 2005 21:06:09 -0000 1.11 +++ tiffUtils.h 4 Mar 2006 23:29:58 -0000 1.12 @@ -55,9 +55,10 @@ */ inline void createTiffDirectory(vigra::TiffImage * tiff, const std::string & pagename, const std::string & documentname, - const std::string comp, + const std::string comp, uint16 page, uint16 nImg, - vigra::Diff2D offset) + vigra::Diff2D offset, + const vigra::ICCProfile & icc) { const float dpi = 150; // create a new directory for our image @@ -88,8 +89,7 @@ TIFFSetField (tiff, TIFFTAG_PAGENAME, pagename.c_str() ); // TIFFSetField (tiff, TIFFTAG_IMAGEDESCRIPTION, "stitched with hugin"); - // FIXME: what should this be set to? - + // set compression unsigned short tiffcomp; if ( comp == "JPEG" ) @@ -100,8 +100,14 @@ tiffcomp = COMPRESSION_DEFLATE; else tiffcomp = COMPRESSION_NONE; - + TIFFSetField(tiff, TIFFTAG_COMPRESSION, tiffcomp); + + // Set ICC profile, if available. + if (icc.isValid()) { + TIFFSetField(tiff, TIFFTAG_ICCPROFILE, icc.getSize(), icc.getPtr()); + } + } Index: ImageTransforms.h =================================================================== RCS file: /cvsroot/hugin/hugin/src/include/vigra_ext/ImageTransforms.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- ImageTransforms.h 5 Feb 2006 14:48:45 -0000 1.6 +++ ImageTransforms.h 4 Mar 2006 23:29:58 -0000 1.7 @@ -33,7 +33,7 @@ #include <vigra_ext/ROIImage.h> #include <vigra_ext/Interpolators.h> #include <vigra/impex.hxx> -#include <vigra/impexalpha.hxx> +#include <vigra_ext/impexalpha.hxx> #include <common/math.h> #include <common/utils.h> Index: FunctorAccessor.h =================================================================== RCS file: /cvsroot/hugin/hugin/src/include/vigra_ext/FunctorAccessor.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- FunctorAccessor.h 30 Sep 2004 19:28:01 -0000 1.5 +++ FunctorAccessor.h 4 Mar 2006 23:29:58 -0000 1.6 @@ -28,6 +28,7 @@ namespace vigra_ext { + /** This class can be used to apply a function when reading the input image. @@ -167,6 +168,13 @@ } } + /** return the size (Number of Bands) */ + template <class ITERATOR> + unsigned int size(ITERATOR const & i) const + { + return 2; + } + Iter1 i1_; Acc1 a1_; Iter2 i2_; @@ -211,6 +219,13 @@ } } + /** return the size (Number of Bands) */ + template <class ITERATOR> + unsigned int size(ITERATOR const & i) const + { + return SIZE; + } + Iter1 i1_; Acc1 a1_; Iter2 i2_; @@ -276,6 +291,13 @@ } } + /** return the size (Number of Bands) */ + template <class ITERATOR> + unsigned int size(ITERATOR const & i) const + { + return 2; + } + Iter1 i1_; Acc1 a1_; Iter2 i2_; @@ -363,6 +385,14 @@ } } + + /** return the size (Number of Bands) */ + template <class ITERATOR> + unsigned int size(ITERATOR const & i) const + { + return SIZE; + } + Iter1 i1_; Acc1 a1_; Iter2 i2_; Index: utils.h =================================================================== RCS file: /cvsroot/hugin/hugin/src/include/vigra_ext/utils.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- utils.h 7 Jan 2006 10:56:01 -0000 1.4 +++ utils.h 4 Mar 2006 23:29:58 -0000 1.5 @@ -32,8 +32,8 @@ namespace vigra { -template <class T1, class T2> -struct PromoteTraits<RGBValue<T1>, T2 > +template <class T1, unsigned int R, unsigned int G, unsigned int B, class T2> +struct PromoteTraits<RGBValue<T1, R, G, B>, T2 > { typedef RGBValue<typename PromoteTraits<T1, T2>::Promote> Promote; }; @@ -50,17 +50,17 @@ } /// component-wise absolute value -template <class T> +template <class T, unsigned int R, unsigned int G, unsigned int B> inline -vigra::RGBValue<T> pow(vigra::RGBValue<T> const & v, double e) { - return vigra::RGBValue<T>(pow(v.red(),e), pow(v.green(),e), pow(v.blue(),e)); +vigra::RGBValue<T, R, G, B> pow(vigra::RGBValue<T, R, G, B> const & v, double e) { + return vigra::RGBValue<T, R, G, B>(pow(v.red(),e), pow(v.green(),e), pow(v.blue(),e)); } /// add a scalar to all components -template <class V1, class V2> +template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2> inline -vigra::RGBValue<V1> & -operator+=(vigra::RGBValue<V1> & l, V2 const & r) +vigra::RGBValue<V1, R, G, B> & +operator+=(vigra::RGBValue<V1, R, G, B> & l, V2 const & r) { l.red() += r; l.green() += r; @@ -69,14 +69,14 @@ } /// add a scalar to all components -template <class V1, class V2> +template <class V1, unsigned int R, unsigned int G, unsigned int B, class V2> inline // WARNING: This is a hack.. //vigra::RGBValue<V1> -typename vigra::PromoteTraits<vigra::RGBValue<V1>, V2 >::Promote -operator+(vigra::RGBValue<V1> const & r1, V2 const & r2) +typename vigra::PromoteTraits<vigra::RGBValue<V1, R, G, B>, V2 >::Promote +operator+(vigra::RGBValue<V1, R, G, B> const & r1, V2 const & r2) { - typename vigra::PromoteTraits<vigra::RGBValue<V1>, V2 >::Promote res(r1); + typename vigra::PromoteTraits<vigra::RGBValue<V1, R, G, B>, V2 >::Promote res(r1); res += r2; --- NEW FILE: impexalpha.hxx --- // -*- c-basic-offset: 4 -*- /** @file impexImageAlpha.h * * Routines to save images with alpha masks. * * These routines handle the conversion of byte alpha * channels into the final output types. * * @author Pablo d'Angelo <pab...@we...> * * $Id: impexalpha.hxx,v 1.2 2006/03/04 23:29:58 dangelo Exp $ * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef VIGRA_EXT_IMPEX_ALPHA_IMAGE_H #define VIGRA_EXT_IMPEX_ALPHA_IMAGE_H #include <iostream> #include <vigra/imageiterator.hxx> #include <vigra/transformimage.hxx> #include <vigra/initimage.hxx> #include <vigra/numerictraits.hxx> #include <vigra/impex.hxx> namespace vigra { /** define values for mask true value. max for integers, 1 for floats */ template <class T1> struct GetMaskTrue; #define VIGRA_EXT_GETMASKTRUE(T1, S) \ template<> \ struct GetMaskTrue<T1> \ { \ static T1 get() \ { \ return S; \ } \ }; #define VIGRA_EXT_GETMASKMAX(T1) \ template<> \ struct GetMaskTrue<T1> \ { \ static T1 get() \ { \ return vigra::NumericTraits<T1>::max(); \ } \ }; VIGRA_EXT_GETMASKMAX(vigra::UInt8) VIGRA_EXT_GETMASKMAX(vigra::Int16) VIGRA_EXT_GETMASKMAX(vigra::UInt16) VIGRA_EXT_GETMASKMAX(vigra::Int32) VIGRA_EXT_GETMASKMAX(vigra::UInt32) VIGRA_EXT_GETMASKTRUE(float, 1.0f) VIGRA_EXT_GETMASKTRUE(double, 1.0) template <class Iter1, class Acc1, class Iter2, class Acc2> class MultiImageMaskAccessor2 { public: /** The accessors value_type: construct a pair that contains the corresponding image values. */ typedef vigra::TinyVector<typename Acc1::value_type, 2> value_type; typedef typename Acc1::value_type component_type; typedef typename Acc2::value_type alpha_type; /** Construct from two image iterators and associated accessors. */ MultiImageMaskAccessor2(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** read the current data item */ template <class DIFFERENCE> value_type operator()(DIFFERENCE const & d) const { return value_type(a1_(i1_, d), a2_(i2_, d)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero()); } /** read the data item at an offset */ template <class DIFFERENCE1, class DIFFERENCE2> value_type operator()(DIFFERENCE1 d, DIFFERENCE2 const & d2) const { d += d2; return value_type(a1_(i1_, d), a2_(i2_, d)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero()); // return std::make_pair(a1_(i1_, d1), a2_(i2_, d1)); } /** write the current data item */ template <class DIFFERENCE> value_type set(const value_type & vt, DIFFERENCE const & d) const { a1_.set(vt[0], i1_, d); a2_.set(vt[1] ? GetMaskTrue<alpha_type>::get() : vigra::NumericTraits<alpha_type>::zero(), i2_, d); } /** scalar & scalar image */ template <class V, class ITERATOR> void setComponent( V const & value, ITERATOR const & i, int idx ) const { switch (idx) { case 0: a1_.set(value, i1_, *i); break; case 1: a2_.set(value ? GetMaskTrue<alpha_type>::get() : vigra::NumericTraits<alpha_type>::zero(), i2_, *i); break; default: vigra_fail("too many components in input value"); } } /** read one component */ template <class ITERATOR> component_type getComponent(ITERATOR const & i, int idx) const { switch (idx) { case 0: return a1_( i1_, *i ); case 1: return a2_( i2_, *i ) ? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero(); default: vigra_fail("too many components in input value"); // never reached, but here to silence compiler exit(1); } } template <class ITERATOR> unsigned int size ( ITERATOR const & i ) const { return 2; } private: Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; template <class Iter1, class Acc1, class Iter2, class Acc2> class MultiImageVectorMaskAccessor4 { public: /** The accessors value_type: construct a pair that contains the corresponding image values. */ typedef typename Acc1::value_type VT1; // todo.. check static_size, currently static_size == 4 enum { static_size = 4 }; typedef vigra::TinyVector<typename VT1::value_type, static_size> value_type; typedef typename value_type::value_type component_type; typedef typename Acc2::value_type alpha_type; /** Construct from two image iterators and associated accessors. */ MultiImageVectorMaskAccessor4(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** read the current data item */ template <class DIFFERENCE> value_type operator()(DIFFERENCE const & d) const { const VT1 & v1 = a1_.get(i1_,d); return value_type(v1[0], v1[1], v1[2], a2_(i2_, d)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero()); } /** read the data item at an offset */ template <class DIFFERENCE1, class DIFFERENCE2> value_type operator()(DIFFERENCE1 d, DIFFERENCE2 const & d2) const { d += d2; const VT1 & v1 = a1_.get(i1_,d); return value_type(v1[0], v1[1], v1[2], a2_(i2_, d)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero()); } /** write the current data item */ template <class DIFFERENCE> value_type set(const value_type & vt, DIFFERENCE const & d) const { Iter1 i1(i1_); i1 +=d; a1_.setComponent(vt[0], i1_, 0); a1_.setComponent(vt[1], i1_, 1); a1_.setComponent(vt[2], i1_, 2); a2_.set(vt[3] ? GetMaskTrue<alpha_type>::get() : vigra::NumericTraits<alpha_type>::zero(), i2_, d); } /** vector & scalar image */ template <class V, class ITERATOR> void setComponent( V const & value, ITERATOR const & i, int idx ) const { if ( idx < static_size - 1 ) { a1_.setComponent(value, i1_, *i, idx); } else if ( idx == static_size - 1 ) { a2_.set(value? GetMaskTrue<alpha_type>::get() : vigra::NumericTraits<alpha_type>::zero(), i2_, *i); } else { vigra_fail("too many components in input value"); } } /** read one component */ template <class ITERATOR> component_type getComponent(ITERATOR const & i, int idx) const { if ( idx < static_size - 1 ) { return a1_.getComponent(i1_, *i, idx); } else #ifndef DEBUG return a2_(i2_, *i)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero(); #else if ( idx == static_size - 1 ) { return a2_(i2_, *i)? GetMaskTrue<component_type>::get() : vigra::NumericTraits<component_type>::zero(); } else { vigra_fail("too many components in input value"); // just to silence the compiler warning. this is // never reached, since vigra_fail will always // throw an exception. throw 0; } #endif } template <class ITERATOR> unsigned int size ( ITERATOR const & i ) const { return static_size; } private: Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; // scalar image template<class SrcIterator, class SrcAccessor, class AlphaIterator, class AlphaAccessor> void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha, vigra::ImageExportInfo const & info, vigra::VigraTrueType) { typedef MultiImageMaskAccessor2<SrcIterator, SrcAccessor, AlphaIterator, AlphaAccessor> MAcc; exportImage(vigra::CoordinateIterator(), vigra::CoordinateIterator() + (image.second - image.first), MAcc(image.first, image.third, alpha.first, alpha.second), info); } // vector image template<class SrcIterator, class SrcAccessor, class AlphaIterator, class AlphaAccessor> void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha, vigra::ImageExportInfo const & info, vigra::VigraFalseType) { typedef MultiImageVectorMaskAccessor4<SrcIterator, SrcAccessor, AlphaIterator, AlphaAccessor> MAcc; exportImage(vigra::CoordinateIterator(), vigra::CoordinateIterator(image.second - image.first), MAcc(image.first, image.third, alpha.first, alpha.second), info ); } /** export an image with a differently typed alpha channel. * * This function handles the merging of the images and the * scales the alpha channel to the correct values. * * can write to all output formats that support 4 channel images. * (currently only png and tiff). */ template<class SrcIterator, class SrcAccessor, class AlphaIterator, class AlphaAccessor> void exportImageAlpha(vigra::triple<SrcIterator, SrcIterator, SrcAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha, vigra::ImageExportInfo const & info) { typedef typename vigra::NumericTraits<typename SrcAccessor::value_type>::isScalar is_scalar; // select function for scalar, or vector image, depending on source type. // the alpha image has to be scalar all the time. stuff will break with strange // compile error if it isn't exportImageAlpha( image, alpha, info, is_scalar()); } // vector image template<class DestIterator, class DestAccessor, class AlphaIterator, class AlphaAccessor> void importImageAlpha(vigra::ImageImportInfo const & info, std::pair<DestIterator, DestAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha, vigra::VigraFalseType) { vigra_precondition(image.second(image.first).size() == 3, "only scalar and 3 channel (vector) images supported by impexalpha.hxx"); typedef MultiImageVectorMaskAccessor4<DestIterator, DestAccessor, AlphaIterator, AlphaAccessor> MAcc; importImage(info, vigra::CoordinateIterator(), MAcc(image.first, image.second, alpha.first, alpha.second) ); } // scalar image template<class DestIterator, class DestAccessor, class AlphaIterator, class AlphaAccessor> void importImageAlpha(vigra::ImageImportInfo const & info, std::pair<DestIterator, DestAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha, vigra::VigraTrueType) { typedef MultiImageMaskAccessor2<DestIterator, DestAccessor, AlphaIterator, AlphaAccessor> MAcc; importImage(info, vigra::CoordinateIterator(), MAcc(image.first, image.second, alpha.first, alpha.second) ); } /** import an image with a differently typed alpha channel. * * This function loads an image, and splits it into a * color image and a separate alpha channel, the alpha channel * should be a 8 bit image. * * If the image doesn't contain any alpha channel, a completely * white one is created. * * can write to all output formats that support 4 channel images. * (currently only png and tiff). */ template<class DestIterator, class DestAccessor, class AlphaIterator, class AlphaAccessor> void importImageAlpha(vigra::ImageImportInfo const & info, vigra::pair<DestIterator, DestAccessor> image, std::pair<AlphaIterator, AlphaAccessor> alpha ) { typedef typename vigra::NumericTraits<typename DestAccessor::value_type>::isScalar is_scalar; if (info.numExtraBands() == 1 ) { // import image and alpha channel importImageAlpha(info, image, alpha, is_scalar()); } else if (info.numExtraBands() == 0 ) { // no alphachannel in file, import as usual. importImage(info, image); // fill alpha image vigra::initImage(alpha.first , alpha.first + vigra::Diff2D(info.width(), info.height()), alpha.second, 255); } else { vigra_fail("Images with two or more alpha channel are not supported"); } } } // namespace #endif // VIGRA_EXT_IMPEX_ALPHA_IMAGE_H |