2007-01-10

Adobe GIL and <windows.h>

I've been playing with Adobe GIL, following it's inclusion into Boost, and I've been getting some fun compile errors in relation to <windows.h>. Note that, even if you aren't including <windows.h>, some of the boost headers do.

Here lies: What not to do, so you don't waste hours on it like I did.

Test-case:

int main()
{
    ::gil::rgb8_image_t a;
    ::gil::jpeg_read_and_convert_image("a", a);
}

Compiled with Visual Studio 2005 SP1, Boost 1.33.1 and JPEG 6b (27-Mar-1998):

cl /EHsc jpegio.cpp /I c:\sdk\libs /I c:\boost\include\boost-1_33_1

First attempt, <windows.h> first:

#include <windows.h>

#include <gil/core/gil_all.hpp>
#include <gil/extension/io/jpeg_dynamic_io.hpp>

Error:

jpegio.cpp
c:\sdk\libs\gil\core\channel.hpp(90) : warning C4003: not enough actual paramete rs for macro 'min'
c:\sdk\libs\gil\core\channel.hpp(92) : warning C4003: not enough actual paramete rs for macro 'max'
c:\sdk\libs\jmorecfg.h(161) : error C2371: 'INT32' : redefinition; different bas ic types
        C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\basetsd.h(62) : see declaration of 'INT32'
c:\sdk\libs\jmorecfg.h(215) : warning C4005: 'FAR' : macro redefinition
        C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\windef.h(145) : see previous definition of 'FAR'

Second attempt, other way around, Error:

jpegio.cpp
C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\basetsd.h(62): error C2371: 'INT32' : redefinition; different basic types
        c:\sdk\libs\jmorecfg.h(161) : see declaration of 'INT32'

Third attempt:

#include <windows.h>
#include <gil/core/gil_all.hpp>

#define XMD_H
#include <gil/extension/io/jpeg_dynamic_io.hpp>
#undef XMD_H

This should, in theory improve matters, as XMD_H being #defined stops <jmorecfg.h> trying to redeclare INT32.

Oh no.

Error:

jpegio.cpp
c:\sdk\libs\gil\core\channel.hpp(90) : warning C4003: not enough actual parameters for macro 'min'
c:\sdk\libs\gil\core\channel.hpp(92) : warning C4003: not enough actual parameters for macro 'max'
c:\sdk\libs\jmorecfg.h(215) : warning C4005: 'FAR' : macro redefinition
        C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\windef.h(145) : see previous definition of 'FAR'
