/*************************************************************************
 *
 *  $RCSfile: bitmap.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2000/12/07 13:37:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_BITMAP_HXX
#define _SV_BITMAP_HXX

#ifndef _SV_SV_H
#include <vcl/sv.h>
#endif
#ifndef _SV_MAPMOD_HXX
#include <vcl/mapmod.hxx>
#endif
#ifndef _SV_RC_HXX
#include <vcl/rc.hxx>
#endif
#ifndef _SV_REGION_HXX
#include <vcl/region.hxx>
#endif

// -----------
// - Defines -
// -----------

#define BMP_MIRROR_NONE				0x00000000UL
#define BMP_MIRROR_HORZ				0x00000001UL
#define BMP_MIRROR_VERT				0x00000002UL

// -----------------------------------------------------------------------------

#define BMP_SCALE_NONE				0x00000000UL
#define BMP_SCALE_FAST				0x00000001UL
#define BMP_SCALE_INTERPOLATE		0x00000002UL

// -----------------------------------------------------------------------------

#define BMP_DITHER_NONE				0x00000000UL
#define BMP_DITHER_MATRIX			0x00000001UL
#define BMP_DITHER_FLOYD			0x00000002UL
#define BMP_DITHER_FLOYD_16			0x00000004UL

// -----------------------------------------------------------------------------

#define BMP_VECTORIZE_NONE			BMP_VECTORIZE_OUTER
#define BMP_VECTORIZE_INNER			0x00000001UL
#define BMP_VECTORIZE_OUTER			0x00000002UL
#define BMP_VECTORIZE_BOUND_ONLY	0x00000004UL
#define BMP_VECTORIZE_REDUCE_EDGES	0x00000008UL

// -----------------------------------------------------------------------------

#define BMP_COL_TRANS				Color( 252, 3, 251 )

// ---------
// - Enums -
// ---------

enum BmpConversion
{
    BMP_CONVERSION_NONE = 0,
    BMP_CONVERSION_1BIT_THRESHOLD = 1,
    BMP_CONVERSION_1BIT_MATRIX = 2,
    BMP_CONVERSION_4BIT_GREYS = 3,
    BMP_CONVERSION_4BIT_COLORS = 4,
    BMP_CONVERSION_8BIT_GREYS = 5,
    BMP_CONVERSION_8BIT_COLORS = 6,
    BMP_CONVERSION_24BIT = 7,
    BMP_CONVERSION_4BIT_TRANS = 8,
    BMP_CONVERSION_8BIT_TRANS = 9,
    BMP_CONVERSION_GHOSTED = 10
};

// ------------------------------------------------------------------------

enum BmpCombine
{
    BMP_COMBINE_COPY = 0,
    BMP_COMBINE_INVERT = 1,
    BMP_COMBINE_AND = 2,
    BMP_COMBINE_NAND = 3,
    BMP_COMBINE_OR = 4,
    BMP_COMBINE_NOR = 5,
    BMP_COMBINE_XOR = 6,
    BMP_COMBINE_NXOR = 7
};

// ------------------------------------------------------------------------

enum BmpReduce
{
	BMP_REDUCE_SIMPLE = 0,
	BMP_REDUCE_POPULAR = 1,
	BMP_REDUCE_MEDIAN = 2
};

// ------------------------------------------------------------------------

enum BmpEmboss
{
	BMP_EMBOSS_TOPLEFT = 0,
	BMP_EMBOSS_TOP = 1,
	BMP_EMBOSS_TOPRIGHT = 2,
	BMP_EMBOSS_LEFT = 3,
	BMP_EMBOSS_MIDDLE = 4,
	BMP_EMBOSS_RIGHT = 5,
	BMP_EMBOSS_BOTTOMLEFT = 6,
	BMP_EMBOSS_BOTTOM = 7,
	BMP_EMBOSS_BOTTOMRIGHT = 8
};

// ------------------------------------------------------------------------

enum BmpFilter
{
    BMP_FILTER_SMOOTH = 0,
    BMP_FILTER_SHARPEN = 1,
    BMP_FILTER_REMOVENOISE = 2,
	BMP_FILTER_SOBEL_GREY = 3,
	BMP_FILTER_EMBOSS_GREY = 4,
	BMP_FILTER_SOLARIZE = 5,
	BMP_FILTER_SEPIA = 6,
	BMP_FILTER_MOSAIC = 7,
	BMP_FILTER_POPART = 8,

	BMP_FILTER_UNKNOWN = 65535
};

// --------------------
// - FilterParameters -
// --------------------

class BmpFilterParam
{
	friend class Bitmap;
	friend class BitmapEx;
	friend class Animation;

private:
	BmpFilter	meFilter;
	ULONG		mnProgressStart;
	ULONG		mnProgressEnd;

	union
	{
		USHORT	mnSepiaPercent;
		BYTE	mcSolarGreyThreshold;

		struct 
		{
			ULONG mnTileWidth;
			ULONG mnTileHeight;
		}
		maMosaicTileSize;

		struct
		{
			USHORT mnAzimuthAngle100;
			USHORT mnElevationAngle100;
		}
		maEmbossAngles;
	};

public:

	BmpFilterParam( ULONG nProgressStart = 0, ULONG nProgressEnd = 0 ) :
		meFilter( BMP_FILTER_UNKNOWN ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ) {}

	BmpFilterParam( BYTE cSolarGreyThreshold, ULONG nProgressStart = 0, ULONG nProgressEnd = 0 ) :
		meFilter( BMP_FILTER_SOLARIZE ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
		mcSolarGreyThreshold( cSolarGreyThreshold ) {}

	BmpFilterParam( USHORT nSepiaPercent, ULONG nProgressStart = 0, ULONG nProgressEnd = 0 ) :
		meFilter( BMP_FILTER_SEPIA ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
		mnSepiaPercent( nSepiaPercent ) {}

	BmpFilterParam( const Size& rMosaicTileSize, ULONG nProgressStart = 0, ULONG nProgressEnd = 0 ) :
		meFilter( BMP_FILTER_MOSAIC ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd )
		{
			maMosaicTileSize.mnTileWidth = rMosaicTileSize.Width();
			maMosaicTileSize.mnTileHeight= rMosaicTileSize.Height();
		}
	BmpFilterParam( USHORT nEmbossAzimuthAngle100, USHORT nEmbossElevationAngle100,
					ULONG nProgressStart = 0, ULONG nProgressEnd = 0 ) :
		meFilter( BMP_FILTER_EMBOSS_GREY ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd )
		{
			maEmbossAngles.mnAzimuthAngle100 = nEmbossAzimuthAngle100;
			maEmbossAngles.mnElevationAngle100 = nEmbossElevationAngle100;
		}
};

// ----------
// - Bitmap -
// ----------

class   BitmapReadAccess;
class   BitmapWriteAccess;
class   BitmapPalette;
class   ImpBitmap;
class   Color;
class   SvStream;
struct  DIBInfoHeader;
class   ResId;
class   RMBitmap;
class	GDIMetaFile;
class	AlphaMask;

class Bitmap
{
private:

    ImpBitmap*              mpImpBmp;
    RMBitmap*               mpRMBitmap;
    MapMode                 maPrefMapMode;
    Size                    maPrefSize;

#if 0 // _SOLAR__PRIVATE

public:

    void                    ImplReleaseRef();
    void                    ImplMakeUnique();
    ImpBitmap*              ImplGetImpBitmap() const;
    void                    ImplSetImpBitmap( ImpBitmap* pImpBmp );
    void                    ImplAssignWithSize( const Bitmap& rBitmap );

    static BOOL             ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, ULONG nOffset );
    static BOOL             ImplReadDIBFileHeader( SvStream& rIStm, ULONG& rOffset );
    static BOOL             ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader );
    static BOOL             ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, BOOL bQuad );
    static BOOL             ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc );
    BOOL                    ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, BOOL bCompressed ) const;
    static BOOL             ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc );
    static BOOL             ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc );
    static BOOL             ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
                                              ULONG nCompression, ULONG& rImageSize );
    static void             ImplDecodeRLE( BYTE* pBuffer, DIBInfoHeader& rHeader,
                                           BitmapWriteAccess& rAcc, BOOL bRLE4 );
    static BOOL             ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, BOOL bRLE4 );

    BOOL                    ImplScaleFast( const double& rScaleX, const double& rScaleY );
    BOOL                    ImplScaleInterpolate( const double& rScaleX, const double& rScaleY );
    BOOL                    ImplMakeMono( BYTE cThreshold );
    BOOL                    ImplMakeMonoDither();
    BOOL                    ImplMakeGreyscales( USHORT nGreyscales );
    BOOL                    ImplConvertUp( USHORT nBitCount, Color* pExtColor = NULL );
    BOOL                    ImplConvertDown( USHORT nBitCount, Color* pExtColor = NULL );
	BOOL					ImplConvertGhosted();
	BOOL					ImplDitherMatrix( const BitmapPalette* pDitherPal );
	BOOL					ImplDitherFloyd( const BitmapPalette* pDitherPal );
	BOOL					ImplDitherFloyd16();
	BOOL					ImplReduceSimple( USHORT nColorCount );
	BOOL					ImplReducePopular( USHORT nColorCount );
	BOOL					ImplReduceMedian( USHORT nColorCount );
	void					ImplMedianCut( ULONG* pColBuf, BitmapPalette& rPal, 
										   long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
										   long nColors, long nPixels, long& rIndex );
	BOOL					ImplConvolute3( const long* pMatrix, long nDivisor, 
											const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplMedianFilter( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplSobelGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplEmbossGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplSolarize( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplSepia( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplMosaic( const BmpFilterParam* pFilterParam, const Link* pProgress );
	BOOL					ImplPopArt( const BmpFilterParam* pFilterParam, const Link* pProgress );

#ifdef REMOTE_APPSERVER

	void                    ImplDrawRemote( OutputDevice* pOut,
                                            const Point& rSrcPt, const Size& rSrcSz,
                                            const Point& rDestPt, const Size& rDestSz ) const;
	void                    ImplDrawRemoteEx( OutputDevice* pOut,
                                            const Point& rSrcPt, const Size& rSrcSz,
                                            const Point& rDestPt, const Size& rDestSz,
											const Bitmap& rMask ) const;
	void                    ImplDrawRemoteAlpha( OutputDevice* pOut,
                                            const Point& rSrcPt, const Size& rSrcSz,
                                            const Point& rDestPt, const Size& rDestSz,
											const AlphaMask& rAlpha ) const;
	void                    ImplDrawRemoteMask( OutputDevice* pOut,
                                            const Point& rSrcPt, const Size& rSrcSz,
                                            const Point& rDestPt, const Size& rDestSz,
											const Color& rColor ) const;
	void					ImplGetRemoteBmp( OutputDevice* pOut, const Point& rPt, 
											  const Size& rSz );

#endif // REMOTE_APPSERVER
#endif // PRIVATE

public:

                            Bitmap();
                            Bitmap( const Bitmap& rBitmap );
                            Bitmap( const Size& rSizePixel, USHORT nBitCount, const BitmapPalette* pPal = NULL );
                            Bitmap( const ResId& rResId );
                            ~Bitmap();

    Bitmap&                 operator=( const Bitmap& rBitmap );
    inline BOOL             operator!() const;
    inline BOOL             operator==( const Bitmap& rBitmap ) const;
    inline BOOL             operator!=( const Bitmap& rBitmap ) const;

	inline BOOL				IsSameInstance( const Bitmap& rBmp ) const;
	BOOL					IsEqual( const Bitmap& rBmp ) const;

	inline BOOL				IsEmpty() const;
	void					SetEmpty();

    inline const MapMode&   GetPrefMapMode() const;
    inline void             SetPrefMapMode( const MapMode& rMapMode );

    inline const Size&      GetPrefSize() const;
    inline void             SetPrefSize( const Size& rSize );

    Size                    GetSizePixel() const;
	void					SetSizePixel( const Size& rNewSize );

    USHORT                  GetBitCount() const;
    inline ULONG            GetColorCount() const;
    inline ULONG            GetSizeBytes() const;
	BOOL					HasGreyPalette() const;

	ULONG					GetChecksum() const;

    Bitmap                  CreateDisplayBitmap( OutputDevice* pDisplay );

	static const BitmapPalette& GetGreyPalette( USHORT nEntries );

public:

    BOOL                    Convert( BmpConversion eConversion );
	BOOL					ReduceColors( USHORT nNewColorCount, 
										  BmpReduce eReduce = BMP_REDUCE_SIMPLE );
	BOOL					Dither( ULONG nDitherFlags = BMP_DITHER_MATRIX,
									const BitmapPalette* pDitherPal = NULL );
    BOOL                    Crop( const Rectangle& rRectPixel );
    BOOL                    Expand( ULONG nDX, ULONG nDY, 
									const Color* pInitColor = NULL );
    BOOL                    CopyPixel( const Rectangle& rRectDst,
									   const Rectangle& rRectSrc,
									   const Bitmap* pBmpSrc = NULL );
    BOOL                    CombineSimple( const Bitmap& rMask,
										   BmpCombine eCombine );
    BOOL                    Erase( const Color& rFillColor );
    BOOL                    Invert();
    BOOL                    Mirror( ULONG nMirrorFlags );
    BOOL                    Scale( const Size& rNewSize,
								   ULONG nScaleFlag = BMP_SCALE_FAST );
    BOOL                    Scale( const double& rScaleX, const double& rScaleY, 
								   ULONG nScaleFlag = BMP_SCALE_FAST );
    BOOL                    Rotate( long nAngle10, const Color& rFillColor );
    Bitmap                  CreateMask( const Color& rTransColor, ULONG nTol = 0UL ) const;
	Region					CreateRegion( const Color& rColor, const Rectangle& rRect ) const;
    BOOL                    Replace( const Bitmap& rMask, const Color& rReplaceColor );
    BOOL                    Replace( const AlphaMask& rAlpha, const Color& rMergeColor );
    BOOL                    Replace( const Color& rSearchColor, const Color& rReplaceColor, ULONG nTol = 0 );
    BOOL                    Replace( const Color* pSearchColors, const Color* rReplaceColors, 
									 ULONG nColorCount, ULONG* pTols = NULL );
	BOOL					Vectorize( PolyPolygon& rPolyPoly, 
									   ULONG nFlags = BMP_VECTORIZE_OUTER,
									   const Link* pProgress = NULL );
	BOOL					Vectorize( GDIMetaFile& rMtf, BYTE cReduce = 0,
									   ULONG nFlags = BMP_VECTORIZE_INNER,
									   const Link* pProgress = NULL );
	BOOL					Adjust( short nLuminancePercent = 0,
									short nContrastPercent = 0,
									short nChannelRPercent = 0, 
									short nChannelGPercent = 0, 
									short nChannelBPercent = 0,
									double fGamma = 1.0,
									BOOL bInvert = FALSE );
	BOOL					Filter( BmpFilter eFilter, 
									const BmpFilterParam* pFilterParam = NULL,
									const Link* pProgress = NULL );

public:

    BitmapReadAccess*       AcquireReadAccess();
    BitmapWriteAccess*      AcquireWriteAccess();
    void                    ReleaseAccess( BitmapReadAccess* pAccess );

public:

    BOOL                    Read( SvStream& rIStm, BOOL bFileHeader = TRUE );
    BOOL                    Write( SvStream& rOStm, BOOL bCompressed = TRUE, BOOL bFileHeader = TRUE ) const;

    friend SvStream&        operator>>( SvStream& rIStm, Bitmap& rBitmap );
    friend SvStream&        operator<<( SvStream& rOStm, const Bitmap& rBitmap );
};

// -----------
// - Inlines -
// -----------

inline BOOL Bitmap::operator!() const
{
    return( mpImpBmp == NULL );
}

// ------------------------------------------------------------------

inline BOOL Bitmap::operator==( const Bitmap& rBitmap ) const
{
    return( rBitmap.mpImpBmp == mpImpBmp );
}

// ------------------------------------------------------------------

inline BOOL Bitmap::operator!=( const Bitmap& rBitmap ) const
{
    return( rBitmap.mpImpBmp != mpImpBmp );
}

// ------------------------------------------------------------------

inline BOOL Bitmap::IsSameInstance( const Bitmap& rBitmap ) const
{
    return( rBitmap.mpImpBmp == mpImpBmp );
}

// ------------------------------------------------------------------

inline BOOL	Bitmap::IsEmpty() const
{
    return( mpImpBmp == NULL );
}

// ------------------------------------------------------------------

inline const MapMode& Bitmap::GetPrefMapMode() const
{
    return maPrefMapMode;
}

// ------------------------------------------------------------------

inline void Bitmap::SetPrefMapMode( const MapMode& rMapMode )
{
    maPrefMapMode = rMapMode;
}

// ------------------------------------------------------------------

inline const Size& Bitmap::GetPrefSize() const
{
    return maPrefSize;
}

// ------------------------------------------------------------------

inline void Bitmap::SetPrefSize( const Size& rSize )
{
    maPrefSize = rSize;
}

// ------------------------------------------------------------------

inline ULONG Bitmap::GetColorCount() const
{
    return( 1UL << (ULONG) GetBitCount() );
}

// ------------------------------------------------------------------

inline ULONG Bitmap::GetSizeBytes() const
{
    const Size aSizePix( GetSizePixel() );
    return( ( (ULONG) aSizePix.Width() * aSizePix.Height() * GetBitCount() ) >> 3UL );
}

#endif // _SV_BITMAP_HXX
