12a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
32a97ec55SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
42a97ec55SAndrew Rist * or more contributor license agreements. See the NOTICE file
52a97ec55SAndrew Rist * distributed with this work for additional information
62a97ec55SAndrew Rist * regarding copyright ownership. The ASF licenses this file
72a97ec55SAndrew Rist * to you under the Apache License, Version 2.0 (the
82a97ec55SAndrew Rist * "License"); you may not use this file except in compliance
92a97ec55SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
112a97ec55SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
132a97ec55SAndrew Rist * Unless required by applicable law or agreed to in writing,
142a97ec55SAndrew Rist * software distributed under the License is distributed on an
152a97ec55SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162a97ec55SAndrew Rist * KIND, either express or implied. See the License for the
172a97ec55SAndrew Rist * specific language governing permissions and limitations
182a97ec55SAndrew Rist * under the License.
19cdf0e10cSrcweir *
202a97ec55SAndrew Rist *************************************************************/
212a97ec55SAndrew Rist
222a97ec55SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir #include <cstdarg>
27cdf0e10cSrcweir #include <math.h>
28cdf0e10cSrcweir #include <osl/file.h>
29cdf0e10cSrcweir #include <tools/stream.hxx>
30cdf0e10cSrcweir #include <sane.hxx>
31cdf0e10cSrcweir #include <dlfcn.h>
32cdf0e10cSrcweir #include <stdio.h>
33cdf0e10cSrcweir #include <unistd.h>
34cdf0e10cSrcweir #include <sys/time.h>
35cdf0e10cSrcweir #include <sys/types.h>
36cdf0e10cSrcweir #include <sal/config.h>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
39cdf0e10cSrcweir #include <stdarg.h>
40cdf0e10cSrcweir #define dump_state( a, b, c, d ) fprintf( stderr, a, b, c, d );
41cdf0e10cSrcweir #else
42cdf0e10cSrcweir #define dump_state( a, b, c, d ) ;
43cdf0e10cSrcweir #endif
dbg_msg(const char * pString,...)44cdf0e10cSrcweir inline void dbg_msg( const char* pString, ... )
45cdf0e10cSrcweir {
46cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
47cdf0e10cSrcweir va_list ap;
48cdf0e10cSrcweir va_start( ap, pString );
49cdf0e10cSrcweir vfprintf( stderr, pString, ap );
50cdf0e10cSrcweir va_end( ap );
51cdf0e10cSrcweir #else
52cdf0e10cSrcweir (void)pString;
53cdf0e10cSrcweir #endif
54cdf0e10cSrcweir }
55cdf0e10cSrcweir
56cdf0e10cSrcweir #define FAIL_SHUTDOWN_STATE( x, y, z ) \
57cdf0e10cSrcweir if( x != SANE_STATUS_GOOD ) \
58cdf0e10cSrcweir { \
59cdf0e10cSrcweir dump_state( "%s returned error %d (%s)\n", \
60cdf0e10cSrcweir y, x, p_strstatus( x ) ); \
61cdf0e10cSrcweir DeInit(); \
62cdf0e10cSrcweir return z; \
63cdf0e10cSrcweir }
64cdf0e10cSrcweir
65cdf0e10cSrcweir #define FAIL_STATE( x, y, z ) \
66cdf0e10cSrcweir if( x != SANE_STATUS_GOOD ) \
67cdf0e10cSrcweir { \
68cdf0e10cSrcweir dump_state( "%s returned error %d (%s)\n", \
69cdf0e10cSrcweir y, x, p_strstatus( x ) ); \
70cdf0e10cSrcweir return z; \
71cdf0e10cSrcweir }
72cdf0e10cSrcweir
73cdf0e10cSrcweir #define DUMP_STATE( x, y ) \
74cdf0e10cSrcweir if( x != SANE_STATUS_GOOD ) \
75cdf0e10cSrcweir { \
76cdf0e10cSrcweir dump_state( "%s returned error %d (%s)\n", \
77cdf0e10cSrcweir y, x, p_strstatus( x ) ); \
78cdf0e10cSrcweir }
79cdf0e10cSrcweir
80cdf0e10cSrcweir #define CHECK_STATE( x, y ) \
81cdf0e10cSrcweir if( x != SANE_STATUS_GOOD ) \
82cdf0e10cSrcweir { \
83cdf0e10cSrcweir dump_state( "%s returned error %d (%s)\n", \
84cdf0e10cSrcweir y, x, p_strstatus( x ) ); \
85cdf0e10cSrcweir } \
86cdf0e10cSrcweir else
87cdf0e10cSrcweir
88cdf0e10cSrcweir int Sane::nRefCount = 0;
89cdf0e10cSrcweir oslModule Sane::pSaneLib = 0;
90cdf0e10cSrcweir SANE_Int Sane::nVersion = 0;
91cdf0e10cSrcweir SANE_Device** Sane::ppDevices = 0;
92cdf0e10cSrcweir int Sane::nDevices = 0;
93cdf0e10cSrcweir
94cdf0e10cSrcweir SANE_Status (*Sane::p_init)( SANE_Int*,
95cdf0e10cSrcweir SANE_Auth_Callback ) = 0;
96cdf0e10cSrcweir void (*Sane::p_exit)() = 0;
97cdf0e10cSrcweir SANE_Status (*Sane::p_get_devices)( const SANE_Device***,
98cdf0e10cSrcweir SANE_Bool ) = 0;
99cdf0e10cSrcweir SANE_Status (*Sane::p_open)( SANE_String_Const, SANE_Handle ) = 0;
100cdf0e10cSrcweir void (*Sane::p_close)( SANE_Handle ) = 0;
101cdf0e10cSrcweir const SANE_Option_Descriptor* (*Sane::p_get_option_descriptor)(
102cdf0e10cSrcweir SANE_Handle, SANE_Int ) = 0;
103cdf0e10cSrcweir SANE_Status (*Sane::p_control_option)( SANE_Handle, SANE_Int,
104cdf0e10cSrcweir SANE_Action, void*,
105cdf0e10cSrcweir SANE_Int* ) = 0;
106cdf0e10cSrcweir SANE_Status (*Sane::p_get_parameters)( SANE_Handle,
107cdf0e10cSrcweir SANE_Parameters* ) = 0;
108cdf0e10cSrcweir SANE_Status (*Sane::p_start)( SANE_Handle ) = 0;
109cdf0e10cSrcweir SANE_Status (*Sane::p_read)( SANE_Handle, SANE_Byte*, SANE_Int,
110cdf0e10cSrcweir SANE_Int* ) = 0;
111cdf0e10cSrcweir void (*Sane::p_cancel)( SANE_Handle ) = 0;
112cdf0e10cSrcweir SANE_Status (*Sane::p_set_io_mode)( SANE_Handle, SANE_Bool ) = 0;
113cdf0e10cSrcweir SANE_Status (*Sane::p_get_select_fd)( SANE_Handle, SANE_Int* ) = 0;
114cdf0e10cSrcweir SANE_String_Const (*Sane::p_strstatus)( SANE_Status ) = 0;
115cdf0e10cSrcweir
116cdf0e10cSrcweir static sal_Bool bSaneSymbolLoadFailed = sal_False;
117cdf0e10cSrcweir
LoadSymbol(const char * pSymbolname)118cdf0e10cSrcweir inline oslGenericFunction Sane::LoadSymbol( const char* pSymbolname )
119cdf0e10cSrcweir {
120cdf0e10cSrcweir oslGenericFunction pFunction = osl_getAsciiFunctionSymbol( pSaneLib, pSymbolname );
121cdf0e10cSrcweir if( ! pFunction )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir fprintf( stderr, "Could not load symbol %s\n",
124cdf0e10cSrcweir pSymbolname );
125cdf0e10cSrcweir bSaneSymbolLoadFailed = sal_True;
126cdf0e10cSrcweir }
127cdf0e10cSrcweir return pFunction;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir
ControlOption(int nOption,SANE_Action nAction,void * pData)130cdf0e10cSrcweir SANE_Status Sane::ControlOption( int nOption, SANE_Action nAction,
131cdf0e10cSrcweir void* pData )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir SANE_Status nStatus = SANE_STATUS_GOOD;
134cdf0e10cSrcweir SANE_Int nInfo = 0;
135cdf0e10cSrcweir
136cdf0e10cSrcweir nStatus = p_control_option( maHandle, (SANE_Int)nOption,
137cdf0e10cSrcweir nAction, pData, &nInfo );
138cdf0e10cSrcweir DUMP_STATE( nStatus, "sane_control_option" );
139cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
140cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir const char* pAction = "Unknown";
143cdf0e10cSrcweir switch( nAction )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir case SANE_ACTION_GET_VALUE:
146cdf0e10cSrcweir pAction = "SANE_ACTION_GET_VALUE";break;
147cdf0e10cSrcweir case SANE_ACTION_SET_VALUE:
148cdf0e10cSrcweir pAction = "SANE_ACTION_SET_VALUE";break;
149cdf0e10cSrcweir case SANE_ACTION_SET_AUTO:
150cdf0e10cSrcweir pAction = "SANE_ACTION_SET_AUTO";break;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir dbg_msg( "Option: \"%s\" action: %s\n",
153cdf0e10cSrcweir ByteString( GetOptionName( nOption ), gsl_getSystemTextEncoding() ).GetBuffer(),
154cdf0e10cSrcweir pAction );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir #endif
157cdf0e10cSrcweir // if( nInfo & ( SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS ) )
158cdf0e10cSrcweir if( nInfo & SANE_INFO_RELOAD_OPTIONS )
159cdf0e10cSrcweir ReloadOptions();
160cdf0e10cSrcweir return nStatus;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir
Sane()163cdf0e10cSrcweir Sane::Sane() :
164cdf0e10cSrcweir mppOptions( 0 ),
165cdf0e10cSrcweir mnOptions( 0 ),
166cdf0e10cSrcweir mnDevice( -1 ),
167cdf0e10cSrcweir maHandle( 0 )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir if( ! nRefCount || ! pSaneLib )
170cdf0e10cSrcweir Init();
171cdf0e10cSrcweir nRefCount++;
172cdf0e10cSrcweir };
173cdf0e10cSrcweir
~Sane()174cdf0e10cSrcweir Sane::~Sane()
175cdf0e10cSrcweir {
176cdf0e10cSrcweir if( IsOpen() )
177cdf0e10cSrcweir Close();
178cdf0e10cSrcweir nRefCount--;
179cdf0e10cSrcweir if( ! nRefCount && pSaneLib )
180cdf0e10cSrcweir DeInit();
181cdf0e10cSrcweir }
182cdf0e10cSrcweir
Init()183cdf0e10cSrcweir void Sane::Init()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir ::rtl::OUString sSaneLibName( ::rtl::OUString::createFromAscii( "libsane" SAL_DLLEXTENSION ) );
186cdf0e10cSrcweir pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
187cdf0e10cSrcweir if( ! pSaneLib )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir sSaneLibName = ::rtl::OUString::createFromAscii( "libsane" SAL_DLLEXTENSION ".1" );
190cdf0e10cSrcweir pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
191cdf0e10cSrcweir }
192cdf0e10cSrcweir // try reasonable places that might not be in the library search path
193cdf0e10cSrcweir if( ! pSaneLib )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir ::rtl::OUString sSaneLibSystemPath( ::rtl::OUString::createFromAscii( "/usr/local/lib/libsane" SAL_DLLEXTENSION ) );
196cdf0e10cSrcweir osl_getFileURLFromSystemPath( sSaneLibSystemPath.pData, &sSaneLibName.pData );
197cdf0e10cSrcweir pSaneLib = osl_loadModule( sSaneLibName.pData, SAL_LOADMODULE_LAZY );
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
200cdf0e10cSrcweir if( pSaneLib )
201cdf0e10cSrcweir {
202cdf0e10cSrcweir bSaneSymbolLoadFailed = sal_False;
203cdf0e10cSrcweir p_init = (SANE_Status(*)(SANE_Int*, SANE_Auth_Callback ))
204cdf0e10cSrcweir LoadSymbol( "sane_init" );
205cdf0e10cSrcweir p_exit = (void(*)())
206cdf0e10cSrcweir LoadSymbol( "sane_exit" );
207cdf0e10cSrcweir p_get_devices = (SANE_Status(*)(const SANE_Device***,
208cdf0e10cSrcweir SANE_Bool ))
209cdf0e10cSrcweir LoadSymbol( "sane_get_devices" );
210cdf0e10cSrcweir p_open = (SANE_Status(*)(SANE_String_Const, SANE_Handle ))
211cdf0e10cSrcweir LoadSymbol( "sane_open" );
212cdf0e10cSrcweir p_close = (void(*)(SANE_Handle))
213cdf0e10cSrcweir LoadSymbol( "sane_close" );
214cdf0e10cSrcweir p_get_option_descriptor = (const SANE_Option_Descriptor*(*)(SANE_Handle,
215cdf0e10cSrcweir SANE_Int))
216cdf0e10cSrcweir LoadSymbol( "sane_get_option_descriptor" );
217cdf0e10cSrcweir p_control_option = (SANE_Status(*)(SANE_Handle, SANE_Int,
218cdf0e10cSrcweir SANE_Action, void*, SANE_Int*))
219cdf0e10cSrcweir LoadSymbol( "sane_control_option" );
220cdf0e10cSrcweir p_get_parameters = (SANE_Status(*)(SANE_Handle,SANE_Parameters*))
221cdf0e10cSrcweir LoadSymbol( "sane_get_parameters" );
222cdf0e10cSrcweir p_start = (SANE_Status(*)(SANE_Handle))
223cdf0e10cSrcweir LoadSymbol( "sane_start" );
224cdf0e10cSrcweir p_read = (SANE_Status(*)(SANE_Handle, SANE_Byte*,
225cdf0e10cSrcweir SANE_Int, SANE_Int* ))
226cdf0e10cSrcweir LoadSymbol( "sane_read" );
227cdf0e10cSrcweir p_cancel = (void(*)(SANE_Handle))
228cdf0e10cSrcweir LoadSymbol( "sane_cancel" );
229cdf0e10cSrcweir p_set_io_mode = (SANE_Status(*)(SANE_Handle, SANE_Bool))
230cdf0e10cSrcweir LoadSymbol( "sane_set_io_mode" );
231cdf0e10cSrcweir p_get_select_fd = (SANE_Status(*)(SANE_Handle, SANE_Int*))
232cdf0e10cSrcweir LoadSymbol( "sane_get_select_fd" );
233cdf0e10cSrcweir p_strstatus = (SANE_String_Const(*)(SANE_Status))
234cdf0e10cSrcweir LoadSymbol( "sane_strstatus" );
235cdf0e10cSrcweir if( bSaneSymbolLoadFailed )
236cdf0e10cSrcweir DeInit();
237cdf0e10cSrcweir else
238cdf0e10cSrcweir {
239cdf0e10cSrcweir SANE_Status nStatus = p_init( &nVersion, 0 );
240cdf0e10cSrcweir FAIL_SHUTDOWN_STATE( nStatus, "sane_init", );
241cdf0e10cSrcweir nStatus = p_get_devices( (const SANE_Device***)&ppDevices,
242cdf0e10cSrcweir SANE_FALSE );
243cdf0e10cSrcweir FAIL_SHUTDOWN_STATE( nStatus, "sane_get_devices", );
244cdf0e10cSrcweir for( nDevices = 0 ; ppDevices[ nDevices ]; nDevices++ ) ;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir }
247cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
248cdf0e10cSrcweir else
249cdf0e10cSrcweir fprintf( stderr, "libsane%s could not be opened: %s\n", SAL_DLLEXTENSION,
250cdf0e10cSrcweir dlerror() );
251cdf0e10cSrcweir #endif
252cdf0e10cSrcweir }
253cdf0e10cSrcweir
DeInit()254cdf0e10cSrcweir void Sane::DeInit()
255cdf0e10cSrcweir {
256cdf0e10cSrcweir if( pSaneLib )
257cdf0e10cSrcweir {
258cdf0e10cSrcweir p_exit();
259cdf0e10cSrcweir osl_unloadModule( pSaneLib );
260cdf0e10cSrcweir pSaneLib = 0;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir }
263cdf0e10cSrcweir
ReloadDevices()264cdf0e10cSrcweir void Sane::ReloadDevices()
265cdf0e10cSrcweir {
266cdf0e10cSrcweir if( IsOpen() )
267cdf0e10cSrcweir Close();
268cdf0e10cSrcweir DeInit();
269cdf0e10cSrcweir Init();
270cdf0e10cSrcweir }
271cdf0e10cSrcweir
ReloadOptions()272cdf0e10cSrcweir void Sane::ReloadOptions()
273cdf0e10cSrcweir {
274cdf0e10cSrcweir if( ! IsOpen() )
275cdf0e10cSrcweir return;
276cdf0e10cSrcweir
277cdf0e10cSrcweir SANE_Option_Descriptor* pZero = (SANE_Option_Descriptor*)
278cdf0e10cSrcweir p_get_option_descriptor( maHandle, 0 );
279cdf0e10cSrcweir SANE_Word pOptions[2];
280cdf0e10cSrcweir SANE_Status nStatus = p_control_option( maHandle, 0, SANE_ACTION_GET_VALUE,
281cdf0e10cSrcweir (void*)pOptions, NULL );
282cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
283cdf0e10cSrcweir fprintf( stderr, "Error: sane driver returned %s while reading number of options !\n", p_strstatus( nStatus ) );
284cdf0e10cSrcweir
285cdf0e10cSrcweir mnOptions = pOptions[ 0 ];
286cdf0e10cSrcweir if( (size_t)pZero->size > sizeof( SANE_Word ) )
287cdf0e10cSrcweir fprintf( stderr, "driver returned numer of options with larger size tha SANE_Word !!!\n" );
288cdf0e10cSrcweir if( mppOptions )
289cdf0e10cSrcweir delete [] mppOptions;
290cdf0e10cSrcweir mppOptions = (const SANE_Option_Descriptor**)new SANE_Option_Descriptor*[ mnOptions ];
291cdf0e10cSrcweir mppOptions[ 0 ] = (SANE_Option_Descriptor*)pZero;
292cdf0e10cSrcweir for( int i = 1; i < mnOptions; i++ )
293cdf0e10cSrcweir mppOptions[ i ] = (SANE_Option_Descriptor*)
294cdf0e10cSrcweir p_get_option_descriptor( maHandle, i );
295cdf0e10cSrcweir
296cdf0e10cSrcweir CheckConsistency( NULL, sal_True );
297cdf0e10cSrcweir
298cdf0e10cSrcweir maReloadOptionsLink.Call( this );
299cdf0e10cSrcweir }
300cdf0e10cSrcweir
Open(const char * name)301cdf0e10cSrcweir sal_Bool Sane::Open( const char* name )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir int i;
304cdf0e10cSrcweir
305cdf0e10cSrcweir SANE_Status nStatus = p_open( (SANE_String_Const)name, &maHandle );
306cdf0e10cSrcweir FAIL_STATE( nStatus, "sane_open", sal_False );
307cdf0e10cSrcweir
308cdf0e10cSrcweir ReloadOptions();
309cdf0e10cSrcweir
310cdf0e10cSrcweir if( mnDevice == -1 )
311cdf0e10cSrcweir {
312cdf0e10cSrcweir ByteString aDevice( name );
313cdf0e10cSrcweir for( i = 0; i < nDevices; i++ )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir if( aDevice.Equals( ppDevices[i]->name ) )
316cdf0e10cSrcweir {
317cdf0e10cSrcweir mnDevice = i;
318cdf0e10cSrcweir break;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir }
321cdf0e10cSrcweir }
322cdf0e10cSrcweir
323cdf0e10cSrcweir return sal_True;
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
Open(int n)326cdf0e10cSrcweir sal_Bool Sane::Open( int n )
327cdf0e10cSrcweir {
328cdf0e10cSrcweir if( n >= 0 && n < nDevices )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir mnDevice = n;
331cdf0e10cSrcweir return Open( (char*)ppDevices[n]->name );
332cdf0e10cSrcweir }
333cdf0e10cSrcweir return sal_False;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir
Close()336cdf0e10cSrcweir void Sane::Close()
337cdf0e10cSrcweir {
338cdf0e10cSrcweir if( maHandle )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir p_close( maHandle );
341cdf0e10cSrcweir delete [] mppOptions;
342cdf0e10cSrcweir mppOptions = 0;
343cdf0e10cSrcweir maHandle = 0;
344cdf0e10cSrcweir mnDevice = -1;
345cdf0e10cSrcweir }
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
GetOptionByName(const char * rName)348cdf0e10cSrcweir int Sane::GetOptionByName( const char* rName )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir int i;
351cdf0e10cSrcweir ByteString aOption( rName );
352cdf0e10cSrcweir for( i = 0; i < mnOptions; i++ )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir if( mppOptions[i]->name && aOption.Equals( mppOptions[i]->name ) )
355cdf0e10cSrcweir return i;
356cdf0e10cSrcweir }
357cdf0e10cSrcweir return -1;
358cdf0e10cSrcweir }
359cdf0e10cSrcweir
GetOptionValue(int n,sal_Bool & rRet)360cdf0e10cSrcweir sal_Bool Sane::GetOptionValue( int n, sal_Bool& rRet )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir if( ! maHandle || mppOptions[n]->type != SANE_TYPE_BOOL )
363cdf0e10cSrcweir return sal_False;
364cdf0e10cSrcweir SANE_Word nRet;
365cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, &nRet );
366cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
367cdf0e10cSrcweir return sal_False;
368cdf0e10cSrcweir
369cdf0e10cSrcweir rRet = nRet;
370cdf0e10cSrcweir return sal_True;
371cdf0e10cSrcweir }
372cdf0e10cSrcweir
GetOptionValue(int n,ByteString & rRet)373cdf0e10cSrcweir sal_Bool Sane::GetOptionValue( int n, ByteString& rRet )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir sal_Bool bSuccess = sal_False;
376cdf0e10cSrcweir if( ! maHandle || mppOptions[n]->type != SANE_TYPE_STRING )
377cdf0e10cSrcweir return sal_False;
378cdf0e10cSrcweir char* pRet = new char[mppOptions[n]->size+1];
379cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pRet );
380cdf0e10cSrcweir if( nStatus == SANE_STATUS_GOOD )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir bSuccess = sal_True;
383cdf0e10cSrcweir rRet = pRet;
384cdf0e10cSrcweir }
385cdf0e10cSrcweir delete [] pRet;
386cdf0e10cSrcweir return bSuccess;
387cdf0e10cSrcweir }
388cdf0e10cSrcweir
GetOptionValue(int n,double & rRet,int nElement)389cdf0e10cSrcweir sal_Bool Sane::GetOptionValue( int n, double& rRet, int nElement )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir sal_Bool bSuccess = sal_False;
392cdf0e10cSrcweir
393cdf0e10cSrcweir if( ! maHandle || ( mppOptions[n]->type != SANE_TYPE_INT &&
394cdf0e10cSrcweir mppOptions[n]->type != SANE_TYPE_FIXED ) )
395cdf0e10cSrcweir return sal_False;
396cdf0e10cSrcweir
397cdf0e10cSrcweir SANE_Word* pRet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
398cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pRet );
399cdf0e10cSrcweir if( nStatus == SANE_STATUS_GOOD )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir bSuccess = sal_True;
402cdf0e10cSrcweir if( mppOptions[n]->type == SANE_TYPE_INT )
403cdf0e10cSrcweir rRet = (double)pRet[ nElement ];
404cdf0e10cSrcweir else
405cdf0e10cSrcweir rRet = SANE_UNFIX( pRet[nElement] );
406cdf0e10cSrcweir }
407cdf0e10cSrcweir delete [] pRet;
408cdf0e10cSrcweir return bSuccess;
409cdf0e10cSrcweir }
410cdf0e10cSrcweir
GetOptionValue(int n,double * pSet)411cdf0e10cSrcweir sal_Bool Sane::GetOptionValue( int n, double* pSet )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir if( ! maHandle || ! ( mppOptions[n]->type == SANE_TYPE_FIXED ||
414cdf0e10cSrcweir mppOptions[n]->type == SANE_TYPE_INT ) )
415cdf0e10cSrcweir return sal_False;
416cdf0e10cSrcweir
417cdf0e10cSrcweir SANE_Word* pFixedSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
418cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pFixedSet );
419cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
420cdf0e10cSrcweir {
421cdf0e10cSrcweir delete [] pFixedSet;
422cdf0e10cSrcweir return sal_False;
423cdf0e10cSrcweir }
424cdf0e10cSrcweir for( size_t i = 0; i <mppOptions[n]->size/sizeof(SANE_Word); i++ )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir if( mppOptions[n]->type == SANE_TYPE_FIXED )
427cdf0e10cSrcweir pSet[i] = SANE_UNFIX( pFixedSet[i] );
428cdf0e10cSrcweir else
429cdf0e10cSrcweir pSet[i] = (double) pFixedSet[i];
430cdf0e10cSrcweir }
431cdf0e10cSrcweir delete [] pFixedSet;
432cdf0e10cSrcweir return sal_True;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
SetOptionValue(int n,sal_Bool bSet)435cdf0e10cSrcweir sal_Bool Sane::SetOptionValue( int n, sal_Bool bSet )
436cdf0e10cSrcweir {
437cdf0e10cSrcweir if( ! maHandle || mppOptions[n]->type != SANE_TYPE_BOOL )
438cdf0e10cSrcweir return sal_False;
439cdf0e10cSrcweir SANE_Word nRet = bSet ? SANE_TRUE : SANE_FALSE;
440cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, &nRet );
441cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
442cdf0e10cSrcweir return sal_False;
443cdf0e10cSrcweir return sal_True;
444cdf0e10cSrcweir }
445cdf0e10cSrcweir
SetOptionValue(int n,const String & rSet)446cdf0e10cSrcweir sal_Bool Sane::SetOptionValue( int n, const String& rSet )
447cdf0e10cSrcweir {
448cdf0e10cSrcweir if( ! maHandle || mppOptions[n]->type != SANE_TYPE_STRING )
449cdf0e10cSrcweir return sal_False;
450cdf0e10cSrcweir ByteString aSet( rSet, gsl_getSystemTextEncoding() );
451cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, (void*)aSet.GetBuffer() );
452cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
453cdf0e10cSrcweir return sal_False;
454cdf0e10cSrcweir return sal_True;
455cdf0e10cSrcweir }
456cdf0e10cSrcweir
SetOptionValue(int n,double fSet,int nElement)457cdf0e10cSrcweir sal_Bool Sane::SetOptionValue( int n, double fSet, int nElement )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir sal_Bool bSuccess = sal_False;
460cdf0e10cSrcweir
461cdf0e10cSrcweir if( ! maHandle || ( mppOptions[n]->type != SANE_TYPE_INT &&
462cdf0e10cSrcweir mppOptions[n]->type != SANE_TYPE_FIXED ) )
463cdf0e10cSrcweir return sal_False;
464cdf0e10cSrcweir
465cdf0e10cSrcweir SANE_Status nStatus;
466cdf0e10cSrcweir if( mppOptions[n]->size/sizeof(SANE_Word) > 1 )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir SANE_Word* pSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
469cdf0e10cSrcweir nStatus = ControlOption( n, SANE_ACTION_GET_VALUE, pSet );
470cdf0e10cSrcweir if( nStatus == SANE_STATUS_GOOD )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir pSet[nElement] = mppOptions[n]->type == SANE_TYPE_INT ?
473cdf0e10cSrcweir (SANE_Word)fSet : SANE_FIX( fSet );
474cdf0e10cSrcweir nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, pSet );
475cdf0e10cSrcweir }
476cdf0e10cSrcweir delete [] pSet;
477cdf0e10cSrcweir }
478cdf0e10cSrcweir else
479cdf0e10cSrcweir {
480cdf0e10cSrcweir SANE_Word nSetTo =
481cdf0e10cSrcweir mppOptions[n]->type == SANE_TYPE_INT ?
482cdf0e10cSrcweir (SANE_Word)fSet : SANE_FIX( fSet );
483cdf0e10cSrcweir
484cdf0e10cSrcweir nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, &nSetTo );
485cdf0e10cSrcweir if( nStatus == SANE_STATUS_GOOD )
486cdf0e10cSrcweir bSuccess = sal_True;
487cdf0e10cSrcweir }
488cdf0e10cSrcweir return bSuccess;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir
SetOptionValue(int n,double * pSet)491cdf0e10cSrcweir sal_Bool Sane::SetOptionValue( int n, double* pSet )
492cdf0e10cSrcweir {
493cdf0e10cSrcweir if( ! maHandle || ( mppOptions[n]->type != SANE_TYPE_INT &&
494cdf0e10cSrcweir mppOptions[n]->type != SANE_TYPE_FIXED ) )
495cdf0e10cSrcweir return sal_False;
496cdf0e10cSrcweir SANE_Word* pFixedSet = new SANE_Word[mppOptions[n]->size/sizeof(SANE_Word)];
497cdf0e10cSrcweir for( size_t i = 0; i < mppOptions[n]->size/sizeof(SANE_Word); i++ )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir if( mppOptions[n]->type == SANE_TYPE_FIXED )
500cdf0e10cSrcweir pFixedSet[i] = SANE_FIX( pSet[i] );
501cdf0e10cSrcweir else
502cdf0e10cSrcweir pFixedSet[i] = (SANE_Word)pSet[i];
503cdf0e10cSrcweir }
504cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, pFixedSet );
505cdf0e10cSrcweir delete [] pFixedSet;
506cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
507cdf0e10cSrcweir return sal_False;
508cdf0e10cSrcweir return sal_True;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511cdf0e10cSrcweir enum FrameStyleType {
512cdf0e10cSrcweir FrameStyle_BW, FrameStyle_Gray, FrameStyle_RGB, FrameStyle_Separated
513cdf0e10cSrcweir };
514cdf0e10cSrcweir
515cdf0e10cSrcweir #define BYTE_BUFFER_SIZE 32768
516cdf0e10cSrcweir
_ReadValue(FILE * fp,int depth)517cdf0e10cSrcweir static inline sal_uInt8 _ReadValue( FILE* fp, int depth )
518cdf0e10cSrcweir {
519cdf0e10cSrcweir if( depth == 16 )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir sal_uInt16 nWord;
522cdf0e10cSrcweir // data always come in native byte order !
523cdf0e10cSrcweir // 16 bits is not really supported by backends as of now
524cdf0e10cSrcweir // e.g. UMAX Astra 1200S delivers 16 bit but in BIGENDIAN
525cdf0e10cSrcweir // against SANE documentation (xscanimage gets the same result
526cdf0e10cSrcweir // as we do
527cdf0e10cSrcweir fread( &nWord, 1, 2, fp );
528cdf0e10cSrcweir return (sal_uInt8)( nWord / 256 );
529cdf0e10cSrcweir }
530cdf0e10cSrcweir sal_uInt8 nByte;
531cdf0e10cSrcweir fread( &nByte, 1, 1, fp );
532cdf0e10cSrcweir return nByte;
533cdf0e10cSrcweir }
534cdf0e10cSrcweir
CheckConsistency(const char * pMes,sal_Bool bInit)535cdf0e10cSrcweir sal_Bool Sane::CheckConsistency( const char* pMes, sal_Bool bInit )
536cdf0e10cSrcweir {
537cdf0e10cSrcweir static SANE_Option_Descriptor** pDescArray = NULL;
538cdf0e10cSrcweir static SANE_Option_Descriptor* pZero = NULL;
539cdf0e10cSrcweir
540cdf0e10cSrcweir if( bInit )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir pDescArray = (SANE_Option_Descriptor**)mppOptions;
543cdf0e10cSrcweir if( mppOptions )
544cdf0e10cSrcweir pZero = (SANE_Option_Descriptor*)mppOptions[0];
545cdf0e10cSrcweir return sal_True;
546cdf0e10cSrcweir }
547cdf0e10cSrcweir
548cdf0e10cSrcweir sal_Bool bConsistent = sal_True;
549cdf0e10cSrcweir
550cdf0e10cSrcweir if( pDescArray != mppOptions )
551cdf0e10cSrcweir bConsistent = sal_False;
552cdf0e10cSrcweir if( pZero != mppOptions[0] )
553cdf0e10cSrcweir bConsistent = sal_False;
554cdf0e10cSrcweir
555cdf0e10cSrcweir if( ! bConsistent )
556cdf0e10cSrcweir dbg_msg( "Sane is not consistent. (%s)\n", pMes );
557cdf0e10cSrcweir
558cdf0e10cSrcweir return bConsistent;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir
Start(BitmapTransporter & rBitmap)561cdf0e10cSrcweir sal_Bool Sane::Start( BitmapTransporter& rBitmap )
562cdf0e10cSrcweir {
563cdf0e10cSrcweir int nStream = 0, nLine = 0, i = 0;
564cdf0e10cSrcweir SANE_Parameters aParams;
565cdf0e10cSrcweir FrameStyleType eType = FrameStyle_Gray;
566cdf0e10cSrcweir sal_Bool bSuccess = sal_True;
567cdf0e10cSrcweir sal_Bool bWidthSet = sal_False;
568cdf0e10cSrcweir
569cdf0e10cSrcweir if( ! maHandle )
570cdf0e10cSrcweir return sal_False;
571cdf0e10cSrcweir
572cdf0e10cSrcweir int nWidthMM = 0;
573cdf0e10cSrcweir int nHeightMM = 0;
574cdf0e10cSrcweir double fTLx, fTLy, fBRx, fBRy, fResl = 0.0;
575cdf0e10cSrcweir int nOption;
576cdf0e10cSrcweir if( ( nOption = GetOptionByName( "tl-x" ) ) != -1 &&
577cdf0e10cSrcweir GetOptionValue( nOption, fTLx, 0 ) &&
578cdf0e10cSrcweir GetOptionUnit( nOption ) == SANE_UNIT_MM )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir if( ( nOption = GetOptionByName( "br-x" ) ) != -1 &&
581cdf0e10cSrcweir GetOptionValue( nOption, fBRx, 0 ) &&
582cdf0e10cSrcweir GetOptionUnit( nOption ) == SANE_UNIT_MM )
583cdf0e10cSrcweir {
584cdf0e10cSrcweir nWidthMM = (int)fabs(fBRx - fTLx);
585cdf0e10cSrcweir }
586cdf0e10cSrcweir }
587cdf0e10cSrcweir if( ( nOption = GetOptionByName( "tl-y" ) ) != -1 &&
588cdf0e10cSrcweir GetOptionValue( nOption, fTLy, 0 ) &&
589cdf0e10cSrcweir GetOptionUnit( nOption ) == SANE_UNIT_MM )
590cdf0e10cSrcweir {
591cdf0e10cSrcweir if( ( nOption = GetOptionByName( "br-y" ) ) != -1 &&
592cdf0e10cSrcweir GetOptionValue( nOption, fBRy, 0 ) &&
593cdf0e10cSrcweir GetOptionUnit( nOption ) == SANE_UNIT_MM )
594cdf0e10cSrcweir {
595cdf0e10cSrcweir nHeightMM = (int)fabs(fBRy - fTLy);
596cdf0e10cSrcweir }
597cdf0e10cSrcweir }
598cdf0e10cSrcweir if( ( nOption = GetOptionByName( "resolution" ) ) != -1 )
599cdf0e10cSrcweir GetOptionValue( nOption, fResl );
600cdf0e10cSrcweir
601cdf0e10cSrcweir sal_uInt8* pBuffer = NULL;
602cdf0e10cSrcweir
603cdf0e10cSrcweir SANE_Status nStatus = SANE_STATUS_GOOD;
604cdf0e10cSrcweir
605cdf0e10cSrcweir rBitmap.lock();
606cdf0e10cSrcweir SvMemoryStream& aConverter = rBitmap.getStream();
607cdf0e10cSrcweir aConverter.Seek( 0 );
608cdf0e10cSrcweir aConverter.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
609cdf0e10cSrcweir
610cdf0e10cSrcweir // write bitmap stream header
611cdf0e10cSrcweir aConverter << 'B' << 'M';
612cdf0e10cSrcweir aConverter << (sal_uInt32) 0;
613cdf0e10cSrcweir aConverter << (sal_uInt32) 0;
614cdf0e10cSrcweir aConverter << (sal_uInt32) 60;
615cdf0e10cSrcweir
616cdf0e10cSrcweir // write BITMAPINFOHEADER
617cdf0e10cSrcweir aConverter << (sal_uInt32)40;
618cdf0e10cSrcweir aConverter << (sal_uInt32)0; // fill in width later
619cdf0e10cSrcweir aConverter << (sal_uInt32)0; // fill in height later
620cdf0e10cSrcweir aConverter << (sal_uInt16)1;
621cdf0e10cSrcweir // create header for 24 bits
622cdf0e10cSrcweir // correct later if necessary
623cdf0e10cSrcweir aConverter << (sal_uInt16)24;
624cdf0e10cSrcweir aConverter << (sal_uInt32)0;
625cdf0e10cSrcweir aConverter << (sal_uInt32)0;
626cdf0e10cSrcweir aConverter << (sal_uInt32)0;
627cdf0e10cSrcweir aConverter << (sal_uInt32)0;
628cdf0e10cSrcweir aConverter << (sal_uInt32)0;
629cdf0e10cSrcweir aConverter << (sal_uInt32)0;
630cdf0e10cSrcweir
631cdf0e10cSrcweir for( nStream=0; nStream < 3 && bSuccess ; nStream++ )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir nStatus = p_start( maHandle );
634cdf0e10cSrcweir DUMP_STATE( nStatus, "sane_start" );
635cdf0e10cSrcweir CheckConsistency( "sane_start" );
636cdf0e10cSrcweir if( nStatus == SANE_STATUS_GOOD )
637cdf0e10cSrcweir {
638cdf0e10cSrcweir nStatus = p_get_parameters( maHandle, &aParams );
639cdf0e10cSrcweir DUMP_STATE( nStatus, "sane_get_parameters" );
640cdf0e10cSrcweir CheckConsistency( "sane_get_parameters" );
641cdf0e10cSrcweir if (nStatus != SANE_STATUS_GOOD || aParams.bytes_per_line == 0)
642cdf0e10cSrcweir {
643cdf0e10cSrcweir bSuccess = sal_False;
644cdf0e10cSrcweir break;
645cdf0e10cSrcweir }
646cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
647cdf0e10cSrcweir const char* ppFormats[] = { "SANE_FRAME_GRAY", "SANE_FRAME_RGB",
648cdf0e10cSrcweir "SANE_FRAME_RED", "SANE_FRAME_GREEN",
649cdf0e10cSrcweir "SANE_FRAME_BLUE", "Unknown !!!" };
650cdf0e10cSrcweir fprintf( stderr, "Parameters for frame %d:\n", nStream );
651cdf0e10cSrcweir if( aParams.format < 0 || aParams.format > 4 )
652cdf0e10cSrcweir aParams.format = (SANE_Frame)5;
653cdf0e10cSrcweir fprintf( stderr, "format: %s\n", ppFormats[ (int)aParams.format ] );
654cdf0e10cSrcweir fprintf( stderr, "last_frame: %s\n", aParams.last_frame ? "TRUE" : "FALSE" );
655cdf0e10cSrcweir fprintf( stderr, "depth: %d\n", (int)aParams.depth );
656cdf0e10cSrcweir fprintf( stderr, "pixels_per_line: %d\n", (int)aParams.pixels_per_line );
657cdf0e10cSrcweir fprintf( stderr, "bytes_per_line: %d\n", (int)aParams.bytes_per_line );
658cdf0e10cSrcweir #endif
659cdf0e10cSrcweir if( ! pBuffer )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir pBuffer = new sal_uInt8[ BYTE_BUFFER_SIZE < 4*aParams.bytes_per_line ? 4*aParams.bytes_per_line : BYTE_BUFFER_SIZE ];
662cdf0e10cSrcweir }
663cdf0e10cSrcweir
664cdf0e10cSrcweir if( aParams.last_frame )
665cdf0e10cSrcweir nStream=3;
666cdf0e10cSrcweir
667cdf0e10cSrcweir switch( aParams.format )
668cdf0e10cSrcweir {
669cdf0e10cSrcweir case SANE_FRAME_GRAY:
670cdf0e10cSrcweir eType = FrameStyle_Gray;
671cdf0e10cSrcweir if( aParams.depth == 1 )
672cdf0e10cSrcweir eType = FrameStyle_BW;
673cdf0e10cSrcweir break;
674cdf0e10cSrcweir case SANE_FRAME_RGB:
675cdf0e10cSrcweir eType = FrameStyle_RGB;
676cdf0e10cSrcweir break;
677cdf0e10cSrcweir case SANE_FRAME_RED:
678cdf0e10cSrcweir case SANE_FRAME_GREEN:
679cdf0e10cSrcweir case SANE_FRAME_BLUE:
680cdf0e10cSrcweir eType = FrameStyle_Separated;
681cdf0e10cSrcweir break;
682cdf0e10cSrcweir default:
683cdf0e10cSrcweir fprintf( stderr, "Warning: unknown frame style !!!\n" );
684cdf0e10cSrcweir }
685cdf0e10cSrcweir
686cdf0e10cSrcweir sal_Bool bSynchronousRead = sal_True;
687cdf0e10cSrcweir
688cdf0e10cSrcweir // should be fail safe, but ... ??
689cdf0e10cSrcweir nStatus = p_set_io_mode( maHandle, SANE_FALSE );
690cdf0e10cSrcweir CheckConsistency( "sane_set_io_mode" );
691cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
692cdf0e10cSrcweir {
693cdf0e10cSrcweir bSynchronousRead = sal_False;
694cdf0e10cSrcweir nStatus = p_set_io_mode( maHandle, SANE_TRUE );
695cdf0e10cSrcweir CheckConsistency( "sane_set_io_mode" );
696cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
697cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
698cdf0e10cSrcweir // what ?!?
699cdf0e10cSrcweir fprintf( stderr, "Sane::Start: driver is confused\n" );
700cdf0e10cSrcweir #endif
701cdf0e10cSrcweir }
702cdf0e10cSrcweir
703cdf0e10cSrcweir SANE_Int nLen=0;
704cdf0e10cSrcweir SANE_Int fd = 0;
705cdf0e10cSrcweir
706cdf0e10cSrcweir if( ! bSynchronousRead )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir nStatus = p_get_select_fd( maHandle, &fd );
709cdf0e10cSrcweir DUMP_STATE( nStatus, "sane_get_select_fd" );
710cdf0e10cSrcweir CheckConsistency( "sane_get_select_fd" );
711cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
712cdf0e10cSrcweir bSynchronousRead = sal_True;
713cdf0e10cSrcweir }
714cdf0e10cSrcweir FILE* pFrame = tmpfile();
715cdf0e10cSrcweir if( ! pFrame )
716cdf0e10cSrcweir {
717cdf0e10cSrcweir bSuccess = sal_False;
718cdf0e10cSrcweir break;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir do {
721cdf0e10cSrcweir if( ! bSynchronousRead )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir fd_set fdset;
724cdf0e10cSrcweir struct timeval tv;
725cdf0e10cSrcweir
726cdf0e10cSrcweir FD_ZERO( &fdset );
727cdf0e10cSrcweir FD_SET( (int)fd, &fdset );
728cdf0e10cSrcweir tv.tv_sec = 5;
729cdf0e10cSrcweir tv.tv_usec = 0;
730cdf0e10cSrcweir if( select( fd+1, &fdset, NULL, NULL, &tv ) == 0 )
731cdf0e10cSrcweir fprintf( stderr, "Timout on sane_read descriptor\n" );
732cdf0e10cSrcweir }
733cdf0e10cSrcweir nLen = 0;
734cdf0e10cSrcweir nStatus = p_read( maHandle, pBuffer, BYTE_BUFFER_SIZE, &nLen );
735cdf0e10cSrcweir CheckConsistency( "sane_read" );
736cdf0e10cSrcweir if( nLen && ( nStatus == SANE_STATUS_GOOD ||
737cdf0e10cSrcweir nStatus == SANE_STATUS_EOF ) )
738cdf0e10cSrcweir {
739cdf0e10cSrcweir fwrite( pBuffer, 1, nLen, pFrame );
740cdf0e10cSrcweir }
741cdf0e10cSrcweir else
742cdf0e10cSrcweir DUMP_STATE( nStatus, "sane_read" );
743cdf0e10cSrcweir } while( nStatus == SANE_STATUS_GOOD );
744cdf0e10cSrcweir if( nStatus != SANE_STATUS_EOF )
745cdf0e10cSrcweir {
746cdf0e10cSrcweir fclose( pFrame );
747cdf0e10cSrcweir bSuccess = sal_False;
748cdf0e10cSrcweir break;
749cdf0e10cSrcweir }
750cdf0e10cSrcweir
751cdf0e10cSrcweir int nFrameLength = ftell( pFrame );
752cdf0e10cSrcweir fseek( pFrame, 0, SEEK_SET );
753cdf0e10cSrcweir sal_uInt32 nWidth = (sal_uInt32) aParams.pixels_per_line;
754cdf0e10cSrcweir sal_uInt32 nHeight = (sal_uInt32) (nFrameLength / aParams.bytes_per_line);
755cdf0e10cSrcweir if( ! bWidthSet )
756cdf0e10cSrcweir {
757cdf0e10cSrcweir if( ! fResl )
758cdf0e10cSrcweir fResl = 300; // if all else fails that's a good guess
759cdf0e10cSrcweir if( ! nWidthMM )
760cdf0e10cSrcweir nWidthMM = (int)(((double)nWidth / fResl) * 25.4);
761cdf0e10cSrcweir if( ! nHeightMM )
762cdf0e10cSrcweir nHeightMM = (int)(((double)nHeight / fResl) * 25.4);
763cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
764cdf0e10cSrcweir fprintf( stderr, "set dimensions to (%d, %d) Pixel, (%d, %d) mm, resolution is %lg\n", (int)nWidth, (int)nHeight, (int)nWidthMM, (int)nHeightMM, fResl );
765cdf0e10cSrcweir #endif
766cdf0e10cSrcweir
767cdf0e10cSrcweir aConverter.Seek( 18 );
768cdf0e10cSrcweir aConverter << (sal_uInt32)nWidth;
769cdf0e10cSrcweir aConverter << (sal_uInt32)nHeight;
770cdf0e10cSrcweir aConverter.Seek( 38 );
771cdf0e10cSrcweir aConverter << (sal_uInt32)(1000*nWidth/nWidthMM);
772cdf0e10cSrcweir aConverter << (sal_uInt32)(1000*nHeight/nHeightMM);
773cdf0e10cSrcweir bWidthSet = sal_True;
774cdf0e10cSrcweir }
775cdf0e10cSrcweir aConverter.Seek(60);
776cdf0e10cSrcweir
777cdf0e10cSrcweir if( eType == FrameStyle_BW )
778cdf0e10cSrcweir {
779cdf0e10cSrcweir aConverter.Seek( 10 );
780cdf0e10cSrcweir aConverter << (sal_uInt32)64;
781cdf0e10cSrcweir aConverter.Seek( 28 );
782cdf0e10cSrcweir aConverter << (sal_uInt16) 1;
783cdf0e10cSrcweir aConverter.Seek( 54 );
784cdf0e10cSrcweir // write color table
785cdf0e10cSrcweir aConverter << (sal_uInt16)0xffff;
786cdf0e10cSrcweir aConverter << (sal_uInt8)0xff;
787cdf0e10cSrcweir aConverter << (sal_uInt8)0;
788cdf0e10cSrcweir aConverter << (sal_uInt32)0;
789cdf0e10cSrcweir aConverter.Seek( 64 );
790cdf0e10cSrcweir }
791cdf0e10cSrcweir else if( eType == FrameStyle_Gray )
792cdf0e10cSrcweir {
793cdf0e10cSrcweir aConverter.Seek( 10 );
794cdf0e10cSrcweir aConverter << (sal_uInt32)1084;
795cdf0e10cSrcweir aConverter.Seek( 28 );
796cdf0e10cSrcweir aConverter << (sal_uInt16) 8;
797cdf0e10cSrcweir aConverter.Seek( 54 );
798cdf0e10cSrcweir // write color table
799cdf0e10cSrcweir for( nLine = 0; nLine < 256; nLine++ )
800cdf0e10cSrcweir {
801cdf0e10cSrcweir aConverter << (sal_uInt8)nLine;
802cdf0e10cSrcweir aConverter << (sal_uInt8)nLine;
803cdf0e10cSrcweir aConverter << (sal_uInt8)nLine;
804cdf0e10cSrcweir aConverter << (sal_uInt8)0;
805cdf0e10cSrcweir }
806cdf0e10cSrcweir aConverter.Seek( 1084 );
807cdf0e10cSrcweir }
808cdf0e10cSrcweir
809cdf0e10cSrcweir for( nLine = nHeight-1;
810cdf0e10cSrcweir nLine >= 0; nLine-- )
811cdf0e10cSrcweir {
812cdf0e10cSrcweir fseek( pFrame, nLine * aParams.bytes_per_line, SEEK_SET );
813cdf0e10cSrcweir if( eType == FrameStyle_BW ||
814cdf0e10cSrcweir ( eType == FrameStyle_Gray && aParams.depth == 8 )
815cdf0e10cSrcweir )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir fread( pBuffer, 1, aParams.bytes_per_line, pFrame );
818cdf0e10cSrcweir aConverter.Write( pBuffer, aParams.bytes_per_line );
819cdf0e10cSrcweir }
820cdf0e10cSrcweir else if( eType == FrameStyle_Gray )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir for( i = 0; i < (aParams.pixels_per_line); i++ )
823cdf0e10cSrcweir {
824cdf0e10cSrcweir sal_uInt8 nGray = _ReadValue( pFrame, aParams.depth );
825cdf0e10cSrcweir aConverter << nGray;
826cdf0e10cSrcweir }
827cdf0e10cSrcweir }
828cdf0e10cSrcweir else if( eType == FrameStyle_RGB )
829cdf0e10cSrcweir {
830cdf0e10cSrcweir for( i = 0; i < (aParams.pixels_per_line); i++ )
831cdf0e10cSrcweir {
832cdf0e10cSrcweir sal_uInt8 nRed, nGreen, nBlue;
833cdf0e10cSrcweir nRed = _ReadValue( pFrame, aParams.depth );
834cdf0e10cSrcweir nGreen = _ReadValue( pFrame, aParams.depth );
835cdf0e10cSrcweir nBlue = _ReadValue( pFrame, aParams.depth );
836cdf0e10cSrcweir aConverter << nBlue;
837cdf0e10cSrcweir aConverter << nGreen;
838cdf0e10cSrcweir aConverter << nRed;
839cdf0e10cSrcweir }
840cdf0e10cSrcweir }
841cdf0e10cSrcweir else if( eType == FrameStyle_Separated )
842cdf0e10cSrcweir {
843cdf0e10cSrcweir for( i = 0; i < (aParams.pixels_per_line); i++ )
844cdf0e10cSrcweir {
845cdf0e10cSrcweir sal_uInt8 nValue = _ReadValue( pFrame, aParams.depth );
846cdf0e10cSrcweir switch( aParams.format )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir case SANE_FRAME_RED:
849cdf0e10cSrcweir aConverter.SeekRel( 2 );
850cdf0e10cSrcweir aConverter << nValue;
851cdf0e10cSrcweir break;
852cdf0e10cSrcweir case SANE_FRAME_GREEN:
853cdf0e10cSrcweir aConverter.SeekRel( 1 );
854cdf0e10cSrcweir aConverter << nValue;
855cdf0e10cSrcweir aConverter.SeekRel( 1 );
856cdf0e10cSrcweir break;
857cdf0e10cSrcweir case SANE_FRAME_BLUE:
858cdf0e10cSrcweir aConverter << nValue;
859cdf0e10cSrcweir aConverter.SeekRel( 2 );
860cdf0e10cSrcweir break;
861cdf0e10cSrcweir case SANE_FRAME_GRAY:
862cdf0e10cSrcweir case SANE_FRAME_RGB:
863cdf0e10cSrcweir break;
864cdf0e10cSrcweir }
865cdf0e10cSrcweir }
866cdf0e10cSrcweir }
867cdf0e10cSrcweir int nGap = aConverter.Tell() & 3;
868cdf0e10cSrcweir if( nGap )
869cdf0e10cSrcweir aConverter.SeekRel( 4-nGap );
870cdf0e10cSrcweir }
871cdf0e10cSrcweir fclose( pFrame ); // deletes tmpfile
872cdf0e10cSrcweir if( eType != FrameStyle_Separated )
873cdf0e10cSrcweir break;
874cdf0e10cSrcweir }
875cdf0e10cSrcweir else
876cdf0e10cSrcweir bSuccess = sal_False;
877cdf0e10cSrcweir }
878cdf0e10cSrcweir // get stream length
879cdf0e10cSrcweir aConverter.Seek( STREAM_SEEK_TO_END );
880cdf0e10cSrcweir int nPos = aConverter.Tell();
881cdf0e10cSrcweir
882cdf0e10cSrcweir aConverter.Seek( 2 );
883cdf0e10cSrcweir aConverter << (sal_uInt32) nPos+1;
884cdf0e10cSrcweir aConverter.Seek( 0 );
885cdf0e10cSrcweir
886cdf0e10cSrcweir rBitmap.unlock();
887cdf0e10cSrcweir
888cdf0e10cSrcweir if( bSuccess )
889cdf0e10cSrcweir {
890cdf0e10cSrcweir // only cancel a successful operation
891cdf0e10cSrcweir // sane disrupts memory else
892cdf0e10cSrcweir p_cancel( maHandle );
893cdf0e10cSrcweir CheckConsistency( "sane_cancel" );
894cdf0e10cSrcweir }
895cdf0e10cSrcweir if( pBuffer )
896cdf0e10cSrcweir delete [] pBuffer;
897cdf0e10cSrcweir
898cdf0e10cSrcweir ReloadOptions();
899cdf0e10cSrcweir
900cdf0e10cSrcweir
901cdf0e10cSrcweir dbg_msg( "Sane::Start returns with %s\n", bSuccess ? "TRUE" : "FALSE" );
902cdf0e10cSrcweir
903cdf0e10cSrcweir return bSuccess;
904cdf0e10cSrcweir }
905cdf0e10cSrcweir
GetRange(int n,double * & rpDouble)906cdf0e10cSrcweir int Sane::GetRange( int n, double*& rpDouble )
907cdf0e10cSrcweir {
908cdf0e10cSrcweir if( mppOptions[n]->constraint_type != SANE_CONSTRAINT_RANGE &&
909cdf0e10cSrcweir mppOptions[n]->constraint_type != SANE_CONSTRAINT_WORD_LIST )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir return -1;
912cdf0e10cSrcweir }
913cdf0e10cSrcweir
914cdf0e10cSrcweir rpDouble = 0;
915cdf0e10cSrcweir int nItems, i;
916cdf0e10cSrcweir sal_Bool bIsFixed = mppOptions[n]->type == SANE_TYPE_FIXED ? sal_True : sal_False;
917cdf0e10cSrcweir
918cdf0e10cSrcweir dbg_msg( "Sane::GetRange of option %s ", mppOptions[n]->name );
919cdf0e10cSrcweir if(mppOptions[n]->constraint_type == SANE_CONSTRAINT_RANGE )
920cdf0e10cSrcweir {
921cdf0e10cSrcweir double fMin, fMax, fQuant;
922cdf0e10cSrcweir if( bIsFixed )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir fMin = SANE_UNFIX( mppOptions[n]->constraint.range->min );
925cdf0e10cSrcweir fMax = SANE_UNFIX( mppOptions[n]->constraint.range->max );
926cdf0e10cSrcweir fQuant = SANE_UNFIX( mppOptions[n]->constraint.range->quant );
927cdf0e10cSrcweir }
928cdf0e10cSrcweir else
929cdf0e10cSrcweir {
930cdf0e10cSrcweir fMin = (double)mppOptions[n]->constraint.range->min;
931cdf0e10cSrcweir fMax = (double)mppOptions[n]->constraint.range->max;
932cdf0e10cSrcweir fQuant = (double)mppOptions[n]->constraint.range->quant;
933cdf0e10cSrcweir }
934cdf0e10cSrcweir if( fQuant != 0.0 )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir dbg_msg( "quantum range [ %lg ; %lg ; %lg ]\n",
937cdf0e10cSrcweir fMin, fQuant, fMax );
938cdf0e10cSrcweir nItems = (int)((fMax - fMin)/fQuant)+1;
939cdf0e10cSrcweir rpDouble = new double[ nItems ];
940cdf0e10cSrcweir double fValue = fMin;
941cdf0e10cSrcweir for( i = 0; i < nItems; i++, fValue += fQuant )
942cdf0e10cSrcweir rpDouble[i] = fValue;
943cdf0e10cSrcweir rpDouble[ nItems-1 ] = fMax;
944cdf0e10cSrcweir return nItems;
945cdf0e10cSrcweir }
946cdf0e10cSrcweir else
947cdf0e10cSrcweir {
948cdf0e10cSrcweir dbg_msg( "normal range [ %lg %lg ]\n",
949cdf0e10cSrcweir fMin, fMax );
950cdf0e10cSrcweir rpDouble = new double[2];
951cdf0e10cSrcweir rpDouble[0] = fMin;
952cdf0e10cSrcweir rpDouble[1] = fMax;
953cdf0e10cSrcweir return 0;
954cdf0e10cSrcweir }
955cdf0e10cSrcweir }
956cdf0e10cSrcweir else
957cdf0e10cSrcweir {
958cdf0e10cSrcweir nItems = mppOptions[n]->constraint.word_list[0];
959cdf0e10cSrcweir rpDouble = new double[nItems];
960cdf0e10cSrcweir for( i=0; i<nItems; i++ )
961cdf0e10cSrcweir {
962cdf0e10cSrcweir rpDouble[i] = bIsFixed ?
963cdf0e10cSrcweir SANE_UNFIX( mppOptions[n]->constraint.word_list[i+1] ) :
964cdf0e10cSrcweir (double)mppOptions[n]->constraint.word_list[i+1];
965cdf0e10cSrcweir }
966cdf0e10cSrcweir dbg_msg( "wordlist [ %lg ... %lg ]\n",
967cdf0e10cSrcweir rpDouble[ 0 ], rpDouble[ nItems-1 ] );
968cdf0e10cSrcweir return nItems;
969cdf0e10cSrcweir }
970cdf0e10cSrcweir }
971cdf0e10cSrcweir
972cdf0e10cSrcweir static const char *ppUnits[] = {
973cdf0e10cSrcweir "",
974cdf0e10cSrcweir "[Pixel]",
975cdf0e10cSrcweir "[Bit]",
976cdf0e10cSrcweir "[mm]",
977cdf0e10cSrcweir "[DPI]",
978cdf0e10cSrcweir "[%]",
979cdf0e10cSrcweir "[usec]"
980cdf0e10cSrcweir };
981cdf0e10cSrcweir
GetOptionUnitName(int n)982cdf0e10cSrcweir String Sane::GetOptionUnitName( int n )
983cdf0e10cSrcweir {
984cdf0e10cSrcweir String aText;
985cdf0e10cSrcweir SANE_Unit nUnit = mppOptions[n]->unit;
986cdf0e10cSrcweir size_t nUnitAsSize = (size_t)nUnit;
987*93ed1f29SArmin Le Grand if (nUnitAsSize >= sizeof(ppUnits)/sizeof(ppUnits[0]))
988cdf0e10cSrcweir aText = String::CreateFromAscii( "[unknown units]" );
989cdf0e10cSrcweir else
990cdf0e10cSrcweir aText = String( ppUnits[ nUnit ], gsl_getSystemTextEncoding() );
991cdf0e10cSrcweir return aText;
992cdf0e10cSrcweir }
993cdf0e10cSrcweir
ActivateButtonOption(int n)994cdf0e10cSrcweir sal_Bool Sane::ActivateButtonOption( int n )
995cdf0e10cSrcweir {
996cdf0e10cSrcweir SANE_Status nStatus = ControlOption( n, SANE_ACTION_SET_VALUE, NULL );
997cdf0e10cSrcweir if( nStatus != SANE_STATUS_GOOD )
998cdf0e10cSrcweir return sal_False;
999cdf0e10cSrcweir return sal_True;
1000cdf0e10cSrcweir }
1001