c:\sdk\libs\gil\core\color_convert.hpp(148) : error C2589: '(' : illegal token on right side of '::'
        c:\sdk\libs\gil\core\color_convert.hpp(221) : see reference to function template instantiation 'void gil::color_converter_default_impl<lt;T1,C1,T2,C2>::operator ()<lt;SrcP,DstP>(const P1 &,P2 &) const' being compiled
        with
        [
            T1=SrcChannel,
            C1=SrcColorSpace,
            T2=DstChannel,
            C2=DstColorSpace,
            SrcP=gil::pixel<lt;gil::bits8,gil::cmyk_t>,
            DstP=gil::pixel<lt;gil::bits8,gil::rgb_t>,
            P1=gil::pixel<lt;gil::bits8,gil::cmyk_t>,
            P2=gil::pixel<lt;gil::bits8,gil::rgb_t>
        ]
        c:\sdk\libs\gil\extension\dynamic_image\../../core/image_view_factory.hpp(71) : see reference to function template instantiation 'void gil::default_color_converter::operator ()<lt;gil::pixel<lt;T,C>,gil::pixel<lt;T,gil::rgb_t>>(const SrcP &,DstP &) const' being compiled
        with
        [
            T=gil::bits8,
            C=gil::cmyk_t,
            SrcP=gil::pixel<lt;gil::bits8,gil::cmyk_t>,
            DstP=gil::pixel<lt;gil::bits8,gil::rgb_t>
        ]
        c:\sdk\libs\gil\extension\dynamic_image\../../core/image_view_factory.hpp(69) : while compiling class template member function 'gil::pixel<lt;T,C> gil::color_convert_deref_fn<lt;SrcConstRefP,DstP,CC>::operator ()(gil::pixel<lt;T,gil::cmyk_t> &) const'
        with
        [
            T=gil::bits8,
            C=gil::rgb_t,
            SrcConstRefP=gil::cmyk8_ref_t,
            DstP=gil::pixel<lt;gil::bits8,gil::rgb_t>,
            CC=gil::default_color_converter
        ]
        c:\sdk\libs\gil\extension\io\jpeg_io_private.hpp(166) : see reference to class template instantiation 'gil::color_convert_deref_fn<lt;SrcConstRefP,DstP,CC>' being compiled
        with
        [
            SrcConstRefP=gil::cmyk8_ref_t,
            DstP=gil::pixel<lt;gil::bits8,gil::rgb_t>,
            CC=gil::default_color_converter
        ]
        c:\sdk\libs\gil\extension\io\jpeg_io_private.hpp(178) : see reference to function template instantiation 'void gil::detail::jpeg_reader_color_convert<lt;CC>::apply<lt;V2>(const View &)' being compiled
        with
        [
            CC=gil::default_color_converter,
            V2=gil::rgb8_view_t,
            View=gil::rgb8_view_t
        ]
        c:\sdk\libs\gil\extension\io\jpeg_io.hpp(147) : see reference to function template instantiation 'void gil::detail::jpeg_reader_color_convert<lt;CC>::read_image<lt;Image>(Image &)' being compiled
        with
        [
            CC=gil::default_color_converter,
            Image=gil::rgb8_image_t
        ]
        jpegio.cpp(12) : see reference to function template instantiation 'void gil::jpeg_read_and_convert_image<lt;gil::rgb8_image_t>(const char *,Image &)' being compiled
        with
        [
            Image=gil::rgb8_image_t
        ]
c:\sdk\libs\gil\core\color_convert.hpp(148) : error C2143: syntax error : missing ')' before '::'
c:\sdk\libs\gil\core\color_convert.hpp(148) : error C2780: 'T gil::channel_invert(T)' : expects 1 arguments - 0 provided
        c:\sdk\libs\gil\core\channel.hpp(235) : see declaration of 'gil::channel_invert'
c:\sdk\libs\gil\core\color_convert.hpp(148) : error C2059: syntax error : ')'
c:\sdk\libs\gil\core\color_convert.hpp(149) : error C2589: '(' : illegal token on right side of '::'
c:\sdk\libs\gil\core\color_convert.hpp(149) : error C2143: syntax error : missing ')' before '::'
c:\sdk\libs\gil\core\color_convert.hpp(149) : error C2780: 'T gil::channel_invert(T)' : expects 1 arguments - 0 provided
        c:\sdk\libs\gil\core\channel.hpp(235) : see declaration of 'gil::channel_invert'
c:\sdk\libs\gil\core\color_convert.hpp(149) : error C2059: syntax error : ')'
c:\sdk\libs\gil\core\color_convert.hpp(150) : error C2589: '(' : illegal token on right side of '::'
c:\sdk\libs\gil\core\color_convert.hpp(150) : error C2143: syntax error : missing ')' before '::'
c:\sdk\libs\gil\core\color_convert.hpp(150) : error C2780: 'T gil::channel_invert(T)' : expects 1 arguments - 0 provided
        c:\sdk\libs\gil\core\channel.hpp(235) : see declaration of 'gil::channel_invert'
c:\sdk\libs\gil\core\color_convert.hpp(150) : error C2059: syntax error : ')'

...

Fourth attempt, the "right" way:

#include <gil/core/gil_all.hpp>

#define XMD_H
#include <gil/extension/io/jpeg_dynamic_io.hpp>
#undef XMD_H

#include <windows.h>

This works as intended.

Solutions?

Assuming that we're not going to get the JPEG code patched, the INT32 definition from <windows.h> comes from <basetsd.h>, which declares the BASETSD_H header-guard macro.. it'd be nice if GIL issued an explanation of what was going to go horribly wrong, instead of that lovely template error in test three?


Commenting is disabled for this post.

Read more of Faux' blog