~ubuntu-branches/ubuntu/wily/python-imaging/wily

« back to all changes in this revision

Viewing changes to .pc/git-updates.diff/Sane/_sane.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-01-31 20:49:20 UTC
  • mfrom: (1.1.4)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130131204920-7tnuhqhlsqdza4c2
Rewrite build dependencies to allow cross builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***********************************************************
 
2
(C) Copyright 2003 A.M. Kuchling.  All Rights Reserved
 
3
(C) Copyright 2004 A.M. Kuchling, Ralph Heinkel  All Rights Reserved
 
4
 
 
5
Permission to use, copy, modify, and distribute this software and its
 
6
documentation for any purpose and without fee is hereby granted,
 
7
provided that the above copyright notice appear in all copies and that
 
8
both that copyright notice and this permission notice appear in
 
9
supporting documentation, and that the name of A.M. Kuchling and
 
10
Ralph Heinkel not be used in advertising or publicity pertaining to 
 
11
distribution of the software without specific, written prior permission.
 
12
 
 
13
A.M. KUCHLING, R.H. HEINKEL DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 
 
14
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
 
15
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
16
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 
17
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 
18
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
19
PERFORMANCE OF THIS SOFTWARE.
 
20
 
 
21
******************************************************************/
 
22
 
 
23
/* SaneDev objects */
 
24
 
 
25
#include "Python.h"
 
26
#include "Imaging.h"
 
27
#include <sane/sane.h>
 
28
 
 
29
#include <sys/time.h>
 
30
 
 
31
static PyObject *ErrorObject;
 
32
 
 
33
typedef struct {
 
34
        PyObject_HEAD
 
35
        SANE_Handle h;
 
36
} SaneDevObject;
 
37
 
 
38
#ifdef WITH_THREAD
 
39
PyThreadState *_save;
 
40
#endif
 
41
 
 
42
/* Raise a SANE exception */
 
43
PyObject * 
 
44
PySane_Error(SANE_Status st)
 
45
{
 
46
  const char *string;
 
47
  
 
48
  if (st==SANE_STATUS_GOOD) {Py_INCREF(Py_None); return (Py_None);}
 
49
  string=sane_strstatus(st);
 
50
  PyErr_SetString(ErrorObject, string);
 
51
  return NULL;
 
52
}
 
53
 
 
54
staticforward PyTypeObject SaneDev_Type;
 
55
 
 
56
#define SaneDevObject_Check(v)  ((v)->ob_type == &SaneDev_Type)
 
57
 
 
58
static SaneDevObject *
 
59
newSaneDevObject(void)
 
60
{
 
61
        SaneDevObject *self;
 
62
        self = PyObject_NEW(SaneDevObject, &SaneDev_Type);
 
63
        if (self == NULL)
 
64
                return NULL;
 
65
        self->h=NULL;
 
66
        return self;
 
67
}
 
68
 
 
69
/* SaneDev methods */
 
70
 
 
71
static void
 
72
SaneDev_dealloc(SaneDevObject *self)
 
73
{
 
74
  if (self->h) sane_close(self->h);
 
75
  self->h=NULL;
 
76
  PyObject_DEL(self);
 
77
}
 
78
 
 
79
static PyObject *
 
80
SaneDev_close(SaneDevObject *self, PyObject *args)
 
81
{
 
82
  if (!PyArg_ParseTuple(args, ""))
 
83
    return NULL;
 
84
  if (self->h) sane_close(self->h);
 
85
  self->h=NULL;
 
86
  Py_INCREF(Py_None);
 
87
  return (Py_None);
 
88
}
 
89
 
 
90
static PyObject *
 
91
SaneDev_get_parameters(SaneDevObject *self, PyObject *args)
 
92
{
 
93
  SANE_Status st;
 
94
  SANE_Parameters p;
 
95
  char *format="unknown format";
 
96
  
 
97
  if (!PyArg_ParseTuple(args, ""))
 
98
    return NULL;
 
99
  if (self->h==NULL)
 
100
    {
 
101
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
102
      return NULL;
 
103
    }
 
104
  Py_BEGIN_ALLOW_THREADS
 
105
  st=sane_get_parameters(self->h, &p);
 
106
  Py_END_ALLOW_THREADS
 
107
  
 
108
  if (st) return PySane_Error(st);
 
109
  switch (p.format)
 
110
    {
 
111
    case(SANE_FRAME_GRAY):  format="gray"; break;
 
112
    case(SANE_FRAME_RGB):   format="color"; break;
 
113
    case(SANE_FRAME_RED):   format="red"; break;
 
114
    case(SANE_FRAME_GREEN): format="green"; break;
 
115
    case(SANE_FRAME_BLUE):  format="blue"; break;
 
116
    }
 
117
  
 
118
  return Py_BuildValue("si(ii)ii", format, p.last_frame, p.pixels_per_line, 
 
119
                       p.lines, p.depth, p.bytes_per_line);
 
120
}
 
121
 
 
122
 
 
123
static PyObject *
 
124
SaneDev_fileno(SaneDevObject *self, PyObject *args)
 
125
{
 
126
  SANE_Status st;
 
127
  SANE_Int fd;
 
128
  
 
129
  if (!PyArg_ParseTuple(args, ""))
 
130
    return NULL;
 
131
  if (self->h==NULL)
 
132
    {
 
133
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
134
      return NULL;
 
135
    }
 
136
  st=sane_get_select_fd(self->h, &fd);
 
137
  if (st) return PySane_Error(st);
 
138
  return PyInt_FromLong(fd);
 
139
}
 
140
 
 
141
static PyObject *
 
142
SaneDev_start(SaneDevObject *self, PyObject *args)
 
143
{
 
144
  SANE_Status st;
 
145
  
 
146
  if (!PyArg_ParseTuple(args, ""))
 
147
    return NULL;
 
148
  if (self->h==NULL)
 
149
    {
 
150
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
151
      return NULL;
 
152
    }
 
153
  /* sane_start can take several seconds, if the user initiates
 
154
     a new scan, while the scan head of a flatbed scanner moves
 
155
     back to the start position after finishing a previous scan.
 
156
     Hence it is worth to allow threads here.
 
157
  */
 
158
  Py_BEGIN_ALLOW_THREADS
 
159
  st=sane_start(self->h);
 
160
  Py_END_ALLOW_THREADS
 
161
  if (st) return PySane_Error(st);
 
162
  Py_INCREF(Py_None);
 
163
  return Py_None;
 
164
}
 
165
 
 
166
static PyObject *
 
167
SaneDev_cancel(SaneDevObject *self, PyObject *args)
 
168
{
 
169
  if (!PyArg_ParseTuple(args, ""))
 
170
    return NULL;
 
171
  if (self->h==NULL)
 
172
    {
 
173
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
174
      return NULL;
 
175
    }
 
176
  sane_cancel(self->h);
 
177
  Py_INCREF(Py_None);
 
178
  return Py_None;
 
179
}
 
