Ticket #1377: GIL-TIFF-SaveRGBA.patch

File GIL-TIFF-SaveRGBA.patch, 4.2 KB (added by william@…, 15 years ago)

Patch which adds ability to save alpha channel as premultiplied alpha in TIFF file.

  • boost/gil/extension/io/tiff_io.hpp

    diff -rwbBui gil/boost/gil/extension/io/tiff_io.hpp boost/boost/include/boost-1_34/boost/gil/extension/io/tiff_io.hpp
    old new  
    2323#include <vector>
    2424#include <string>
    2525#include <algorithm>
     26#include <boost/gil/color_base_algorithm.hpp>
     27#include <boost/gil/image_view_factory.hpp>
     28#include <boost/gil/rgba.hpp>
    2629#include <boost/static_assert.hpp>
    2730#include <tiffio.h>
    2831#include "../../gil_all.hpp"
     
    94115    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
    95116};
    96117template <>
     118struct tiff_write_support_private<bits8,rgba_t> {
     119    BOOST_STATIC_CONSTANT(bool,is_supported=true);
     120    BOOST_STATIC_CONSTANT(int,bit_depth=8);
     121    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
     122};
     123template <>
    97124struct tiff_write_support_private<bits16,gray_t> {
    98125    BOOST_STATIC_CONSTANT(bool,is_supported=true);
    99126    BOOST_STATIC_CONSTANT(int,bit_depth=16);
     
    106133    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
    107134};
    108135template <>
     136struct tiff_write_support_private<bits16,rgba_t> {
     137    BOOST_STATIC_CONSTANT(bool,is_supported=true);
     138    BOOST_STATIC_CONSTANT(int,bit_depth=16);
     139    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
     140};
     141template <>
    109142struct tiff_write_support_private<bits32f,gray_t> {
    110143    BOOST_STATIC_CONSTANT(bool,is_supported=true);
    111144    BOOST_STATIC_CONSTANT(int,bit_depth=32);
     
    117150    BOOST_STATIC_CONSTANT(int,bit_depth=32);
    118151    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
    119152};
     153template <>
     154struct tiff_write_support_private<bits32f,rgba_t> {
     155    BOOST_STATIC_CONSTANT(bool,is_supported=true);
     156    BOOST_STATIC_CONSTANT(int,bit_depth=32);
     157    BOOST_STATIC_CONSTANT(int,color_type=PHOTOMETRIC_RGB);
     158};
    120159
    121160class tiff_reader {
    122161protected:
     
    286357    }
    287358};
    288359
     360template <typename SrcColorSpace, typename DstColorSpace>
     361struct premultiplier_impl
     362  : public default_color_converter_impl<SrcColorSpace,DstColorSpace> {
     363        template <typename SrcP, typename DstP>  // Model PixelConcept
     364        void operator()(const SrcP& src, DstP& dst) const {
     365                get_color <red_t> (dst) = channel_multiply (get_color <red_t> (src), get_color <alpha_t> (src));
     366                get_color <green_t> (dst) = channel_multiply (get_color <green_t> (src), get_color <alpha_t> (src));
     367                get_color <blue_t> (dst) = channel_multiply (get_color <blue_t> (src), get_color <alpha_t> (src));
     368                get_color <alpha_t> (dst) = get_color <alpha_t> (src);
     369        }
     370};
     371
     372struct premultiplier {
     373    template <typename SrcP, typename DstP>  // Model PixelConcept
     374    void operator()(const SrcP& src,DstP& dst) const {
     375        typedef typename color_space_type<SrcP>::type SrcColorSpace;
     376        typedef typename color_space_type<DstP>::type DstColorSpace;
     377        premultiplier_impl<SrcColorSpace,DstColorSpace>()(src,dst);
     378    }
     379};
     380
    289381class tiff_writer {
    290382protected:
    291383    TIFF* _tp;
     
    308402        io_error_if(TIFFSetField(_tp,TIFFTAG_BITSPERSAMPLE, tiff_write_support_private<typename channel_type<View>::type,
    309403                                                                     typename color_space_type<View>::type>::bit_depth)!=1);
    310404        io_error_if(TIFFSetField(_tp,TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(_tp, 0))!=1);
     405
     406                                if (3 < num_channels<View>::value) {
     407                                        uint16_t alphaStyle = EXTRASAMPLE_ASSOCALPHA;
     408                                        io_error_if(TIFFSetField(_tp,TIFFTAG_EXTRASAMPLES, 1, & alphaStyle)!=1);
     409                                }
     410       
     411                                View ccv = color_converted_view <typename View:: value_type> (view, premultiplier ());
     412                                View const & outputView =       3 < num_channels<View>::value? ccv:     view;
     413
    311414        std::vector<pixel<typename channel_type<View>::type,
    312415                          layout<typename color_space_type<View>::type> > > row(view.width());
     416                               
    313417        for (int y=0;y<view.height();++y) {
    314             std::copy(view.row_begin(y),view.row_end(y),row.begin());
     418            std::copy(outputView.row_begin(y),outputView.row_end(y),row.begin());
    315419            io_error_if(TIFFWriteScanline(_tp,&row.front(),y,0)!=1,
    316420                        "tiff_write_view: fail to write file");
    317421        }