static PyObject *readScan (_ScanDevice * self, PyObject * args) { SANE_Status st; SANE_Int len; SANE_Byte buffer[MAX_READSIZE]; int bytes_to_read; if (!PyArg_ParseTuple (args, "i", &bytes_to_read)) raiseError("Invalid arguments."); if (bytes_to_read > MAX_READSIZE) return raiseError("bytes_to_read > MAX_READSIZE"); if (self->h == NULL) return raiseDeviceClosedError(); //Py_BEGIN_ALLOW_THREADS Py_UNBLOCK_THREADS st = sane_read (self->h, buffer, bytes_to_read, &len); //Py_END_ALLOW_THREADS Py_BLOCK_THREADS if (st != SANE_STATUS_GOOD && st != SANE_STATUS_EOF && st != SANE_STATUS_NO_DOCS) { sane_cancel(self->h); //Py_BLOCK_THREADS return raiseSaneError(st); } return Py_BuildValue (FORMAT_STRING, st, buffer, len); }
void KSaneScanThread::readData() { SANE_Int readBytes = 0; m_saneStatus = sane_read(m_saneHandle, m_readData, SCAN_READ_CHUNK_SIZE, &readBytes); switch (m_saneStatus) { case SANE_STATUS_GOOD: // continue to parsing the data break; case SANE_STATUS_EOF: if (m_frameRead < m_frameSize) { kDebug() << "frameRead =" << m_frameRead << ", frameSize =" << m_frameSize << "readBytes =" << readBytes; if ((readBytes > 0) && ((m_frameRead + readBytes) <= m_frameSize)) { kDebug() << "This is not a standard compliant backend"; copyToScanData(readBytes); } m_readStatus = READ_READY; // It is better to return a broken image than nothing return; } if (m_params.last_frame == SANE_TRUE) { // this is where it all ends well :) m_readStatus = READ_READY; return; } else { // start reading next frame m_saneStatus = sane_start(m_saneHandle); if (m_saneStatus != SANE_STATUS_GOOD) { kDebug() << "sane_start =" << sane_strstatus(m_saneStatus); m_readStatus = READ_ERROR; return; } m_saneStatus = sane_get_parameters(m_saneHandle, &m_params); if (m_saneStatus != SANE_STATUS_GOOD) { kDebug() << "sane_get_parameters =" << sane_strstatus(m_saneStatus); m_readStatus = READ_ERROR; sane_cancel(m_saneHandle); return; } //kDebug() << "New Frame"; m_frameRead = 0; m_frame_t_count++; break; } default: kDebug() << "sane_read=" << m_saneStatus << "=" << sane_strstatus(m_saneStatus); m_readStatus = READ_ERROR; sane_cancel(m_saneHandle); return; } copyToScanData(readBytes); }
void tcp_dev_close (struct device *dev) { if (!dev) return; DBG (3, "%s: closing dev %p\n", __FUNCTION__, (void *)dev); /* finish all operations */ if (dev->scanning) { dev->cancel = 1; /* flush READ_IMAGE data */ if (dev->reading) sane_read(dev, NULL, 1, NULL); /* send cancel if not sent before */ if (dev->state != SANE_STATUS_CANCELLED) ret_cancel(dev, 0); } sanei_tcp_close(dev->dn); dev->dn = -1; }
static void sane_idaread(unsigned char *dst, unsigned int line, void *data) { struct sane_state *h = data; unsigned int lines, total, offset, len; int rc, i; SANE_Byte *row; if (0 == (line % BUF_LINES)) { lines = BUF_LINES; if (lines > h->parm.lines - line) lines = h->parm.lines - line; total = h->parm.bytes_per_line * lines; offset = 0; while (offset < total) { rc = sane_read(h->sane, h->buf + offset, total - offset, &len); if (rc != SANE_STATUS_GOOD) return; offset += len; } } row = h->buf + (line % BUF_LINES) * h->parm.bytes_per_line; switch (h->parm.format) { case SANE_FRAME_GRAY: for (i = 0; i < h->parm.pixels_per_line; i++) { dst[3*i+0] = row[i]; dst[3*i+1] = row[i]; dst[3*i+2] = row[i]; } break; case SANE_FRAME_RGB: memcpy(dst,row,h->parm.pixels_per_line*3); break; default: fprintf(stderr,"sane: read: internal error\n"); exit(1); } }
static PyObject * SaneDev_snap(SaneDevObject *self, PyObject *args) { SANE_Status st; /* The buffer should be a multiple of 3 in size, so each sane_read operation will return an integral number of RGB triples. */ SANE_Byte buffer[READSIZE]; /* XXX how big should the buffer be? */ SANE_Int len, lastlen; Imaging im; SANE_Parameters p; int px, py, remain, cplen, bufpos, padbytes; long L; char errmsg[80]; union { char c[2]; INT16 i16; } endian; PyObject *pyNoCancel = NULL; int noCancel = 0; endian.i16 = 1; if (!PyArg_ParseTuple(args, "l|O", &L, &pyNoCancel)) return NULL; if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } im=(Imaging)L; if (pyNoCancel) noCancel = PyObject_IsTrue(pyNoCancel); st=SANE_STATUS_GOOD; px=py=0; /* xxx not yet implemented - handscanner support (i.e., unknown image length during start) - generally: move the functionality from method snap in sane.py down here -- I don't like this cross-dependency. we need to call sane_get_parameters here, and we can create the result Image object here. */ Py_UNBLOCK_THREADS sane_get_parameters(self->h, &p); if (p.format == SANE_FRAME_GRAY) { switch (p.depth) { case 1: remain = p.bytes_per_line * im->ysize; padbytes = p.bytes_per_line - (im->xsize+7)/8; bufpos = 0; lastlen = len = 0; while (st!=SANE_STATUS_EOF && py < im->ysize) { while (len > 0 && py < im->ysize) { int i, j, k; j = buffer[bufpos++]; k = 0x80; for (i = 0; i < 8 && px < im->xsize; i++) { im->image8[py][px++] = (k&j) ? 0 : 0xFF; k = k >> 1; } len--; if (px >= im->xsize) { bufpos += padbytes; len -= padbytes; py++; px = 0; } } st=sane_read(self->h, buffer, remain<READSIZE ? remain : READSIZE, &len); if (st && (st!=SANE_STATUS_EOF)) { sane_cancel(self->h); Py_BLOCK_THREADS return PySane_Error(st); } bufpos -= lastlen; lastlen = len; remain -= len; /* skip possible pad bytes at the start of the buffer */ len -= bufpos; } break; case 8: remain = p.bytes_per_line * im->ysize; padbytes = p.bytes_per_line - im->xsize; bufpos = 0; len = 0; while (st!=SANE_STATUS_EOF && py < im->ysize) { while (len > 0 && py < im->ysize) { cplen = len; if (px + cplen >= im->xsize) cplen = im->xsize - px; memcpy(&im->image8[py][px], &buffer[bufpos], cplen); len -= cplen; bufpos += cplen; px += cplen; if (px >= im->xsize) { px = 0; py++; bufpos += padbytes; len -= padbytes; } } bufpos = -len; st=sane_read(self->h, buffer, remain<READSIZE ? remain : READSIZE, &len); if (st && (st!=SANE_STATUS_EOF)) { sane_cancel(self->h); Py_BLOCK_THREADS return PySane_Error(st); } remain -= len; len -= bufpos; } break; case 16: remain = p.bytes_per_line * im->ysize; padbytes = p.bytes_per_line - 2 * im->xsize; bufpos = endian.c[0]; lastlen = len = 0; while (st!=SANE_STATUS_EOF && py < im->ysize) { while (len > 0 && py < im->ysize) { im->image8[py][px++] = buffer[bufpos]; bufpos += 2; len -= 2; if (px >= im->xsize) { bufpos += padbytes; len -= padbytes; py++; px = 0; } } st=sane_read(self->h, buffer, remain<READSIZE ? remain : READSIZE, &len); if (st && (st!=SANE_STATUS_EOF)) { sane_cancel(self->h); Py_BLOCK_THREADS return PySane_Error(st); } remain -= len; bufpos -= lastlen; lastlen = len; len -= bufpos; }
// -------------------------------------------------------------- int32 ControlsWindow::ScanThread() { SANE_Status status; SANE_Handle device; int len; SANE_Parameters parm; BBitmap * image; bool first_frame; device = Device(); Lock(); m_status_bar->Show(); rgb_color default_color = m_status_bar->BarColor(); m_scan_button->SetLabel("Cancel"); m_status_bar->Reset("Scanning..."); Unlock(); first_frame = true; do // for each frame... { // start frame reading if ( m_cancel_scan ) break; status = sane_start(device); if ( status != SANE_STATUS_GOOD ) { fprintf (stderr, "sane_start: %s\n", sane_strstatus (status)); break; }; // get frame parameters status = sane_get_parameters(device, &parm); if (status != SANE_STATUS_GOOD) { fprintf (stderr, "sane_get_parameters: %s\n", sane_strstatus (status)); break; }; if (parm.lines >= 0) { Lock(); m_status_bar->SetMaxValue(((parm.format == SANE_FRAME_RGB) ? 1.0 : 3.0) * parm.bytes_per_line * parm.lines); Unlock(); fprintf (stderr, "scanning image of size %dx%d pixels at " "%d bits/pixel\n", parm.pixels_per_line, parm.lines, 8 * parm.bytes_per_line / parm.pixels_per_line); if ( first_frame ) { image = new BBitmap(BRect(0, 0, parm.pixels_per_line - 1, parm.lines - 1), ((parm.depth == 1) ? B_GRAY1 : B_RGBA32)); m_parent_window->Lock(); m_parent_window->SetImage(image); m_parent_window->Unlock(); }; } else { fprintf (stderr, "scanning image %d pixels wide and " "variable height at %d bits/pixel\n", parm.pixels_per_line, 8 * parm.bytes_per_line / parm.pixels_per_line); BAlert * alert = new BAlert("Well...", "Variable height scanning not supported (yet?)", "Sorry"); alert->Go(); break; }; uint8 * buffer, * data; uint8 * ptr; int32 x, y; int channel; rgb_color red_color = { 255, 0, 0, 255 }; rgb_color green_color = { 0, 255, 0, 255 }; rgb_color blue_color = { 0, 0, 255, 255 }; BRect updated_rect; x = y = 0; channel = 0; updated_rect.Set(0, 0, parm.pixels_per_line, 0); Lock(); switch(parm.format) { case SANE_FRAME_RED: channel = 2; m_status_bar->SetBarColor(red_color); break; case SANE_FRAME_GREEN: channel = 1; m_status_bar->SetBarColor(green_color); break; case SANE_FRAME_BLUE: channel = 0; m_status_bar->SetBarColor(blue_color); break; default: channel = 0; m_status_bar->SetBarColor(default_color); break; }; Unlock(); buffer = (uint8 *) malloc(parm.bytes_per_line); while (1) // read until end of frame or error { if ( m_cancel_scan ) break; len = 0; status = sane_read(device, buffer, parm.bytes_per_line, &len); if (status != SANE_STATUS_GOOD) { if (status != SANE_STATUS_EOF) { fprintf (stderr, "sane_read: %s\n", sane_strstatus (status)); BAlert * alert = new BAlert("sane_read()", sane_strstatus(status), "Glup."); alert->Go(); }; break; }; Lock(); m_status_bar->Update((float) len); Unlock(); if ( image ) { image->Lock(); ptr = (uint8 *) image->Bits(); ptr += (y * image->BytesPerRow()); ptr += (4*x); data = buffer; while ( len > 0 ) { switch (parm.format) { case SANE_FRAME_RED: case SANE_FRAME_GREEN: case SANE_FRAME_BLUE: { uint8 value; if (parm.depth == 16) { value = (*((uint16 *) data)) >> 8; data += 2; len -= 2; } else { value = *((uint8 *) data); data++; len--; }; *(ptr + channel) = value; *(ptr + 3) = 255; // Alpha channel break; }; case SANE_FRAME_RGB: { uint8 red, green, blue; if (parm.depth == 16) { red = (*((uint16 *) data)) >> 8; data += 2; green = (*((uint16 *) data)) >> 8; data += 2; blue = (*((uint16 *) data)) >> 8; data += 2; len -= 6; } else { red = *((uint8 *) data); data++; green = *((uint8 *) data); data++; blue = *((uint8 *) data); data++; len -= 3; }; *ptr = blue; *(ptr+1) = green; *(ptr+2) = red; // red channel *(ptr+3) = 255; // Alpha channel break; }; case SANE_FRAME_GRAY: { uint8 value; if (parm.depth == 1 ) { *ptr = *((uint8 *) data); data++; len--; break; }; if (parm.depth == 16) { value = (*((uint16 *) data)) >> 8; data += 2; len -= 2; } else if ( parm.depth == 8 ) { value = *((uint8 *) data); data++; len--; }; *ptr = value; // blue channel *(ptr+1) = value; // green channel *(ptr+2) = value; // red channel *(ptr+3) = 255; // Alpha channel break; };
/* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { #ifndef HAVE_SANE return TWRC_FAILURE; #else TW_UINT16 twRC = TWRC_SUCCESS; pTW_UINT32 pHandle = (pTW_UINT32) pData; SANE_Status status; SANE_Byte buffer[32*1024]; int buff_len; HBITMAP hDIB; BITMAPINFO bmpInfo; VOID *pBits; HDC dc; TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n"); if (activeDS.currentState != 6) { twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; } else { /* Transfer an image from the source to the application */ status = sane_start (activeDS.deviceHandle); if (status != SANE_STATUS_GOOD) { WARN("sane_start: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param); activeDS.sane_param_valid = TRUE; if (status != SANE_STATUS_GOOD) { WARN("sane_get_parameters: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n" , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines, activeDS.sane_param.depth, activeDS.sane_param.format, activeDS.sane_param.last_frame); ZeroMemory (&bmpInfo, sizeof (BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = activeDS.sane_param.pixels_per_line; bmpInfo.bmiHeader.biHeight = activeDS.sane_param.lines; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = activeDS.sane_param.depth; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 1; bmpInfo.bmiHeader.biClrImportant = 0; bmpInfo.bmiColors[0].rgbBlue = 128; bmpInfo.bmiColors[0].rgbGreen = 128; bmpInfo.bmiColors[0].rgbRed = 128; hDIB = CreateDIBSection ((dc = GetDC(activeDS.hwndOwner)), &bmpInfo, DIB_RGB_COLORS, &pBits, 0, 0); if (!hDIB) { sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_LOWMEMORY; return TWRC_FAILURE; } do { status = sane_read (activeDS.deviceHandle, buffer, sizeof (buffer), &buff_len); if (status == SANE_STATUS_GOOD) { /* FIXME: put code for converting the image data into DIB here */ } else if (status != SANE_STATUS_EOF) { WARN("sane_read: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } } while (status == SANE_STATUS_GOOD); sane_cancel (activeDS.deviceHandle); ReleaseDC (activeDS.hwndOwner, dc); *pHandle = (TW_UINT32)hDIB; twRC = TWRC_XFERDONE; activeDS.twCC = TWCC_SUCCESS; activeDS.currentState = 7; } return twRC; #endif }
/* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { #ifndef HAVE_SANE return TWRC_FAILURE; #else TW_UINT16 twRC = TWRC_SUCCESS; pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData; SANE_Status status = SANE_STATUS_GOOD; TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n"); if (activeDS.currentState < 6 || activeDS.currentState > 7) { twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; } else { LPBYTE buffer; int buff_len = 0; int consumed_len = 0; LPBYTE ptr; int rows; /* Transfer an image from the source to the application */ if (activeDS.currentState == 6) { /* trigger scanning dialog */ activeDS.progressWnd = ScanningDialogBox(NULL,0); ScanningDialogBox(activeDS.progressWnd,0); status = sane_start (activeDS.deviceHandle); if (status != SANE_STATUS_GOOD) { WARN("sane_start: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param); activeDS.sane_param_valid = TRUE; if (status != SANE_STATUS_GOOD) { WARN("sane_get_parameters: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n" , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines, activeDS.sane_param.depth, activeDS.sane_param.format, activeDS.sane_param.last_frame); activeDS.currentState = 7; } /* access memory buffer */ if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line) { sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_BADVALUE; return TWRC_FAILURE; } if (pImageMemXfer->Memory.Flags & TWMF_HANDLE) { FIXME("Memory Handle, may not be locked correctly\n"); buffer = LocalLock(pImageMemXfer->Memory.TheMem); } else buffer = pImageMemXfer->Memory.TheMem; memset(buffer,0,pImageMemXfer->Memory.Length); ptr = buffer; consumed_len = 0; rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line; /* must fill full lines */ while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) && status == SANE_STATUS_GOOD) { status = sane_read (activeDS.deviceHandle, ptr, (activeDS.sane_param.bytes_per_line*rows) - consumed_len , &buff_len); consumed_len += buff_len; ptr += buff_len; } if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF) { pImageMemXfer->Compression = TWCP_NONE; pImageMemXfer->BytesPerRow = activeDS.sane_param.bytes_per_line; pImageMemXfer->Columns = activeDS.sane_param.pixels_per_line; pImageMemXfer->Rows = rows; pImageMemXfer->XOffset = 0; pImageMemXfer->YOffset = 0; pImageMemXfer->BytesWritten = consumed_len; ScanningDialogBox(activeDS.progressWnd, consumed_len); if (status == SANE_STATUS_EOF) { ScanningDialogBox(activeDS.progressWnd, -1); TRACE("sane_read: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); twRC = TWRC_XFERDONE; } activeDS.twCC = TWRC_SUCCESS; } else if (status != SANE_STATUS_EOF) { ScanningDialogBox(activeDS.progressWnd, -1); WARN("sane_read: %s\n", sane_strstatus (status)); sane_cancel (activeDS.deviceHandle); activeDS.twCC = TWCC_OPERATIONERROR; twRC = TWRC_FAILURE; } } if (pImageMemXfer->Memory.Flags & TWMF_HANDLE) LocalUnlock(pImageMemXfer->Memory.TheMem); return twRC; #endif }
SANE_Byte *collectData( char *uuid, SANE_Handle *openDeviceHandle, size_t totbytes, int bpl, char *header ) { SANE_Status status; SANE_Int received_length_from_sane = 0; SANE_Byte *raw_image; SANE_Byte *raw_image_current_pos; int progress = 0; int feedback = 5; int bufferSize = 32768; size_t readSoFar = 0; size_t headerLength = strlen(header); size_t stillToRead = totbytes; struct timeval start, end; // Initialise the blank image; raw_image = calloc( totbytes + headerLength + 1, sizeof(unsigned char) ); if( raw_image == NULL ) { o_log(ERROR, "Out of memory, when assiging the new image storage."); return NULL; } strcpy((char *)raw_image, header); raw_image_current_pos = raw_image + headerLength; //status = sane_set_io_mode (openDeviceHandle, SANE_TRUE); //o_log(DEBUGM, "setting non-blocking mode was %s", sane_strstatus( status ) ); o_log(DEBUGM, "scan_read - start"); gettimeofday(&start, NULL); do { // Set status as 'scanning' if ( 0 > feedback ) { updateScanProgress(uuid, SCAN_SCANNING, progress); feedback = 5; } feedback--; // // Read buffer from sane (the scanner) //status = sane_read (openDeviceHandle, raw_image_current_pos, stillToRead, &received_length_from_sane); status = sane_read (openDeviceHandle, raw_image_current_pos, bufferSize, &received_length_from_sane); o_log(DEBUGM, "At %d%, requested %d bytes, got %d, with status %d)", progress, stillToRead, received_length_from_sane, status); // // Write the read 'buffer' onto 'raw_image' if( received_length_from_sane > 0 ) { readSoFar += received_length_from_sane; stillToRead -= received_length_from_sane; raw_image_current_pos += received_length_from_sane; if ( received_length_from_sane == bufferSize ) { bufferSize += 32768; } if ( bufferSize > stillToRead ) { bufferSize = stillToRead; } // Update the progress info progress = (int)((readSoFar*100) / totbytes); if(progress > 100) progress = 100; if ( stillToRead == 0 ) { o_log(ERROR, "No more bytes to read" ); break; } } // get some data from sane if (status != SANE_STATUS_GOOD) { if (status == SANE_STATUS_EOF) { o_log(ERROR, "sane told us were at the end" ); break; } else { o_log(ERROR, "something wrong while scanning: %s", sane_strstatus(status) ); break; } } } while (1); gettimeofday(&end, NULL); o_log(DEBUGM, "scan_read - end." ); o_log( INFORMATION, "Read %d of an expected %d bytes, in %lu ms", readSoFar, totbytes, timevaldiff(&start, &end) ); return raw_image; }
void testsane (const char *dev_name) { int hlp, x; SANE_Status bla; SANE_Int blubb; SANE_Handle hand; SANE_Parameters pars; const SANE_Option_Descriptor *sod; const SANE_Device **device_list; char buffer[2048]; bla = sane_init (&blubb, auth_callback); fprintf (stderr, "Init : stat=%d ver=%x\nPress Enter to continue...", bla, blubb); getchar (); if (bla != SANE_STATUS_GOOD) return; bla = sane_get_devices (&device_list, SANE_FALSE); fprintf (stderr, "GetDev : stat=%s\n", sane_strstatus (bla)); if (bla != SANE_STATUS_GOOD) return; bla = sane_open (dev_name, &hand); fprintf (stderr, "Open : stat=%s hand=%p\n", sane_strstatus (bla), hand); if (bla != SANE_STATUS_GOOD) return; bla = sane_set_io_mode (hand, 0); fprintf (stderr, "SetIoMode : stat=%s\n", sane_strstatus (bla)); for (hlp = 0; hlp < 9999; hlp++) { sod = sane_get_option_descriptor (hand, hlp); if (sod == NULL) break; fprintf (stderr, "Gopt(%d) : stat=%p\n", hlp, sod); fprintf (stderr, "name : %s\n", sod->name); fprintf (stderr, "title: %s\n", sod->title); fprintf (stderr, "desc : %s\n", sod->desc); fprintf (stderr, "type : %d\n", sod->type); fprintf (stderr, "unit : %d\n", sod->unit); fprintf (stderr, "size : %d\n", sod->size); fprintf (stderr, "cap : %d\n", sod->cap); fprintf (stderr, "ctyp : %d\n", sod->constraint_type); switch (sod->constraint_type) { case SANE_CONSTRAINT_NONE: break; case SANE_CONSTRAINT_STRING_LIST: fprintf (stderr, "stringlist:\n"); break; case SANE_CONSTRAINT_WORD_LIST: fprintf (stderr, "wordlist (%d) : ", sod->constraint.word_list[0]); for (x = 1; x <= sod->constraint.word_list[0]; x++) fprintf (stderr, " %d ", sod->constraint.word_list[x]); fprintf (stderr, "\n"); break; case SANE_CONSTRAINT_RANGE: fprintf (stderr, "range: %d-%d %d \n", sod->constraint.range->min, sod->constraint.range->max, sod->constraint.range->quant); break; } } bla = sane_get_parameters (hand, &pars); fprintf (stderr, "Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d\n", sane_strstatus (bla), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); if (bla != SANE_STATUS_GOOD) return; bla = sane_start (hand); fprintf (stderr, "Start : stat=%s\n", sane_strstatus (bla)); if (bla != SANE_STATUS_GOOD) return; do { bla = sane_read (hand, buffer, sizeof (buffer), &blubb); /*printf("Read : stat=%s len=%d\n",sane_strstatus (bla),blubb); */ if (bla != SANE_STATUS_GOOD) { if (bla == SANE_STATUS_EOF) break; return; } fwrite (buffer, 1, blubb, stdout); } while (1); sane_cancel (hand); fprintf (stderr, "Cancel.\n"); sane_close (hand); fprintf (stderr, "Close\n"); for (hlp = 0; hlp < 20; hlp++) fprintf (stderr, "STRS %d=%s\n", hlp, sane_strstatus (hlp)); fprintf (stderr, "Exit.\n"); }