180
 
 
181
static PyObject *
 
182
SaneDev_get_options(SaneDevObject *self, PyObject *args)
 
183
{
 
184
  const SANE_Option_Descriptor *d;
 
185
  PyObject *list, *value;
 
186
  int i=1;
 
187
  
 
188
  if (!PyArg_ParseTuple(args, ""))
 
189
    return NULL;
 
190
  if (self->h==NULL)
 
191
    {
 
192
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
193
      return NULL;
 
194
    }
 
195
  if (!(list = PyList_New(0)))
 
196
            return NULL;
 
197
 
 
198
  do 
 
199
    {
 
200
      d=sane_get_option_descriptor(self->h, i);
 
201
      if (d!=NULL) 
 
202
        {
 
203
          PyObject *constraint=NULL;
 
204
          int j;
 
205
          
 
206
          switch (d->constraint_type)
 
207
            {
 
208
            case(SANE_CONSTRAINT_NONE): 
 
209
              Py_INCREF(Py_None); constraint=Py_None; break;
 
210
            case(SANE_CONSTRAINT_RANGE): 
 
211
              if (d->type == SANE_TYPE_INT)
 
212
                constraint=Py_BuildValue("iii", d->constraint.range->min, 
 
213
                                         d->constraint.range->max, 
 
214
                                         d->constraint.range->quant);
 
215
              else
 
216
                constraint=Py_BuildValue("ddd", 
 
217
                                         SANE_UNFIX(d->constraint.range->min), 
 
218
                                         SANE_UNFIX(d->constraint.range->max), 
 
219
                                         SANE_UNFIX(d->constraint.range->quant));
 
220
              break;
 
221
            case(SANE_CONSTRAINT_WORD_LIST): 
 
222
              constraint=PyList_New(d->constraint.word_list[0]);
 
223
              if (d->type == SANE_TYPE_INT)
 
224
                for (j=1; j<=d->constraint.word_list[0]; j++)
 
225
                  PyList_SetItem(constraint, j-1, 
 
226
                                 PyInt_FromLong(d->constraint.word_list[j]));
 
227
              else
 
228
                for (j=1; j<=d->constraint.word_list[0]; j++)
 
229
                  PyList_SetItem(constraint, j-1, 
 
230
                                 PyFloat_FromDouble(SANE_UNFIX(d->constraint.word_list[j])));
 
231
              break;
 
232
            case(SANE_CONSTRAINT_STRING_LIST): 
 
233
              constraint=PyList_New(0);
 
234
              for(j=0; d->constraint.string_list[j]!=NULL; j++)
 
235
                PyList_Append(constraint, 
 
236
                              PyString_FromString(d->constraint.string_list[j]));
 
237
              break;
 
238
            }
 
239
          value=Py_BuildValue("isssiiiiO", i, d->name, d->title, d->desc, 
 
240
                              d->type, d->unit, d->size, d->cap, constraint);
 
241
          PyList_Append(list, value);
 
242
        }
 
243
      i++;
 
244
    } while (d!=NULL);
 
245
  return list;
 
246
}
 
247
 
 
248
static PyObject *
 
249
SaneDev_get_option(SaneDevObject *self, PyObject *args)
 
250
{
 
251
  SANE_Status st;
 
252
  const SANE_Option_Descriptor *d;
 
253
  PyObject *value=NULL;
 
254
  int n;
 
255
  void *v;
 
256
  
 
257
  if (!PyArg_ParseTuple(args, "i", &n))
 
258
    {
 
259
      return NULL;
 
260
    }
 
261
  if (self->h==NULL)
 
262
    {
 
263
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
264
      return NULL;
 
265
    }
 
266
  d=sane_get_option_descriptor(self->h, n);
 
267
  v=malloc(d->size+1);
 
268
  st=sane_control_option(self->h, n, SANE_ACTION_GET_VALUE,
 
269
                         v, NULL);
 
270
 
 
271
  if (st) 
 
272
    {
 
273
      free(v); 
 
274
      return PySane_Error(st);
 
275
    }
 
276
  
 
277
  switch(d->type)
 
278
    {
 
279
    case(SANE_TYPE_BOOL):
 
280
    case(SANE_TYPE_INT):
 
281
      value=Py_BuildValue("i", *( (SANE_Int*)v) );
 
282
      break;
 
283
    case(SANE_TYPE_FIXED):
 
284
      value=Py_BuildValue("d", SANE_UNFIX((*((SANE_Fixed*)v))) );
 
285
      break;
 
286
    case(SANE_TYPE_STRING):
 
287
      value=Py_BuildValue("s", v);
 
288
      break;
 
289
    case(SANE_TYPE_BUTTON):
 
290
    case(SANE_TYPE_GROUP):
 
291
      value=Py_BuildValue("O", Py_None);
 
292
      break;
 
293
    }
 
294
  
 
295
  free(v);
 
296
  return value;
 
297
}
 
298
 
 
299
static PyObject *
 
300
SaneDev_set_option(SaneDevObject *self, PyObject *args)
 
301
{
 
302
  SANE_Status st;
 
303
  const SANE_Option_Descriptor *d;
 
304
  SANE_Int i;
 
305
  PyObject *value;
 
306
  int n;
 
307
  void *v;
 
308
  
 
309
  if (!PyArg_ParseTuple(args, "iO", &n, &value))
 
310
    return NULL;
 
311
  if (self->h==NULL)
 
312
    {
 
313
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
314
      return NULL;
 
315
    }
 
316
  d=sane_get_option_descriptor(self->h, n);
 
317
  v=malloc(d->size+1);
 
318
 
 
319
  switch(d->type)
 
320
    {
 
321
    case(SANE_TYPE_BOOL):
 
322
      if (!PyInt_Check(value)) 
 
323
        {
 
324
          PyErr_SetString(PyExc_TypeError, "SANE_BOOL requires an integer");
 
325
          free(v);
 
326
          return NULL;
 
327
        }
 
328
        /* fall through */
 
329
    case(SANE_TYPE_INT):
 
330
      if (!PyInt_Check(value)) 
 
331
        {
 
332
          PyErr_SetString(PyExc_TypeError, "SANE_INT requires an integer");
 
333
          free(v);
 
334
          return NULL;
 
335
        }
 
336
      *( (SANE_Int*)v) = PyInt_AsLong(value);
 
337
      break;
 
338
    case(SANE_TYPE_FIXED):
 
339
      if (!PyFloat_Check(value)) 
 
340
        {
 
341
          PyErr_SetString(PyExc_TypeError, "SANE_FIXED requires a floating point number");
 
342
          free(v);
 
343
          return NULL;
 
344
        }
 
345
      *( (SANE_Fixed*)v) = SANE_FIX(PyFloat_AsDouble(value));
 
346
      break;
 
347
    case(SANE_TYPE_STRING):
 
348
      if (!PyString_Check(value)) 
 
349
        {
 
350
          PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string");
 
351
          free(v);
 
352
          return NULL;
 
353
        }
 
354
      strncpy(v, PyString_AsString(value), d->size-1);
 
355
      ((char*)v)[d->size-1] = 0;
 
356
      break;
 
357
    case(SANE_TYPE_BUTTON): 
 
358
    case(SANE_TYPE_GROUP):
 
359
      break;
 
360
    }
 
361
  
 
362
  st=sane_control_option(self->h, n, SANE_ACTION_SET_VALUE,
 
363
                         v, &i);
 
364
  if (st) {free(v); return PySane_Error(st);}
 
365
  
 
366
  free(v);
 
367
  return Py_BuildValue("i", i);
 
368
}
 
