/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _PNGREAD_HXX
#define _PNGREAD_HXX

#include <tools/gen.hxx>
#include <vcl/graph.h>

class SvStream;
class Graphic;
class ZCodec;
class Bitmap;
class BitmapColor;
class AlphaMask;
class BitmapWriteAccess;

namespace binfilter
{

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

enum ReadState
{
    PNGREAD_OK,
    PNGREAD_ERROR,
    PNGREAD_NEED_MORE
};

// -------------
// - PNGReader -
// -------------

#define CHUNK_IS_OPEN		1
#define CHUNK_IS_CLOSED		2
#define CHUNK_IS_IN_USE		4

class PNGReader : public GraphicReader
{
    ReadState			meReadState;
    SvStream*			mpIStm;
    void*				mpCallerData;
    USHORT				mnIStmOldMode;
    BOOL				mbStatus;
    BOOL				mbFinished;
    BOOL				mbFirstEntry;
    UINT32				mnChunkStatus;
    UINT32				mnChunkStartPosition;
    UINT32				mnIDATCRCCount;
    UINT32				mnLatestStreamPos;
    static const BYTE	mnBlockHeight[ 8 ];
    static const BYTE	mnBlockWidth[ 8 ];
    static const BYTE	mpDefaultColorTable[ 256 ];
    Bitmap*				mpBmp;
    BitmapWriteAccess*	mpAcc;
    Bitmap*				mpMaskBmp;
    AlphaMask*			mpAlphaMask;
    BitmapWriteAccess*	mpMaskAcc;
    

    ZCodec* 			mpZCodec;
    BYTE*				mpInflateInBuf; // as big as the size of a scanline + alphachannel + 1
    BYTE*				mpScanprior;	// pointer to the latest scanline
    BYTE*				mpTransTab;		//
    BYTE				mnTransRed;
    BYTE				mnTransGreen;
    BYTE				mnTransBlue;
    BYTE				mnDummy;

    ULONG				mnChunkType;	// Chunk which is currently open
    ULONG				mnCRC;
    long				mnChunkDatSizeOrg;
    long				mnChunkDatSize;

    ULONG				mnWidth;
    ULONG				mnHeight;
    sal_uInt32			mnPrefWidth;	// preferred width in meter
    sal_uInt32			mnPrefHeight;	// preferred Height in meter
    BYTE				mnBitDepth;		// sample depth
    BYTE				mnColorType;
    BYTE				mnCompressionType;
    BYTE				mnFilterType;
    BYTE				mnInterlaceType;

    USHORT				mnDepth;		// pixel depth
    ULONG				mnBBP;			// number of bytes per pixel
    ULONG				mnScansize;		// max size of scanline
    BOOL				mbTransparent;	// graphic includes an tRNS Chunk or an alpha Channel
    BOOL				mbAlphaChannel;
    BOOL				mbRGBTriple;
    BOOL				mbPalette;		// FALSE if we need a Palette
    BOOL				mbGrayScale;
    BOOL				mbzCodecInUse;
    BOOL				mbIDAT;			// TRUE if finished with the complete IDAT...
    BOOL				mbGamma;		// TRUE if Gamma Correction available
    BOOL				mbpHYs;			// TRUE if pysical size of pixel available
    BYTE				mnPass;			// if interlaced the latest pass ( 1..7 ) else 7
    ULONG				mnYpos;			// latest y position;
    BYTE*				mpScan;			// pointer in the current scanline
    BYTE*				mpColorTable;	//
    BYTE				cTransIndex1;
    BYTE				cNonTransIndex1;

    
    void				ImplSetPixel( ULONG y, ULONG x, const BitmapColor &, BOOL bTrans );
    void				ImplSetPixel( ULONG y, ULONG x, BYTE nPalIndex, BOOL bTrans );
    void				ImplSetAlphaPixel( ULONG y, ULONG x, const BitmapColor&, BYTE nAlpha );
    void				ImplReadIDAT();
    void				ImplResizeScanline();
    void				ImplGetFilter( ULONG nXStart=0, ULONG nXAdd=1 );
    void				ImplReadTransparent();
    void				ImplGetGamma();
    void				ImplGetBackground();
    BYTE				ImplScaleColor();
    BOOL				ImplReadHeader();
    BOOL				ImplReadPalette();
    void				ImplGetGrayPalette( ULONG );
    void				ImplOpenChunk();
    BYTE				ImplReadBYTE();
    ULONG				ImplReadULONG();
    void				ImplReadDAT( unsigned char* pSource, long nDatSize );
    BOOL				ImplCloseChunk();
    void				ImplSkipChunk();
    sal_Bool			ImplIsPending( sal_uInt32 nPos, sal_uInt32 nSize );

public:

    ReadState			ReadPNG( Graphic& rGraphic );

                        PNGReader( SvStream& rStm, void* pCallData );
    virtual				~PNGReader();
};


// -------------
// - ImportPNG -
// -------------

 BOOL ImportPNG( SvStream& rStream, Graphic& rGraphic, void* pCallerData );

 }

#endif // _PNGREAD_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
