From 6976e2016d28249988ed975657f704fb5682b715 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Tue, 21 Feb 2006 08:41:07 -0600 Subject: [PATCH] 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 | 156 ++++++++++++++++++++++++++++++++++++++---- dlls/twain/dsm_ctrl.c | 1 + dlls/twain/twain_i.h | 1 + 4 files changed, 170 insertions(+), 16 deletions(-) diff --git a/dlls/twain/ds_ctrl.c b/dlls/twain/ds_ctrl.c index bc6841a539a..ff49c28745f 100644 --- a/dlls/twain/ds_ctrl.c +++ b/dlls/twain/ds_ctrl.c @@ -332,7 +332,7 @@ TW_UINT16 TWAIN_ProcessEvent (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest, { 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_IDENTITY pOrigin, pTW_IDENTITY pDest, { 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_IDENTITY pOrigin, pTW_IDENTITY pDest, 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 c9fc1b04ca0..07ebad820d8 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_IDENTITY pOrigin, pTW_IDENTITY pDest, { /* 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_IDENTITY pOrigin, pTW_IDENTITY pDest, 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->Planar = TRUE; - pImageInfo->PixelType = TWPT_RGB; + 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; } - 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_IDENTITY pOrigin, pTW_IDENTITY pDest, 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_IDENTITY pOrigin, pTW_IDENTITY pDest, } 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 6ebff418599..002a3bfddcd 100644 --- a/dlls/twain/dsm_ctrl.c +++ b/dlls/twain/dsm_ctrl.c @@ -178,6 +178,7 @@ TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData) 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 bc8f664905e..6d98763a63f 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 */