369
 
 
370
static PyObject *
 
371
SaneDev_set_auto_option(SaneDevObject *self, PyObject *args)
 
372
{
 
373
  SANE_Status st;
 
374
  const SANE_Option_Descriptor *d;
 
375
  SANE_Int i;
 
376
  int n;
 
377
  
 
378
  if (!PyArg_ParseTuple(args, "i", &n))
 
379
    return NULL;
 
380
  if (self->h==NULL)
 
381
    {
 
382
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
383
      return NULL;
 
384
    }
 
385
  d=sane_get_option_descriptor(self->h, n);
 
386
  st=sane_control_option(self->h, n, SANE_ACTION_SET_AUTO,
 
387
                         NULL, &i);
 
388
  if (st) {return PySane_Error(st);}
 
389
  
 
390
  return Py_BuildValue("i", i);
 
391
 }
 
392
 
 
393
#define READSIZE 32768
 
394
 
 
395
static PyObject *
 
396
SaneDev_snap(SaneDevObject *self, PyObject *args)
 
397
{
 
398
  SANE_Status st; 
 
399
   /* The buffer should be a multiple of 3 in size, so each sane_read
 
400
      operation will return an integral number of RGB triples. */
 
401
  SANE_Byte buffer[READSIZE];  /* XXX how big should the buffer be? */
 
402
  SANE_Int len, lastlen;
 
403
  Imaging im;
 
404
  SANE_Parameters p;
 
405
  int px, py, remain, cplen, bufpos, padbytes;
 
406
  long L;
 
407
  char errmsg[80];
 
408
  union 
 
409
    { char c[2];
 
410
      INT16 i16;
 
411
    } 
 
412
  endian;
 
413
  PyObject *pyNoCancel = NULL;
 
414
  int noCancel = 0;
 
415
    
 
416
  endian.i16 = 1;
 
417
  
 
418
  if (!PyArg_ParseTuple(args, "l|O", &L, &pyNoCancel))
 
419
    return NULL;
 
420
  if (self->h==NULL)
 
421
    {
 
422
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
423
      return NULL;
 
424
    }
 
425
  im=(Imaging)L;
 
426
  
 
427
  if (pyNoCancel)
 
428
    noCancel = PyObject_IsTrue(pyNoCancel);
 
429
 
 
430
  st=SANE_STATUS_GOOD; px=py=0;
 
431
  /* xxx not yet implemented
 
432
     - handscanner support (i.e., unknown image length during start)
 
433
     - generally: move the functionality from method snap in sane.py
 
434
       down here -- I don't like this cross-dependency.
 
435
       we need to call sane_get_parameters here, and we can create
 
436
       the result Image object here.
 
437
  */
 
438
  
 
439
  Py_UNBLOCK_THREADS
 
440
  sane_get_parameters(self->h, &p);
 
441
  if (p.format == SANE_FRAME_GRAY)
 
442
    {
 
443
      switch (p.depth)
 
444
        {
 
445
          case 1: 
 
446
            remain = p.bytes_per_line * im->ysize;
 
447
            padbytes = p.bytes_per_line - (im->xsize+7)/8;
 
448
            bufpos = 0;
 
449
            lastlen = len = 0;
 
450
            while (st!=SANE_STATUS_EOF && py < im->ysize)
 
451
              {
 
452
                while (len > 0 && py < im->ysize)
 
453
                  {
 
454
                    int i, j, k;
 
455
                    j = buffer[bufpos++];
 
456
                    k = 0x80;
 
457
                    for (i = 0; i < 8 && px < im->xsize; i++)
 
458
                      {
 
459
                        im->image8[py][px++] = (k&j) ? 0 : 0xFF;
 
460
                        k = k >> 1;
 
461
                      }
 
462
                    len--;
 
463
                    if (px >= im->xsize)
 
464
                      {
 
465
                        bufpos += padbytes;
 
466
                        len -= padbytes;
 
467
                        py++;
 
468
                        px = 0;
 
469
                      }
 
470
                  }
 
471
                st=sane_read(self->h, buffer, 
 
472
                             remain<READSIZE ? remain : READSIZE, &len);
 
473
                if (st && (st!=SANE_STATUS_EOF))
 
474
                  {
 
475
                    sane_cancel(self->h);
 
476
                    Py_BLOCK_THREADS
 
477
                    return PySane_Error(st);
 
478
                  }
 
479
                bufpos -= lastlen;
 
480
                lastlen = len;
 
481
                remain -= len;
 
482
                /* skip possible pad bytes at the start of the buffer */
 
483
                len -= bufpos;
 
484
              }
 
485
            break;
 
486
          case 8:
 
487
            remain = p.bytes_per_line * im->ysize;
 
488
            padbytes = p.bytes_per_line - im->xsize;
 
489
            bufpos = 0;
 
490
            len = 0;
 
491
            while (st!=SANE_STATUS_EOF && py < im->ysize)
 
492
              {
 
493
                while (len > 0 && py < im->ysize)
 
494
                  {
 
495
                    cplen = len;
 
496
                    if (px + cplen >= im->xsize)
 
497
                        cplen = im->xsize - px;
 
498
                    memcpy(&im->image8[py][px], &buffer[bufpos], cplen);
 
499
                    len -= cplen;
 
500
                    bufpos += cplen;
 
501
                    px += cplen;
 
502
                    if (px >= im->xsize)
 
503
                      {
 
504
                        px = 0;
 
505
                        py++;
 
506
                        bufpos += padbytes;
 
507
                        len -= padbytes;
 
508
                      }
 
509
                  }
 
510
                bufpos = -len;
 
511
 
 
512
                st=sane_read(self->h, buffer, 
 
513
                             remain<READSIZE ? remain : READSIZE, &len);
 
514
                if (st && (st!=SANE_STATUS_EOF))
 
515
                  {
 
516
                    sane_cancel(self->h);
 
517
                    Py_BLOCK_THREADS
 
518
                    return PySane_Error(st);
 
519
                  }
 
520
                remain -= len;
 
521
                len -= bufpos;
 
522
              }
 
523
              break;
 
524
          case 16:
 
525
            remain = p.bytes_per_line * im->ysize;
 
526
            padbytes = p.bytes_per_line - 2 * im->xsize;
 
527
            bufpos = endian.c[0];
 
528
            lastlen = len = 0;
 
529
            while (st!=SANE_STATUS_EOF && py < im->ysize)
 
530
              {
 
531
                while (len > 0 && py < im->ysize)
 
532
                  {
 
533
                    im->image8[py][px++] = buffer[bufpos];
 
534
                    bufpos += 2;
 
535
                    len -= 2;
 
536
                    if (px >= im->xsize)
 
537
                      {
 
538
                        bufpos += padbytes;
 
539
                        len -= padbytes;
 
540
                        py++;
 
541
                        px = 0;
 
542
                      }
 
543
                  }
 
544
                st=sane_read(self->h, buffer, 
 
545
                             remain<READSIZE ? remain : READSIZE, &len);
 
546
                if (st && (st!=SANE_STATUS_EOF))
 
547
                  {
 
548
                    sane_cancel(self->h);
 
549
                    Py_BLOCK_THREADS
 
550
                    return PySane_Error(st);
 
551
                  }
 
552
                remain -= len;
 
553
                bufpos -= lastlen;
 
554
                lastlen = len;
 
555
                len -= bufpos;
 
556
              }
 
557
            break;
 
558
          default:
 
559
            /* other depths are not formally "illegal" according to the 
 
560
               Sane API, but it's agreed by Sane developers that other
 
561
               depths than 1, 8, 16 should not be used
 
562
            */
 
563
            sane_cancel(self->h);
 
564
            Py_BLOCK_THREADS
 
565
            snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth);
 
566
            PyErr_SetString(ErrorObject, errmsg);
 
567
            return NULL;
 
568
        }
 
569
    }
 
570
  else if (p.format == SANE_FRAME_RGB)
 
571
    {
 
572
      int incr, color, pxs, pxmax, bit, val, mask;
 
573
      switch (p.depth)
 
574
        {
 
575
          case 1: 
 
576
            remain = p.bytes_per_line * im->ysize;
 
577
            padbytes = p.bytes_per_line - ((im->xsize+7)/8) * 3;
 
578
            bufpos = 0;
 
579
            len = 0;
 
580
            lastlen = 0;
 
581
            pxmax = 4 * im->xsize;
 
582
            while (st!=SANE_STATUS_EOF && py < im->ysize)
 
583
              {
 
584
                pxs = px;
 
585
                for (color = 0; color < 3; color++)
 
586
                  {
 
587
                    while (len <= 0 && st == SANE_STATUS_GOOD)
 
588
                      {
 
589
                        st=sane_read(self->h, buffer, 
 
590
                                     remain<READSIZE ? remain : READSIZE, &len);
 
591
                        if (st && (st!=SANE_STATUS_EOF))
 
592
                          {
 
593
                            sane_cancel(self->h);
 
594
                            Py_BLOCK_THREADS
 
595
                            return PySane_Error(st);
 
596
                          }
 
597
                        bufpos -= lastlen;
 
598
                        remain -= len;
 
599
                        lastlen = len;
 
600
                        /* skip possible pad bytes at the start of the buffer */
 
601
                        len -= bufpos;
 
602
                      }
 
603
                    if (st == SANE_STATUS_EOF) break;
 
604
                    pxs = px;
 
605
                    val = buffer[bufpos++];
 
606
                    len--;
 
607
                    mask = 0x80;
 
608
                    for (bit = 0; (bit < 8) && (px < pxmax); bit++)
 
609
                      {
 
610
                         ((UINT8**)(im->image32))[py][px] = (val&mask) ? 0xFF : 0;
 
611
                        mask = mask >> 1;
 
612
                        px += 4;
 
613
                      }
 
614
                    pxs++;
 
615
                    px = pxs;
 
616
                  }
 
617
                if (st == SANE_STATUS_EOF)
 
618
                  break;
 
619
                for (bit = 0; bit < 8 && px < pxmax; bit++)
 
620
                  {
 
621
                     ((UINT8**)(im->image32))[py][px] = 0;
 
622
                     px += 4;
 
623
                  }
 
624
                px -= 3;
 
625
                if (px >= pxmax)
 
626
                  {
 
627
                    bufpos += padbytes;
 
628
                    len -= padbytes;
 
629
                    py++;
 
630
                    px = 0;
 
631
                  }
 
632
              }
 
633
            break;
 
634
          case 8:
 
635
          case 16:
 
636
            if (p.depth == 8)
 
637
              {
 
638
                padbytes = p.bytes_per_line - 3 * im->xsize;
 
639
                bufpos = 0;
 
640
                incr = 1;
 
641
              }
 
642
            else 
 
643
              {
 
644
                padbytes = p.bytes_per_line - 6 * im->xsize;
 
645
                bufpos = endian.c[0];
 
646
                incr = 2;
 
647
              }
 
648
            remain = p.bytes_per_line * im->ysize;
 
649
            len = 0;
 
650
            lastlen = 0;
 
651
            pxmax = 4 * im->xsize;
 
652
            /* probably not very efficient. But we have to deal with these
 
653
               possible conditions:
 
654
               - we may have padding bytes at the end of a scan line
 
655
               - the number of bytes read with sane_read may be smaller
 
656
                 than the number of pad bytes
 
657
               - the buffer may become empty after setting any of the 
 
658
                 red/green/blue pixel values
 
659
             
 
660
            */
 
661
            while (st != SANE_STATUS_EOF && py < im->ysize)
 
662
              {
 
663
                for (color = 0; color < 3; color++)
 
664
                  {
 
665
                    while (len <= 0 && st == SANE_STATUS_GOOD)
 
666
                      {
 
667
                        bufpos -= lastlen;
 
668
                        if (remain == 0)
 
669
                          {
 
670
                            sane_cancel(self->h);
 
671
                            Py_BLOCK_THREADS
 
672
                            PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan");
 
673
                            return NULL;
 
674
                          }
 
675
                        st = sane_read(self->h, buffer,
 
676
                              remain<(READSIZE) ? remain : (READSIZE), &len);
 
677
                        if (st && (st!=SANE_STATUS_EOF))
 
678
                          {
 
679
                            sane_cancel(self->h);
 
680
                            Py_BLOCK_THREADS
 
681
                            return PySane_Error(st);
 
682
                          }
 
683
                        lastlen = len;
 
684
                        remain -= len;
 
685
                        len -= bufpos;
 
686
                      }
 
687
                    if (st == SANE_STATUS_EOF) break;
 
688
                    ((UINT8**)(im->image32))[py][px++] = buffer[bufpos]; 
 
689
                    bufpos += incr;
 
690
                    len -= incr;
 
691
                  }
 
692
                if (st == SANE_STATUS_EOF) break;
 
693
 
 
694
                ((UINT8**)(im->image32))[py][px++] = 0;
 
695
 
 
696
                if (px >= pxmax)
 
697
                  {
 
698
                    px = 0;
 
699
                    py++;
 
700
                    bufpos += padbytes;
 
701
                    len -= padbytes;
 
702
                  }
 
703
              }
 
704
            break;
 
705
          default:
 
706
            Py_BLOCK_THREADS
 
707
            sane_cancel(self->h);
 
708
            snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth);
 
709
            PyErr_SetString(ErrorObject, errmsg);
 
710
            return NULL;
 
711
        }
 
712
      
 
713
    }
 
714
  else /* should be SANE_FRAME_RED, GREEN or BLUE */
 
715
    {
 
716
      int lastlen, pxa, pxmax, offset, incr, frame_count = 0;
 
717
      /* at least the Sane test backend behaves a bit weird, if 
 
718
         it returns "premature EOF" for sane_read, i.e., if the 
 
719
         option "return value of sane_read" is set to SANE_STATUS_EOF.
 
720
         In this case, the test backend does not advance to the next frame,
 
721
         so p.last_frame will never be set...
 
722
         So let's count the number of frames we try to acquire
 
723
      */
 
724
      while (!p.last_frame && frame_count < 4)
 
725
        {
 
726
          frame_count++;
 
727
          st = sane_get_parameters(self->h, &p);
 
728
          if (st)
 
729
            {
 
730
              sane_cancel(self->h);
 
731
              Py_BLOCK_THREADS
 
732
              return PySane_Error(st);
 
733
            }
 
734
          remain = p.bytes_per_line * im->ysize;
 
735
          bufpos = 0;
 
736
          len = 0;
 
737
          lastlen = 0;
 
738
          py = 0;
 
739
          switch (p.format)
 
740
            { 
 
741
              case SANE_FRAME_RED:
 
742
                offset = 0;
 
743
                break;
 
744
              case SANE_FRAME_GREEN:
 
745
                offset = 1;
 
746
                break;
 
747
              case SANE_FRAME_BLUE:
 
748
                offset = 2;
 
749
                break;
 
750
              default:
 
751
                sane_cancel(self->h);
 
752
                Py_BLOCK_THREADS
 
753
                snprintf(errmsg, 80, "unknown/invalid frame format: %i", p.format);
 
754
                PyErr_SetString(ErrorObject, errmsg);
 
755
                return NULL;
 
756
            }
 
757
          px = offset;
 
758
          pxa = 3;
 
759
          pxmax = im->xsize * 4;
 
760
          switch (p.depth)
 
761
            {
 
762
              case 1:
 
763
                padbytes = p.bytes_per_line - (im->xsize+7)/8;
 
764
                st = SANE_STATUS_GOOD;
 
765
                while (st != SANE_STATUS_EOF && py < im->ysize)
 
766
                  {
 
767
                    while (len > 0)
 
768
                      {
 
769
                        int bit, mask, val;
 
770
                        val = buffer[bufpos++]; len--;
 
771
                        mask = 0x80;
 
772
                        for (bit = 0; bit < 8 && px < pxmax; bit++)
 
773
                          {
 
774
                            ((UINT8**)(im->image32))[py][px] 
 
775
                                = val&mask ? 0xFF : 0;
 
776
                            ((UINT8**)(im->image32))[py][pxa] = 0;
 
777
                            px += 4;
 
778
                            pxa += 4;
 
779
                            mask = mask >> 1;
 
780
                          }
 
781
 
 
782
                        if (px >= pxmax)
 
783
                          {
 
784
                            px = offset;
 
785
                            pxa = 3;
 
786
                            py++;
 
787
                            bufpos += padbytes;
 
788
                            len -= padbytes;
 
789
                          }
 
790
                      }
 
791
                    while (len <= 0 && st == SANE_STATUS_GOOD && remain > 0)
 
792
                      {
 
793
                        bufpos -= lastlen;
 
794
                        st = sane_read(self->h, buffer,
 
795
                              remain<(READSIZE) ? remain : (READSIZE), &len);
 
796
                        if (st && (st!=SANE_STATUS_EOF))
 
797
                          {
 
798
                            sane_cancel(self->h);
 
799
                            Py_BLOCK_THREADS
 
800
                            return PySane_Error(st);
 
801
                          }
 
802
                        remain -= len;
 
803
                        lastlen = len;
 
804
                        len -= bufpos;
 
805
                      }
 
806
                  }
 
807
                break;
 
808
              case 8:
 
809
              case 16:
 
810
                if (p.depth == 8)
 
811
                  {
 
812
                    padbytes = p.bytes_per_line - im->xsize;
 
813
                    incr = 1;
 
814
                  }
 
815
                else
 
816
                  {
 
817
                    padbytes = p.bytes_per_line - 2 * im->xsize;
 
818
                    incr = 2;
 
819
                    bufpos = endian.c[0];
 
820
                  }
 
821
                st = SANE_STATUS_GOOD;
 
822
                while (st != SANE_STATUS_EOF && py < im->ysize)
 
823
                  {
 
824
                    while (len <= 0)
 
825
                      {
 
826
                        bufpos -= lastlen;
 
827
                        if (remain == 0)
 
828
                          {
 
829
                            sane_cancel(self->h);
 
830
                            Py_BLOCK_THREADS
 
831
                            PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan");
 
832
                            return NULL;
 
833
                          }
 
834
                        st = sane_read(self->h, buffer,
 
835
                              remain<(READSIZE) ? remain : (READSIZE), &len);
 
836
                        if (st && (st!=SANE_STATUS_EOF))
 
837
                          {
 
838
                            sane_cancel(self->h);
 
839
                            Py_BLOCK_THREADS
 
840
                            return PySane_Error(st);
 
841
                          }
 
842
                        if (st == SANE_STATUS_EOF)
 
843
                          break;
 
844
                        lastlen = len;
 
845
                        remain -= len;
 
846
                        if (bufpos >= len)
 
847
                          len = 0;
 
848
                        else
 
849
                          len -= bufpos;
 
850
                      }
 
851
                    if (st == SANE_STATUS_EOF)
 
852
                      break;
 
853
                    ((UINT8**)(im->image32))[py][px] = buffer[bufpos];
 
854
                    ((UINT8**)(im->image32))[py][pxa] = 0;
 
855
                    bufpos += incr;
 
856
                    len -= incr;
 
857
                    px += 4;
 
858
                    pxa += 4;
 
859
 
 
860
                    if (px >= pxmax)
 
861
                      {
 
862
                        px = offset;
 
863
                        pxa = 3;
 
864
                        py++;
 
865
                        bufpos += padbytes;
 
866
                        len -= padbytes;
 
867
                      }
 
868
                  }
 
869
                break;
 
870
              default:
 
871
                sane_cancel(self->h);
 
872
                Py_BLOCK_THREADS
 
873
                snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth);
 
874
                PyErr_SetString(ErrorObject, errmsg);
 
875
                return NULL;
 
876
            }
 
877
          if (!p.last_frame)
 
878
            {
 
879
              /* all sane_read calls in the above loop may return
 
880
                 SANE_STATUS_GOOD, but the backend may need another sane_read
 
881
                 call which returns SANE_STATUS_EOF in order to start
 
882
                 a new frame.
 
883
              */
 
884
              do {
 
885
                   st = sane_read(self->h, buffer, READSIZE, &len);
 
886
                 }
 
887
              while (st == SANE_STATUS_GOOD);
 
888
              if (st != SANE_STATUS_EOF)
 
889
                {
 
890
                   Py_BLOCK_THREADS
 
891
                   sane_cancel(self->h);
 
892
                   return PySane_Error(st);
 
893
                }
 
894
              
 
895
              st = sane_start(self->h);
 
896
              if (st) 
 
897
                {
 
898
                   Py_BLOCK_THREADS
 
899
                   return PySane_Error(st);
 
900
                }
 
901
            }
 
902
        }
 
