/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"

#include <vcl/graph.hxx>
#include <vcl/bmpacc.hxx>
#include <svtools/fltcall.hxx>

//============================ PBMReader ==================================

class PBMReader {

private:

	SvStream*			mpPBM;			// Die einzulesende PBM-Datei

	sal_Bool				mbStatus;
	sal_Bool				mbRemark;		// sal_False wenn sich stream in einem Kommentar befindet
	sal_Bool				mbRaw;			// RAW/ASCII MODE
	sal_uLong				mnMode;			// 0->PBM, 1->PGM, 2->PPM
	Bitmap				maBmp;
	BitmapWriteAccess*	mpAcc;
	sal_uLong				mnWidth, mnHeight;	// Bildausmass in Pixeln
	sal_uLong				mnCol;
	sal_uLong				mnMaxVal;			// maximaler wert in den
	sal_Bool				ImplCallback( sal_uInt16 nPercent );
	sal_Bool				ImplReadBody();
	sal_Bool				ImplReadHeader();

public:
						PBMReader();
						~PBMReader();
	sal_Bool				ReadPBM( SvStream & rPBM, Graphic & rGraphic );
};

//=================== Methoden von PBMReader ==============================

PBMReader::PBMReader() :
	mbStatus	( sal_True ),
	mbRemark	( sal_False ),
	mbRaw		( sal_True ),
	mpAcc		( NULL )
{
}

PBMReader::~PBMReader()
{
}

sal_Bool PBMReader::ImplCallback( sal_uInt16 /*nPercent*/ )
{
/*
	if ( pCallback != NULL )
	{
		if ( ( (*pCallback)( pCallerData, nPercent ) ) == sal_True )
		{
			mpPBM->SetError( SVSTREAM_FILEFORMAT_ERROR );
			return sal_True;
		}
	}
*/
	return sal_False;
}

sal_Bool PBMReader::ReadPBM( SvStream & rPBM, Graphic & rGraphic )
{
	sal_uInt16 i;

	if ( rPBM.GetError() )
		return sal_False;

	mpPBM = &rPBM;
	mpPBM->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );

	// Kopf einlesen:

	if ( ( mbStatus = ImplReadHeader() ) == sal_False )
		return sal_False;

	if ( ( mnMaxVal == 0 ) || ( mnWidth == 0 ) || ( mnHeight == 0 ) )
		return sal_False;

	// 0->PBM, 1->PGM, 2->PPM
	switch ( mnMode )
	{
		case 0 :
			maBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
			mpAcc = maBmp.AcquireWriteAccess();
			if ( !mpAcc )
				return sal_False;
			mpAcc->SetPaletteEntryCount( 2 );
			mpAcc->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
			mpAcc->SetPaletteColor( 1, BitmapColor( 0x00, 0x00, 0x00 ) );
			break;

		case 1 :
			if ( mnMaxVal <= 1 )
				maBmp = Bitmap( Size( mnWidth, mnHeight ), 1);
			else if ( mnMaxVal <= 15 )
				maBmp = Bitmap( Size( mnWidth, mnHeight ), 4);
			else
				maBmp = Bitmap( Size( mnWidth, mnHeight ), 8);

			mpAcc = maBmp.AcquireWriteAccess();
			if ( !mpAcc )
				return sal_False;
			mnCol = (sal_uInt16)mnMaxVal + 1;
			if ( mnCol > 256 )
				mnCol = 256;

			mpAcc->SetPaletteEntryCount( 256 );
			for ( i = 0; i < mnCol; i++ )
			{
				sal_uLong nCount = 255 * i / mnCol;
				mpAcc->SetPaletteColor( i, BitmapColor( (sal_uInt8)nCount, (sal_uInt8)nCount, (sal_uInt8)nCount ) );
			}
			break;
		case 2 :
			maBmp = Bitmap( Size( mnWidth, mnHeight ), 24 );
			mpAcc = maBmp.AcquireWriteAccess();
			if ( !mpAcc )
				return sal_False;
			break;
	}

	// Bitmap-Daten einlesen
	mbStatus = ImplReadBody();

	if ( mpAcc )
	{
		maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
	}
	if ( mbStatus )
		rGraphic = maBmp;

	return mbStatus;
}

