Jeremy White : sane.ds: Implement NATIVEXFER/MSG_GET for RGB scans.
Alexandre Julliard
julliard at winehq.org
Mon Feb 16 09:35:01 CST 2009
Module: wine
Branch: master
Commit: aaf83dc1b20d037195075580545127ba4dfd1606
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aaf83dc1b20d037195075580545127ba4dfd1606
Author: Jeremy White <jwhite at codeweavers.com>
Date: Fri Feb 13 13:14:58 2009 -0600
sane.ds: Implement NATIVEXFER/MSG_GET for RGB scans.
---
dlls/sane.ds/ds_image.c | 132 ++++++++++++++++++++++++++++++++---------------
1 files changed, 90 insertions(+), 42 deletions(-)
diff --git a/dlls/sane.ds/ds_image.c b/dlls/sane.ds/ds_image.c
index 5bb6cbb..38689da 100644
--- a/dlls/sane.ds/ds_image.c
+++ b/dlls/sane.ds/ds_image.c
@@ -327,6 +327,30 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
#endif
}
+#ifdef SONAME_LIBSANE
+static SANE_Status read_one_line(SANE_Handle h, BYTE *line, int len)
+{
+ int read_len;
+ SANE_Status status;
+
+ for (;;)
+ {
+ read_len = 0;
+ status = psane_read (activeDS.deviceHandle, line, len, &read_len);
+ if (status != SANE_STATUS_GOOD)
+ break;
+
+ if (read_len == len)
+ break;
+
+ line += read_len;
+ len -= read_len;
+ }
+
+ return status;
+}
+#endif
+
/* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
TW_MEMREF pData)
@@ -337,12 +361,12 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
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;
+ HANDLE hDIB;
+ BITMAPINFOHEADER *header = NULL;
+ int dib_bytes;
+ int dib_bytes_per_line;
+ BYTE *line;
+ int i;
TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
@@ -373,55 +397,79 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
return TWRC_FAILURE;
}
- TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
+ if (activeDS.sane_param.format != SANE_FRAME_RGB)
+ {
+ FIXME("For NATIVE, we support only RGB, not %d\n", activeDS.sane_param.format);
+ psane_cancel (activeDS.deviceHandle);
+ activeDS.twCC = TWCC_OPERATIONERROR;
+ return TWRC_FAILURE;
+ }
+
+ TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d bpl=%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.sane_param.last_frame, activeDS.sane_param.bytes_per_line);
- 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)
+ dib_bytes_per_line = ((activeDS.sane_param.bytes_per_line + 3) / 4) * 4;
+ dib_bytes = activeDS.sane_param.lines * dib_bytes_per_line;
+
+ hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header));
+ if (hDIB)
+ header = GlobalLock(hDIB);
+
+ if (!header)
{
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_LOWMEMORY;
+ if (hDIB)
+ GlobalFree(hDIB);
return TWRC_FAILURE;
}
- do
+ header->biSize = sizeof (*header);
+ header->biWidth = activeDS.sane_param.pixels_per_line;
+ header->biHeight = activeDS.sane_param.lines;
+ header->biPlanes = 1;
+ header->biBitCount = activeDS.sane_param.depth * 3;
+ header->biCompression = BI_RGB;
+ header->biSizeImage = dib_bytes;
+ header->biXPelsPerMeter = 0;
+ header->biYPelsPerMeter = 0;
+ header->biClrUsed = 0;
+ header->biClrImportant = 0;
+
+ /* Sane returns data in top down order. Acrobat does best with
+ a bottom up DIB being returned. */
+ line = (BYTE *)(header + 1) +
+ (activeDS.sane_param.lines - 1) * dib_bytes_per_line;
+ for (i = activeDS.sane_param.lines - 1; i >= 0; i--)
{
- status = psane_read (activeDS.deviceHandle, buffer,
- sizeof (buffer), &buff_len);
- if (status == SANE_STATUS_GOOD)
- {
- /* FIXME: put code for converting the image data into DIB here */
+ activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd,
+ ((activeDS.sane_param.lines - 1 - i) * 100)
+ /
+ (activeDS.sane_param.lines - 1));
- }
- else if (status != SANE_STATUS_EOF)
- {
- WARN("psane_read: %s\n", psane_strstatus (status));
- psane_cancel (activeDS.deviceHandle);
- activeDS.twCC = TWCC_OPERATIONERROR;
- return TWRC_FAILURE;
- }
- } while (status == SANE_STATUS_GOOD);
+ status = read_one_line(activeDS.deviceHandle, line,
+ activeDS.sane_param.bytes_per_line);
+ if (status != SANE_STATUS_GOOD)
+ break;
+
+ line -= dib_bytes_per_line;
+ }
+ activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd, -1);
+
+ GlobalUnlock(hDIB);
+
+ if (status != SANE_STATUS_GOOD && status != SANE_STATUS_EOF)
+ {
+ WARN("psane_read: %s, reading line %d\n", psane_strstatus(status), i);
+ psane_cancel (activeDS.deviceHandle);
+ activeDS.twCC = TWCC_OPERATIONERROR;
+ GlobalFree(hDIB);
+ return TWRC_FAILURE;
+ }
psane_cancel (activeDS.deviceHandle);
- ReleaseDC (activeDS.hwndOwner, dc);
*pHandle = (TW_UINT32)hDIB;
twRC = TWRC_XFERDONE;
activeDS.twCC = TWCC_SUCCESS;
More information about the wine-cvs
mailing list