903
    }
 
904
  /* enforce SANE_STATUS_EOF. Can be necessary for ADF scans for some backends */
 
905
  do {
 
906
       st = sane_read(self->h, buffer, READSIZE, &len);
 
907
     }
 
908
  while (st == SANE_STATUS_GOOD);
 
909
  if (st != SANE_STATUS_EOF)
 
910
    {
 
911
      sane_cancel(self->h);
 
912
      Py_BLOCK_THREADS
 
913
      return PySane_Error(st);
 
914
    }
 
915
  
 
916
  if (!noCancel)
 
917
    sane_cancel(self->h);
 
918
  Py_BLOCK_THREADS
 
919
  Py_INCREF(Py_None);
 
920
  return Py_None;
 
921
}
 
922
 
 
923
 
 
924
#ifdef WITH_NUMARRAY
 
925
 
 
926
#include "numarray/libnumarray.h"
 
927
 
 
928
/* this global variable is set to 1 in 'init_sane()' after successfully
 
929
   importing the numarray module. */
 
930
int NUMARRAY_IMPORTED = 0;
 
931
 
 
932
static PyObject *
 
933
SaneDev_arr_snap(SaneDevObject *self, PyObject *args)
 
934
{
 
935
  SANE_Status st; 
 
936
  SANE_Byte buffer[READSIZE];
 
937
  SANE_Int len;
 
938
  SANE_Parameters p;
 
939
 
 
940
  PyArrayObject *pyArr = NULL;
 
941
  NumarrayType arrType;
 
942
  int line, line_index, buffer_index, remain_bytes_line, num_pad_bytes;
 
943
  int cp_num_bytes, total_remain, bpp, arr_bytes_per_line;
 
944
  int pixels_per_line = -1;
 
945
  char errmsg[80];
 
946
 
 
947
  if (!NUMARRAY_IMPORTED)
 
948
    {
 
949
      PyErr_SetString(ErrorObject, "numarray package not available");
 
950
      return NULL;
 
951
    }
 
952
 
 
953
  if (!PyArg_ParseTuple(args, "|i", &pixels_per_line))
 
954
    return NULL;
 
955
  if (self->h==NULL)
 
956
    {
 
957
      PyErr_SetString(ErrorObject, "SaneDev object is closed");
 
958
      return NULL;
 
959
    }
 
960
 
 
961
  sane_get_parameters(self->h, &p);
 
962
  if (p.format != SANE_FRAME_GRAY)
 
963
    {
 
964
      sane_cancel(self->h);
 
965
      snprintf(errmsg, 80, "numarray only supports gray-scale images");
 
966
      PyErr_SetString(ErrorObject, errmsg);
 
967
      return NULL;
 
968
    }
 
969
 
 
970
  if (p.depth == 8)
 
971
    {
 
972
      bpp=1;   /* bytes-per-pixel */
 
973
      arrType = tUInt8;
 
974
    }
 
975
  else if (p.depth == 16)
 
976
    {
 
977
      bpp=2;   /* bytes-per-pixel */
 
978
      arrType = tUInt16;
 
979
    }
 
980
  else
 
981
    {
 
982
      sane_cancel(self->h);
 
983
      snprintf(errmsg, 80, "arrsnap: unsupported pixel depth: %i", p.depth);
 
984
      PyErr_SetString(ErrorObject, errmsg);
 
985
      return NULL;
 
986
    }
 
987
 
 
988
  if (pixels_per_line < 1)
 
989
    /* The user can choose a smaller result array than the actual scan */
 
990
    pixels_per_line = p.pixels_per_line;
 
991
  else
 
992
    if (pixels_per_line > p.pixels_per_line)
 
993
      {
 
994
        PyErr_SetString(ErrorObject,"given pixels_per_line too big");
 
995
        return NULL;
 
996
      }
 
997
  /* important: NumArray have indices like (y, x) !! */
 
998
  if (!(pyArr = NA_NewArray(NULL, arrType, 2, p.lines, pixels_per_line)))
 
999
    {
 
1000
      PyErr_SetString(ErrorObject, "failed to create NumArray object");
 
1001
      return NULL;
 
1002
    }
 
1003
    
 
1004
  arr_bytes_per_line = pixels_per_line * bpp;
 
1005
  st=SANE_STATUS_GOOD;
 
1006
#ifdef WRITE_PGM
 
1007
  FILE *fp;
 
1008
  fp = fopen("sane_p5.pgm", "w");
 
1009
  fprintf(fp, "P5\n%d %d\n%d\n", p.pixels_per_line, 
 
1010
          p.lines, (int) pow(2.0, (double) p.depth)-1);
 
1011
#endif
 
1012
  line_index = line = 0;
 
1013
  remain_bytes_line = arr_bytes_per_line;
 
1014
  total_remain = p.bytes_per_line * p.lines;
 
1015
  num_pad_bytes = p.bytes_per_line - arr_bytes_per_line;
 
1016
  
 
1017
  while (st!=SANE_STATUS_EOF)
 
1018
    {
 
1019
      Py_BEGIN_ALLOW_THREADS
 
1020
      st = sane_read(self->h, buffer, 
 
1021
                     READSIZE < total_remain ? READSIZE : total_remain, &len);
 
1022
      Py_END_ALLOW_THREADS
 
1023
#ifdef WRITE_PGM
 
1024
      printf("p5_write: read %d of %d\n", len, READSIZE);
 
1025
      fwrite(buffer, 1, len, fp);
 
1026
#endif
 
1027
 
 
1028
      buffer_index = 0;
 
1029
      total_remain -= len;
 
1030
 
 
1031
      while (len > 0)
 
1032
        {
 
1033
          /* copy at most the number of bytes that fit into (the rest of)
 
1034
             one line: */
 
1035
          cp_num_bytes = (len > remain_bytes_line ? remain_bytes_line : len);
 
1036
          remain_bytes_line -= cp_num_bytes;
 
1037
          len -= cp_num_bytes;
 
1038
#ifdef DEBUG
 
1039
          printf("copying %d bytes from b_idx %d to d_idx %d\n",
 
1040
                 cp_num_bytes, buffer_index, 
 
1041
                 line * arr_bytes_per_line + line_index);
 
1042
          printf("len is now %d\n", len);
 
1043
#endif
 
1044
          memcpy(pyArr->data + line * arr_bytes_per_line + line_index,
 
1045
                 buffer + buffer_index, cp_num_bytes);
 
1046
 
 
1047
          buffer_index += cp_num_bytes;
 
1048
          if (remain_bytes_line ==0)
 
1049
            {
 
1050
              /* The line has been completed, so reinitialize remain_bytes_line
 
1051
                 increase the line counter, and reset line_index */
 
1052
#ifdef DEBUG
 
1053
              printf("line %d full, skipping %d bytes\n",line,num_pad_bytes);
 
1054
#endif
 
1055
              remain_bytes_line = arr_bytes_per_line;
 
1056
              line++;
 
1057
              line_index = 0;
 
1058
              /* Skip the number of bytes in the input stream which 
 
1059
                 are not used: */
 
1060
              len -= num_pad_bytes;
 
1061
              buffer_index += num_pad_bytes;
 
1062
            }
 
1063
          else
 
1064
            line_index += cp_num_bytes;
 
1065
        }
 
1066
    }
 
1067
#ifdef WRITE_PGM
 
1068
  fclose(fp);
 
1069
  printf("p5_write finished\n");
 
1070
#endif
 
1071
  sane_cancel(self->h);
 
1072
  return (PyObject*) pyArr;
 
1073
}
 