sal_Bool PBMReader::ImplReadHeader()
{
	sal_uInt8	nID[ 2 ];
	sal_uInt8	nDat;
	sal_uInt8	nMax, nCount = 0;
	sal_Bool	bFinished = sal_False;

	*mpPBM >> nID[ 0 ] >> nID[ 1 ];
	if ( nID[ 0 ] != 'P' )
		return sal_False;
	mnMaxVal = mnWidth = mnHeight = 0;
	switch ( nID[ 1 ] )
	{
		case '1' :
			mbRaw = sal_False;
		case '4' :
			mnMode = 0;
			nMax = 2;				// number of parameters in Header
			mnMaxVal = 1;
			break;
		case '2' :
			mbRaw = sal_False;
		case '5' :
			mnMode = 1;
			nMax = 3;
			break;
		case '3' :
			mbRaw = sal_False;
		case '6' :
			mnMode = 2;
			nMax = 3;
			break;
		default:
			return sal_False;
	}
	while ( bFinished == sal_False )
	{
		if ( mpPBM->GetError() )
			return sal_False;

		*mpPBM >> nDat;

		if ( nDat == '#' )
		{
			mbRemark = sal_True;
			continue;
		}
		else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
		{
			mbRemark = sal_False;
			nDat = 0x20;
		}
		if ( mbRemark )
			continue;

		if ( ( nDat == 0x20 ) || ( nDat == 0x09 ) )
		{
			if ( ( nCount == 0 ) && mnWidth )
				nCount++;
			else if ( ( nCount == 1 ) && mnHeight )
			{
				if ( ++nCount == nMax )
					bFinished = sal_True;
			}
			else if ( ( nCount == 2 ) && mnMaxVal )
			{
				bFinished = sal_True;
			}
			continue;
		}
		if ( ( nDat >= '0' ) && ( nDat <= '9' ) )
		{
			nDat -= '0';
			if ( nCount == 0 )
			{
				mnWidth *= 10;
				mnWidth += nDat;
			}
			else if ( nCount == 1 )
			{
				mnHeight *= 10;
				mnHeight += nDat;
			}
			else if ( nCount == 2 )
			{
				mnMaxVal *= 10;
				mnMaxVal += nDat;
			}
		}
		else
			return sal_False;
	}
	return mbStatus;
}

