static SANE_Status read_data(struct scanner *s) { SANE_Status st; int duplex = s->val[DUPLEX].w; s->read = 0; s->side = SIDE_FRONT; st = duplex ? read_image_duplex(s) : read_image_simplex(s); if (st && (st != SANE_STATUS_EOF)) goto err; st = kvs40xx_read_picture_element(s, SIDE_FRONT, &s->params); if (st) goto err; if (!s->params.lines) { st = SANE_STATUS_INVAL; goto err; } sane_get_parameters(s, NULL); s->page++; return SANE_STATUS_GOOD; err: s->scanning = 0; return st; }
static PyObject * SaneDev_get_parameters(SaneDevObject *self, PyObject *args) { SANE_Status st; SANE_Parameters p; char *format="unknown format"; if (!PyArg_ParseTuple(args, "")) return NULL; if (self->h==NULL) { PyErr_SetString(ErrorObject, "SaneDev object is closed"); return NULL; } Py_BEGIN_ALLOW_THREADS st=sane_get_parameters(self->h, &p); Py_END_ALLOW_THREADS if (st) return PySane_Error(st); switch (p.format) { case(SANE_FRAME_GRAY): format="gray"; break; case(SANE_FRAME_RGB): format="color"; break; case(SANE_FRAME_RED): format="red"; break; case(SANE_FRAME_GREEN): format="green"; break; case(SANE_FRAME_BLUE): format="blue"; break; } return Py_BuildValue("si(ii)ii", format, p.last_frame, p.pixels_per_line, p.lines, p.depth, p.bytes_per_line); }
SANE_Status sane_start (SANE_Handle h) { TScanner *s; SANE_Parameters par; HP5400_DBG (DBG_MSG, "sane_start\n"); s = (TScanner *) h; if (sane_get_parameters (h, &par) != SANE_STATUS_GOOD) { HP5400_DBG (DBG_MSG, "Invalid scan parameters (sane_get_parameters)\n"); return SANE_STATUS_INVAL; } s->iLinesLeft = par.lines; /* fill in the scanparams using the option values */ s->ScanParams.iDpi = s->aValues[optDPI].w; s->ScanParams.iLpi = s->aValues[optDPI].w; /* Guessing here. 75dpi => 1, 2400dpi => 32 */ /* s->ScanParams.iColourOffset = s->aValues[optDPI].w / 75; */ /* now we don't need correction => corrected by scan request type ? */ s->ScanParams.iColourOffset = 0; s->ScanParams.iTop = MM_TO_PIXEL (s->aValues[optTLY].w + s->HWParams.iTopLeftY, HW_LPI); s->ScanParams.iLeft = MM_TO_PIXEL (s->aValues[optTLX].w + s->HWParams.iTopLeftX, HW_DPI); /* Note: All measurements passed to the scanning routines must be in HW_LPI */ s->ScanParams.iWidth = MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w, HW_LPI); s->ScanParams.iHeight = MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w, HW_LPI); /* After the scanning, the iLines and iBytesPerLine will be filled in */ /* copy gamma table */ WriteGammaCalibTable (s->HWParams.iXferHandle, s->aGammaTableR, s->aGammaTableG, s->aGammaTableB); /* prepare the actual scan */ /* We say normal here. In future we should have a preview flag to set preview mode */ if (InitScan (SCAN_TYPE_NORMAL, &s->ScanParams, &s->HWParams) != 0) { HP5400_DBG (DBG_MSG, "Invalid scan parameters (InitScan)\n"); return SANE_STATUS_INVAL; } /* for the moment no lines has been read */ s->ScanParams.iLinesRead = 0; s->fScanning = TRUE; return SANE_STATUS_GOOD; }
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 KSaneScanThread::run() { m_dataSize = 0; m_readStatus = READ_ON_GOING; m_saneStartDone = false; // Start the scanning with sane_start m_saneStatus = sane_start(m_saneHandle); m_saneStartDone = true; if (m_readStatus == READ_CANCEL) { return; } if (m_saneStatus != SANE_STATUS_GOOD) { kDebug() << "sane_start=" << sane_strstatus(m_saneStatus); m_readStatus = READ_ERROR; // oneFinalScanDone() does the sane_cancel() return; } // Read image parameters 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; // oneFinalScanDone() does the sane_cancel() return; } // calculate data size m_frameSize = m_params.lines * m_params.bytes_per_line; if ((m_params.format == SANE_FRAME_RED) || (m_params.format == SANE_FRAME_GREEN) || (m_params.format == SANE_FRAME_BLUE)) { m_dataSize = m_frameSize*3; } else { m_dataSize = m_frameSize; } m_data->clear(); if (m_dataSize > 0) { m_data->reserve(m_dataSize); } m_frameRead = 0; m_frame_t_count = 0; m_readStatus = READ_ON_GOING; while (m_readStatus == READ_ON_GOING) { readData(); } }
/* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS */ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin, TW_MEMREF pData) { TW_UINT16 twRC = TWRC_SUCCESS; pTW_USERINTERFACE pUserInterface = (pTW_USERINTERFACE) pData; TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS\n"); if (activeDS.currentState != 4) { twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; FIXME("sequence error %d\n", activeDS.currentState); } else { activeDS.hwndOwner = pUserInterface->hParent; if (pUserInterface->ShowUI) { BOOL rc; activeDS.currentState = 5; /* Transitions to state 5 */ FIXME("showing UI\n"); rc = DoScannerUI(); if (!rc) { activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ; } #ifdef HAVE_SANE else { sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param); activeDS.sane_param_valid = TRUE; } #endif } else { /* no UI will be displayed, so source is ready to transfer data */ activeDS.pendingEvent.TWMessage = MSG_XFERREADY; activeDS.currentState = 6; /* Transitions to state 6 directly */ } activeDS.hwndOwner = pUserInterface->hParent; twRC = TWRC_SUCCESS; activeDS.twCC = TWCC_SUCCESS; } return twRC; }
SANE_Status sane_start (SANE_Handle handle) { AS6E_Scan *s = handle; SANE_Status status; int repeat = 1; SANE_Word numbytes; int scan_params[8]; /* First make sure we have a current parameter set. Some of the * parameters will be overwritten below, but that's OK. */ DBG (2, "sane_start\n"); status = sane_get_parameters (s, 0); if (status != SANE_STATUS_GOOD) return status; DBG (1, "Got params again...\n"); numbytes = write (s->as6e_params.ctloutpipe, &repeat, sizeof (repeat)); if (numbytes != sizeof (repeat)) return (SANE_STATUS_IO_ERROR); DBG (1, "sending start_scan signal\n"); scan_params[0] = s->as6e_params.resolution; if (strcmp (s->value[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0) scan_params[1] = 0; else if (strcmp (s->value[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0) scan_params[1] = 1; else if (strcmp (s->value[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0) scan_params[1] = 2; else return (SANE_STATUS_JAMMED); /*this should never happen */ scan_params[2] = s->as6e_params.startpos; scan_params[3] = s->as6e_params.stoppos; scan_params[4] = s->as6e_params.startline; scan_params[5] = s->as6e_params.stopline; scan_params[6] = s->value[OPT_BRIGHTNESS].w; scan_params[7] = s->value[OPT_CONTRAST].w; DBG (1, "scan params = %d %d %d %d %d %d %d %d\n", scan_params[0], scan_params[1], scan_params[2], scan_params[3], scan_params[4], scan_params[5], scan_params[6], scan_params[7]); numbytes = write (s->as6e_params.ctloutpipe, scan_params, sizeof (scan_params)); if (numbytes != sizeof (scan_params)) return (SANE_STATUS_IO_ERROR); s->scanning = SANE_TRUE; s->scan_buffer_count = 0; s->image_counter = 0; s->cancelled = 0; return (SANE_STATUS_GOOD); }
static PyObject *getParameters (_ScanDevice * self, PyObject * args) { SANE_Status st; SANE_Parameters p; char *format_name = "unknown"; if (!PyArg_ParseTuple (args, "")) raiseError("Invalid arguments."); if (self->h == NULL) return raiseDeviceClosedError(); Py_BEGIN_ALLOW_THREADS st = sane_get_parameters (self->h, &p); Py_END_ALLOW_THREADS if (st != SANE_STATUS_GOOD) return raiseSaneError (st); switch (p.format) { case (SANE_FRAME_GRAY): format_name = "gray"; break; case (SANE_FRAME_RGB): format_name = "color"; break; case (SANE_FRAME_RED): format_name = "red"; break; case (SANE_FRAME_GREEN): format_name = "green"; break; case (SANE_FRAME_BLUE): format_name = "blue"; break; } return Py_BuildValue ("isiiiii", p.format, format_name, p.last_frame, p.pixels_per_line, p.lines, p.depth, p.bytes_per_line); }
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; }
SANE_Status sane_start (SANE_Handle handle) { char *mode_str; Ibm_Scanner *s = handle; SANE_Status status; struct ibm_window_data wbuf; struct measurements_units_page mup; DBG (11, ">> sane_start\n"); /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ status = sane_get_parameters (s, 0); if (status != SANE_STATUS_GOOD) return status; status = sanei_scsi_open (s->hw->sane.name, &s->fd, 0, 0); if (status != SANE_STATUS_GOOD) { DBG (1, "open of %s failed: %s\n", s->hw->sane.name, sane_strstatus (status)); return (status); } mode_str = s->val[OPT_MODE].s; s->xres = s->val[OPT_X_RESOLUTION].w; s->yres = s->val[OPT_Y_RESOLUTION].w; s->ulx = s->val[OPT_TL_X].w; s->uly = s->val[OPT_TL_Y].w; s->width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w; s->length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w; s->brightness = s->val[OPT_BRIGHTNESS].w; s->contrast = s->val[OPT_CONTRAST].w; s->bpp = s->params.depth; if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART) == 0) { s->image_composition = IBM_BINARY_MONOCHROME; } else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE) == 0) { s->image_composition = IBM_DITHERED_MONOCHROME; } else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY) == 0) { s->image_composition = IBM_GRAYSCALE; } memset (&wbuf, 0, sizeof (wbuf)); /* next line commented out by mf */ /* _lto2b(sizeof(wbuf) - 8, wbuf.len); */ /* next line by mf */ _lto2b(IBM_WINDOW_DATA_SIZE, wbuf.len); /* size=320 */ _lto2b(s->xres, wbuf.x_res); _lto2b(s->yres, wbuf.y_res); _lto4b(s->ulx, wbuf.x_org); _lto4b(s->uly, wbuf.y_org); _lto4b(s->width, wbuf.width); _lto4b(s->length, wbuf.length); wbuf.image_comp = s->image_composition; /* if you throw the MRIF bit the brighness control reverses too */ /* so I reverse the reversal in software for symmetry's sake */ if (wbuf.image_comp == IBM_GRAYSCALE || wbuf.image_comp == IBM_DITHERED_MONOCHROME) { if (wbuf.image_comp == IBM_GRAYSCALE) wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x80; /* it was 0x90 */ if (wbuf.image_comp == IBM_DITHERED_MONOCHROME) wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x10; wbuf.brightness = 256 - (SANE_Byte) s->brightness; /* if (is50) wbuf.contrast = (SANE_Byte) s->contrast; else */ wbuf.contrast = 256 - (SANE_Byte) s->contrast; } else /* wbuf.image_comp == IBM_BINARY_MONOCHROME */ { wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x00; wbuf.brightness = (SANE_Byte) s->brightness; wbuf.contrast = (SANE_Byte) s->contrast; } wbuf.threshold = 0; wbuf.bits_per_pixel = s->bpp; wbuf.halftone_code = 2; /* diithering */ wbuf.halftone_id = 0x0A; /* 8x8 Bayer pattenr */ wbuf.pad_type = 3; wbuf.bit_ordering[0] = 0; wbuf.bit_ordering[1] = 7; /* modified by mf (it was 3) */ DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); DBG (5, "width=%d\n", _4btol(wbuf.width)); DBG (5, "length=%d\n", _4btol(wbuf.length)); DBG (5, "image_comp=%d\n", wbuf.image_comp); DBG (11, "sane_start: sending SET WINDOW\n"); status = set_window (s->fd, &wbuf); if (status != SANE_STATUS_GOOD) { DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status)); return (status); } DBG (11, "sane_start: sending GET WINDOW\n"); memset (&wbuf, 0, sizeof (wbuf)); status = get_window (s->fd, &wbuf); if (status != SANE_STATUS_GOOD) { DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status)); return (status); } DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); DBG (5, "width=%d\n", _4btol(wbuf.width)); DBG (5, "length=%d\n", _4btol(wbuf.length)); DBG (5, "image_comp=%d\n", wbuf.image_comp); DBG (11, "sane_start: sending MODE SELECT\n"); memset (&mup, 0, sizeof (mup)); mup.page_code = MEASUREMENTS_PAGE; mup.parameter_length = 0x06; mup.bmu = INCHES; mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff; mup.mud[1] = (DEFAULT_MUD & 0xff); /* next lines by mf */ mup.adf_page_code = 0x26; mup.adf_parameter_length = 6; if (s->adf_state == ADF_ARMED) mup.adf_control = 1; else mup.adf_control = 0; /* end lines by mf */ status = mode_select (s->fd, (struct mode_pages *) &mup); if (status != SANE_STATUS_GOOD) { DBG (1, "attach: MODE_SELECT failed\n"); return (SANE_STATUS_INVAL); } status = trigger_scan (s->fd); if (status != SANE_STATUS_GOOD) { DBG (1, "start of scan failed: %s\n", sane_strstatus (status)); /* next line introduced not to freeze xscanimage */ do_cancel(s); return status; } /* Wait for scanner to become ready to transmit data */ status = ibm_wait_ready (s); if (status != SANE_STATUS_GOOD) { DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status)); return (status); } s->bytes_to_read = s->params.bytes_per_line * s->params.lines; DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w); s->scanning = SANE_TRUE; DBG (11, "<< sane_start\n"); return (SANE_STATUS_GOOD); }
// -------------------------------------------------------------- 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; };
SANE_Status sane_start (SANE_Handle handle) { Tamarack_Scanner *s = handle; SANE_Status status; int fds[2]; /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ status = sane_get_parameters (s, 0); if (status != SANE_STATUS_GOOD) return status; if (s->fd < 0) { /* translate options into s->mode for convenient access: */ s->mode = make_mode (s->val[OPT_MODE].s); if (s->mode == TRUECOLOR) { if (s->val[OPT_PREVIEW].w && s->val[OPT_GRAY_PREVIEW].w) { /* Force gray-scale mode when previewing. */ s->mode = GREYSCALE; s->params.format = SANE_FRAME_GRAY; s->params.bytes_per_line = s->params.pixels_per_line; s->params.last_frame = SANE_TRUE; } } status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0); if (status != SANE_STATUS_GOOD) { DBG(1, "open: open of %s failed: %s\n", s->hw->sane.name, sane_strstatus (status)); return status; } } status = wait_ready (s->fd); if (status != SANE_STATUS_GOOD) { DBG(1, "open: wait_ready() failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = scan_area_and_windows (s); if (status != SANE_STATUS_GOOD) { DBG(1, "open: set scan area command failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = mode_select (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; s->scanning = SANE_TRUE; status = start_scan (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; status = get_image_status (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; s->line = 0; if (pipe (fds) < 0) return SANE_STATUS_IO_ERROR; s->pipe = fds[0]; s->reader_pipe = fds[1]; s->reader_pid = sanei_thread_begin (reader_process, (void *) s); if (sanei_thread_is_forked()) close (s->reader_pipe); return SANE_STATUS_GOOD; stop_scanner_and_return: do_cancel (s); return status; }
/* Start scanning */ SANE_Status sane_start (SANE_Handle handle) { struct scanner *s = (struct scanner *) handle; SANE_Status st = SANE_STATUS_GOOD; int duplex = s->val[DUPLEX].w, i; unsigned data_avalible; int start = 0; if (s->thread) { pthread_join (s->thread, NULL); s->thread = 0; } if (!s->scanning) { st = kvs40xx_test_unit_ready (s); if (st) return st; st = wait_document (s); if (st) return st; st = kvs40xx_reset_window (s); if (st) return st; st = kvs40xx_set_window (s, SIDE_FRONT); if (st) return st; if (duplex) { st = kvs40xx_set_window (s, SIDE_BACK); if (st) return st; } st = scan (s); if (st) return st; if (s->val[CROP].b || s->val[LENGTHCTL].b || s->val[LONG_PAPER].b) { unsigned w, h, res = s->val[RESOLUTION].w; SANE_Parameters *p = &s->params; w = 297; /*A3 */ h = 420; p->pixels_per_line = w * res / 25.4 + .5; p->lines = h * res / 25.4 + .5; } else { st = kvs40xx_read_picture_element (s, SIDE_FRONT, &s->params); if (st) return st; } start = 1; s->scanning = 1; s->page = 0; s->read = 0; s->side = SIDE_FRONT; sane_get_parameters (s, NULL); } if (duplex && s->side == SIDE_FRONT && !start) { s->side = SIDE_BACK; s->read = 0; return SANE_STATUS_GOOD; } do { st = get_buffer_status(s, &data_avalible); if (st) goto err; } while (!data_avalible); for (i = 0; i < (duplex ? 2 : 1); i++) { st = buf_init (&s->buf[i], s->side_size); if (st) goto err; } if (pthread_create (&s->thread, NULL, (void *(*)(void *)) read_data, s)) { st = SANE_STATUS_IO_ERROR; goto err; } if (s->val[CROP].b || s->val[LENGTHCTL].b || s->val[LONG_PAPER].b) { pthread_join (s->thread, NULL); s->thread = 0; } return SANE_STATUS_GOOD; err: s->scanning = 0; return st; }
SANE_Status sane_start( SANE_Handle handle ) { ST400_Device *dev = handle; SANE_Status status; DBG(DCODE, "sane_start(%p)\n", handle); if( !dev->status.open ) return SANE_STATUS_INVAL; if( dev->status.scanning ) return SANE_STATUS_DEVICE_BUSY; status = sane_get_parameters(dev, NULL); if( status != SANE_STATUS_GOOD ) return status; if( !dev->buffer ) { if( st400_maxread > 0 ) dev->bufsize = min(st400_maxread, (unsigned int) sanei_scsi_max_request_size); else if( dev->model->maxread > 0 ) dev->bufsize = min(dev->model->maxread, (unsigned int) sanei_scsi_max_request_size); else dev->bufsize = sanei_scsi_max_request_size; DBG(DVAR, "allocating %lu bytes buffer\n", (u_long)dev->bufsize); dev->buffer = malloc(dev->bufsize); if( !dev->buffer ) return SANE_STATUS_NO_MEM; } dev->bufp = dev->buffer; dev->bytes_in_buffer = 0; if( dev->fd < 0 ) { status = sanei_scsi_open(dev->sane.name, &dev->fd, st400_sense_handler, dev); if( status != SANE_STATUS_GOOD ) goto return_error; } dev->status.eof = 0; status = st400_wait_ready(dev->fd); if( status != SANE_STATUS_GOOD ) goto close_and_return; status = st400_reserve(dev->fd); if( status != SANE_STATUS_GOOD ) goto close_and_return; if( st400_light_delay > 0 ) { status = st400_light_on(dev->fd); if( status != SANE_STATUS_GOOD ) goto release_and_return; usleep(st400_light_delay * 100000); /* 1/10 seconds */ } dev->wy = dev->y; dev->lines_to_read = dev->h; dev->bytes_in_scanner = 0; status = st400_fill_scanner_buffer(dev); if( status != SANE_STATUS_GOOD ) goto lightoff_and_return; /* everything ok */ dev->status.scanning = 1; return SANE_STATUS_GOOD; lightoff_and_return: if( st400_light_delay ) st400_light_off(dev->fd); release_and_return: st400_release(dev->fd); close_and_return: sanei_scsi_close(dev->fd); return_error: dev->fd = -1; return status; }
/* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { #ifndef HAVE_SANE return TWRC_FAILURE; #else TW_UINT16 twRC = TWRC_SUCCESS; pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData; SANE_Status status; TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n"); if (activeDS.currentState != 6 && activeDS.currentState != 7) { twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; } else { if (activeDS.currentState == 6) { /* return general image description information about the image about to be transferred */ status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param); activeDS.sane_param_valid = TRUE; TRACE("Getting parameters\n"); } pImageInfo->XResolution.Whole = -1; pImageInfo->XResolution.Frac = 0; pImageInfo->YResolution.Whole = -1; pImageInfo->YResolution.Frac = 0; pImageInfo->ImageWidth = activeDS.sane_param.pixels_per_line; pImageInfo->ImageLength = activeDS.sane_param.lines; TRACE("Bits per Sample %i\n",activeDS.sane_param.depth); TRACE("Frame Format %i\n",activeDS.sane_param.format); if (activeDS.sane_param.format == SANE_FRAME_RGB ) { pImageInfo->BitsPerPixel = activeDS.sane_param.depth * 3; pImageInfo->Compression = TWCP_NONE; pImageInfo->Planar = TRUE; pImageInfo->SamplesPerPixel = 3; pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth; pImageInfo->BitsPerSample[1] = activeDS.sane_param.depth; pImageInfo->BitsPerSample[2] = activeDS.sane_param.depth; pImageInfo->PixelType = TWPT_RGB; } else if (activeDS.sane_param.format == SANE_FRAME_GRAY) { pImageInfo->BitsPerPixel = activeDS.sane_param.depth; pImageInfo->Compression = TWCP_NONE; pImageInfo->Planar = TRUE; pImageInfo->SamplesPerPixel = 1; pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth; pImageInfo->PixelType = TWPT_GRAY; } else { ERR("Unhandled source frame type %i\n",activeDS.sane_param.format); twRC = TWRC_FAILURE; activeDS.twCC = TWCC_SEQERROR; } } return twRC; #endif }
/* 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 }
static void* sane_idainit(FILE *fp, char *filename, unsigned int page, struct ida_image_info *info, int thumbnail) { const SANE_Option_Descriptor *opt; SANE_Int flags, count; struct sane_state *h; int rc,i,value,dpi = 0; h = malloc(sizeof(*h)); memset(h,0,sizeof(*h)); if (SANE_STATUS_GOOD != (rc = sane_init(NULL,NULL))) { fprintf(stderr,"sane_init: %s\n",sane_strstatus(rc)); goto oops; } if (SANE_STATUS_GOOD != (rc = sane_open(filename,&h->sane))) { fprintf(stderr,"sane_open: %s\n",sane_strstatus(rc)); goto oops; } /* set options */ opt = sane_get_option_descriptor(h->sane,0); rc = sane_control_option(h->sane, 0, SANE_ACTION_GET_VALUE, &count, &flags); for (i = 1; i < count; i++) { opt = sane_get_option_descriptor(h->sane,i); if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_X)) { value = opt->constraint.range->min; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_Y)) { value = opt->constraint.range->min; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_X)) { value = opt->constraint.range->max; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_Y)) { value = opt->constraint.range->max; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_PREVIEW)) { value = SANE_FALSE; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &value, &flags); } else if (opt->cap & SANE_CAP_AUTOMATIC) sane_control_option(h->sane, i, SANE_ACTION_SET_AUTO, NULL, &flags); if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_RESOLUTION)) { if (sane_res) { dpi = sane_res; sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE, &dpi, &flags); } sane_control_option(h->sane, i, SANE_ACTION_GET_VALUE, &dpi, &flags); } if (debug) dump_desc(h->sane,i,opt); } if (SANE_STATUS_GOOD != (rc = sane_start(h->sane))) { fprintf(stderr,"sane_start: %s\n",sane_strstatus(rc)); goto oops; } h->started = 1; if (SANE_STATUS_GOOD != (rc = sane_get_parameters(h->sane,&h->parm))) { fprintf(stderr,"sane_get_parameters: %s\n",sane_strstatus(rc)); goto oops; } if (h->parm.format != SANE_FRAME_GRAY && h->parm.format != SANE_FRAME_RGB) { fprintf(stderr,"sane: unsupported frame format (%d)\n",h->parm.format); goto oops; } if (h->parm.depth != 8) { fprintf(stderr,"sane: unsupported color depth (%d)\n",h->parm.depth); goto oops; } if (-1 == h->parm.lines) { fprintf(stderr,"sane: can't handle unknown image size\n"); goto oops; } info->width = h->parm.pixels_per_line; info->height = h->parm.lines; if (dpi) info->dpi = dpi; h->buf = malloc(h->parm.bytes_per_line * BUF_LINES); if (debug) fprintf(stderr,"sane: scanning %dx%d %s\n",info->width,info->height, (h->parm.format == SANE_FRAME_GRAY) ? "gray" : "color"); return h; oops: if (h->buf) free(h->buf); if (h->started) sane_cancel(h->sane); if (h->sane) sane_close(h->sane); sane_exit(); free(h); return NULL; }
SANE_Status sane_start (SANE_Handle handle) { Leo_Scanner *dev = handle; SANE_Status status; DBG (DBG_proc, "sane_start: enter\n"); if (!(dev->scanning)) { sane_get_parameters (dev, NULL); /* Open again the scanner. */ if (sanei_scsi_open (dev->devicename, &(dev->sfd), leo_sense_handler, dev) != 0) { DBG (DBG_error, "ERROR: sane_start: open failed\n"); return SANE_STATUS_INVAL; } /* The scanner must be ready. */ status = leo_wait_scanner (dev); if (status) { leo_close (dev); return status; } status = leo_set_window (dev); if (status) { leo_close (dev); return status; } status = leo_send_gamma (dev); if (status) { leo_close (dev); return status; } status = leo_send_halftone_pattern (dev); if (status) { leo_close (dev); return status; } status = leo_scan (dev); if (status) { leo_close (dev); return status; } status = leo_wait_scanner (dev); if (status) { leo_close (dev); return status; } status = leo_get_scan_size (dev); if (status) { leo_close (dev); return status; } } dev->image_end = 0; dev->image_begin = 0; dev->bytes_left = dev->params.bytes_per_line * dev->params.lines; dev->real_bytes_left = dev->params.bytes_per_line * dev->params.lines; dev->scanning = SANE_TRUE; DBG (DBG_proc, "sane_start: exit\n"); return SANE_STATUS_GOOD; }
/* Start scanning */ SANE_Status sane_start (SANE_Handle handle) { struct scanner *s = (struct scanner *) handle; SANE_Status st; int duplex = s->val[DUPLEX].w; if (!s->scanning) { unsigned dummy_length; st = kvs20xx_test_unit_ready (s); if (st) return st; st = wait_document (s); if (st) return st; st = kvs20xx_reset_window (s); if (st) return st; st = kvs20xx_set_window (s, SIDE_FRONT); if (st) return st; if (duplex) { st = kvs20xx_set_window (s, SIDE_BACK); if (st) return st; } st = kvs20xx_scan (s); if (st) return st; st = kvs20xx_read_picture_element (s, SIDE_FRONT, &s->params); if (st) return st; if (duplex) { st = get_adjust_data (s, &dummy_length); if (st) return st; } else { dummy_length = 0; } s->scanning = 1; s->page = 0; s->read = 0; s->side = SIDE_FRONT; sane_get_parameters (s, NULL); s->saved_dummy_size = s->dummy_size = dummy_length ? (dummy_length * s->val[RESOLUTION].w / 1200 - 1) * s->params.bytes_per_line : 0; s->side_size = s->params.lines * s->params.bytes_per_line; s->data = realloc (s->data, duplex ? s->side_size * 2 : s->side_size); if (!s->data) { s->scanning = 0; return SANE_STATUS_NO_MEM; } } if (duplex) { unsigned side = SIDE_FRONT; unsigned read, mx; if (s->side == SIDE_FRONT && s->read == s->side_size - s->dummy_size) { s->side = SIDE_BACK; s->read = s->dummy_size; s->dummy_size = 0; return SANE_STATUS_GOOD; } s->read = 0; s->dummy_size = s->saved_dummy_size; s->side = SIDE_FRONT; st = kvs20xx_document_exist (s); if (st) return st; for (mx = s->side_size * 2; !st; mx -= read, side ^= SIDE_BACK) st = kvs20xx_read_image_data (s, s->page, side, &s->data[s->side_size * 2 - mx], mx, &read); } else { unsigned read, mx; s->read = 0; st = kvs20xx_document_exist (s); if (st) return st; DBG (DBG_INFO, "start: %d\n", s->page); for (mx = s->side_size; !st; mx -= read) st = kvs20xx_read_image_data (s, s->page, SIDE_FRONT, &s->data[s->side_size - mx], mx, &read); } if (st && st != SANE_STATUS_EOF) { s->scanning = 0; return st; } s->page++; return SANE_STATUS_GOOD; }
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"); }
char *internalDoScanningOperation(char *uuid, char *lang) { int request_resolution = 0; int docid; int current_page = 0; int total_requested_pages; double totbytes = 0; SANE_Status status; SANE_Handle *openDeviceHandle; SANE_Byte *raw_image; SANE_Parameters pars; char *docid_s; char *total_requested_pages_s; char *devName; char *outFilename; char *raw_image_format; char *header; o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid); updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0); // Open the device devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); o_log(DEBUGM, "sane_open of \"%s\"",devName); status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { handleSaneErrors("Cannot open device ", devName, status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); free(devName); return 0; } free(devName); /* ========================================================== */ if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) ) return 0; o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution); int timeout = 5; while( 0 < timeout ) { status = sane_start (openDeviceHandle); if(status == SANE_STATUS_GOOD) { break; } else { if(status == SANE_STATUS_DEVICE_BUSY ) { // BUSY signal could be the scanner just having a // bit of lag - specially network connected devices timeout--; if ( timeout == 0 ) { handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } else { o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout); usleep(500 * 1000); // 500ms or 0.5sec } } else { handleSaneErrors("Cannot start scanning", "", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } } } // Get scanning params (from the scanner) if( request_resolution == 0 ) { o_log(DEBUGM, "Resolution did not get set in scanner setup."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004); return 0; } o_log(DEBUGM, "Get scanning params"); status = sane_get_parameters (openDeviceHandle, &pars); o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d", sane_strstatus (status), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); switch (pars.format) { case SANE_FRAME_GRAY: o_log(DEBUGM, "Expecting Gray data (1 channel only)."); raw_image_format = o_strdup( "P5" ); break; case SANE_FRAME_RGB: o_log(DEBUGM, "Expecting RGB data (3 channels)."); raw_image_format = o_strdup( "P6" ); break; default: o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003); return 0; break; } header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", raw_image_format, pars.pixels_per_line, pars.lines, (pars.depth <= 8) ? 255 : 65535); free( raw_image_format ); // Save Record // docid_s = getScanParam(uuid, SCAN_PARAM_DOCID); total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES); total_requested_pages = atoi(total_requested_pages_s); free(total_requested_pages_s); if( docid_s == NULL ) { o_log(DEBUGM, "Saving record"); updateScanProgress(uuid, SCAN_DB_WORKING, 0); docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); setScanParam(uuid, SCAN_PARAM_DOCID, docid_s); setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1"); current_page = 1; } else { char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE); current_page = atoi(current_page_s); free(current_page_s); current_page++; current_page_s = itoa(current_page, 10); setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s); free(current_page_s); } docid = atoi(docid_s); free(docid_s); totbytes = (double)((pars.bytes_per_line * pars.lines)); /* ========================================================== */ raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header ); o_log(INFORMATION, "Scanning done."); o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // Convert Raw into JPEG // updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0); PIX *pix; if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) { o_log(ERROR, "Could not load the image data into a PIX"); } updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55); o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix)); free(raw_image); free(header); outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page); pixWrite(outFilename, pix, IFF_JFIF_JPEG); free(outFilename); updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100); o_log(INFORMATION, "Conversion process: Complete"); // Do OCR - on this page // - OCR libs just wants the raw data and not the image header ocrImage( uuid, docid, current_page, request_resolution, pix, lang ); #ifdef CAN_PHASH // Calulate the pHash, so we can compare images later if( current_page == 1 ) { updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0); unsigned long long hash = getImagePhash_px( pix ); savePhash( docid, hash ); } #endif /* CAN_PHASH */ pixDestroy( &pix ); // cleaup && What should we do next // o_log(DEBUGM, "mostly done."); if(current_page >= total_requested_pages) updateScanProgress(uuid, SCAN_FINISHED, docid); else updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page); o_log(DEBUGM, "Page scan done."); return o_strdup("OK"); }