1074
 
 
1075
 
 
1076
 
 
1077
#endif /* WITH_NUMARRAY */
 
1078
 
 
1079
static PyMethodDef SaneDev_methods[] = {
 
1080
        {"get_parameters",      (PyCFunction)SaneDev_get_parameters,    1},
 
1081
 
 
1082
        {"get_options", (PyCFunction)SaneDev_get_options,       1},
 
1083
        {"get_option",  (PyCFunction)SaneDev_get_option,        1},
 
1084
        {"set_option",  (PyCFunction)SaneDev_set_option,        1},
 
1085
        {"set_auto_option",     (PyCFunction)SaneDev_set_auto_option,   1},
 
1086
 
 
1087
        {"start",       (PyCFunction)SaneDev_start,     1},
 
1088
        {"cancel",      (PyCFunction)SaneDev_cancel,    1},
 
1089
        {"snap",        (PyCFunction)SaneDev_snap,      1},
 
1090
#ifdef WITH_NUMARRAY
 
1091
        {"arr_snap",    (PyCFunction)SaneDev_arr_snap,  1},
 
1092
#endif /* WITH_NUMARRAY */
 
1093
        {"fileno",      (PyCFunction)SaneDev_fileno,    1},
 
1094
        {"close",       (PyCFunction)SaneDev_close,     1},
 
1095
        {NULL,          NULL}           /* sentinel */
 
1096
};
 
1097
 
 
1098
static PyObject *
 
1099
SaneDev_getattr(SaneDevObject *self, char *name)
 
1100
{
 
1101
        return Py_FindMethod(SaneDev_methods, (PyObject *)self, name);
 
1102
}
 
1103
 
 
1104
staticforward PyTypeObject SaneDev_Type = {
 
1105
        PyObject_HEAD_INIT(&PyType_Type)
 
1106
        0,                      /*ob_size*/
 
1107
        "SaneDev",                      /*tp_name*/
 
1108
        sizeof(SaneDevObject),  /*tp_basicsize*/
 
1109
        0,                      /*tp_itemsize*/
 
1110
        /* methods */
 
1111
        (destructor)SaneDev_dealloc, /*tp_dealloc*/
 
1112
        0,                      /*tp_print*/
 
1113
        (getattrfunc)SaneDev_getattr, /*tp_getattr*/
 
1114
        0, /*tp_setattr*/
 
1115
        0,                      /*tp_compare*/
 
1116
        0,                      /*tp_repr*/
 
1117
        0,                      /*tp_as_number*/
 
1118
        0,                      /*tp_as_sequence*/
 
1119
        0,                      /*tp_as_mapping*/
 
1120
        0,                      /*tp_hash*/
 
1121
};
 
1122
 
 
1123
/* --------------------------------------------------------------------- */
 
1124
 
 
1125
static PyObject *
 
1126
PySane_init(PyObject *self, PyObject *args)
 
1127
{
 
1128
  SANE_Status st;
 
1129
  SANE_Int version;
 
1130
  
 
1131
  if (!PyArg_ParseTuple(args, ""))
 
1132
    return NULL;
 
1133
 
 
1134
  /* XXX Authorization is not yet supported */
 
1135
  st=sane_init(&version, NULL); 
 
1136
  if (st) return PySane_Error(st);
 
1137
  return Py_BuildValue("iiii", version, SANE_VERSION_MAJOR(version),
 
1138
                       SANE_VERSION_MINOR(version), SANE_VERSION_BUILD(version));
 
1139
}
 
1140
 
 
1141
static PyObject *
 
1142
PySane_exit(PyObject *self, PyObject *args)
 
1143
{
 
1144
  if (!PyArg_ParseTuple(args, ""))
 
1145
    return NULL;
 
1146
 
 
1147
  sane_exit();
 
1148
  Py_INCREF(Py_None);
 
1149
  return Py_None;
 
1150
}
 
1151
 
 
1152
static PyObject *
 
1153
PySane_get_devices(PyObject *self, PyObject *args)
 
1154
{
 
1155
  SANE_Device **devlist;
 
1156
  SANE_Device *dev;
 
1157
  SANE_Status st;
 
1158
  PyObject *list;
 
1159
  int local_only, i;
 
1160
  
 
1161
  if (!PyArg_ParseTuple(args, "|i", &local_only))
 
1162
    {
 
1163
      return NULL;
 
1164
    }
 
1165
  
 
1166
  st=sane_get_devices(&devlist, local_only);
 
1167
  if (st) return PySane_Error(st);
 
1168
  if (!(list = PyList_New(0)))
 
1169
            return NULL;
 
1170
  for(i=0; devlist[i]!=NULL; i++)
 
1171
    {
 
1172
      dev=devlist[i];
 
1173
      PyList_Append(list, Py_BuildValue("ssss", dev->name, dev->vendor, 
 
1174
                                        dev->model, dev->type));
 
1175
    }
 
1176
  
 
1177
  return list;
 
1178
}
 
1179
 
 
1180
/* Function returning new SaneDev object */
 
1181
 
 
1182
static PyObject *
 
1183
PySane_open(PyObject *self, PyObject *args)
 
1184
{
 
1185
        SaneDevObject *rv;
 
1186
        SANE_Status st;
 
1187
        char *name;
 
1188
 
 
1189
        if (!PyArg_ParseTuple(args, "s", &name))
 
1190
                return NULL;
 
1191
        rv = newSaneDevObject();
 
1192
        if ( rv == NULL )
 
1193
            return NULL;
 
1194
        st = sane_open(name, &(rv->h));
 
1195
        if (st) 
 
1196
          {
 
1197
            Py_DECREF(rv);
 
1198
            return PySane_Error(st);
 
1199
          }
 
1200
        return (PyObject *)rv;
 
1201
}
 