sal_Bool PBMReader::ImplReadBody()
{
	sal_Bool	bPara, bFinished = sal_False;
	sal_uInt8	nDat = 0, nCount;
	sal_uLong	nGrey, nRGB[3];
	sal_uLong	nWidth = 0;
	sal_uLong	nHeight = 0;
	signed char	nShift = 0;

	if ( mbRaw )
	{
		switch ( mnMode )
		{

			// PBM
			case 0 :
				while ( nHeight != mnHeight )
				{
					if ( mpPBM->IsEof() || mpPBM->GetError() )
						return sal_False;

					if ( --nShift < 0 )
					{
						*mpPBM >> nDat;
						nShift = 7;
					}
					mpAcc->SetPixelIndex( nHeight, nWidth, nDat >> nShift );
					if ( ++nWidth == mnWidth )
					{
						nShift = 0;
						nWidth = 0;
						nHeight++;
						ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
				}
				break;

			// PGM
			case 1 :
				while ( nHeight != mnHeight )
				{
					if ( mpPBM->IsEof() || mpPBM->GetError() )
						return sal_False;

					*mpPBM >> nDat;
					mpAcc->SetPixelIndex( nHeight, nWidth++, nDat);

					if ( nWidth == mnWidth )
					{
						nWidth = 0;
						nHeight++;
						ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
				}
				break;

			// PPM
			case 2 :
				while ( nHeight != mnHeight )
				{
					if ( mpPBM->IsEof() || mpPBM->GetError() )
						return sal_False;

					sal_uInt8	nR, nG, nB;
					sal_uLong	nRed, nGreen, nBlue;
					*mpPBM >> nR >> nG >> nB;
					nRed = 255 * nR / mnMaxVal;
					nGreen = 255 * nG / mnMaxVal;
					nBlue = 255 * nB / mnMaxVal;
					mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
					if ( nWidth == mnWidth )
					{
						nWidth = 0;
						nHeight++;
						ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
				}
				break;
		}
	}
	else switch  ( mnMode )
	{
		// PBM
		case 0 :
			while ( bFinished == sal_False )
			{
				if ( mpPBM->IsEof() || mpPBM->GetError() )
					return sal_False;

				*mpPBM >> nDat;

				if ( nDat == '#' )
				{
					mbRemark = sal_True;
					continue;
				}
				else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
				{
					mbRemark = sal_False;
					continue;
				}
				if ( mbRemark || nDat == 0x20 || nDat == 0x09 )
					continue;

				if ( nDat == '0' || nDat == '1' )
				{
					mpAcc->SetPixelIndex( nHeight, nWidth, static_cast<sal_uInt8>(nDat - '0') );
					nWidth++;
					if ( nWidth == mnWidth )
					{
						nWidth = 0;
						if ( ++nHeight == mnHeight )
							bFinished = sal_True;
						ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
				}
				else
					return sal_False;
			}
			break;

		// PGM
		case 1 :

			bPara = sal_False;
			nCount = 0;
			nGrey = 0;

			while ( bFinished == sal_False )
			{
				if ( nCount )
				{
					nCount--;
					if ( nGrey <= mnMaxVal )
						nGrey = 255 * nGrey / mnMaxVal;
						mpAcc->SetPixelIndex( nHeight, nWidth++, static_cast<sal_uInt8>(nGrey) );
					nGrey = 0;
					if ( nWidth == mnWidth )
					{
						nWidth = 0;
						if ( ++nHeight == mnHeight )
							bFinished = sal_True;
						ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
					continue;
				}

				if ( mpPBM->IsEof() || mpPBM->GetError() )
					return sal_False;

				*mpPBM >> nDat;

				if ( nDat == '#' )
				{
					mbRemark = sal_True;
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}
				else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
				{
					mbRemark = sal_False;
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}

				if ( nDat == 0x20 || nDat == 0x09 )
				{
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}
				if ( nDat >= '0' && nDat <= '9' )
				{
					bPara = sal_True;
					nGrey *= 10;
					nGrey += nDat-'0';
					continue;
				}
				else
					return sal_False;
			}
			break;



		// PPM
		case 2 :

			bPara = sal_False;
			nCount = 0;
			nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;

			while ( bFinished == sal_False )
			{
				if ( nCount == 3 )
				{
					nCount = 0;
					mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( static_cast< sal_uInt8 >( ( nRGB[ 0 ] * 255 ) / mnMaxVal ),
																	 static_cast< sal_uInt8 >( ( nRGB[ 1 ] * 255 ) / mnMaxVal ),
																	 static_cast< sal_uInt8 >( ( nRGB[ 2 ] * 255 ) / mnMaxVal ) ) );
					nCount = 0;
					nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;
					if ( nWidth == mnWidth )
					{
						nWidth = 0;
						if ( ++nHeight == mnHeight )
							bFinished = sal_True;
						ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );	// processing output in percent
					}
					continue;
				}

				if ( mpPBM->IsEof() || mpPBM->GetError() )
					return sal_False;

				*mpPBM >> nDat;

				if ( nDat == '#' )
				{
					mbRemark = sal_True;
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}
				else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
				{
					mbRemark = sal_False;
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}

				if ( nDat == 0x20 || nDat == 0x09 )
				{
					if ( bPara )
					{
						bPara = sal_False;
						nCount++;
					}
					continue;
				}
				if ( nDat >= '0' && nDat <= '9' )
				{
					bPara = sal_True;
					nRGB[ nCount ] *= 10;
					nRGB[ nCount ] += nDat-'0';
					continue;
				}
				else
					return sal_False;
			}
			break;
	}
	return mbStatus;
}

//================== GraphicImport - die exportierte Funktion ================

extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool )
{
	PBMReader aPBMReader;

	return aPBMReader.ReadPBM( rStream, rGraphic );
}

