2 * Copyright 2000 Corel Corporation
3 * Copyright 2006 CodeWeavers, Aric Stewart
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
34 /* DG_IMAGE/DAT_CIECOLOR/MSG_GET */
35 TW_UINT16 SANE_CIEColorGet (pTW_IDENTITY pOrigin,
43 /* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
44 TW_UINT16 SANE_ExtImageInfoGet (pTW_IDENTITY pOrigin,
52 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
53 TW_UINT16 SANE_GrayResponseReset (pTW_IDENTITY pOrigin,
61 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
62 TW_UINT16 SANE_GrayResponseSet (pTW_IDENTITY pOrigin,
70 /* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
71 TW_UINT16 SANE_ImageFileXferGet (pTW_IDENTITY pOrigin,
79 /* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
80 TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
83 #ifndef SONAME_LIBSANE
86 TW_UINT16 twRC = TWRC_SUCCESS;
87 pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
90 TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
92 if (activeDS.currentState != 6 && activeDS.currentState != 7)
95 activeDS.twCC = TWCC_SEQERROR;
99 if (activeDS.currentState == 6)
101 /* return general image description information about the image about to be transferred */
102 status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
103 activeDS.sane_param_valid = TRUE;
104 TRACE("Getting parameters\n");
107 pImageInfo->XResolution.Whole = -1;
108 pImageInfo->XResolution.Frac = 0;
109 pImageInfo->YResolution.Whole = -1;
110 pImageInfo->YResolution.Frac = 0;
111 pImageInfo->ImageWidth = activeDS.sane_param.pixels_per_line;
112 pImageInfo->ImageLength = activeDS.sane_param.lines;
114 TRACE("Bits per Sample %i\n",activeDS.sane_param.depth);
115 TRACE("Frame Format %i\n",activeDS.sane_param.format);
117 if (activeDS.sane_param.format == SANE_FRAME_RGB )
119 pImageInfo->BitsPerPixel = activeDS.sane_param.depth * 3;
120 pImageInfo->Compression = TWCP_NONE;
121 pImageInfo->Planar = TRUE;
122 pImageInfo->SamplesPerPixel = 3;
123 pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
124 pImageInfo->BitsPerSample[1] = activeDS.sane_param.depth;
125 pImageInfo->BitsPerSample[2] = activeDS.sane_param.depth;
126 pImageInfo->PixelType = TWPT_RGB;
128 else if (activeDS.sane_param.format == SANE_FRAME_GRAY)
130 pImageInfo->BitsPerPixel = activeDS.sane_param.depth;
131 pImageInfo->Compression = TWCP_NONE;
132 pImageInfo->Planar = TRUE;
133 pImageInfo->SamplesPerPixel = 1;
134 pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
135 pImageInfo->PixelType = TWPT_GRAY;
139 ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
141 activeDS.twCC = TWCC_SEQERROR;
149 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
150 TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin,
158 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
159 TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin,
167 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
168 TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin,
176 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
177 TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin,
185 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
186 TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
189 #ifndef SONAME_LIBSANE
192 TW_UINT16 twRC = TWRC_SUCCESS;
193 pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
194 SANE_Status status = SANE_STATUS_GOOD;
196 TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
198 if (activeDS.currentState < 6 || activeDS.currentState > 7)
201 activeDS.twCC = TWCC_SEQERROR;
207 int consumed_len = 0;
211 /* Transfer an image from the source to the application */
212 if (activeDS.currentState == 6)
215 /* trigger scanning dialog */
216 activeDS.progressWnd = ScanningDialogBox(NULL,0);
218 ScanningDialogBox(activeDS.progressWnd,0);
220 status = psane_start (activeDS.deviceHandle);
221 if (status != SANE_STATUS_GOOD)
223 WARN("psane_start: %s\n", psane_strstatus (status));
224 psane_cancel (activeDS.deviceHandle);
225 activeDS.twCC = TWCC_OPERATIONERROR;
229 status = psane_get_parameters (activeDS.deviceHandle,
230 &activeDS.sane_param);
231 activeDS.sane_param_valid = TRUE;
233 if (status != SANE_STATUS_GOOD)
235 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
236 psane_cancel (activeDS.deviceHandle);
237 activeDS.twCC = TWCC_OPERATIONERROR;
241 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
242 , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
243 activeDS.sane_param.depth, activeDS.sane_param.format,
244 activeDS.sane_param.last_frame);
246 activeDS.currentState = 7;
249 /* access memory buffer */
250 if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
252 psane_cancel (activeDS.deviceHandle);
253 activeDS.twCC = TWCC_BADVALUE;
257 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
259 FIXME("Memory Handle, may not be locked correctly\n");
260 buffer = LocalLock(pImageMemXfer->Memory.TheMem);
263 buffer = pImageMemXfer->Memory.TheMem;
265 memset(buffer,0,pImageMemXfer->Memory.Length);
269 rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line;
271 /* must fill full lines */
272 while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) &&
273 status == SANE_STATUS_GOOD)
275 status = psane_read (activeDS.deviceHandle, ptr,
276 (activeDS.sane_param.bytes_per_line*rows) - consumed_len ,
278 consumed_len += buff_len;
282 if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
284 pImageMemXfer->Compression = TWCP_NONE;
285 pImageMemXfer->BytesPerRow = activeDS.sane_param.bytes_per_line;
286 pImageMemXfer->Columns = activeDS.sane_param.pixels_per_line;
287 pImageMemXfer->Rows = rows;
288 pImageMemXfer->XOffset = 0;
289 pImageMemXfer->YOffset = 0;
290 pImageMemXfer->BytesWritten = consumed_len;
292 ScanningDialogBox(activeDS.progressWnd, consumed_len);
294 if (status == SANE_STATUS_EOF)
296 ScanningDialogBox(activeDS.progressWnd, -1);
297 TRACE("psane_read: %s\n", psane_strstatus (status));
298 psane_cancel (activeDS.deviceHandle);
299 twRC = TWRC_XFERDONE;
301 activeDS.twCC = TWRC_SUCCESS;
303 else if (status != SANE_STATUS_EOF)
305 ScanningDialogBox(activeDS.progressWnd, -1);
306 WARN("psane_read: %s\n", psane_strstatus (status));
307 psane_cancel (activeDS.deviceHandle);
308 activeDS.twCC = TWCC_OPERATIONERROR;
313 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
314 LocalUnlock(pImageMemXfer->Memory.TheMem);
320 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
321 TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
324 #ifndef SONAME_LIBSANE
327 TW_UINT16 twRC = TWRC_SUCCESS;
328 pTW_UINT32 pHandle = (pTW_UINT32) pData;
330 SANE_Byte buffer[32*1024];
337 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
339 if (activeDS.currentState != 6)
342 activeDS.twCC = TWCC_SEQERROR;
346 /* Transfer an image from the source to the application */
347 status = psane_start (activeDS.deviceHandle);
348 if (status != SANE_STATUS_GOOD)
350 WARN("psane_start: %s\n", psane_strstatus (status));
351 psane_cancel (activeDS.deviceHandle);
352 activeDS.twCC = TWCC_OPERATIONERROR;
356 status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
357 activeDS.sane_param_valid = TRUE;
358 if (status != SANE_STATUS_GOOD)
360 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
361 psane_cancel (activeDS.deviceHandle);
362 activeDS.twCC = TWCC_OPERATIONERROR;
366 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
367 , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
368 activeDS.sane_param.depth, activeDS.sane_param.format,
369 activeDS.sane_param.last_frame);
371 ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
372 bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
373 bmpInfo.bmiHeader.biWidth = activeDS.sane_param.pixels_per_line;
374 bmpInfo.bmiHeader.biHeight = activeDS.sane_param.lines;
375 bmpInfo.bmiHeader.biPlanes = 1;
376 bmpInfo.bmiHeader.biBitCount = activeDS.sane_param.depth;
377 bmpInfo.bmiHeader.biCompression = BI_RGB;
378 bmpInfo.bmiHeader.biSizeImage = 0;
379 bmpInfo.bmiHeader.biXPelsPerMeter = 0;
380 bmpInfo.bmiHeader.biYPelsPerMeter = 0;
381 bmpInfo.bmiHeader.biClrUsed = 1;
382 bmpInfo.bmiHeader.biClrImportant = 0;
383 bmpInfo.bmiColors[0].rgbBlue = 128;
384 bmpInfo.bmiColors[0].rgbGreen = 128;
385 bmpInfo.bmiColors[0].rgbRed = 128;
386 hDIB = CreateDIBSection ((dc = GetDC(activeDS.hwndOwner)), &bmpInfo,
387 DIB_RGB_COLORS, &pBits, 0, 0);
390 psane_cancel (activeDS.deviceHandle);
391 activeDS.twCC = TWCC_LOWMEMORY;
397 status = psane_read (activeDS.deviceHandle, buffer,
398 sizeof (buffer), &buff_len);
399 if (status == SANE_STATUS_GOOD)
401 /* FIXME: put code for converting the image data into DIB here */
404 else if (status != SANE_STATUS_EOF)
406 WARN("psane_read: %s\n", psane_strstatus (status));
407 psane_cancel (activeDS.deviceHandle);
408 activeDS.twCC = TWCC_OPERATIONERROR;
411 } while (status == SANE_STATUS_GOOD);
413 psane_cancel (activeDS.deviceHandle);
414 ReleaseDC (activeDS.hwndOwner, dc);
415 *pHandle = (TW_UINT32)hDIB;
416 twRC = TWRC_XFERDONE;
417 activeDS.twCC = TWCC_SUCCESS;
418 activeDS.currentState = 7;
424 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
425 TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin,
433 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
434 TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
443 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
444 TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin,
452 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
453 TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin,
461 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
462 TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin,
470 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
471 TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin,
479 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
480 TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin,
488 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
489 TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin,
497 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
498 TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin,
506 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
507 TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin,