Sweden-Number/dlls/twain/ds_image.c

532 lines
16 KiB
C

/*
* 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "twain.h"
#include "twain_i.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(twain);
/* DG_IMAGE/DAT_CIECOLOR/MSG_GET */
TW_UINT16 TWAIN_CIEColorGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
TW_UINT16 TWAIN_ExtImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
TW_UINT16 TWAIN_GrayResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
TW_UINT16 TWAIN_GrayResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
TW_UINT16 TWAIN_ImageFileXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
TW_UINT16 TWAIN_ImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
#ifndef HAVE_SANE
return TWRC_FAILURE;
#else
TW_UINT16 twRC = TWRC_SUCCESS;
pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
activeDS *pSource = TWAIN_LookupSource (pDest);
SANE_Status status;
TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
if (!pSource)
{
twRC = TWRC_FAILURE;
DSM_twCC = TWCC_BADDEST;
}
else if (pSource->currentState != 6 && pSource->currentState != 7)
{
twRC = TWRC_FAILURE;
pSource->twCC = TWCC_SEQERROR;
}
else
{
if (pSource->currentState == 6)
{
/* 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;
pImageInfo->XResolution.Frac = 0;
pImageInfo->YResolution.Whole = -1;
pImageInfo->YResolution.Frac = 0;
pImageInfo->ImageWidth = pSource->sane_param.pixels_per_line;
pImageInfo->ImageLength = pSource->sane_param.lines;
TRACE("Bits per Sample %i\n",pSource->sane_param.depth);
TRACE("Frame Format %i\n",pSource->sane_param.format);
if (pSource->sane_param.format == SANE_FRAME_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.format == SANE_FRAME_GRAY)
{
pImageInfo->BitsPerPixel = pSource->sane_param.depth;
pImageInfo->Compression = TWCP_NONE;
pImageInfo->Planar = TRUE;
pImageInfo->SamplesPerPixel = 1;
pImageInfo->BitsPerSample[0] = pSource->sane_param.depth;
pImageInfo->PixelType = TWPT_GRAY;
}
else
{
ERR("Unhandled source frame type %i\n",pSource->sane_param.format);
twRC = TWRC_FAILURE;
pSource->twCC = TWCC_SEQERROR;
}
}
return twRC;
#endif
}
/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
TW_UINT16 TWAIN_ImageLayoutGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
TW_UINT16 TWAIN_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
TW_UINT16 TWAIN_ImageLayoutReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
TW_UINT16 TWAIN_ImageLayoutSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
#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)
{
/* trigger scanning dialog */
pSource->progressWnd = ScanningDialogBox(NULL,0);
ScanningDialogBox(pSource->progressWnd,0);
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;
ScanningDialogBox(pSource->progressWnd, consumed_len);
if (status == SANE_STATUS_EOF)
{
ScanningDialogBox(pSource->progressWnd, -1);
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)
{
ScanningDialogBox(pSource->progressWnd, -1);
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 */
TW_UINT16 TWAIN_ImageNativeXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
#ifndef HAVE_SANE
return TWRC_FAILURE;
#else
TW_UINT16 twRC = TWRC_SUCCESS;
pTW_UINT32 pHandle = (pTW_UINT32) pData;
activeDS *pSource = TWAIN_LookupSource (pDest);
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 (!pSource)
{
twRC = TWRC_FAILURE;
DSM_twCC = TWCC_NODS;
}
else if (pSource->currentState != 6)
{
twRC = TWRC_FAILURE;
pSource->twCC = TWCC_SEQERROR;
}
else
{
/* Transfer an image from the source to the application */
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);
ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = pSource->sane_param.pixels_per_line;
bmpInfo.bmiHeader.biHeight = pSource->sane_param.lines;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = pSource->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(pSource->hwndOwner)), &bmpInfo,
DIB_RGB_COLORS, &pBits, 0, 0);
if (!hDIB)
{
sane_cancel (pSource->deviceHandle);
pSource->twCC = TWCC_LOWMEMORY;
return TWRC_FAILURE;
}
do
{
status = sane_read (pSource->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 (pSource->deviceHandle);
pSource->twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
} while (status == SANE_STATUS_GOOD);
sane_cancel (pSource->deviceHandle);
ReleaseDC (pSource->hwndOwner, dc);
*pHandle = (TW_UINT32)hDIB;
twRC = TWRC_XFERDONE;
pSource->twCC = TWCC_SUCCESS;
pSource->currentState = 7;
}
return twRC;
#endif
}
/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
TW_UINT16 TWAIN_JPEGCompressionGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
TW_UINT16 TWAIN_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
TW_UINT16 TWAIN_JPEGCompressionReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
TW_UINT16 TWAIN_JPEGCompressionSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_PALETTE8/MSG_GET */
TW_UINT16 TWAIN_Palette8Get (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
TW_UINT16 TWAIN_Palette8GetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
TW_UINT16 TWAIN_Palette8Reset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_PALETTE8/MSG_SET */
TW_UINT16 TWAIN_Palette8Set (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
TW_UINT16 TWAIN_RGBResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}
/* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
TW_UINT16 TWAIN_RGBResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
TW_MEMREF pData)
{
FIXME ("stub!\n");
return TWRC_FAILURE;
}