/**************************************************************
 * 
 * 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_extensions.hxx"
#include <cstdarg>
#include <math.h>
#include <osl/file.h>
#include <tools/stream.hxx>
#include <sane.hxx>
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sal/config.h>

#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
#include <stdarg.h>
#define dump_state( a, b, c, d ) fprintf( stderr, a, b, c, d );
#else
#define dump_state( a, b, c, d ) ;
#endif
inline void dbg_msg( const char* pString, ... )
{
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
	va_list ap;
	va_start( ap, pString );
	vfprintf( stderr, pString, ap );
	va_end( ap );
#else
    (void)pString;
#endif
}

#define FAIL_SHUTDOWN_STATE( x, y, z ) \
	if( x != SANE_STATUS_GOOD )								\
	{														\
		dump_state( "%s returned error %d (%s)\n",			\
				 y, x, p_strstatus( x ) );					\
		DeInit();											\
		return z;											\
	}

#define FAIL_STATE( x, y, z ) \
	if( x != SANE_STATUS_GOOD )								\
	{														\
		dump_state( "%s returned error %d (%s)\n",			\
				 y, x, p_strstatus( x ) );					\
		return z;											\
	}

#define DUMP_STATE( x, y ) \
	if( x != SANE_STATUS_GOOD )								\
	{														\
		dump_state( "%s returned error %d (%s)\n",			\
				 y, x, p_strstatus( x ) );					\
	}

#define CHECK_STATE( x, y ) \
	if( x != SANE_STATUS_GOOD )								\
	{														\
		dump_state( "%s returned error %d (%s)\n",			\
				 y, x, p_strstatus( x ) );					\
	}														\
	else

int				Sane::nRefCount = 0;
oslModule       Sane::pSaneLib = 0;
SANE_Int		Sane::nVersion = 0;
SANE_Device**	Sane::ppDevices = 0;
int				Sane::nDevices = 0;

SANE_Status		(*Sane::p_init)( SANE_Int*,
								 SANE_Auth_Callback ) = 0;
void			(*Sane::p_exit)() = 0;
SANE_Status		(*Sane::p_get_devices)( const SANE_Device***,
										SANE_Bool ) = 0;
SANE_Status		(*Sane::p_open)( SANE_String_Const, SANE_Handle ) = 0;
void			(*Sane::p_close)( SANE_Handle ) = 0;
const SANE_Option_Descriptor* (*Sane::p_get_option_descriptor)(
	SANE_Handle, SANE_Int ) = 0;
SANE_Status		(*Sane::p_control_option)( SANE_Handle, SANE_Int,
										   SANE_Action, void*,
										   SANE_Int* ) = 0;
SANE_Status		(*Sane::p_get_parameters)( SANE_Handle,
										   SANE_Parameters* ) = 0;
SANE_Status		(*Sane::p_start)( SANE_Handle ) = 0;
SANE_Status		(*Sane::p_read)( SANE_Handle, SANE_Byte*, SANE_Int,
								 SANE_Int* ) = 0;
void			(*Sane::p_cancel)( SANE_Handle ) = 0;
SANE_Status		(*Sane::p_set_io_mode)( SANE_Handle, SANE_Bool ) = 0;
SANE_Status		(*Sane::p_get_select_fd)( SANE_Handle, SANE_Int* ) = 0;
SANE_String_Const (*Sane::p_strstatus)( SANE_Status ) = 0;

static sal_Bool bSaneSymbolLoadFailed = sal_False;

inline oslGenericFunction Sane::LoadSymbol( const char* pSymbolname )
{
    oslGenericFunction pFunction = osl_getAsciiFunctionSymbol( pSaneLib, pSymbolname );
	if( ! pFunction )
	{
		fprintf( stderr, "Could not load symbol %s\n",
				 pSymbolname );
		bSaneSymbolLoadFailed = sal_True;
	}
    return pFunction;
}

SANE_Status Sane::ControlOption( int nOption, SANE_Action nAction,
								 void* pData )
{
	SANE_Status	nStatus = SANE_STATUS_GOOD;
	SANE_Int	nInfo = 0;

	nStatus = p_control_option( maHandle, (SANE_Int)nOption,
								nAction, pData, &nInfo );
	DUMP_STATE( nStatus, "sane_control_option" );
#if OSL_DEBUG_LEVEL > 1
	if( nStatus != SANE_STATUS_GOOD )
	{
		const char* pAction = "Unknown";
		switch( nAction )
		{
			case SANE_ACTION_GET_VALUE:
				pAction = "SANE_ACTION_GET_VALUE";break;
			case SANE_ACTION_SET_VALUE:
				pAction = "SANE_ACTION_SET_VALUE";break;
			case SANE_ACTION_SET_AUTO:
				pAction = "SANE_ACTION_SET_AUTO";break;
		}
		dbg_msg( "Option: \"%s\" action: %s\n",
				 ByteString( GetOptionName( nOption ), gsl_getSystemTextEncoding() ).GetBuffer(),
				 pAction );
	}
#endif
//	if( nInfo & ( SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS ) )
	if( nInfo &  SANE_INFO_RELOAD_OPTIONS )
		ReloadOptions();
	return nStatus;
}

Sane::Sane() :
		mppOptions( 0 ),
		mnOptions( 0 ),
		mnDevice( -1 ),
		maHandle( 0 )
{
	if( ! nRefCount || ! pSaneLib )
		Init();
	nRefCount++;
};

Sane::~Sane()
{
	if( IsOpen() )
		Close();
	nRefCount--;
	if( ! nRefCount && pSaneLib )
		DeInit();
}

void Sane::Init()
{
    ::rtl::OUString sSaneLibName( ::rtl::OUString::createFromAscii( "libsane" SAL_DLLEXTENSION ) );
    pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
    if( ! pSaneLib )
    {
        sSaneLibName = ::rtl::OUString::createFromAscii( "libsane" SAL_DLLEXTENSION ".1" );
        pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
    }
    // try reasonable places that might not be in the library search path
	if( ! pSaneLib )
    {
        ::rtl::OUString sSaneLibSystemPath( ::rtl::OUString::createFromAscii( "/usr/local/lib/libsane" SAL_DLLEXTENSION ) );
        osl_getFileURLFromSystemPath( sSaneLibSystemPath.pData, &sSaneLibName.pData );
        pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
    }

	if( pSaneLib )
	{
		bSaneSymbolLoadFailed = sal_False;
		p_init = (SANE_Status(*)(SANE_Int*, SANE_Auth_Callback ))
			LoadSymbol( "sane_init" );
		p_exit = (void(*)())
			LoadSymbol( "sane_exit" );
		p_get_devices = (SANE_Status(*)(const SANE_Device***,
										SANE_Bool ))
			LoadSymbol( "sane_get_devices" );
		p_open = (SANE_Status(*)(SANE_String_Const, SANE_Handle ))
			LoadSymbol( "sane_open" );
		p_close = (void(*)(SANE_Handle))
			LoadSymbol( "sane_close" );
		p_get_option_descriptor = (const SANE_Option_Descriptor*(*)(SANE_Handle,
															  SANE_Int))
			LoadSymbol( "sane_get_option_descriptor" );
		p_control_option = (SANE_Status(*)(SANE_Handle, SANE_Int,
										   SANE_Action, void*, SANE_Int*))
			LoadSymbol( "sane_control_option" );
		p_get_parameters = (SANE_Status(*)(SANE_Handle,SANE_Parameters*))
			LoadSymbol( "sane_get_parameters" );
		p_start = (SANE_Status(*)(SANE_Handle))
			LoadSymbol( "sane_start" );
		p_read = (SANE_Status(*)(SANE_Handle, SANE_Byte*,
								 SANE_Int, SANE_Int* ))
			LoadSymbol( "sane_read" );
		p_cancel = (void(*)(SANE_Handle))
			LoadSymbol( "sane_cancel" );
		p_set_io_mode = (SANE_Status(*)(SANE_Handle, SANE_Bool))
			LoadSymbol( "sane_set_io_mode" );
		p_get_select_fd = (SANE_Status(*)(SANE_Handle, SANE_Int*))
			LoadSymbol( "sane_get_select_fd" );
		p_strstatus = (SANE_String_Const(*)(SANE_Status))
			LoadSymbol( "sane_strstatus" );
		if( bSaneSymbolLoadFailed )
			DeInit();
		else
		{
			SANE_Status nStatus = p_init( &nVersion, 0 );
			FAIL_SHUTDOWN_STATE( nStatus, "sane_init", );
			nStatus = p_get_devices( (const SANE_Device***)&ppDevices,
									 SANE_FALSE );
			FAIL_SHUTDOWN_STATE( nStatus, "sane_get_devices", );
			for( nDevices = 0 ; ppDevices[ nDevices ]; nDevices++ ) ;
		}
	}
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
	else
		fprintf( stderr, "libsane%s could not be opened: %s\n", SAL_DLLEXTENSION,
				 dlerror() );
#endif
}

void Sane::DeInit()
{
	if( pSaneLib )
	{
		p_exit();
        osl_unloadModule( pSaneLib );
		pSaneLib = 0;
	}
}

void Sane::ReloadDevices()
{
	if( IsOpen() )
		Close();
	DeInit();
	Init();
}

void Sane::ReloadOptions()
{
	if( ! IsOpen() )
		return;

	SANE_Option_Descriptor* pZero = (SANE_Option_Descriptor*)
		p_get_option_descriptor( maHandle, 0 );
	SANE_Word pOptions[2];
	SANE_Status nStatus = p_control_option( maHandle, 0, SANE_ACTION_GET_VALUE,
											(void*)pOptions, NULL );
	if( nStatus != SANE_STATUS_GOOD )
		fprintf( stderr, "Error: sane driver returned %s while reading number of options !\n", p_strstatus( nStatus ) );

	mnOptions = pOptions[ 0 ];
	if( (size_t)pZero->size > sizeof( SANE_Word ) )
		fprintf( stderr, "driver returned numer of options with larger size tha SANE_Word !!!\n" );
	if( mppOptions )
		delete [] mppOptions;
	mppOptions = (const SANE_Option_Descriptor**)new SANE_Option_Descriptor*[ mnOptions ];
	mppOptions[ 0 ] = (SANE_Option_Descriptor*)pZero;
	for( int i = 1; i < mnOptions; i++ )
		mppOptions[ i ] =  (SANE_Option_Descriptor*)
			p_get_option_descriptor( maHandle, i );

	CheckConsistency( NULL, sal_True );

	maReloadOptionsLink.Call( this );
}

sal_Bool Sane::Open( const char* name )
{
	int i;

	SANE_Status nStatus = p_open( (SANE_String_Const)name, &maHandle );
	FAIL_STATE( nStatus, "sane_open", sal_False );

	ReloadOptions();

	if( mnDevice == -1 )
	{
		ByteString aDevice( name );
		for( i = 0; i < nDevices; i++ )
		{
			if( aDevice.Equals( ppDevices[i]->name ) )
			{
				mnDevice = i;
				break;
			}
		}
	}

	return sal_True;
}

sal_Bool Sane::Open( int n )
{
	if( n >= 0 && n < nDevices )
	{
		mnDevice = n;
		return Open( (char*)ppDevices[n]->name );
	}
	return sal_False;
}

void Sane::Close()
{
	if( maHandle )
	{
		p_close( maHandle );
		delete [] mppOptions;
		mppOptions = 0;
		maHandle = 0;
		mnDevice = -1;
	}
}

int Sane::GetOptionByName( const char* rName )
{
	int i;
	ByteString aOption( rName );
	for( i = 0; i < mnOptions; i++ )
	{
		if( mppOptions[i]->name && aOption.Equals( mppOptions[i]->name ) )
			return i;
	}
	return -1;
}

sal_Bool Sane::GetOptionValue( int n, sal_Bool& rRet )
{
	if( ! maHandle  ||  mppOptions[n]->type != SANE_TYPE_BOOL )
		return sal_False;
	SANE_Word nRet;
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, &nRet );
	if( nStatus != SANE_STATUS_GOOD )
		return sal_False;

	rRet = nRet;
	return sal_True;
}

sal_Bool Sane::GetOptionValue( int n, ByteString& rRet )
{
	sal_Bool bSuccess = sal_False;
	if( ! maHandle  ||  mppOptions[n]->type != SANE_TYPE_STRING )
		return sal_False;
	char* pRet = new char[mppOptions[n]->size+1];
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pRet );
	if( nStatus == SANE_STATUS_GOOD )
	{
		bSuccess = sal_True;
		rRet = pRet;
	}
	delete [] pRet;
	return bSuccess;
}

sal_Bool Sane::GetOptionValue( int n, double& rRet, int nElement )
{
	sal_Bool bSuccess = sal_False;

	if( ! maHandle  ||  ( mppOptions[n]->type != SANE_TYPE_INT &&
						  mppOptions[n]->type != SANE_TYPE_FIXED ) )
		return sal_False;

	SANE_Word* pRet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pRet );
	if( nStatus == SANE_STATUS_GOOD )
	{
		bSuccess = sal_True;
		if( mppOptions[n]->type == SANE_TYPE_INT )
			rRet = (double)pRet[ nElement ];
		else
			rRet = SANE_UNFIX( pRet[nElement] );
	}
	delete [] pRet;
	return bSuccess;
}

sal_Bool Sane::GetOptionValue( int n, double* pSet )
{
	if( ! maHandle  || ! ( mppOptions[n]->type == SANE_TYPE_FIXED ||
						   mppOptions[n]->type == SANE_TYPE_INT ) )
		return sal_False;

	SANE_Word* pFixedSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pFixedSet );
	if( nStatus != SANE_STATUS_GOOD )
	{
		delete [] pFixedSet;
		return sal_False;
	}
	for( size_t i = 0; i <mppOptions[n]->size/sizeof(SANE_Word); i++ )
	{
		if( mppOptions[n]->type == SANE_TYPE_FIXED )
			pSet[i] = SANE_UNFIX( pFixedSet[i] );
		else
			pSet[i] = (double) pFixedSet[i];
	}
	delete [] pFixedSet;
	return sal_True;
}

sal_Bool Sane::SetOptionValue( int n, sal_Bool bSet )
{
	if( ! maHandle  ||  mppOptions[n]->type != SANE_TYPE_BOOL )
		return sal_False;
	SANE_Word nRet = bSet ? SANE_TRUE : SANE_FALSE;
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, &nRet );
	if( nStatus != SANE_STATUS_GOOD )
		return sal_False;
	return sal_True;
}

sal_Bool Sane::SetOptionValue( int n, const String& rSet )
{
	if( ! maHandle  ||  mppOptions[n]->type != SANE_TYPE_STRING )
		return sal_False;
	ByteString aSet( rSet, gsl_getSystemTextEncoding() );
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, (void*)aSet.GetBuffer() );
	if( nStatus != SANE_STATUS_GOOD )
		return sal_False;
	return sal_True;
}

sal_Bool Sane::SetOptionValue( int n, double fSet, int nElement )
{
	sal_Bool bSuccess = sal_False;

	if( ! maHandle  ||  ( mppOptions[n]->type != SANE_TYPE_INT &&
						  mppOptions[n]->type != SANE_TYPE_FIXED ) )
		return sal_False;

	SANE_Status nStatus;
	if( mppOptions[n]->size/sizeof(SANE_Word) > 1 )
	{
		SANE_Word* pSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
		nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pSet );
		if( nStatus == SANE_STATUS_GOOD )
		{
			pSet[nElement] = mppOptions[n]->type == SANE_TYPE_INT ?
				(SANE_Word)fSet : SANE_FIX( fSet );
			nStatus = ControlOption(  n, SANE_ACTION_SET_VALUE, pSet );
		}
		delete [] pSet;
	}
	else
	{
		SANE_Word nSetTo =
			mppOptions[n]->type == SANE_TYPE_INT ?
			(SANE_Word)fSet : SANE_FIX( fSet );

		nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, &nSetTo );
		if( nStatus == SANE_STATUS_GOOD )
			bSuccess = sal_True;
	}
	return bSuccess;
}

sal_Bool Sane::SetOptionValue( int n, double* pSet )
{
	if( ! maHandle  ||  ( mppOptions[n]->type != SANE_TYPE_INT &&
						  mppOptions[n]->type != SANE_TYPE_FIXED ) )
		return sal_False;
	SANE_Word* pFixedSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
	for( size_t i = 0; i < mppOptions[n]->size/sizeof(SANE_Word); i++ )
	{
		if( mppOptions[n]->type == SANE_TYPE_FIXED )
			pFixedSet[i] = SANE_FIX( pSet[i] );
		else
			pFixedSet[i] = (SANE_Word)pSet[i];
	}
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, pFixedSet );
	delete [] pFixedSet;
	if( nStatus != SANE_STATUS_GOOD )
		return sal_False;
	return sal_True;
}

enum FrameStyleType {
	FrameStyle_BW, FrameStyle_Gray, FrameStyle_RGB, FrameStyle_Separated
};

#define BYTE_BUFFER_SIZE 32768

static inline sal_uInt8 _ReadValue( FILE* fp, int depth )
{
	if( depth == 16 )
	{
		sal_uInt16 nWord;
		// data always come in native byte order !
		// 16 bits is not really supported by backends as of now
		// e.g. UMAX Astra 1200S delivers 16 bit but in BIGENDIAN
		// against SANE documentation (xscanimage gets the same result
		// as we do
		fread( &nWord, 1, 2, fp );
		return (sal_uInt8)( nWord / 256 );
	}
	sal_uInt8 nByte;
	fread( &nByte, 1, 1, fp );
	return nByte;
}

sal_Bool Sane::CheckConsistency( const char* pMes, sal_Bool bInit )
{
	static SANE_Option_Descriptor** pDescArray = NULL;
	static SANE_Option_Descriptor*  pZero = NULL;

	if( bInit )
	{
		pDescArray = (SANE_Option_Descriptor**)mppOptions;
		if( mppOptions )
			pZero = (SANE_Option_Descriptor*)mppOptions[0];
		return sal_True;
	}

	sal_Bool bConsistent = sal_True;

	if( pDescArray != mppOptions )
		bConsistent = sal_False;
	if( pZero != mppOptions[0] )
		bConsistent = sal_False;

	if( ! bConsistent )
		dbg_msg( "Sane is not consistent. (%s)\n", pMes );

	return bConsistent;
}

sal_Bool Sane::Start( BitmapTransporter& rBitmap )
{
	int nStream = 0, nLine = 0, i = 0;
	SANE_Parameters	aParams;
	FrameStyleType eType = FrameStyle_Gray;
	sal_Bool bSuccess = sal_True;
	sal_Bool bWidthSet = sal_False;

	if( ! maHandle )
		return sal_False;

    int nWidthMM	= 0;
    int nHeightMM	= 0;
    double fTLx, fTLy, fBRx, fBRy, fResl = 0.0;
    int nOption;
    if( ( nOption = GetOptionByName( "tl-x" ) ) != -1	&&
        GetOptionValue( nOption, fTLx, 0 )				&&
        GetOptionUnit( nOption ) == SANE_UNIT_MM )
    {
        if( ( nOption = GetOptionByName( "br-x" ) ) != -1	&&
            GetOptionValue( nOption, fBRx, 0 )				&&
            GetOptionUnit( nOption ) == SANE_UNIT_MM )
        {
            nWidthMM = (int)fabs(fBRx - fTLx);
        }
    }
    if( ( nOption = GetOptionByName( "tl-y" ) ) != -1	&&
        GetOptionValue( nOption, fTLy, 0 )				&&
        GetOptionUnit( nOption ) == SANE_UNIT_MM )
    {
        if( ( nOption = GetOptionByName( "br-y" ) ) != -1	&&
            GetOptionValue( nOption, fBRy, 0 )				&&
            GetOptionUnit( nOption ) == SANE_UNIT_MM )
        {
            nHeightMM = (int)fabs(fBRy - fTLy);
        }
    }
    if( ( nOption = GetOptionByName( "resolution" ) ) != -1 )
        GetOptionValue( nOption, fResl );

	sal_uInt8* pBuffer = NULL;

	SANE_Status nStatus = SANE_STATUS_GOOD;

	rBitmap.lock();
	SvMemoryStream& aConverter = rBitmap.getStream();
	aConverter.Seek( 0 );
	aConverter.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );

	// write bitmap stream header
	aConverter << 'B' << 'M';
	aConverter << (sal_uInt32) 0;
	aConverter << (sal_uInt32) 0;
	aConverter << (sal_uInt32) 60;

	// write BITMAPINFOHEADER
	aConverter << (sal_uInt32)40;
	aConverter << (sal_uInt32)0; // fill in width later
	aConverter << (sal_uInt32)0; // fill in height later
	aConverter << (sal_uInt16)1;
	// create header for 24 bits
	// correct later if necessary
	aConverter << (sal_uInt16)24;
	aConverter << (sal_uInt32)0;
	aConverter << (sal_uInt32)0;
	aConverter << (sal_uInt32)0;
	aConverter << (sal_uInt32)0;
	aConverter << (sal_uInt32)0;
	aConverter << (sal_uInt32)0;

	for( nStream=0; nStream < 3 && bSuccess ; nStream++ )
	{
		nStatus = p_start( maHandle );
		DUMP_STATE( nStatus, "sane_start" );
		CheckConsistency( "sane_start" );
		if( nStatus == SANE_STATUS_GOOD )
		{
			nStatus = p_get_parameters( maHandle, &aParams );
			DUMP_STATE( nStatus, "sane_get_parameters" );
			CheckConsistency( "sane_get_parameters" );
			if (nStatus != SANE_STATUS_GOOD || aParams.bytes_per_line == 0)
			{
				bSuccess = sal_False;
			    break;
			}
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
			const char* ppFormats[] = { "SANE_FRAME_GRAY", "SANE_FRAME_RGB",
								  "SANE_FRAME_RED", "SANE_FRAME_GREEN",
								  "SANE_FRAME_BLUE", "Unknown !!!" };
			fprintf( stderr, "Parameters for frame %d:\n", nStream );
			if( aParams.format < 0 || aParams.format > 4 )
				aParams.format = (SANE_Frame)5;
			fprintf( stderr, "format:           %s\n", ppFormats[ (int)aParams.format ] );
			fprintf( stderr, "last_frame:       %s\n", aParams.last_frame ? "TRUE" : "FALSE" );
			fprintf( stderr, "depth:            %d\n", (int)aParams.depth );
			fprintf( stderr, "pixels_per_line:  %d\n", (int)aParams.pixels_per_line );
			fprintf( stderr, "bytes_per_line:   %d\n", (int)aParams.bytes_per_line );
#endif
			if( ! pBuffer )
			{
				pBuffer = new sal_uInt8[ BYTE_BUFFER_SIZE < 4*aParams.bytes_per_line ? 4*aParams.bytes_per_line : BYTE_BUFFER_SIZE ];
			}

			if( aParams.last_frame )
				nStream=3;

			switch( aParams.format )
			{
				case SANE_FRAME_GRAY:
					eType = FrameStyle_Gray;
					if( aParams.depth == 1 )
						eType = FrameStyle_BW;
					break;
				case SANE_FRAME_RGB:
					eType = FrameStyle_RGB;
					break;
				case SANE_FRAME_RED:
				case SANE_FRAME_GREEN:
				case SANE_FRAME_BLUE:
					eType = FrameStyle_Separated;
					break;
				default:
					fprintf( stderr, "Warning: unknown frame style !!!\n" );
			}

			sal_Bool bSynchronousRead = sal_True;

			// should be fail safe, but ... ??
			nStatus = p_set_io_mode( maHandle, SANE_FALSE );
			CheckConsistency( "sane_set_io_mode" );
			if( nStatus != SANE_STATUS_GOOD )
			{
				bSynchronousRead = sal_False;
				nStatus = p_set_io_mode( maHandle, SANE_TRUE );
				CheckConsistency( "sane_set_io_mode" );
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
				if( nStatus != SANE_STATUS_GOOD )
					// what ?!?
					fprintf( stderr, "Sane::Start: driver is confused\n" );
#endif
			}

			SANE_Int nLen=0;
			SANE_Int fd = 0;

			if( ! bSynchronousRead )
			{
				nStatus = p_get_select_fd( maHandle, &fd );
				DUMP_STATE( nStatus, "sane_get_select_fd" );
				CheckConsistency( "sane_get_select_fd" );
				if( nStatus != SANE_STATUS_GOOD )
					bSynchronousRead = sal_True;
			}
			FILE* pFrame = tmpfile();
			if( ! pFrame )
			{
				bSuccess = sal_False;
				break;
			}
			do {
				if( ! bSynchronousRead )
				{
					fd_set fdset;
					struct timeval tv;

					FD_ZERO( &fdset );
					FD_SET( (int)fd, &fdset );
					tv.tv_sec = 5;
					tv.tv_usec = 0;
					if( select( fd+1, &fdset, NULL, NULL, &tv ) == 0 )
						fprintf( stderr, "Timout on sane_read descriptor\n" );
				}
				nLen = 0;
				nStatus = p_read( maHandle, pBuffer, BYTE_BUFFER_SIZE, &nLen );
				CheckConsistency( "sane_read" );
				if( nLen && ( nStatus == SANE_STATUS_GOOD ||
							  nStatus == SANE_STATUS_EOF ) )
				{
					fwrite( pBuffer, 1, nLen, pFrame );
				}
				else
					DUMP_STATE( nStatus, "sane_read" );
			} while( nStatus == SANE_STATUS_GOOD );
			if( nStatus != SANE_STATUS_EOF )
			{
				fclose( pFrame );
				bSuccess = sal_False;
				break;
			}

			int nFrameLength = ftell( pFrame );
			fseek( pFrame, 0, SEEK_SET );
			sal_uInt32 nWidth = (sal_uInt32) aParams.pixels_per_line;
			sal_uInt32 nHeight = (sal_uInt32) (nFrameLength / aParams.bytes_per_line);
			if( ! bWidthSet )
			{
                if( ! fResl )
                    fResl = 300; // if all else fails that's a good guess
                if( ! nWidthMM )
                    nWidthMM = (int)(((double)nWidth / fResl) * 25.4);
                if( ! nHeightMM )
                    nHeightMM = (int)(((double)nHeight / fResl) * 25.4);
#if OSL_DEBUG_LEVEL > 1
				fprintf( stderr, "set dimensions to (%d, %d) Pixel, (%d, %d) mm, resolution is %lg\n", (int)nWidth, (int)nHeight, (int)nWidthMM, (int)nHeightMM, fResl );
#endif

				aConverter.Seek( 18 );
				aConverter << (sal_uInt32)nWidth;
				aConverter << (sal_uInt32)nHeight;
                aConverter.Seek( 38 );
                aConverter << (sal_uInt32)(1000*nWidth/nWidthMM);
                aConverter << (sal_uInt32)(1000*nHeight/nHeightMM);
				bWidthSet = sal_True;
			}
			aConverter.Seek(60);

			if( eType == FrameStyle_BW )
			{
				aConverter.Seek( 10 );
				aConverter << (sal_uInt32)64;
				aConverter.Seek( 28 );
				aConverter << (sal_uInt16) 1;
				aConverter.Seek( 54 );
				// write color table
				aConverter << (sal_uInt16)0xffff;
				aConverter << (sal_uInt8)0xff;
				aConverter << (sal_uInt8)0;
				aConverter << (sal_uInt32)0;
				aConverter.Seek( 64 );
			}
			else if( eType == FrameStyle_Gray )
			{
 				aConverter.Seek( 10 );
 				aConverter << (sal_uInt32)1084;
				aConverter.Seek( 28 );
				aConverter << (sal_uInt16) 8;
				aConverter.Seek( 54 );
				// write color table
				for( nLine = 0; nLine < 256; nLine++ )
				{
					aConverter << (sal_uInt8)nLine;
					aConverter << (sal_uInt8)nLine;
					aConverter << (sal_uInt8)nLine;
					aConverter << (sal_uInt8)0;
				}
				aConverter.Seek( 1084 );
			}

			for( nLine = nHeight-1;
				 nLine >= 0; nLine-- )
			{
				fseek( pFrame, nLine * aParams.bytes_per_line, SEEK_SET );
				if( eType == FrameStyle_BW ||
					( eType == FrameStyle_Gray && aParams.depth == 8 )
					)
				{
					fread( pBuffer, 1, aParams.bytes_per_line, pFrame );
					aConverter.Write( pBuffer, aParams.bytes_per_line );
				}
				else if( eType == FrameStyle_Gray )
				{
					for( i = 0; i < (aParams.pixels_per_line); i++ )
					{
						sal_uInt8 nGray = _ReadValue( pFrame, aParams.depth );
						aConverter << nGray;
					}
				}
				else if( eType == FrameStyle_RGB )
				{
					for( i = 0; i < (aParams.pixels_per_line); i++ )
					{
						sal_uInt8 nRed, nGreen, nBlue;
						nRed	= _ReadValue( pFrame, aParams.depth );
						nGreen	= _ReadValue( pFrame, aParams.depth );
						nBlue	= _ReadValue( pFrame, aParams.depth );
						aConverter << nBlue;
						aConverter << nGreen;
						aConverter << nRed;
					}
				}
				else if( eType == FrameStyle_Separated )
				{
					for( i = 0; i < (aParams.pixels_per_line); i++ )
					{
						sal_uInt8 nValue = _ReadValue( pFrame, aParams.depth );
						switch( aParams.format )
						{
							case SANE_FRAME_RED:
								aConverter.SeekRel( 2 );
								aConverter << nValue;
								break;
							case SANE_FRAME_GREEN:
								aConverter.SeekRel( 1 );
								aConverter << nValue;
								aConverter.SeekRel( 1 );
								break;
							case SANE_FRAME_BLUE:
								aConverter << nValue;
								aConverter.SeekRel( 2 );
								break;
                            case SANE_FRAME_GRAY:
                            case SANE_FRAME_RGB:
                                break;
						}
					}
				}
 				int nGap = aConverter.Tell() & 3;
 				if( nGap )
 					aConverter.SeekRel( 4-nGap );
			}
			fclose( pFrame ); // deletes tmpfile
			if( eType != FrameStyle_Separated )
				break;
		}
		else
			bSuccess = sal_False;
	}
	// get stream length
	aConverter.Seek( STREAM_SEEK_TO_END );
	int nPos = aConverter.Tell();

	aConverter.Seek( 2 );
	aConverter << (sal_uInt32) nPos+1;
	aConverter.Seek( 0 );

	rBitmap.unlock();

	if( bSuccess )
	{
		// only cancel a successful operation
		// sane disrupts memory else
		p_cancel( maHandle );
		CheckConsistency( "sane_cancel" );
	}
	if( pBuffer )
		delete [] pBuffer;

	ReloadOptions();


	dbg_msg( "Sane::Start returns with %s\n", bSuccess ? "TRUE" : "FALSE" );

	return bSuccess;
}

int Sane::GetRange( int n, double*& rpDouble )
{
	if( mppOptions[n]->constraint_type != SANE_CONSTRAINT_RANGE &&
		mppOptions[n]->constraint_type != SANE_CONSTRAINT_WORD_LIST )
	{
		return -1;
	}

	rpDouble = 0;
	int nItems, i;
	sal_Bool bIsFixed = mppOptions[n]->type == SANE_TYPE_FIXED ? sal_True : sal_False;

	dbg_msg( "Sane::GetRange of option %s ", mppOptions[n]->name );
	if(mppOptions[n]->constraint_type == SANE_CONSTRAINT_RANGE )
	{
		double fMin, fMax, fQuant;
		if( bIsFixed )
		{
			fMin = SANE_UNFIX( mppOptions[n]->constraint.range->min );
			fMax = SANE_UNFIX( mppOptions[n]->constraint.range->max );
			fQuant = SANE_UNFIX( mppOptions[n]->constraint.range->quant );
		}
		else
		{
			fMin = (double)mppOptions[n]->constraint.range->min;
			fMax = (double)mppOptions[n]->constraint.range->max;
			fQuant = (double)mppOptions[n]->constraint.range->quant;
		}
		if( fQuant != 0.0 )
		{
			dbg_msg( "quantum range [ %lg ; %lg ; %lg ]\n",
					 fMin, fQuant, fMax );
			nItems = (int)((fMax - fMin)/fQuant)+1;
			rpDouble = new double[ nItems ];
			double fValue = fMin;
			for( i = 0; i < nItems; i++, fValue += fQuant )
				rpDouble[i] = fValue;
			rpDouble[ nItems-1 ] = fMax;
			return nItems;
		}
		else
		{
			dbg_msg( "normal range [ %lg %lg ]\n",
					 fMin, fMax );
			rpDouble = new double[2];
			rpDouble[0] = fMin;
			rpDouble[1] = fMax;
			return 0;
		}
	}
	else
	{
		nItems = mppOptions[n]->constraint.word_list[0];
		rpDouble = new double[nItems];
		for( i=0; i<nItems; i++ )
		{
			rpDouble[i] = bIsFixed ?
				SANE_UNFIX( mppOptions[n]->constraint.word_list[i+1] ) :
				(double)mppOptions[n]->constraint.word_list[i+1];
		}
		dbg_msg( "wordlist [ %lg ... %lg ]\n",
				 rpDouble[ 0 ], rpDouble[ nItems-1 ] );
		return nItems;
	}
}

static const char *ppUnits[] = {
	"",
	"[Pixel]",
	"[Bit]",
	"[mm]",
	"[DPI]",
	"[%]",
	"[usec]"
};

String Sane::GetOptionUnitName( int n )
{
	String aText;
	SANE_Unit nUnit = mppOptions[n]->unit;
    size_t nUnitAsSize = (size_t)nUnit;
    if (nUnitAsSize >= sizeof(ppUnits)/sizeof(ppUnits[0]))
		aText = String::CreateFromAscii( "[unknown units]" );
	else
		aText = String( ppUnits[ nUnit ], gsl_getSystemTextEncoding() );
	return aText;
}

sal_Bool Sane::ActivateButtonOption( int n )
{
	SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, NULL );
	if( nStatus != SANE_STATUS_GOOD )
		return sal_False;
	return sal_True;
}