1202
 
 
1203
static PyObject *
 
1204
PySane_OPTION_IS_ACTIVE(PyObject *self, PyObject *args)
 
1205
{
 
1206
  SANE_Int cap;
 
1207
  long lg;
 
1208
  
 
1209
  if (!PyArg_ParseTuple(args, "l", &lg))
 
1210
    return NULL;
 
1211
  cap=lg;
 
1212
  return PyInt_FromLong( SANE_OPTION_IS_ACTIVE(cap));
 
1213
}
 
1214
 
 
1215
static PyObject *
 
1216
PySane_OPTION_IS_SETTABLE(PyObject *self, PyObject *args)
 
1217
{
 
1218
  SANE_Int cap;
 
1219
  long lg;
 
1220
  
 
1221
  if (!PyArg_ParseTuple(args, "l", &lg))
 
1222
    return NULL;
 
1223
  cap=lg;
 
1224
  return PyInt_FromLong( SANE_OPTION_IS_SETTABLE(cap));
 
1225
}
 
1226
 
 
1227
 
 
1228
/* List of functions defined in the module */
 
1229
 
 
1230
static PyMethodDef PySane_methods[] = {
 
1231
        {"init",        PySane_init,            1},
 
1232
        {"exit",        PySane_exit,            1},
 
1233
        {"get_devices", PySane_get_devices,     1},
 
1234
        {"_open",       PySane_open,    1},
 
1235
        {"OPTION_IS_ACTIVE",    PySane_OPTION_IS_ACTIVE,        1},
 
1236
        {"OPTION_IS_SETTABLE",  PySane_OPTION_IS_SETTABLE,      1},
 
1237
        {NULL,          NULL}           /* sentinel */
 
1238
};
 
1239
 
 
1240
 
 
1241
static void
 
1242
insint(PyObject *d, char *name, int value)
 
1243
{
 
1244
        PyObject *v = PyInt_FromLong((long) value);
 
1245
        if (!v || PyDict_SetItemString(d, name, v))
 
1246
                Py_FatalError("can't initialize sane module");
 
1247
 
 
1248
        Py_DECREF(v);
 
1249
}
 
1250
 
 
1251
void
 
1252
init_sane(void)
 
1253
{
 
1254
        PyObject *m, *d;
 
1255
 
 
1256
        /* Create the module and add the functions */
 
1257
        m = Py_InitModule("_sane", PySane_methods);
 
1258
 
 
1259
        /* Add some symbolic constants to the module */
 
1260
        d = PyModule_GetDict(m);
 
1261
        ErrorObject = PyString_FromString("_sane.error");
 
1262
        PyDict_SetItemString(d, "error", ErrorObject);
 
1263
 
 
1264
        insint(d, "INFO_INEXACT", SANE_INFO_INEXACT);
 
1265
        insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS);
 
1266
        insint(d, "RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS);
 
1267
 
 
1268
        insint(d, "FRAME_GRAY", SANE_FRAME_GRAY);
 
1269
        insint(d, "FRAME_RGB", SANE_FRAME_RGB);
 
1270
        insint(d, "FRAME_RED", SANE_FRAME_RED);
 
1271
        insint(d, "FRAME_GREEN", SANE_FRAME_GREEN);
 
1272
        insint(d, "FRAME_BLUE", SANE_FRAME_BLUE);
 
1273
 
 
1274
        insint(d, "CONSTRAINT_NONE", SANE_CONSTRAINT_NONE);
 
1275
        insint(d, "CONSTRAINT_RANGE", SANE_CONSTRAINT_RANGE);
 
1276
        insint(d, "CONSTRAINT_WORD_LIST", SANE_CONSTRAINT_WORD_LIST);
 
1277
        insint(d, "CONSTRAINT_STRING_LIST", SANE_CONSTRAINT_STRING_LIST);
 
1278
 
 
1279
        insint(d, "TYPE_BOOL", SANE_TYPE_BOOL);
 
1280
        insint(d, "TYPE_INT", SANE_TYPE_INT);
 
1281
        insint(d, "TYPE_FIXED", SANE_TYPE_FIXED);
 
1282
        insint(d, "TYPE_STRING", SANE_TYPE_STRING);
 
1283
        insint(d, "TYPE_BUTTON", SANE_TYPE_BUTTON);
 
1284
        insint(d, "TYPE_GROUP", SANE_TYPE_GROUP);
 
1285
 
 
1286
        insint(d, "UNIT_NONE", SANE_UNIT_NONE);
 
1287
        insint(d, "UNIT_PIXEL", SANE_UNIT_PIXEL);
 
1288
        insint(d, "UNIT_BIT", SANE_UNIT_BIT);
 
1289
        insint(d, "UNIT_MM", SANE_UNIT_MM);
 
1290
        insint(d, "UNIT_DPI", SANE_UNIT_DPI);
 
1291
        insint(d, "UNIT_PERCENT", SANE_UNIT_PERCENT);
 
1292
        insint(d, "UNIT_MICROSECOND", SANE_UNIT_MICROSECOND);
 
1293
 
 
1294
        insint(d, "CAP_SOFT_SELECT", SANE_CAP_SOFT_SELECT);
 
1295
        insint(d, "CAP_HARD_SELECT", SANE_CAP_HARD_SELECT);
 
1296
        insint(d, "CAP_SOFT_DETECT", SANE_CAP_SOFT_DETECT);
 
1297
        insint(d, "CAP_EMULATED", SANE_CAP_EMULATED);
 
1298
        insint(d, "CAP_AUTOMATIC", SANE_CAP_AUTOMATIC);
 
1299
        insint(d, "CAP_INACTIVE", SANE_CAP_INACTIVE);
 
1300
        insint(d, "CAP_ADVANCED", SANE_CAP_ADVANCED);
 
1301
 
 
1302
        /* handy for checking array lengths: */
 
1303
        insint(d, "SANE_WORD_SIZE", sizeof(SANE_Word));
 
1304
 
 
1305
        /* possible return values of set_option() */
 
1306
        insint(d, "INFO_INEXACT", SANE_INFO_INEXACT);
 
1307
        insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS);
 
1308
        insint(d, "INFO_RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS);
 
1309
        
 
1310
        /* Check for errors */
 
1311
        if (PyErr_Occurred())
 
1312
                Py_FatalError("can't initialize module _sane");
 
1313
 
 
1314
#ifdef WITH_NUMARRAY
 
1315
        import_libnumarray();
 
1316
        if (PyErr_Occurred())
 
1317
          PyErr_Clear();
 
1318
        else
 
1319
          /* this global variable is declared just in front of the 
 
1320
             arr_snap() function and should be set to 1 after
 
1321
             successfully importing the numarray module. */
 
1322
          NUMARRAY_IMPORTED = 1;
 
1323
 
 
1324
#endif /* WITH_NUMARRAY */
 
1325
}