hostsupport/hostopenvg/src/src/riImage.h
branchbug235_bringup_0
changeset 54 067180f57b12
parent 53 c2ef9095503a
child 55 09263774e342
--- a/hostsupport/hostopenvg/src/src/riImage.h	Wed Oct 06 17:59:01 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1593 +0,0 @@
-#ifndef __RIIMAGE_H
-#define __RIIMAGE_H
-
-/*------------------------------------------------------------------------
- *
- * OpenVG 1.1 Reference Implementation
- * -----------------------------------
- *
- * Copyright (c) 2007 The Khronos Group Inc.
- * Portions copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and /or associated documentation files
- * (the "Materials "), to deal in the Materials without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Materials,
- * and to permit persons to whom the Materials are furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Materials.
- *
- * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
- * THE USE OR OTHER DEALINGS IN THE MATERIALS.
- *
- *//**
- * \file
- * \brief	Color and Image classes.
- * \note
- *//*-------------------------------------------------------------------*/
-
-#ifndef _OPENVG_H
-#include "VG/openvg.h"
-#endif
-
-#ifndef __RIMATH_H
-#include "riMath.h"
-#endif
-
-#ifndef __RIARRAY_H
-#include "riArray.h"
-#endif
-
-#include "sfAlphaRcp.h"
-#include "sfGammaLUT.h"
-#include "riUtils.h"
-
-//==============================================================================================
-
-namespace OpenVGRI
-{
-
-class VGContext;
-class DynamicBlitter;
-
-/*-------------------------------------------------------------------*//*!
-* \brief	A class representing rectangles.
-* \param
-* \return
-* \note
-*//*-------------------------------------------------------------------*/
-
-class Rectangle
-{
-public:
-    Rectangle() : x(0), y(0), width(0), height(0) {}
-    Rectangle(int rx, int ry, int rw, int rh) : x(rx), y(ry), width(rw), height(rh) {}
-    void		intersect(const Rectangle& r)
-    {
-        if(width >= 0 && r.width >= 0 && height >= 0 && r.height >= 0)
-        {
-            int x1 = RI_INT_MIN(RI_INT_ADDSATURATE(x, width), RI_INT_ADDSATURATE(r.x, r.width));
-            x = RI_INT_MAX(x, r.x);
-            width = RI_INT_MAX(x1 - x, 0);
-
-            int y1 = RI_INT_MIN(RI_INT_ADDSATURATE(y, height), RI_INT_ADDSATURATE(r.y, r.height));
-            y = RI_INT_MAX(y, r.y);
-            height = RI_INT_MAX(y1 - y, 0);
-        }
-        else
-        {
-            x = 0;
-            y = 0;
-            width = 0;
-            height = 0;
-        }
-    }
-    bool isEmpty() const { return width == 0 || height == 0; }
-
-    int			x;
-    int			y;
-    int			width;
-    int			height;
-};
-
-/*-------------------------------------------------------------------*//*!
-* \brief	A class representing color for processing and converting it
-*			to and from various surface formats.
-* \param
-* \return
-* \note
-*//*-------------------------------------------------------------------*/
-
-class Color
-{
-public:
-    enum FormatSize
-    {
-        SIZE_1      = 0,
-        SIZE_4      = 1,
-        SIZE_8      = 2,
-        SIZE_16     = 3,
-        SIZE_24     = 4,
-        SIZE_32     = 5
-    };
-
-    enum Shape
-    {
-        SHAPE_RGBA            = 0,
-        SHAPE_RGBX            = 1,
-        SHAPE_RGB             = 2,
-        SHAPE_LA              = 3,
-        SHAPE_L               = 4,
-        SHAPE_A               = 5,
-        SHAPE_ARGB            = 6,
-        SHAPE_XRGB            = 7,
-        SHAPE_AL              = 8,
-        SHAPE_BGRA            = 9,
-        SHAPE_BGRX            = 10,
-        SHAPE_BGR             = 11,
-        SHAPE_ABGR            = 12,
-        SHAPE_XBGR            = 13
-    };
-    enum InternalFormat
-    {
-        lRGBA			= 0,
-        sRGBA			= 1,
-        lRGBA_PRE		= 2,
-        sRGBA_PRE		= 3,
-        lLA				= 4,
-        sLA				= 5,
-        lLA_PRE			= 6,
-        sLA_PRE			= 7
-    };
-    enum FormatBits
-    {
-        NONLINEAR		= (1<<0),
-        PREMULTIPLIED	= (1<<1),
-        LUMINANCE		= (1<<2)
-    };
-    struct SmallDescriptor
-    {
-        RIuint32        toUint32()
-        {
-            RIuint32 ret = 0;
-            ret = (RIuint32)size;
-            ret |= (RIuint32)shape << 3;
-            ret |= (RIuint32)internalFormat << (3 + 4);
-            return ret;
-        }
-        FormatSize      size;
-        Shape           shape;
-        InternalFormat  internalFormat;
-    };
-    class Descriptor
-    {
-    public:
-        Descriptor() {};
-        RI_INLINE Descriptor(int dredBits, int dredShift, int dgreenBits, int dgreenShift, int dblueBits, int dblueShift, int dalphaBits, int dalphaShift, int dluminanceBits, int dluminanceShift, InternalFormat dinternalFormat, int dbpp, Shape shape);
-        RI_INLINE bool      isNonlinear() const                                 { return (internalFormat & NONLINEAR) ? true : false; }
-        RI_INLINE void      setNonlinear(bool nonlinear);
-        RI_INLINE bool      isPremultiplied() const                             { return (internalFormat & PREMULTIPLIED) ? true : false; }
-        RI_INLINE bool      isLuminance() const                                 { return (internalFormat & LUMINANCE) ? true : false; }
-        RI_INLINE bool      isAlphaOnly() const                                 { return (alphaBits && (redBits+greenBits+blueBits+luminanceBits) == 0) ? true : false; }
-        RI_INLINE bool      isBW() const { return isLuminance() && (luminanceBits == 1); }
-        RI_INLINE bool      hasAlpha() const { return alphaBits > 0; }
-        RI_INLINE bool      operator==(const Descriptor& rhs) const;
-        RI_INLINE bool      isShiftConversionToLower(const Descriptor& rhs) const;
-        RI_INLINE bool      isShiftConversion(const Descriptor& rhs) const;
-        RI_INLINE bool      isZeroConversion(const Descriptor& rhs) const;
-        RI_INLINE bool      maybeUnsafe() const { return internalFormat & PREMULTIPLIED ? true : false; };
-        static RI_INLINE RIuint32  crossConvertToLower(RIuint32 c, const Descriptor& src, const Descriptor& dst);
-        void                toSmallDescriptor(SmallDescriptor& smallDesc) const;
-        RI_INLINE RIuint32  toIndex() const;
-        static Descriptor   getDummyDescriptor();
-        Shape               getShape() const;
-
-        int				redBits;
-        int				redShift;
-        int				greenBits;
-        int				greenShift;
-        int				blueBits;
-        int				blueShift;
-        int				alphaBits;
-        int				alphaShift;
-        int				luminanceBits;
-        int				luminanceShift;
-        Shape           shape;
-        VGImageFormat   vgFormat; // \note Storage only
-        InternalFormat	internalFormat;
-        int				bitsPerPixel;
-        // Derived info:
-        int             bytesPerPixel;
-        int             maskBits;
-        int             maskShift;
-    };
-
-    RI_INLINE Color() : r(0.0f), g(0.0f), b(0.0f), a(0.0f), m_format(sRGBA_PRE)													{}
-    RI_INLINE Color(RIfloat cl, RIfloat ca, InternalFormat cs) : r(cl), g(cl), b(cl), a(ca), m_format(cs)							{ RI_ASSERT(cs == lLA || cs == sLA || cs == lLA_PRE || cs == sLA_PRE); }
-    RI_INLINE Color(RIfloat cr, RIfloat cg, RIfloat cb, RIfloat ca, InternalFormat cs) : r(cr), g(cg), b(cb), a(ca), m_format(cs)	{ RI_ASSERT(cs == lRGBA || cs == sRGBA || cs == lRGBA_PRE || cs == sRGBA_PRE || cs == lLA || cs == sLA || cs == lLA_PRE || cs == sLA_PRE); }
-    RI_INLINE Color(const Color& c) : r(c.r), g(c.g), b(c.b), a(c.a), m_format(c.m_format)									{}
-    RI_INLINE Color& operator=(const Color&c)										{ r = c.r; g = c.g; b = c.b; a = c.a; m_format = c.m_format; return *this; }
-    RI_INLINE void operator*=(RIfloat f)											{ r *= f; g *= f; b *= f; a*= f; }
-    RI_INLINE void operator+=(const Color& c1)										{ RI_ASSERT(m_format == c1.getInternalFormat()); r += c1.r; g += c1.g; b += c1.b; a += c1.a; }
-    RI_INLINE void operator-=(const Color& c1)										{ RI_ASSERT(m_format == c1.getInternalFormat()); r -= c1.r; g -= c1.g; b -= c1.b; a -= c1.a; }
-
-    void						set(RIfloat cl, RIfloat ca, InternalFormat cs)							{ RI_ASSERT(cs == lLA || cs == sLA || cs == lLA_PRE || cs == sLA_PRE); r = cl; g = cl; b = cl; a = ca; m_format = cs; }
-    void						set(RIfloat cr, RIfloat cg, RIfloat cb, RIfloat ca, InternalFormat cs)	{ RI_ASSERT(cs == lRGBA || cs == sRGBA || cs == lRGBA_PRE || cs == sRGBA_PRE); r = cr; g = cg; b = cb; a = ca; m_format = cs; }
-    void						unpack(unsigned int inputData, const Descriptor& inputDesc);
-    unsigned int				pack(const Descriptor& outputDesc) const;
-    RI_INLINE InternalFormat	getInternalFormat() const							{ return m_format; }
-
-    //clamps nonpremultiplied colors and alpha to [0,1] range, and premultiplied alpha to [0,1], colors to [0,a]
-    void						clamp()												{ a = RI_CLAMP(a,0.0f,1.0f); RIfloat u = (m_format & PREMULTIPLIED) ? a : (RIfloat)1.0f; r = RI_CLAMP(r,0.0f,u); g = RI_CLAMP(g,0.0f,u); b = RI_CLAMP(b,0.0f,u); }
-    void						convert(InternalFormat outputFormat);
-    void						premultiply()										{ if(!(m_format & PREMULTIPLIED)) { r *= a; g *= a; b *= a; m_format = (InternalFormat)(m_format | PREMULTIPLIED); } }
-    void						unpremultiply()										{ if(m_format & PREMULTIPLIED) { RIfloat ooa = (a != 0.0f) ? 1.0f/a : (RIfloat)0.0f; r *= ooa; g *= ooa; b *= ooa; m_format = (InternalFormat)(m_format & ~PREMULTIPLIED); } }
-    void                        luminanceToRGB()                                    { if(m_format & LUMINANCE) { RI_ASSERT(r == g && g == b); m_format = (InternalFormat)(m_format & ~LUMINANCE); } }
-
-    bool                        isNonlinear() const                                 { return (m_format & NONLINEAR) ? true : false; }
-    bool                        isPremultiplied() const                             { return (m_format & PREMULTIPLIED) ? true : false; }
-    bool                        isLuminance() const                                 { return (m_format & LUMINANCE) ? true : false; }
-
-    RI_INLINE void              assertConsistency() const;
-
-    // \note Why are these in the color class instead of descriptor?
-    static VGImageFormat        descriptorToVGImageFormat(const Descriptor& desc);
-    RI_INLINE static Descriptor formatToDescriptorConst(VGImageFormat format);
-    static Descriptor			formatToDescriptor(VGImageFormat format);
-    static bool					isValidDescriptor(const Descriptor& desc);
-
-    RIfloat		r;
-    RIfloat		g;
-    RIfloat		b;
-    RIfloat		a;
-private:
-    InternalFormat	m_format;
-};
-
-RI_INLINE Color::Descriptor::Descriptor(int dredBits, int dredShift, int dgreenBits, int dgreenShift, int dblueBits, int dblueShift, int dalphaBits, int dalphaShift, int dluminanceBits, int dluminanceShift, InternalFormat dinternalFormat, int dbpp, Shape shape) :
-    redBits(dredBits),
-    redShift(dredShift),
-    greenBits(dgreenBits),
-    greenShift(dgreenShift),
-    blueBits(dblueBits),
-    blueShift(dblueShift),
-    alphaBits(dalphaBits),
-    alphaShift(dalphaShift),
-    luminanceBits(dluminanceBits),
-    luminanceShift(dluminanceShift),
-    shape(shape),
-    internalFormat(dinternalFormat),
-    bitsPerPixel(dbpp)
-{
-    bytesPerPixel = bitsPerPixel / 8;
-
-    if (alphaBits)
-    {
-        maskBits = alphaBits;
-        maskShift = alphaShift;
-    }
-    else if (!this->isLuminance())
-    {
-        maskBits = redBits;
-        maskShift = redShift;
-    }
-    else
-    {
-        maskBits = luminanceBits;
-        maskShift = luminanceShift;
-    }
-    RI_ASSERT(getShape() == shape);
-}
-
-RI_INLINE void Color::Descriptor::setNonlinear(bool nonlinear)
-{
-    if (nonlinear)
-        internalFormat = (InternalFormat)(((RIuint32)internalFormat)|NONLINEAR);
-    else
-        internalFormat = (InternalFormat)(((RIuint32)internalFormat)&(~NONLINEAR));
-}
-
-/**
- * \brief	Creates a pixel format descriptor out of VGImageFormat
- * \todo    The formats without alpha were non-premultiplied in the reference
- *          implementation, but wouldn't it make more sense to consider them
- *          premultiplied? This would make sense at least when blitting to
- *          windows, etc., where the output color should have the alpha
- *          multiplied "in".
- */
-RI_INLINE Color::Descriptor Color::formatToDescriptorConst(VGImageFormat format)
-{
-    switch(format)
-    {
-    case VG_sRGBX_8888:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 0, 0, 0, 0, Color::sRGBA, 32, SHAPE_RGBX);
-    case VG_sRGBA_8888:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 8, 0, 0, 0, Color::sRGBA, 32, SHAPE_RGBA);
-    case VG_sRGBA_8888_PRE:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 8, 0, 0, 0, Color::sRGBA_PRE, 32, SHAPE_RGBA);
-    case VG_sRGB_565:
-        return Color::Descriptor(5, 11, 6, 5, 5, 0, 0, 0, 0, 0, Color::sRGBA, 16, SHAPE_RGB);
-    case VG_sRGBA_5551:
-        return Color::Descriptor(5, 11, 5, 6, 5, 1, 1, 0, 0, 0, Color::sRGBA, 16, SHAPE_RGBA);
-    case VG_sRGBA_4444:
-        return Color::Descriptor(4, 12, 4, 8, 4, 4, 4, 0, 0, 0, Color::sRGBA, 16, SHAPE_RGBA);
-    case VG_sL_8:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 0, 0, 8, 0, Color::sLA, 8, SHAPE_L);
-    case VG_lRGBX_8888:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 0, 0, 0, 0, Color::lRGBA, 32, SHAPE_RGBX);
-    case VG_lRGBA_8888:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 8, 0, 0, 0, Color::lRGBA, 32, SHAPE_RGBA);
-    case VG_lRGBA_8888_PRE:
-        return Color::Descriptor(8, 24, 8, 16, 8, 8, 8, 0, 0, 0, Color::lRGBA_PRE, 32, SHAPE_RGBA);
-    case VG_lL_8:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 0, 0, 8, 0, Color::lLA, 8, SHAPE_L);
-    case VG_A_8:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 8, 0, 0, 0, Color::lRGBA, 8, SHAPE_A);
-    case VG_BW_1:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, Color::lLA, 1, SHAPE_L);
-    case VG_A_1:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, Color::lRGBA, 1, SHAPE_A);
-    case VG_A_4:
-        return Color::Descriptor(0, 0, 0, 0, 0, 0, 4, 0, 0, 0, Color::lRGBA, 4, SHAPE_A);
-
-  /* {A,X}RGB channel ordering */
-    case VG_sXRGB_8888:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 0, 0, 0, 0, Color::sRGBA, 32, SHAPE_XRGB);
-    case VG_sARGB_8888:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 8, 24, 0, 0, Color::sRGBA, 32, SHAPE_ARGB);
-    case VG_sARGB_8888_PRE:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 8, 24, 0, 0, Color::sRGBA_PRE, 32, SHAPE_ARGB);
-    case VG_sARGB_1555:
-        return Color::Descriptor(5, 10, 5, 5, 5, 0, 1, 15, 0, 0, Color::sRGBA, 16, SHAPE_ARGB);
-    case VG_sARGB_4444:
-        return Color::Descriptor(4, 8, 4, 4, 4, 0, 4, 12, 0, 0, Color::sRGBA, 16, SHAPE_ARGB);
-    case VG_lXRGB_8888:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 0, 0, 0, 0, Color::lRGBA, 32, SHAPE_XRGB);
-    case VG_lARGB_8888:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 8, 24, 0, 0, Color::lRGBA, 32, SHAPE_ARGB);
-    case VG_lARGB_8888_PRE:
-        return Color::Descriptor(8, 16, 8, 8, 8, 0, 8, 24, 0, 0, Color::lRGBA_PRE, 32, SHAPE_ARGB);
-
-  /* BGR{A,X} channel ordering */
-    case VG_sBGRX_8888:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 0, 0, 0, 0, Color::sRGBA, 32, SHAPE_BGRX);
-    case VG_sBGRA_8888:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 8, 0, 0, 0, Color::sRGBA, 32, SHAPE_BGRA);
-    case VG_sBGRA_8888_PRE:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 8, 0, 0, 0, Color::sRGBA_PRE, 32, SHAPE_BGRA);
-    case VG_sBGR_565:
-        return Color::Descriptor(5, 0, 6, 5, 5, 11, 0, 0, 0, 0, Color::sRGBA, 16, SHAPE_BGR);
-    case VG_sBGRA_5551:
-        return Color::Descriptor(5, 1, 5, 6, 5, 11, 1, 0, 0, 0, Color::sRGBA, 16, SHAPE_BGRA);
-    case VG_sBGRA_4444:
-        return Color::Descriptor(4, 4, 4, 8, 4, 12, 4, 0, 0, 0, Color::sRGBA, 16, SHAPE_BGRA);
-    case VG_lBGRX_8888:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 0, 0, 0, 0, Color::lRGBA, 32, SHAPE_BGRX);
-    case VG_lBGRA_8888:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 8, 0, 0, 0, Color::lRGBA, 32, SHAPE_BGRA);
-    case VG_lBGRA_8888_PRE:
-        return Color::Descriptor(8, 8, 8, 16, 8, 24, 8, 0, 0, 0, Color::lRGBA_PRE, 32, SHAPE_BGRA);
-
-  /* {A,X}BGR channel ordering */
-    case VG_sXBGR_8888:
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 0, 0, 0, 0, Color::sRGBA, 32, SHAPE_XBGR);
-    case VG_sABGR_8888:
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 8, 24, 0, 0, Color::sRGBA, 32, SHAPE_ABGR);
-    case VG_sABGR_8888_PRE:
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 8, 24, 0, 0, Color::sRGBA_PRE, 32, SHAPE_ABGR);
-    case VG_sABGR_1555:
-        return Color::Descriptor(5, 0, 5, 5, 5, 10, 1, 15, 0, 0, Color::sRGBA, 16, SHAPE_ABGR);
-    case VG_sABGR_4444:
-        return Color::Descriptor(4, 0, 4, 4, 4, 8, 4, 12, 0, 0, Color::sRGBA, 16, SHAPE_ABGR);
-    case VG_lXBGR_8888:
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 0, 0, 0, 0, Color::lRGBA, 32, SHAPE_XBGR);
-    case VG_lABGR_8888:
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 8, 24, 0, 0, Color::lRGBA, 32, SHAPE_ABGR);
-    default:
-    //case VG_lABGR_8888_PRE:
-        RI_ASSERT(format == VG_lABGR_8888_PRE);
-        return Color::Descriptor(8, 0, 8, 8, 8, 16, 8, 24, 0, 0, Color::lRGBA_PRE, 32, SHAPE_ABGR);
-    }
-}
-
-RI_INLINE bool 	Color::Descriptor::operator==(const Descriptor& rhs) const
-{
-    return memcmp(this, &rhs, sizeof(Descriptor)) ? false : true;
-}
-
-RI_INLINE bool Color::Descriptor::isZeroConversion(const Descriptor& rhs) const
-{
-    return (shape == rhs.shape) &&
-        (internalFormat == rhs.internalFormat) &&
-        (redBits == rhs.redBits) &&
-        (greenBits == rhs.greenBits) &&
-        (blueBits == rhs.blueBits) &&
-        (alphaBits == rhs.alphaBits) &&
-        (luminanceBits == rhs.luminanceBits);
-}
-
-RI_INLINE bool Color::Descriptor::isShiftConversion(const Descriptor& rhs) const
-{
-    // \note BW conversion is always forced to full at the moment.
-    if (isBW() != rhs.isBW()) 
-        return false;
-
-    return (isPremultiplied() == rhs.isPremultiplied())
-            && (isNonlinear() == rhs.isNonlinear())
-            && (isLuminance() == rhs.isLuminance());
-}
-
-RI_INLINE bool Color::Descriptor::isShiftConversionToLower(const Descriptor& rhs) const
-{
-    // \note BW conversion is always forced to full at the moment.
-    if (isBW() != rhs.isBW()) 
-        return false;
-    // \note Mask bits are not checked because they are derived information.
-    return (isShiftConversion(rhs)
-            && (rhs.redBits <= redBits)
-            && (rhs.greenBits <= greenBits)
-            && (rhs.blueBits <= blueBits)
-            && (rhs.alphaBits <= alphaBits)
-            && (rhs.luminanceBits <= luminanceBits));
-
-}
-
-/**
- * \brief   In-place conversion of packed color to lower bit-depth
- * \param   c   Input packed color
- * \param   src Source color descriptor
- * \param   dst Destination color descriptor
- */
-RI_INLINE RIuint32  Color::Descriptor::crossConvertToLower(RIuint32 c, const Descriptor& src, const Descriptor& dst)
-{
-    RIuint32 r = 0;
-
-    RI_ASSERT(dst.redBits <= src.redBits);
-    RI_ASSERT(dst.greenBits <= src.greenBits);
-    RI_ASSERT(dst.blueBits <= src.blueBits);
-    RI_ASSERT(dst.alphaBits <= src.alphaBits);
-
-    if (src.isLuminance())
-    {
-        RI_ASSERT(dst.isLuminance());
-        r = ((c >> (src.luminanceShift + src.luminanceBits - dst.luminanceBits)) & ((1u<<dst.luminanceBits)-1)) << dst.luminanceShift;
-    } else
-    {
-        r = ((c >> (src.redShift + src.redBits - dst.redBits)) & ((1u<<dst.redBits)-1)) << dst.redShift;
-        r |= ((c >> (src.greenShift + src.greenBits - dst.greenBits)) & ((1u<<dst.greenBits)-1)) << dst.greenShift;
-        r |= ((c >> (src.blueShift + src.blueBits - dst.blueBits)) & ((1u<<dst.blueBits)-1)) << dst.blueShift;
-    }
-
-    if (src.hasAlpha())
-    {
-        if (dst.hasAlpha())
-            r |= ((c >> (src.alphaShift + src.alphaBits - dst.alphaBits)) & ((1u<<dst.alphaBits)-1)) << dst.alphaShift;
-        else
-        {
-            // Make sure that the alpha is applied to the color if doing only a shift conversion.
-            RI_ASSERT(src.isPremultiplied() == dst.isPremultiplied());
-        }
-    }
-
-    return r;
-}
-
-RI_INLINE RIuint32 Color::Descriptor::toIndex() const
-{
-    SmallDescriptor smallDesc;
-    toSmallDescriptor(smallDesc);
-    return smallDesc.toUint32();
-}
-
-RI_INLINE Color operator*(const Color& c, RIfloat f)			{ return Color(c.r*f, c.g*f, c.b*f, c.a*f, c.getInternalFormat()); }
-RI_INLINE Color operator*(RIfloat f, const Color& c)			{ return Color(c.r*f, c.g*f, c.b*f, c.a*f, c.getInternalFormat()); }
-RI_INLINE Color operator+(const Color& c0, const Color& c1)		{ RI_ASSERT(c0.getInternalFormat() == c1.getInternalFormat()); return Color(c0.r+c1.r, c0.g+c1.g, c0.b+c1.b, c0.a+c1.a, c0.getInternalFormat()); }
-RI_INLINE Color operator-(const Color& c0, const Color& c1)		{ RI_ASSERT(c0.getInternalFormat() == c1.getInternalFormat()); return Color(c0.r-c1.r, c0.g-c1.g, c0.b-c1.b, c0.a-c1.a, c0.getInternalFormat()); }
-RI_INLINE void  Color::assertConsistency() const
-{
-    RI_ASSERT(r >= 0.0f && r <= 1.0f);
-    RI_ASSERT(g >= 0.0f && g <= 1.0f);
-    RI_ASSERT(b >= 0.0f && b <= 1.0f);
-    RI_ASSERT(a >= 0.0f && a <= 1.0f);
-    RI_ASSERT(!isPremultiplied() || (r <= a && g <= a && b <= a));	//premultiplied colors must have color channels less than or equal to alpha
-    RI_ASSERT((isLuminance() && r == g && r == b) || !isLuminance());	//if luminance, r=g=b
-}
-
-class IntegerColor
-{
-public:
-
-    IntegerColor() {r = g = b = a = 0;}
-    IntegerColor(const Color& color);
-
-    RI_INLINE           IntegerColor(RIuint32 packedColor, const Color::Descriptor& desc) { fromPackedColor(packedColor, desc); }
-    RI_INLINE           IntegerColor(RIuint32 cr, RIuint32 cg, RIuint32 cb, RIuint32 ca) { r = cr; g = cg; b = cb; a = ca; }
-    RI_INLINE void      asFixedPoint(const Color& color);
-    RI_INLINE void      fromPackedColor(RIuint32 packedColor, const Color::Descriptor& desc);
-    RI_INLINE void      expandColor(const Color::Descriptor& desc);
-    RI_INLINE void      truncateColor(const Color::Descriptor& desc);
-    RI_INLINE void      clampToAlpha();
-    RI_INLINE RIuint32  getPackedColor(const Color::Descriptor& desc) const;
-    RI_INLINE RIuint32  getPackedMaskColor(const Color::Descriptor& desc) const;
-    RI_INLINE void      premultiply(bool luminance = false);
-    RI_INLINE void      unpremultiply(bool luminance = false);
-    //RI_INLINE void      linearToGamma(bool luminance, bool premultipliedIn, bool premultipliedOut);
-    RI_INLINE void      linearToGamma(bool luminance = false);
-    RI_INLINE void      gammaToLinear(bool luminance = false);
-    RI_INLINE void      fromPackedMask(RIuint32 packedColor, const Color::Descriptor& desc);
-    RI_INLINE void      expandMask(const Color::Descriptor& desc);
-    RI_INLINE void      truncateMask(const Color::Descriptor& desc);
-    RI_INLINE void      fullLuminanceToRGB(bool premultipliedIn, bool gammaIn, bool premultipliedOut, bool gammaOut);
-    RI_INLINE void      fullRGBToLuminance(bool premultipliedIn, bool gammaIn, bool premultipliedOut, bool gammaOut);
-    RI_INLINE void      luminanceToRGB();
-    RI_INLINE void      rgbToLuminance();
-    RI_INLINE void      convertToFrom(const Color::Descriptor& dst, const Color::Descriptor& src, bool srcIsMask);
-
-    RI_INLINE static IntegerColor linearBlendNS(const IntegerColor& c0, const IntegerColor& c1, int k);
-
-    RIuint32 r;
-    RIuint32 g;
-    RIuint32 b;
-    RIuint32 a;
-
-};
-
-/**
- * \brief   Blend two colors linearly. The output will not be scaled into original range.
- * \param   k   Blend coefficient. Must be [0..255] for correct results.
- * \todo    Parameterize against bits in k? To perform well, that setup must be compiled rt.
- */
-RI_INLINE IntegerColor IntegerColor::linearBlendNS(const IntegerColor& c0, const IntegerColor& c1, int k)
-{
-    RI_ASSERT(k >= 0 && k <= 255);
-    IntegerColor ret;
-    RIuint32 ik = 255 - k;
-
-    ret.r = ik * c0.r + k * c1.r;
-    ret.g = ik * c0.g + k * c1.g;
-    ret.b = ik * c0.b + k * c1.b;
-    ret.a = ik * c0.a + k * c1.a;
-
-    return ret;
-}
-
-/**
- *	\note 	Assumes that each individual component is in proper range (usually indicated by the
- *			corresponding shift).
- */
-RI_INLINE RIuint32 packRGBAInteger(RIuint32 cr, int rs, RIuint32 cg, int gs, RIuint32 cb, int bs, RIuint32 ca, int as)
-{
-    return (cr << rs) | (cg << gs) | (cb << bs) | (ca << as);
-}
-
-/**
- * \brief   Packs a color into RIuint32.
- * \note    The color must have been truncated to contain correct amount of bits per channel
- * \note    This function is efficient only if runtime compilation is used.
- */
-RI_INLINE RIuint32 IntegerColor::getPackedColor(const Color::Descriptor& desc) const
-{
-    RIuint32 res = 0;
-    if (desc.luminanceBits)
-    {
-        RI_ASSERT(desc.redBits == 0 && desc.greenBits == 0 && desc.blueBits == 0);
-        RI_ASSERT(r < (1u<<desc.luminanceBits));
-        res = r << desc.luminanceShift;
-    }
-    else if (desc.redBits)
-    {
-        RI_ASSERT(r < (1u<<desc.redBits));
-        res = r << desc.redShift;
-        if (desc.greenBits)
-        {
-            RI_ASSERT(desc.blueBits);
-            RI_ASSERT(g < (1u<<desc.greenBits));
-            RI_ASSERT(b < (1u<<desc.blueBits));
-            res |= g << desc.greenShift;
-            res |= b << desc.blueShift;
-        }
-    }
-
-    if (desc.alphaBits)
-    {
-        RI_ASSERT(a < (1u<<desc.alphaBits));
-        res |= a << desc.alphaShift;
-    }
-
-    return res;
-}
-
-RI_INLINE RIuint32 IntegerColor::getPackedMaskColor(const Color::Descriptor& desc) const
-{
-    if (desc.alphaBits)
-        return packRGBAInteger(0, desc.redShift, 0, desc.greenShift, 0, desc.blueShift, a, desc.alphaShift);
-    else if(desc.redBits)
-        return packRGBAInteger(a, desc.redShift, 0, desc.greenShift, 0, desc.blueShift, 0, desc.alphaShift);
-    else
-    {
-        RI_ASSERT(desc.luminanceBits);
-        return packRGBAInteger(a, desc.luminanceBits, 0, desc.greenShift, 0, desc.blueShift, 0, desc.alphaShift);
-    }
-
-}
-
-RI_INLINE void IntegerColor::premultiply(bool luminance)
-{
-    // \todo Check the round!!!
-    RIuint32 fxa = a + (a>>7);
-    r = (r * fxa); r = (r + (1<<7))>>8;
-
-    if (!luminance)
-    {
-        g = (g * fxa); g = (g + (1<<7))>>8;
-        b = (b * fxa); b = (b + (1<<7))>>8;
-    }
-}
-
-RI_INLINE void IntegerColor::unpremultiply(bool luminance)
-{
-    RI_ASSERT(a <= 255);
-
-    RIuint32 rcp = sc_alphaRcp[a];
-    r = (r * rcp) >> 8;
-
-    if (!luminance)
-    {
-        g = (g * rcp) >> 8;
-        b = (b * rcp) >> 8;
-    }
-}
-
-RI_INLINE void IntegerColor::linearToGamma(bool luminance)
-{
-    RI_ASSERT(r <= 255 && g <= 255 && b <= 255 && a <= 255);
-
-    r = sc_lRGB_to_sRGB[r];
-
-    if (!luminance)
-    {
-        g = sc_lRGB_to_sRGB[g];
-        b = sc_lRGB_to_sRGB[b];
-    }
-
-    // \note Alpha is _not_ converted and it must be considered linear always
-}
-
-RI_INLINE void IntegerColor::gammaToLinear(bool luminance)
-{
-    RI_ASSERT(r <= 255 && g <= 255 && b <= 255 && a <= 255);
-
-    r = sc_sRGB_to_lRGB[r];
-    if (!luminance)
-    {
-        g = sc_sRGB_to_lRGB[g];
-        b = sc_sRGB_to_lRGB[b];
-    }
-
-    // \note Alpha is _not_ converted and it must be considered linear always
-}
-
-RI_INLINE void IntegerColor::asFixedPoint(const Color& color)
-{
-    r = (RIuint32)(color.r * 256.0f + 0.5f);
-    g = (RIuint32)(color.g * 256.0f + 0.5f);
-    b = (RIuint32)(color.b * 256.0f + 0.5f);
-    a = (RIuint32)(color.a * 256.0f + 0.5f);
-}
-
-RI_INLINE void IntegerColor::fromPackedColor(RIuint32 packedColor, const Color::Descriptor& desc)
-{
-    /* \note Expand MUST be done separately! */
-
-    if (desc.luminanceBits)
-    {
-        r = (packedColor >> desc.luminanceShift) & ((1u << desc.luminanceBits)-1);
-        g = b = r;
-    }
-    else
-    {
-        r = (packedColor >> desc.redShift) & ((1u << desc.redBits)-1);
-        g = (packedColor >> desc.greenShift) & ((1u << desc.greenBits)-1);
-        b = (packedColor >> desc.blueShift) & ((1u << desc.blueBits)-1);
-    }
-
-    if (desc.alphaBits)
-        a = (packedColor >> desc.alphaShift) & ((1u << desc.alphaBits)-1);
-    else
-        a = 255;
-}
-
-/**
- * \brief   Expand color to larger (or same) bit depth as in the OpenVG specification.
- * \todo    1 and 2 bpp!
- */
-RI_INLINE RIuint32 expandComponent(RIuint32 c, RIuint32 srcBits)
-{
-    const RIuint32 destBits = 8;
-    RI_ASSERT(destBits >= srcBits);
-
-    if (!srcBits) return 0;
-
-    if (srcBits == destBits) return c;
-
-    switch (srcBits)
-    {
-    case 6:
-        return (c << 2) | (c >> 4);
-    case 5:
-        return (c << 3) | (c >> 2);
-    case 4:
-        return (c << 4) | c;
-    case 2:
-        return c | (c << 2) | (c << 4) | (c << 6);
-    default:
-        RI_ASSERT(srcBits == 1);
-        if (c) return 0xff;
-        return 0;
-    }
-}
-
-/**
- * \brief   Expands integer color representation to internal format (8-bits per component atm.).
- * \todo    Do nothing when bits == 8.
- */
-RI_INLINE void IntegerColor::expandColor(const Color::Descriptor& desc)
-{
-    if (desc.luminanceBits)
-    {
-        r = expandComponent(r, desc.luminanceBits);
-        g = b = r;
-        a = 255;
-    } else
-    {
-        if (desc.redBits < 8 || desc.luminanceBits < 8)
-            r = expandComponent(r, desc.redBits);
-        if (desc.greenBits < 8)
-            g = expandComponent(g, desc.greenBits);
-        if (desc.blueBits < 8)
-            b = expandComponent(b, desc.blueBits);
-    }
-
-    if (desc.alphaBits && desc.alphaBits < 8)
-        a = expandComponent(a, desc.alphaBits);
-
-    if (desc.isAlphaOnly())
-    {
-        if (!desc.isPremultiplied())
-            r = g = b = 255;
-        else
-            r = g = b = a;
-    }
-}
-
-/**
- * \brief   Convert IntegerColor components to destination bitdepth (from internal) by
- *          shifting. Rounding does not take place.
- */
-RI_INLINE void IntegerColor::truncateColor(const Color::Descriptor& desc)
-{
-    if (desc.luminanceBits)
-    {
-        RI_ASSERT(desc.redBits == 0 && desc.greenBits == 0 && desc.blueBits == 0);
-        if (desc.luminanceBits == 1)
-        {
-            // Round the 1-bit case a bit better?
-            r = (r + 128)>>8;
-        } else if (desc.luminanceBits < 8)
-            r >>= (8 - desc.luminanceBits);
-    }
-    else
-    {
-        if (desc.redBits < 8)
-            r >>= (8 - desc.redBits);
-        if (desc.greenBits < 8)
-            g >>= (8 - desc.greenBits);
-        if (desc.blueBits < 8)
-            b >>= (8 - desc.blueBits);
-    }
-
-    if (desc.alphaBits < 8)
-    {
-        if (desc.alphaBits == 1)
-            a = (a+128)>>8;
-        else
-            a >>= (8 - desc.alphaBits);
-    }
-}
-
-RI_INLINE void IntegerColor::truncateMask(const Color::Descriptor& desc)
-{
-    if (desc.redBits < 8 || desc.luminanceBits < 8)
-        r >>= (8 - desc.maskBits);
-    if (desc.greenBits < 8)
-        g >>= (8 - desc.maskBits);
-    if (desc.blueBits < 8)
-        b >>= (8 - desc.maskBits);
-    if (desc.alphaBits < 8)
-        a >>= (8 - desc.maskBits);
-}
-
-RI_INLINE void IntegerColor::clampToAlpha()
-{
-    if (r > a) r = a;
-    if (g > a) g = a;
-    if (b > a) b = a;
-}
-
-RI_INLINE void IntegerColor::fromPackedMask(RIuint32 packedMask, const Color::Descriptor& desc)
-{
-    RI_ASSERT(desc.maskBits);
-    a = (packedMask >> desc.maskShift) & ((1u << desc.maskBits)-1);
-}
-
-RI_INLINE void IntegerColor::expandMask(const Color::Descriptor& desc)
-{
-    a = expandComponent(a, desc.maskBits);
-    r = g = b = a;
-}
-
-#if 0
-RI_INLINE void IntegerColor::truncateMask(const Color::Descriptor& desc)
-{
-    a >>= (8 - desc.maskBits);
-}
-#endif
-
-RI_INLINE void IntegerColor::fullLuminanceToRGB(bool premultipliedIn, bool gammaIn, bool premultipliedOut, bool gammaOut)
-{
-    if (premultipliedIn)
-        unpremultiply();
-
-    luminanceToRGB();
-
-    if (gammaIn != gammaOut)
-    {
-        if (gammaIn)
-            gammaToLinear();
-        else
-            linearToGamma();
-    }
-
-    if (premultipliedOut)
-        premultiply();
-
-}
-
-RI_INLINE void IntegerColor::fullRGBToLuminance(bool premultipliedIn, bool gammaIn, bool premultipliedOut, bool gammaOut)
-{
-    if (premultipliedIn)
-        unpremultiply();
-
-    if (gammaIn)
-        gammaToLinear();
-
-    rgbToLuminance();
-
-    if (gammaOut)
-        linearToGamma();
-
-    if (premultipliedOut)
-        premultiply();
-
-}
-
-
-// \todo This should not be needed (only r-channel is used anyway)
-RI_INLINE void IntegerColor::luminanceToRGB()
-{
-    g = b = r;
-}
-
-// \todo Only write to R!
-RI_INLINE void IntegerColor::rgbToLuminance()
-{
-    enum { Rx = 871, Gx = 2929, Bx = 296, Bits = 12 };
-    //enum { Rx = 54, Gx = 183, Bx = 18, Bits = 8 };
-    RIuint32 l = Rx * r + Gx * g + Bx * b;
-    r = g = b = l >> Bits;
-}
-
-#if 0
-RI_INLINE void IntegerColor::convertFromInternal(const Color::Descriptor& dst)
-{
-}
-#endif
-
-/**
- * \brief   Convert color from one format to another using integer operations.
- * \note    Currently expands the color to intermediate format first (8 bits
- *          per component.
- */
-RI_INLINE void IntegerColor::convertToFrom(const Color::Descriptor& dst, const Color::Descriptor& src, bool srcIsMask)
-{
-    if (src.isZeroConversion(dst))
-        return;
-
-    if (src.isShiftConversionToLower(dst))
-    {
-        if (dst.luminanceBits)
-        {
-            if (dst.luminanceBits == 1)
-            {
-                RI_ASSERT(src.luminanceBits == 8);
-                r = (r + 128)>>8;
-            }
-            else
-                r = r >> (src.luminanceBits - dst.luminanceBits);
-        } else
-        {
-            r = r >> (src.redBits - dst.redBits);
-            g = g >> (src.greenBits - dst.greenBits);
-            b = b >> (src.blueBits - dst.blueBits);
-        }
-        if (dst.alphaBits)
-        {
-                //a = (a+128)>>8;
-            if (dst.alphaBits == 1)
-                a = (a+(1<<(src.alphaBits-1)))>>src.alphaBits;
-            else
-                a = a >> (src.alphaBits - dst.alphaBits);
-        }
-
-        return;
-    }
-
-    if (!srcIsMask)
-        expandColor(src);
-    else
-        expandMask(src);
-
-
-    if (dst.isLuminance() != src.isLuminance())
-    {
-        if (src.isLuminance())
-            fullLuminanceToRGB(src.isPremultiplied(), src.isNonlinear(), dst.isPremultiplied(), dst.isNonlinear());
-        else
-            fullRGBToLuminance(src.isPremultiplied(), src.isNonlinear(), dst.isPremultiplied(), dst.isNonlinear());
-    }
-    else if (dst.isNonlinear() != src.isNonlinear())
-    {
-        // No luminance/rgb change.
-        // Change of gamma requires unpremultiplication:
-        if (src.isPremultiplied() && !(src.isAlphaOnly()))
-            unpremultiply();
-
-        if (src.isNonlinear())
-            gammaToLinear(src.isLuminance());
-        else
-            linearToGamma(src.isLuminance());
-
-        if (dst.isPremultiplied() && !(dst.isAlphaOnly()))
-            premultiply();
-    }
-    else
-    if ((dst.isPremultiplied() != src.isPremultiplied()) && !(dst.isAlphaOnly() || dst.isAlphaOnly()))
-    {
-        // \todo Make sure non-alpha formats are properly handled.
-        if (src.isPremultiplied())
-            unpremultiply(dst.isLuminance());
-        else
-            premultiply(dst.isLuminance());
-    }
-
-    truncateColor(dst);
-}
-
-//==============================================================================================
-
-/*-------------------------------------------------------------------*//*!
-* \brief	Storage and operations for VGImage.
-* \param
-* \return
-* \note
-*//*-------------------------------------------------------------------*/
-
-class Surface;
-class Image
-{
-public:
-    Image(const Color::Descriptor& desc, int width, int height, VGbitfield allowedQuality);	//throws bad_alloc
-    //use data from a memory buffer. NOTE: data is not copied, so it is user's responsibility to make sure the data remains valid while the Image is in use.
-    Image(const Color::Descriptor& desc, int width, int height, int stride, RIuint8* data);	//throws bad_alloc
-    //child image constructor
-    Image(Image* parent, int x, int y, int width, int height);	//throws bad_alloc
-    ~Image();
-
-    const Color::Descriptor&	getDescriptor() const		{ return m_desc; }
-    int					getWidth() const					{ return m_width; }
-    int					getHeight() const					{ return m_height; }
-    int					getStride() const					{ return m_stride; }
-    Image*				getParent() const					{ return m_parent; }
-    VGbitfield			getAllowedQuality() const			{ return m_allowedQuality; }
-    void				addInUse()							{ m_inUse++; }
-    void				removeInUse()						{ RI_ASSERT(m_inUse > 0); m_inUse--; }
-    int					isInUse() const						{ return m_inUse; }
-    RIuint8*			getData() const						{ return m_data; }
-    void				addReference()						{ m_referenceCount++; }
-    int					removeReference()					{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
-    bool				overlaps(const Image* src) const;
-    void                setUnsafe(bool unsafe) { if (unsafe && m_desc.maybeUnsafe()) m_unsafeData = unsafe; else m_unsafeData = false; }
-    bool                isUnsafe() const { return m_unsafeData; }
-
-    void				clear(const Color& clearColor, int x, int y, int w, int h);
-    void				blit(VGContext* context, const Image* src, int sx, int sy, int dx, int dy, int w, int h, Array<Rectangle>* scissors = NULL, bool dither = false);	//throws bad_alloc
-
-    RI_INLINE static const void* incrementPointer(const void* ptr, int bpp, RIint32 x);
-    RI_INLINE static void* calculateAddress(const void* basePtr, int bpp, int x, int y, int stride);
-
-    static RI_INLINE RIuint32   readPackedPixelFromAddress(const void *ptr, int bpp, int x);
-    static RI_INLINE void       writePackedPixelToAddress(void* ptr, int bpp, int x, RIuint32 packedColor);
-
-    RI_INLINE RIuint32 			readPackedPixel(int x, int y) const;
-    Color				readPixel(int x, int y) const;
-    RI_INLINE void      writePackedPixelToAddress(void* ptr, int x, RIuint32 packedColor);
-    void				writePackedPixel(int x, int y, RIuint32 packedColor);
-    void				writePixel(int x, int y, const Color& c);
-
-    void                fillPacked(RIuint32 packedColor);
-
-    static RI_INLINE void   fillPackedPixels(void* data, int bpp, int x, int y, int stride, int nPixels, RIuint32 packedColor);
-    RI_INLINE void		    fillPackedPixels(int x, int y, int nPixels, RIuint32 packedColor);
-    RI_INLINE void          fillPackedRectangle(int x0, int y0, int width, int height, RIuint32 packedColor);
-
-    void				writeFilteredPixel(int x, int y, const Color& c, VGbitfield channelMask);
-
-    RIfloat				readMaskPixel(int x, int y) const;		//can read any image format
-    void				writeMaskPixel(int x, int y, RIfloat m);	//can write only to VG_A_x
-
-    Color				resample(RIfloat x, RIfloat y, const Matrix3x3& surfaceToImage, VGImageQuality quality, VGTilingMode tilingMode, const Color& tileFillColor);	//throws bad_alloc
-    void				makeMipMaps();	//throws bad_alloc
-
-    void				colorMatrix(const Image& src, const RIfloat* matrix, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-    void				convolve(const Image& src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernel, RIfloat scale, RIfloat bias, VGTilingMode tilingMode, const Color& edgeFillColor, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-    void				separableConvolve(const Image& src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernelX, const RIint16* kernelY, RIfloat scale, RIfloat bias, VGTilingMode tilingMode, const Color& edgeFillColor, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-    void				gaussianBlur(const Image& src, RIfloat stdDeviationX, RIfloat stdDeviationY, VGTilingMode tilingMode, const Color& edgeFillColor, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-    void				lookup(const Image& src, const RIuint8 * redLUT, const RIuint8 * greenLUT, const RIuint8 * blueLUT, const RIuint8 * alphaLUT, bool outputLinear, bool outputPremultiplied, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-    void				lookupSingle(const Image& src, const RIuint32 * lookupTable, VGImageChannel sourceChannel, bool outputLinear, bool outputPremultiplied, bool filterFormatLinear, bool filterFormatPremultiplied, VGbitfield channelMask);
-
-    RI_INLINE static int descriptorToStride(const Color::Descriptor& desc, int width) { return (width*desc.bitsPerPixel+7)/8; };
-
-    void getStorageOffset(int& x, int& y) const { x = m_storageOffsetX; y = m_storageOffsetY; }
-
-private:
-    Image(const Image&);					//!< Not allowed.
-    void operator=(const Image&);			//!< Not allowed.
-
-#if defined(RI_DEBUG)
-    bool                ptrInImage(const void* ptr) const;
-#endif
-    Color				readTexel(int u, int v, int level, VGTilingMode tilingMode, const Color& tileFillColor) const;
-
-    Color::Descriptor	m_desc;
-    int					m_width;
-    int					m_height;
-    VGbitfield			m_allowedQuality;
-    int					m_inUse;
-    int					m_stride;
-    RIuint8*			m_data;
-    int					m_referenceCount;
-    bool				m_ownsData;
-    Image*				m_parent;
-    int					m_storageOffsetX;
-    int					m_storageOffsetY;
-    bool                m_unsafeData; // Data may contain incorrect pixel data
-
-#ifndef RI_COMPILE_LLVM_BYTECODE
-
-#endif /* RI_COMPILE_LLVM_BYTECODE */
-};
-
-#if defined(RI_DEBUG)
-RI_INLINE bool Image::ptrInImage(const void* ptr) const
-{
-    RIuint8* p = (RIuint8*)ptr;
-
-    if (p < m_data) return false;
-    if (p >= (m_data + m_height * m_stride)) return false;
-    return true;
-}
-#endif
-
-RI_INLINE const void* Image::incrementPointer(const void* ptr, int bpp, int x)
-{
-    if (bpp >= 8)
-        return (((RIuint8*)ptr) + (bpp >> 3));
-    // Increment the pointer only when the byte is actually about to change.
-    int mask;
-    if (bpp == 4)
-        mask = 1;
-    else if (bpp == 2)
-        mask = 3;
-    else
-        mask = 7;
-    if ((x & mask) == mask)
-        return ((RIuint8*)ptr + 1);
-    return ptr;
-}
-
-RI_INLINE void* Image::calculateAddress(const void* basePtr, int bpp, int x, int y, int stride)
-{
-    if (bpp >= 8)
-    {
-        return (void*)((RIuint8*)basePtr + y * stride + x * (bpp >> 3));
-    } else
-    {
-        // 4, 2, or 1 bits per pixel
-        RI_ASSERT(bpp == 4 || bpp == 2 || bpp == 1);
-        return (void*)((RIuint8*)basePtr + y * stride + ((x * bpp) >> 3));
-    }
-}
-
-RI_INLINE RIuint32 Image::readPackedPixel(int x, int y) const
-{
-    RI_ASSERT(m_data);
-    RI_ASSERT(x >= 0 && x < m_width);
-    RI_ASSERT(y >= 0 && y < m_height);
-    RI_ASSERT(m_referenceCount > 0);
-
-    RIuint32 p = 0;
-
-    void* ptr = Image::calculateAddress(m_data, m_desc.bitsPerPixel, x+m_storageOffsetX, y+m_storageOffsetY, m_stride);
-    p = readPackedPixelFromAddress(ptr, m_desc.bitsPerPixel, x+m_storageOffsetX);
-
-    return p;
-}
-
-
-RI_INLINE void Image::writePackedPixelToAddress(void* ptr, int bpp, int x, RIuint32 packedColor)
-{
-    // \note packedColor must contain the whole data (including < 8 bpp data)?
-    switch(bpp)
-    {
-    case 32:
-    {
-        RIuint32* s = ((RIuint32*)ptr);
-        *s = (RIuint32)packedColor;
-        break;
-    }
-
-    case 16:
-    {
-        RIuint16* s = ((RIuint16*)ptr);
-        *s = (RIuint16)packedColor;
-        break;
-    }
-
-    case 8:
-    {
-        RIuint8* s = ((RIuint8*)ptr);
-        *s = (RIuint8)packedColor;
-        break;
-    }
-    case 4:
-    {
-        RIuint8* s = ((RIuint8*)ptr);
-        *s = (RIuint8)((packedColor << ((x&1)<<2)) | ((unsigned int)*s & ~(0xf << ((x&1)<<2))));
-        break;
-    }
-
-    case 2:
-    {
-        RIuint8* s = ((RIuint8*)ptr);
-        *s = (RIuint8)((packedColor << ((x&3)<<1)) | ((unsigned int)*s & ~(0x3 << ((x&3)<<1))));
-        break;
-    }
-
-    default:
-    {
-        RI_ASSERT(bpp == 1);
-        RIuint8* s = ((RIuint8*)ptr);
-        *s = (RIuint8)((packedColor << (x&7)) | ((unsigned int)*s & ~(0x1 << (x&7))));
-        break;
-    }
-    }
-    // m_mipmapsValid = false; // \note Will never do this, must be handled outside this class somehow!
-}
-
-/**
- * \brief   Write packed pixel into address.
- * \param   x   Which x-coordinate (starting from the start of the scanline
- *              pointed to) is addressed? This is only required for formats
- *              that have less than 8 bpp.
- */
-void Image::writePackedPixelToAddress(void* address, int x, RIuint32 packedColor)
-{
-    writePackedPixelToAddress(address, m_desc.bitsPerPixel, x, packedColor);
-}
-
-/**
- * \brief   Read a packed pixel from a given address. Notice the use of param x!
- * \param   x   Check which part of byte to return if bpp < 8
- */
-RI_INLINE RIuint32 Image::readPackedPixelFromAddress(const void *ptr, int bpp, int x)
-{
-    switch(bpp)
-    {
-    case 32:
-    {
-        RIuint32* s = (RIuint32*)ptr;
-        return *s;
-    }
-
-    case 16:
-    {
-        RIuint16* s = (RIuint16*)ptr;
-        return (RIuint32)*s;
-    }
-
-    case 8:
-    {
-        RIuint8* s = (RIuint8*)ptr;
-        return (RIuint32)*s;
-    }
-    case 4:
-    {
-        RIuint8* s = ((RIuint8*)ptr);
-        return (RIuint32)(*s >> ((x&1)<<2)) & 0xf;
-    }
-
-    case 2:
-    {
-        RIuint8* s = ((RIuint8*)ptr);
-        return (RIuint32)(*s >> ((x&3)<<1)) & 0x3;
-    }
-
-    default:
-    {
-        RI_ASSERT(bpp == 1);
-        RIuint8* s = ((RIuint8*)ptr);
-        return (RIuint32)(*s >> (x&7)) & 0x1;
-    }
-    }
-}
-
-RI_INLINE void Image::writePackedPixel(int x, int y, RIuint32 packedColor)
-{
-    RI_ASSERT(m_data);
-    RI_ASSERT(x >= 0 && x < m_width);
-    RI_ASSERT(y >= 0 && y < m_height);
-    RI_ASSERT(m_referenceCount > 0);
-
-    x += m_storageOffsetX;
-    y += m_storageOffsetY;
-
-    RIuint8* scanline = m_data + y * m_stride;
-    switch(m_desc.bitsPerPixel)
-    {
-    case 32:
-    {
-        RIuint32* s = ((RIuint32*)scanline) + x;
-        *s = (RIuint32)packedColor;
-        break;
-    }
-
-    case 16:
-    {
-        RIuint16* s = ((RIuint16*)scanline) + x;
-        *s = (RIuint16)packedColor;
-        break;
-    }
-
-    case 8:
-    {
-        RIuint8* s = ((RIuint8*)scanline) + x;
-        *s = (RIuint8)packedColor;
-        break;
-    }
-    case 4:
-    {
-        RIuint8* s = ((RIuint8*)scanline) + (x>>1);
-        *s = (RIuint8)((packedColor << ((x&1)<<2)) | ((unsigned int)*s & ~(0xf << ((x&1)<<2))));
-        break;
-    }
-
-    case 2:
-    {
-        RIuint8* s = ((RIuint8*)scanline) + (x>>2);
-        *s = (RIuint8)((packedColor << ((x&3)<<1)) | ((unsigned int)*s & ~(0x3 << ((x&3)<<1))));
-        break;
-    }
-
-    default:
-    {
-        RI_ASSERT(m_desc.bitsPerPixel == 1);
-        RIuint8* s = ((RIuint8*)scanline) + (x>>3);
-        *s = (RIuint8)((packedColor << (x&7)) | ((unsigned int)*s & ~(0x1 << (x&7))));
-        break;
-    }
-    }
-    //m_mipmapsValid = false;
-}
-
-
-/**
- * \brief   Unsafe static method for setting image pixels
- */
-RI_INLINE void Image::fillPackedPixels(void* data, int bpp, int x, int y, int stride, int nPixels, RIuint32 packedColor)
-{
-    RI_ASSERT(nPixels > 0);
-    RI_ASSERT(data);
-
-    RIuint8* scanline = (RIuint8*)data + y * stride;
-
-    switch(bpp)
-    {
-    case 32:
-    {
-        RIuint32* s = ((RIuint32*)scanline) + x;
-
-        for (int i = 0; i < nPixels; i++)
-            s[i] = packedColor;
-
-        break;
-    }
-
-    case 16:
-    {
-        RIuint16* s = ((RIuint16*)scanline) + x;
-
-        for (int i = 0; i < nPixels; i++)
-            s[i] = (RIuint16)packedColor;
-
-        break;
-    }
-
-    case 8:
-    {
-        RIuint8* s = ((RIuint8*)scanline) + x;
-
-        for (int i = 0; i < nPixels; i++)
-            s[i] = (RIuint8)packedColor;
-
-        break;
-    }
-    case 4:
-    {
-        //RI_ASSERT((packedColor & 0xf) == 0);
-        //packedColor &= 0xf;
-        RIuint8* s = ((RIuint8*)scanline) + (x>>1);
-        if (x & 1)
-        {
-            *s = (RIuint8)((packedColor << ((x&1)<<2)) | ((unsigned int)*s & ~(0xf << ((x&1)<<2))));
-            s++;
-            x++;
-            nPixels--;
-        }
-        RI_ASSERT(!(x&1));
-
-        int c = nPixels / 2;
-        RIuint8 bytePacked = packedColor | (packedColor << 4);
-        while (c)
-        {
-            *s++ = bytePacked;
-            c--;
-            x+=2;
-        }
-        nPixels &= 1;
-
-        if (nPixels)
-        {
-            *s = (RIuint8)((packedColor << ((x&1)<<2)) | ((unsigned int)*s & ~(0xf << ((x&1)<<2))));
-            s++;
-            x++;
-            nPixels--;
-        }
-        RI_ASSERT(nPixels == 0);
-        break;
-    }
-
-    case 2:
-    {
-        // This case should not be needed!
-        RI_ASSERT(false);
-        RIuint8* s = ((RIuint8*)scanline) + (x>>2);
-        *s = (RIuint8)((packedColor << ((x&3)<<1)) | ((unsigned int)*s & ~(0x3 << ((x&3)<<1))));
-        break;
-    }
-
-    default:
-    {
-        RI_ASSERT(bpp == 1);
-        RIuint8* s = ((RIuint8*)scanline) + (x>>3);
-        // \todo Get this as input instead?
-        RI_ASSERT(packedColor == 1 || packedColor == 0);
-        RIuint8 fullyPacked = (RIuint8)(-(RIint8)packedColor);
-
-        if (x & 7)
-        {
-            // Handle the first byte:
-            RIuint8 o = *s;
-            int a = x&7;
-            RI_ASSERT(a>=1);
-            int b = RI_INT_MIN(a + nPixels, 8);
-            RI_ASSERT(b > a);
-            RIuint8 emask = (1u << b)-1;
-            RIuint8 mask = (0xffu<<a) & emask;
-            RI_ASSERT(mask>0);
-            RI_ASSERT(mask<=254);
-            *s++ = (o&(~mask))|(fullyPacked & mask);
-            nPixels -= 8-(x&7);
-            x += 8-(x&7);
-        }
-
-        if (nPixels < 0)
-            return;
-
-        RI_ASSERT(!(x&1));
-
-        int c = nPixels/8;
-        while (c)
-        {
-            *s++ = fullyPacked;
-            c--;
-            x+=8;
-        }
-        nPixels -= ((nPixels/8) * 8);
-
-
-        if (nPixels)
-        {
-            RI_ASSERT((x&7) == 0);
-
-            RIuint8 o = *s;
-            int b = nPixels;
-            RI_ASSERT(b<=7);
-            RIuint8 mask = (1u<<b)-1;
-            RI_ASSERT(mask <= 127);
-            *s++ = (o&(~mask))|(fullyPacked & mask);
-        }
-        break;
-    }
-    }
-    //m_mipmapsValid = false;
-}
-RI_INLINE void Image::fillPackedPixels(int x, int y, int nPixels, RIuint32 packedColor)
-{
-    fillPackedPixels((void*)m_data, m_desc.bitsPerPixel, x + m_storageOffsetX, y + m_storageOffsetY, m_stride, nPixels, packedColor);
-}
-
-RI_INLINE void Image::fillPackedRectangle(int x0, int y0, int width, int height, RIuint32 packedColor)
-{
-    int y = y0;
-    while (height)
-    {
-        fillPackedPixels(x0, y, width, packedColor);
-        y++;
-        height--;
-    }
-}
-
-/*-------------------------------------------------------------------*//*!
-* \brief	Surface class abstracting multisampled rendering surface.
-* \param
-* \return
-* \note
-*//*-------------------------------------------------------------------*/
-
-class Surface
-{
-public:
-    Surface(const Color::Descriptor& desc, int width, int height, int numSamples);	//throws bad_alloc
-    Surface(Image* image);	//throws bad_alloc
-    Surface(const Color::Descriptor& desc, int width, int height, int stride, RIuint8* data);	//throws bad_alloc
-    ~Surface();
-
-    RI_INLINE const Image* getImage() const {return m_image;}
-    RI_INLINE const Color::Descriptor&	getDescriptor() const		{ return m_image->getDescriptor(); }
-    RI_INLINE int		getWidth() const							{ return m_width; }
-    RI_INLINE int		getHeight() const							{ return m_height; }
-    RI_INLINE int		getNumSamples() const						{ return m_numSamples; }
-    RI_INLINE void		addReference()								{ m_referenceCount++; }
-    RI_INLINE int		removeReference()							{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
-    RI_INLINE int		isInUse() const								{ return m_image->isInUse(); }
-    RI_INLINE bool		isInUse(Image* image) const					{ return image == m_image ? true : false; }
-
-    void				clear(const Color& clearColor, int x, int y, int w, int h, const Array<Rectangle>* scissors = NULL);
-#if 0
-    // Currently does not support msaa surfaces
-    void				blit(const Image& src, int sx, int sy, int dx, int dy, int w, int h);	//throws bad_alloc
-    void				blit(const Image& src, int sx, int sy, int dx, int dy, int w, int h, const Array<Rectangle>& scissors);	//throws bad_alloc
-    void				blit(const Surface* src, int sx, int sy, int dx, int dy, int w, int h);	//throws bad_alloc
-    void				blit(const Surface* src, int sx, int sy, int dx, int dy, int w, int h, const Array<Rectangle>& scissors);	//throws bad_alloc
-#endif
-    void				mask(DynamicBlitter& blitter, const Image* src, VGMaskOperation operation, int x, int y, int w, int h);
-
-    RI_INLINE void      writePackedPixelToAddress(void* address, int x, RIuint32 p)        { m_image->writePackedPixelToAddress(address, x, p); }
-   RI_INLINE RIuint32 	readPackedSample(int x, int y, int sample) const			 { return m_image->readPackedPixel(x*m_numSamples+sample, y); }
-    RI_INLINE Color		readSample(int x, int y, int sample) const                   { return m_image->readPixel(x*m_numSamples+sample, y); }
-    RI_INLINE void		writePackedSample(int x, int y, int sample, RIuint32 p)		 { m_image->writePackedPixel(x*m_numSamples+sample, y, p); }
-    RI_INLINE void		writeSample(int x, int y, int sample, const Color& c)        { m_image->writePixel(x*m_numSamples+sample, y, c); }
-    RI_INLINE void		fillPackedSamples(int x, int y, int nPixels, RIuint32 p);
-
-    RIfloat				readMaskCoverage(int x, int y) const;
-    void				writeMaskCoverage(int x, int y, RIfloat m);
-    unsigned int		readMaskMSAA(int x, int y) const;
-    void				writeMaskMSAA(int x, int y, unsigned int m);
-
-    RIuint32 			FSAAResolvePacked(int x, int y) const;
-    Color				FSAAResolve(int x, int y) const;	//for fb=>img: vgGetPixels, vgReadPixels
-
-private:
-    Surface(const Surface&);			//!< Not allowed.
-    void operator=(const Surface&);			//!< Not allowed.
-
-    struct ScissorEdge
-    {
-        ScissorEdge() : x(0), miny(0), maxy(0), direction(0) {}
-        bool operator<(const ScissorEdge& e) const	{ return x < e.x; }
-        int			x;
-        int			miny;
-        int			maxy;
-        int			direction;		//1 start, -1 end
-    };
-
-    int				m_width;
-    int				m_height;
-    int				m_numSamples;
-    int				m_referenceCount;
-
-public:
-    // \todo TERO: Broke the design of this by making it public, make proper
-    // friend/etc. C++ accessor for optimized pixel-pipelines. Combine with the
-    // removal of (remnants of) the FSAA support.
-    Image*			m_image;
-};
-
-RI_INLINE void Surface::fillPackedSamples(int x, int y, int nPixels, RIuint32 p)
-{
-    m_image->fillPackedPixels(x, y, nPixels, p);
-}
-
-
-/*-------------------------------------------------------------------*//*!
-* \brief	Drawable class for encapsulating color and mask buffers.
-* \param
-* \return
-* \note
-*//*-------------------------------------------------------------------*/
-
-class Drawable
-{
-public:
-    Drawable(const Color::Descriptor& desc, int width, int height, int numSamples, int maskBits);	//throws bad_alloc
-    Drawable(Image* image, int maskBits);	//throws bad_alloc
-    Drawable(const Color::Descriptor& desc, int width, int height, int stride, RIuint8* data, int maskBits);	//throws bad_alloc
-    ~Drawable();
-
-    RI_INLINE const Color::Descriptor&	getDescriptor() const		{ return m_color->getDescriptor(); }
-    RI_INLINE int       getNumMaskBits() const                      { if(!m_mask) return 0; return m_mask->getDescriptor().alphaBits; }
-    RI_INLINE int		getWidth() const							{ return m_color->getWidth(); }
-    RI_INLINE int		getHeight() const							{ return m_color->getHeight(); }
-    RI_INLINE int		getNumSamples() const						{ return m_color->getNumSamples(); }
-    RI_INLINE void		addReference()								{ m_referenceCount++; }
-    RI_INLINE int		removeReference()							{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
-    RI_INLINE int		isInUse() const								{ return m_color->isInUse() || (m_mask && m_mask->isInUse()); }
-    RI_INLINE bool		isInUse(Image* image) const					{ return m_color->isInUse(image) || (m_mask && m_mask->isInUse(image)); }
-    RI_INLINE Surface*  getColorBuffer() const                      { return m_color; }
-    RI_INLINE Surface*  getMaskBuffer() const                       { return m_mask; }
-
-    void				resize(VGContext* context, int newWidth, int newHeight);	//throws bad_alloc
-private:
-    Drawable(const Drawable&);			//!< Not allowed.
-    void operator=(const Drawable&);	//!< Not allowed.
-
-    int                 m_referenceCount;
-    Surface*			m_color;
-    Surface*            m_mask;
-};
-
-//==============================================================================================
-
-}	//namespace OpenVGRI
-
-//==============================================================================================
-
-#endif /* __RIIMAGE_H */