Aric Stewart : twain: Implment DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Feb 21 13:13:09 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 6976e2016d28249988ed975657f704fb5682b715
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=6976e2016d28249988ed975657f704fb5682b715
Author: Aric Stewart <aric at codeweavers.com>
Date: Tue Feb 21 08:41:07 2006 -0600
twain: Implment DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET.
Implement the DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET code path. Along with
a number of corrections and improvements to allow the actual aquiring
of images to succeed.
---
dlls/twain/ds_ctrl.c | 28 ++++++++-
dlls/twain/ds_image.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++---
dlls/twain/dsm_ctrl.c | 1
dlls/twain/twain_i.h | 1
4 files changed, 169 insertions(+), 15 deletions(-)
diff --git a/dlls/twain/ds_ctrl.c b/dlls/twain/ds_ctrl.c
index bc6841a..ff49c28 100644
--- a/dlls/twain/ds_ctrl.c
+++ b/dlls/twain/ds_ctrl.c
@@ -332,7 +332,7 @@ TW_UINT16 TWAIN_ProcessEvent (pTW_IDENTI
{
pEvent->TWMessage = pSource->pendingEvent.TWMessage;
pSource->pendingEvent.TWMessage = MSG_NULL;
- twRC = TWRC_DSEVENT;
+ twRC = TWRC_NOTDSEVENT;
}
else
{
@@ -360,7 +360,7 @@ TW_UINT16 TWAIN_PendingXfersEndXfer (pTW
{
TW_UINT16 twRC = TWRC_SUCCESS;
pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
- activeDS *pSource = TWAIN_LookupSource (pData);
+ activeDS *pSource = TWAIN_LookupSource (pDest);
TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER\n");
@@ -542,9 +542,29 @@ TW_UINT16 TWAIN_SetupFileXfer2Set (pTW_I
TW_UINT16 TWAIN_SetupMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
- FIXME ("stub!\n");
-
+#ifndef HAVE_SANE
return TWRC_FAILURE;
+#else
+ activeDS *pSource = TWAIN_LookupSource (pDest);
+ pTW_SETUPMEMXFER pSetupMemXfer = (pTW_SETUPMEMXFER)pData;
+
+ TRACE("DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET\n");
+ if (pSource->sane_param_valid)
+ {
+ pSetupMemXfer->MinBufSize = pSource->sane_param.bytes_per_line;
+ pSetupMemXfer->MaxBufSize = pSource->sane_param.bytes_per_line * 8;
+ pSetupMemXfer->Preferred = pSource->sane_param.bytes_per_line * 2;
+ }
+ else
+ {
+ /* Guessing */
+ pSetupMemXfer->MinBufSize = 2000;
+ pSetupMemXfer->MaxBufSize = 8000;
+ pSetupMemXfer->Preferred = 4000;
+ }
+
+ return TWRC_SUCCESS;
+#endif
}
/* DG_CONTROL/DAT_STATUS/MSG_GET */
diff --git a/dlls/twain/ds_image.c b/dlls/twain/ds_image.c
index c9fc1b0..07ebad8 100644
--- a/dlls/twain/ds_image.c
+++ b/dlls/twain/ds_image.c
@@ -1,5 +1,6 @@
/*
* Copyright 2000 Corel Corporation
+ * Copyright 2006 CodeWeavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -105,6 +106,8 @@ TW_UINT16 TWAIN_ImageInfoGet (pTW_IDENTI
{
/* return general image description information about the image about to be transferred */
status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
+ pSource->sane_param_valid = TRUE;
+ TRACE("Getting parameters\n");
}
pImageInfo->XResolution.Whole = -1;
@@ -113,20 +116,26 @@ TW_UINT16 TWAIN_ImageInfoGet (pTW_IDENTI
pImageInfo->YResolution.Frac = 0;
pImageInfo->ImageWidth = pSource->sane_param.pixels_per_line;
pImageInfo->ImageLength = pSource->sane_param.lines;
- if (pSource->sane_param.depth == 24)
+
+ TRACE("Bits per Sample %i\n",pSource->sane_param.depth);
+ TRACE("Frame Format %i\n",pSource->sane_param.format);
+
+ if (pSource->sane_param.format == 1 /*RGB*/ )
{
- pImageInfo->SamplesPerPixel = 3;
- pImageInfo->BitsPerSample[0] = 8;
- pImageInfo->BitsPerSample[1] = 8;
- pImageInfo->BitsPerSample[2] = 8;
- pImageInfo->BitsPerPixel = 24;
+ pImageInfo->BitsPerPixel = pSource->sane_param.depth * 3;
+ pImageInfo->Compression = TWCP_NONE;
pImageInfo->Planar = TRUE;
+ pImageInfo->SamplesPerPixel = 3;
+ pImageInfo->BitsPerSample[0] = pSource->sane_param.depth;
+ pImageInfo->BitsPerSample[1] = pSource->sane_param.depth;
+ pImageInfo->BitsPerSample[2] = pSource->sane_param.depth;
pImageInfo->PixelType = TWPT_RGB;
- pImageInfo->Compression = TWCP_NONE;
}
- else if (pSource->sane_param.depth == 8)
+ else
{
- /* FIXME: fill the image info structure for 8-bit image */
+ ERR("Unhandled source frame type\n");
+ twRC = TWRC_FAILURE;
+ pSource->twCC = TWCC_SEQERROR;
}
}
@@ -174,9 +183,131 @@ TW_UINT16 TWAIN_ImageLayoutSet (pTW_IDEN
TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
- FIXME ("stub!\n");
-
+#ifndef HAVE_SANE
return TWRC_FAILURE;
+#else
+ TW_UINT16 twRC = TWRC_SUCCESS;
+ pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
+ activeDS *pSource = TWAIN_LookupSource (pDest);
+ SANE_Status status = SANE_STATUS_GOOD;
+
+ TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
+
+ if (!pSource)
+ {
+ twRC = TWRC_FAILURE;
+ DSM_twCC = TWCC_NODS;
+ }
+ else if (pSource->currentState < 6 || pSource->currentState > 7)
+ {
+ twRC = TWRC_FAILURE;
+ pSource->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 (pSource->currentState == 6)
+ {
+ status = sane_start (pSource->deviceHandle);
+ if (status != SANE_STATUS_GOOD)
+ {
+ WARN("sane_start: %s\n", sane_strstatus (status));
+ sane_cancel (pSource->deviceHandle);
+ pSource->twCC = TWCC_OPERATIONERROR;
+ return TWRC_FAILURE;
+ }
+
+ status = sane_get_parameters (pSource->deviceHandle,
+ &pSource->sane_param);
+ pSource->sane_param_valid = TRUE;
+
+ if (status != SANE_STATUS_GOOD)
+ {
+ WARN("sane_get_parameters: %s\n", sane_strstatus (status));
+ sane_cancel (pSource->deviceHandle);
+ pSource->twCC = TWCC_OPERATIONERROR;
+ return TWRC_FAILURE;
+ }
+
+ TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
+ , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
+ pSource->sane_param.depth, pSource->sane_param.format,
+ pSource->sane_param.last_frame);
+
+ pSource->currentState = 7;
+ }
+
+ /* access memory buffer */
+ if (pImageMemXfer->Memory.Length < pSource->sane_param.bytes_per_line)
+ {
+ sane_cancel (pSource->deviceHandle);
+ pSource->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 / pSource->sane_param.bytes_per_line;
+
+ /* must fill full lines */
+ while (consumed_len < (pSource->sane_param.bytes_per_line*rows) &&
+ status == SANE_STATUS_GOOD)
+ {
+ status = sane_read (pSource->deviceHandle, ptr,
+ (pSource->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 = pSource->sane_param.bytes_per_line;
+ pImageMemXfer->Columns = pSource->sane_param.pixels_per_line;
+ pImageMemXfer->Rows = rows;
+ pImageMemXfer->XOffset = 0;
+ pImageMemXfer->YOffset = 0;
+ pImageMemXfer->BytesWritten = consumed_len;
+
+ if (status == SANE_STATUS_EOF)
+ {
+ TRACE("sane_read: %s\n", sane_strstatus (status));
+ sane_cancel (pSource->deviceHandle);
+ twRC = TWRC_XFERDONE;
+ }
+ pSource->twCC = TWRC_SUCCESS;
+ }
+ else if (status != SANE_STATUS_EOF)
+ {
+ WARN("sane_read: %s\n", sane_strstatus (status));
+ sane_cancel (pSource->deviceHandle);
+ pSource->twCC = TWCC_OPERATIONERROR;
+ twRC = TWRC_FAILURE;
+ }
+ }
+
+ if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
+ LocalUnlock(pImageMemXfer->Memory.TheMem);
+
+ return twRC;
+#endif
}
/* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
@@ -222,6 +353,7 @@ TW_UINT16 TWAIN_ImageNativeXferGet (pTW_
}
status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
+ pSource->sane_param_valid = TRUE;
if (status != SANE_STATUS_GOOD)
{
WARN("sane_get_parameters: %s\n", sane_strstatus (status));
diff --git a/dlls/twain/dsm_ctrl.c b/dlls/twain/dsm_ctrl.c
index 6ebff41..002a3bf 100644
--- a/dlls/twain/dsm_ctrl.c
+++ b/dlls/twain/dsm_ctrl.c
@@ -178,6 +178,7 @@ TW_UINT16 TWAIN_IdentityGetFirst (pTW_ID
TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST\n");
+ device_list = NULL;
status = sane_get_devices (&device_list, SANE_FALSE);
if (status == SANE_STATUS_GOOD)
{
diff --git a/dlls/twain/twain_i.h b/dlls/twain/twain_i.h
index bc8f664..6d98763 100644
--- a/dlls/twain/twain_i.h
+++ b/dlls/twain/twain_i.h
@@ -46,6 +46,7 @@ typedef struct tagActiveDS
SANE_Handle deviceHandle; /* device handle */
SANE_Parameters sane_param; /* parameters about the image
transferred */
+ BOOL sane_param_valid; /* true if valid sane_param*/
#endif
/* Capabiblities */
TW_UINT16 capXferMech; /* ICAP_XFERMECH */
More information about the wine-cvs
mailing list