kopia lustrzana https://gitlab.com/sane-project/backends
new buffer portioning and full DIN A4 support
rodzic
a776ea2311
commit
e7ac842c81
|
|
@ -1,3 +1,8 @@
|
|||
2004-10-17 Ullrich Sigwanz <usigwanz@freesurf.ch>
|
||||
|
||||
* backend/niash_core.c: rewrote buffer portioning
|
||||
* backend/niash.c: Enabling support of full DIN A4 size
|
||||
|
||||
2004-10-16 Oliver Rauch <Oliver.Rauch@Rauch-DOmain.DE>
|
||||
* backend/umax.c: added default options for Linotype OPAL2
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ _UnityGammaTable (unsigned char *hwGamma)
|
|||
}
|
||||
|
||||
static const SANE_Range rangeXmm = { 0, 220, 1 };
|
||||
static const SANE_Range rangeYmm = { 0, 290, 1 };
|
||||
static const SANE_Range rangeYmm = { 0, 297, 1 };
|
||||
static const SANE_Int startUpGamma = SANE_FIX (1.6);
|
||||
|
||||
static const char colorStr[] = { "Color" };
|
||||
|
|
@ -654,7 +654,7 @@ _InitOptions (TScanner * s)
|
|||
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
pDesc->constraint.range = &rangeXmm;
|
||||
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
||||
pVal->w = rangeXmm.max;
|
||||
pVal->w = 210 /* A4 width instead of rangeXmm.max */ ;
|
||||
break;
|
||||
|
||||
case optBRY:
|
||||
|
|
@ -665,7 +665,7 @@ _InitOptions (TScanner * s)
|
|||
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
pDesc->constraint.range = &rangeYmm;
|
||||
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
||||
pVal->w = rangeYmm.max;
|
||||
pVal->w = 290 /* have a bit reserve instaed of rangeYmm.max */ ;
|
||||
break;
|
||||
|
||||
case optDPI:
|
||||
|
|
@ -1394,10 +1394,17 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
|
|||
/* time to read the next line? */
|
||||
if (s->iBytesLeft == 0)
|
||||
{
|
||||
SANE_Bool fJustDone = SANE_FALSE;
|
||||
/* read a line from the transfer buffer */
|
||||
if (CircBufferGetLine (s->HWParams.iXferHandle, p, p->pabLineBuf,
|
||||
s->HWParams.iReversedHead))
|
||||
if (CircBufferGetLineEx (s->HWParams.iXferHandle, p, p->pabLineBuf,
|
||||
s->HWParams.iReversedHead, &fJustDone))
|
||||
{
|
||||
if (fJustDone)
|
||||
{
|
||||
DBG (DBG_MSG, "\n");
|
||||
DBG (DBG_MSG, "sane_read: returning cartridge\n");
|
||||
FinishScan (&s->HWParams);
|
||||
}
|
||||
pMode->adaptFormat (p->pabLineBuf, s->iPixelsPerLine,
|
||||
s->aValues[optThreshold].w);
|
||||
s->iBytesLeft = pMode->bytesPerLine (s->iPixelsPerLine);
|
||||
|
|
|
|||
|
|
@ -724,10 +724,14 @@ InitScan (TScanParams * pParams, THWParams * pHWParams)
|
|||
/************************************************************************/
|
||||
|
||||
static SANE_Bool
|
||||
XferBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine)
|
||||
XferBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
||||
SANE_Bool * pfJustDone)
|
||||
{
|
||||
unsigned char bData;
|
||||
|
||||
if (pfJustDone)
|
||||
{
|
||||
*pfJustDone = SANE_FALSE;
|
||||
}
|
||||
/* all calculated transfers done ? */
|
||||
if (p->iLinesLeft == 0)
|
||||
return SANE_FALSE;
|
||||
|
|
@ -735,13 +739,28 @@ XferBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine)
|
|||
/* time for a fresh read? */
|
||||
if (p->iCurLine == 0)
|
||||
{
|
||||
/* DBG(DBG_MSG, "Reading buffer %d unsigned chars\n", _iLinesPerXferBuf
|
||||
* _iBytesPerLine); */
|
||||
int iLines;
|
||||
iLines = p->iLinesPerXferBuf;
|
||||
/* read only as many lines as needed */
|
||||
if (p->iLinesLeft > 0 && p->iLinesLeft <= iLines)
|
||||
{
|
||||
iLines = p->iLinesLeft;
|
||||
DBG (DBG_MSG, "\n");
|
||||
if (p->iLinesLeft < iLines)
|
||||
{
|
||||
DBG (DBG_MSG,
|
||||
"reading reduced number of lines: %d instead of %d\n",
|
||||
iLines, p->iLinesPerXferBuf);
|
||||
}
|
||||
if (pfJustDone)
|
||||
{
|
||||
*pfJustDone = SANE_TRUE;
|
||||
}
|
||||
}
|
||||
NiashReadReg (iHandle, 0x20, &bData);
|
||||
DBG (DBG_MSG, "buffer level = %3d, <reading %5d unsigned chars>, ",
|
||||
(int) bData, p->iLinesPerXferBuf * p->iBytesPerLine);
|
||||
NiashReadBulk (iHandle, p->pabXferBuf,
|
||||
p->iLinesPerXferBuf * p->iBytesPerLine);
|
||||
(int) bData, iLines * p->iBytesPerLine);
|
||||
NiashReadBulk (iHandle, p->pabXferBuf, iLines * p->iBytesPerLine);
|
||||
NiashReadReg (iHandle, 0x20, &bData);
|
||||
DBG (DBG_MSG, "buffer level = %3d\r", bData);
|
||||
fflush (stdout);
|
||||
|
|
@ -773,7 +792,7 @@ XferBufferInit (int iHandle, TDataPipe * p)
|
|||
/* skip garbage lines */
|
||||
for (i = 0; i < p->iSkipLines; i++)
|
||||
{
|
||||
XferBufferGetLine (iHandle, p, NULL);
|
||||
XferBufferGetLine (iHandle, p, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -788,12 +807,14 @@ CircBufferFill (int iHandle, TDataPipe * p, SANE_Bool iReversedHead)
|
|||
if (iReversedHead)
|
||||
{
|
||||
XferBufferGetLine (iHandle, p,
|
||||
&p->pabCircBuf[p->iRedLine * p->iBytesPerLine]);
|
||||
&p->pabCircBuf[p->iRedLine * p->iBytesPerLine],
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
XferBufferGetLine (iHandle, p,
|
||||
&p->pabCircBuf[p->iBluLine * p->iBytesPerLine]);
|
||||
&p->pabCircBuf[p->iBluLine * p->iBytesPerLine],
|
||||
NULL);
|
||||
}
|
||||
/* advance pointers */
|
||||
p->iRedLine = (p->iRedLine + 1) % p->iLinesPerCircBuf;
|
||||
|
|
@ -902,10 +923,11 @@ _UnscrambleLine (unsigned char *pabLine,
|
|||
}
|
||||
|
||||
|
||||
/* gets an unscrambled line from the circular buffer. the first couple of lines contain garbage */
|
||||
/* gets an unscrambled line from the circular buffer. the first couple of lines contain garbage,
|
||||
if pfJustDone!=NULL this element will be set SANE_TRUE, when the last scan was done*/
|
||||
STATIC SANE_Bool
|
||||
CircBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
||||
SANE_Bool iReversedHead)
|
||||
CircBufferGetLineEx (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
||||
SANE_Bool iReversedHead, SANE_Bool * pfJustDone)
|
||||
{
|
||||
int iLineCount;
|
||||
for (iLineCount = 0; iLineCount < p->iScaleDownLpi; ++iLineCount)
|
||||
|
|
@ -914,17 +936,18 @@ CircBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
|||
{
|
||||
if (!XferBufferGetLine (iHandle, p,
|
||||
&p->pabCircBuf[p->iRedLine *
|
||||
p->iBytesPerLine]))
|
||||
p->iBytesPerLine],
|
||||
pfJustDone))
|
||||
return SANE_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!XferBufferGetLine (iHandle, p,
|
||||
&p->pabCircBuf[p->iBluLine *
|
||||
p->iBytesPerLine]))
|
||||
p->iBytesPerLine],
|
||||
pfJustDone))
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
if (pabLine != NULL)
|
||||
{
|
||||
_UnscrambleLine (pabLine,
|
||||
|
|
@ -944,6 +967,15 @@ CircBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
|||
}
|
||||
|
||||
|
||||
/* gets an unscrambled line from the circular buffer. the first couple of lines contain garbage */
|
||||
STATIC SANE_Bool
|
||||
CircBufferGetLine (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
||||
SANE_Bool iReversedHead)
|
||||
{
|
||||
return CircBufferGetLineEx (iHandle, p, pabLine, iReversedHead, NULL);
|
||||
}
|
||||
|
||||
|
||||
STATIC void
|
||||
CircBufferInit (int iHandle, TDataPipe * p,
|
||||
int iWidth, int iHeight,
|
||||
|
|
@ -951,7 +983,6 @@ CircBufferInit (int iHandle, TDataPipe * p,
|
|||
int iScaleDownDpi, int iScaleDownLpi)
|
||||
{
|
||||
|
||||
long iXFerSize;
|
||||
/* relevant for internal read and write functions */
|
||||
p->iScaleDownLpi = iScaleDownLpi;
|
||||
p->iScaleDownDpi = iScaleDownDpi;
|
||||
|
|
@ -1007,41 +1038,22 @@ CircBufferInit (int iHandle, TDataPipe * p,
|
|||
}
|
||||
else
|
||||
{
|
||||
#define SAFETY_LINES 2
|
||||
#define MAX_LINES_PER_XFERBUF 800
|
||||
/* estimate of number of unsigned chars to transfer at all via the USB */
|
||||
/* add 20 lines for securtiy */
|
||||
int iTransfers = 1;
|
||||
/* add some lines for securtiy */
|
||||
|
||||
p->iLinesLeft = p->iLinesPerXferBuf = (iHeight + p->iSkipLines + 20);
|
||||
iXFerSize = p->iBytesPerLine * p->iLinesLeft;
|
||||
|
||||
/* is the buffersize too big ? */
|
||||
/* or ... 800 vertical dots to be scanned in one pass are too many */
|
||||
while (iXFerSize > XFER_BUF_SIZE || p->iLinesPerXferBuf > 800)
|
||||
p->iLinesLeft =
|
||||
iHeight + p->iSkipLines + p->iLinesPerCircBuf + SAFETY_LINES;
|
||||
p->iLinesPerXferBuf = XFER_BUF_SIZE / p->iBytesPerLine;
|
||||
/* with more than 800 lines the timing is spoiled */
|
||||
if (p->iLinesPerXferBuf > MAX_LINES_PER_XFERBUF)
|
||||
{
|
||||
if (iTransfers == 1 && iXFerSize > XFER_BUF_SIZE)
|
||||
{
|
||||
/* get the number of optimized transfers for a needed size */
|
||||
iTransfers = (iXFerSize + (XFER_BUF_SIZE - 1)) / XFER_BUF_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* either size is still too big */
|
||||
/* or height to be scanned in one pass is too big */
|
||||
/* try with more transfers, to get a smaller size of buffer */
|
||||
iXFerSize = p->iBytesPerLine * p->iLinesLeft;
|
||||
++iTransfers;
|
||||
}
|
||||
|
||||
/* get the new buffer size */
|
||||
iXFerSize = (iXFerSize + (iTransfers - 1)) / iTransfers;
|
||||
/* make sure that it is dividable by the number of unsigned chars per line */
|
||||
iXFerSize =
|
||||
((iXFerSize +
|
||||
(p->iBytesPerLine - 1)) / p->iBytesPerLine) * p->iBytesPerLine;
|
||||
p->iLinesPerXferBuf = (int) iXFerSize / p->iBytesPerLine;
|
||||
p->iLinesPerXferBuf = MAX_LINES_PER_XFERBUF;
|
||||
}
|
||||
DBG (DBG_MSG, "_iXFerSize = %d for %d transfer(s)\n", (int) iXFerSize,
|
||||
iTransfers);
|
||||
DBG (DBG_MSG, "_iXFerSize = %d for %d transfer(s)\n",
|
||||
(int) p->iLinesPerXferBuf * p->iBytesPerLine,
|
||||
(p->iLinesLeft + p->iLinesPerXferBuf - 1) / p->iLinesPerXferBuf);
|
||||
}
|
||||
DBG (DBG_MSG, "_iLinesPerXferBuf = %d\n", p->iLinesPerXferBuf);
|
||||
|
||||
|
|
@ -1330,4 +1342,3 @@ FinishScan (THWParams * pHWParams)
|
|||
{
|
||||
NiashWriteReg (pHWParams->iXferHandle, 0x02, 0x80);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ typedef struct
|
|||
int iTopLeftY; /* in mm */
|
||||
int iSensorSkew; /* in units of 1/1200 inch */
|
||||
int iSkipLines; /* lines of garbage to skip */
|
||||
SANE_Bool fReg07; /* NIASH00019 */
|
||||
SANE_Bool fReg07; /* NIASH00019 */
|
||||
SANE_Bool fGamma16; /* if TRUE, gamma entries are 16 bit */
|
||||
int iExpTime;
|
||||
SANE_Bool iReversedHead; /* Head is reversed */
|
||||
SANE_Bool iReversedHead; /* Head is reversed */
|
||||
int iBufferSize; /* Size of internal scan buffer */
|
||||
EScannerModel eModel;
|
||||
} THWParams;
|
||||
|
|
@ -94,8 +94,9 @@ STATIC int NiashOpen (THWParams * pHWParams, const char *pszName);
|
|||
STATIC void NiashClose (THWParams * pHWParams);
|
||||
|
||||
/* more sof. method that also returns the values of the white (RGB) value */
|
||||
STATIC SANE_Bool SimpleCalibExt (THWParams * pHWPar, unsigned char *pabCalibTable,
|
||||
unsigned char *pabCalWhite);
|
||||
STATIC SANE_Bool SimpleCalibExt (THWParams * pHWPar,
|
||||
unsigned char *pabCalibTable,
|
||||
unsigned char *pabCalWhite);
|
||||
|
||||
STATIC SANE_Bool GetLamp (THWParams * pHWParams, SANE_Bool * pfLampIsOn);
|
||||
STATIC SANE_Bool SetLamp (THWParams * pHWParams, SANE_Bool fLampOn);
|
||||
|
|
@ -120,7 +121,15 @@ STATIC void CircBufferInit (int iHandle, TDataPipe * p,
|
|||
|
||||
/* returns false, when trying to read after end of buffer */
|
||||
STATIC SANE_Bool CircBufferGetLine (int iHandle, TDataPipe * p,
|
||||
unsigned char *pabLine, SANE_Bool iReversedHead);
|
||||
unsigned char *pabLine,
|
||||
SANE_Bool iReversedHead);
|
||||
|
||||
/* returns false, when trying to read after end of buffer
|
||||
if pfJustDone!=NULL this element will be set SANE_TRUE, when the last scan was done*/
|
||||
STATIC SANE_Bool
|
||||
CircBufferGetLineEx (int iHandle, TDataPipe * p, unsigned char *pabLine,
|
||||
SANE_Bool iReversedHead, SANE_Bool * pfJustDone);
|
||||
|
||||
STATIC void CircBufferExit (TDataPipe * p);
|
||||
|
||||
#endif /* _NIASH_CORE_H_ */
|
||||
|
|
|
|||
|
|
@ -90,6 +90,6 @@ STATIC void NiashReadBulk (int iXferHandle, unsigned char *pabBuf, int iSize);
|
|||
STATIC void NiashWakeup (int iXferHandle);
|
||||
|
||||
STATIC SANE_Bool MatchUsbDevice (int iVendor, int iProduct,
|
||||
TScannerModel ** ppeModel);
|
||||
TScannerModel ** ppeModel);
|
||||
|
||||
#endif /* _NIASH_XFER_H_ */
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue