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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
34 /* DG_IMAGE/DAT_CIECOLOR/MSG_GET */
35 TW_UINT16 TWAIN_CIEColorGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
43 /* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
44 TW_UINT16 TWAIN_ExtImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
52 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
53 TW_UINT16 TWAIN_GrayResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
61 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
62 TW_UINT16 TWAIN_GrayResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
70 /* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
71 TW_UINT16 TWAIN_ImageFileXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
79 /* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
80 TW_UINT16 TWAIN_ImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
86 TW_UINT16 twRC = TWRC_SUCCESS;
87 pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
88 activeDS *pSource = TWAIN_LookupSource (pDest);
91 TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
96 DSM_twCC = TWCC_BADDEST;
98 else if (pSource->currentState != 6 && pSource->currentState != 7)
101 pSource->twCC = TWCC_SEQERROR;
105 if (pSource->currentState == 6)
107 /* return general image description information about the image about to be transferred */
108 status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
109 pSource->sane_param_valid = TRUE;
110 TRACE("Getting parameters\n");
113 pImageInfo->XResolution.Whole = -1;
114 pImageInfo->XResolution.Frac = 0;
115 pImageInfo->YResolution.Whole = -1;
116 pImageInfo->YResolution.Frac = 0;
117 pImageInfo->ImageWidth = pSource->sane_param.pixels_per_line;
118 pImageInfo->ImageLength = pSource->sane_param.lines;
120 TRACE("Bits per Sample %i\n",pSource->sane_param.depth);
121 TRACE("Frame Format %i\n",pSource->sane_param.format);
123 if (pSource->sane_param.format == SANE_FRAME_RGB )
125 pImageInfo->BitsPerPixel = pSource->sane_param.depth * 3;
126 pImageInfo->Compression = TWCP_NONE;
127 pImageInfo->Planar = TRUE;
128 pImageInfo->SamplesPerPixel = 3;
129 pImageInfo->BitsPerSample[0] = pSource->sane_param.depth;
130 pImageInfo->BitsPerSample[1] = pSource->sane_param.depth;
131 pImageInfo->BitsPerSample[2] = pSource->sane_param.depth;
132 pImageInfo->PixelType = TWPT_RGB;
134 else if (pSource->sane_param.format == SANE_FRAME_GRAY)
136 pImageInfo->BitsPerPixel = pSource->sane_param.depth;
137 pImageInfo->Compression = TWCP_NONE;
138 pImageInfo->Planar = TRUE;
139 pImageInfo->SamplesPerPixel = 1;
140 pImageInfo->BitsPerSample[0] = pSource->sane_param.depth;
141 pImageInfo->PixelType = TWPT_GRAY;
145 ERR("Unhandled source frame type %i\n",pSource->sane_param.format);
147 pSource->twCC = TWCC_SEQERROR;
155 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
156 TW_UINT16 TWAIN_ImageLayoutGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
164 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
165 TW_UINT16 TWAIN_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
173 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
174 TW_UINT16 TWAIN_ImageLayoutReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
182 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
183 TW_UINT16 TWAIN_ImageLayoutSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
191 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
192 TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
198 TW_UINT16 twRC = TWRC_SUCCESS;
199 pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
200 activeDS *pSource = TWAIN_LookupSource (pDest);
201 SANE_Status status = SANE_STATUS_GOOD;
203 TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
208 DSM_twCC = TWCC_NODS;
210 else if (pSource->currentState < 6 || pSource->currentState > 7)
213 pSource->twCC = TWCC_SEQERROR;
219 int consumed_len = 0;
223 /* Transfer an image from the source to the application */
224 if (pSource->currentState == 6)
227 /* trigger scanning dialog */
228 pSource->progressWnd = ScanningDialogBox(NULL,0);
230 ScanningDialogBox(pSource->progressWnd,0);
232 status = sane_start (pSource->deviceHandle);
233 if (status != SANE_STATUS_GOOD)
235 WARN("sane_start: %s\n", sane_strstatus (status));
236 sane_cancel (pSource->deviceHandle);
237 pSource->twCC = TWCC_OPERATIONERROR;
241 status = sane_get_parameters (pSource->deviceHandle,
242 &pSource->sane_param);
243 pSource->sane_param_valid = TRUE;
245 if (status != SANE_STATUS_GOOD)
247 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
248 sane_cancel (pSource->deviceHandle);
249 pSource->twCC = TWCC_OPERATIONERROR;
253 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
254 , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
255 pSource->sane_param.depth, pSource->sane_param.format,
256 pSource->sane_param.last_frame);
258 pSource->currentState = 7;
261 /* access memory buffer */
262 if (pImageMemXfer->Memory.Length < pSource->sane_param.bytes_per_line)
264 sane_cancel (pSource->deviceHandle);
265 pSource->twCC = TWCC_BADVALUE;
269 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
271 FIXME("Memory Handle, may not be locked correctly\n");
272 buffer = LocalLock(pImageMemXfer->Memory.TheMem);
275 buffer = pImageMemXfer->Memory.TheMem;
277 memset(buffer,0,pImageMemXfer->Memory.Length);
281 rows = pImageMemXfer->Memory.Length / pSource->sane_param.bytes_per_line;
283 /* must fill full lines */
284 while (consumed_len < (pSource->sane_param.bytes_per_line*rows) &&
285 status == SANE_STATUS_GOOD)
287 status = sane_read (pSource->deviceHandle, ptr,
288 (pSource->sane_param.bytes_per_line*rows) - consumed_len ,
290 consumed_len += buff_len;
294 if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
296 pImageMemXfer->Compression = TWCP_NONE;
297 pImageMemXfer->BytesPerRow = pSource->sane_param.bytes_per_line;
298 pImageMemXfer->Columns = pSource->sane_param.pixels_per_line;
299 pImageMemXfer->Rows = rows;
300 pImageMemXfer->XOffset = 0;
301 pImageMemXfer->YOffset = 0;
302 pImageMemXfer->BytesWritten = consumed_len;
304 ScanningDialogBox(pSource->progressWnd, consumed_len);
306 if (status == SANE_STATUS_EOF)
308 ScanningDialogBox(pSource->progressWnd, -1);
309 TRACE("sane_read: %s\n", sane_strstatus (status));
310 sane_cancel (pSource->deviceHandle);
311 twRC = TWRC_XFERDONE;
313 pSource->twCC = TWRC_SUCCESS;
315 else if (status != SANE_STATUS_EOF)
317 ScanningDialogBox(pSource->progressWnd, -1);
318 WARN("sane_read: %s\n", sane_strstatus (status));
319 sane_cancel (pSource->deviceHandle);
320 pSource->twCC = TWCC_OPERATIONERROR;
325 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
326 LocalUnlock(pImageMemXfer->Memory.TheMem);
332 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
333 TW_UINT16 TWAIN_ImageNativeXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
339 TW_UINT16 twRC = TWRC_SUCCESS;
340 pTW_UINT32 pHandle = (pTW_UINT32) pData;
341 activeDS *pSource = TWAIN_LookupSource (pDest);
343 SANE_Byte buffer[32*1024];
350 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
355 DSM_twCC = TWCC_NODS;
357 else if (pSource->currentState != 6)
360 pSource->twCC = TWCC_SEQERROR;
364 /* Transfer an image from the source to the application */
365 status = sane_start (pSource->deviceHandle);
366 if (status != SANE_STATUS_GOOD)
368 WARN("sane_start: %s\n", sane_strstatus (status));
369 sane_cancel (pSource->deviceHandle);
370 pSource->twCC = TWCC_OPERATIONERROR;
374 status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
375 pSource->sane_param_valid = TRUE;
376 if (status != SANE_STATUS_GOOD)
378 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
379 sane_cancel (pSource->deviceHandle);
380 pSource->twCC = TWCC_OPERATIONERROR;
384 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
385 , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
386 pSource->sane_param.depth, pSource->sane_param.format,
387 pSource->sane_param.last_frame);
389 ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
390 bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
391 bmpInfo.bmiHeader.biWidth = pSource->sane_param.pixels_per_line;
392 bmpInfo.bmiHeader.biHeight = pSource->sane_param.lines;
393 bmpInfo.bmiHeader.biPlanes = 1;
394 bmpInfo.bmiHeader.biBitCount = pSource->sane_param.depth;
395 bmpInfo.bmiHeader.biCompression = BI_RGB;
396 bmpInfo.bmiHeader.biSizeImage = 0;
397 bmpInfo.bmiHeader.biXPelsPerMeter = 0;
398 bmpInfo.bmiHeader.biYPelsPerMeter = 0;
399 bmpInfo.bmiHeader.biClrUsed = 1;
400 bmpInfo.bmiHeader.biClrImportant = 0;
401 bmpInfo.bmiColors[0].rgbBlue = 128;
402 bmpInfo.bmiColors[0].rgbGreen = 128;
403 bmpInfo.bmiColors[0].rgbRed = 128;
404 hDIB = CreateDIBSection ((dc = GetDC(pSource->hwndOwner)), &bmpInfo,
405 DIB_RGB_COLORS, &pBits, 0, 0);
408 sane_cancel (pSource->deviceHandle);
409 pSource->twCC = TWCC_LOWMEMORY;
415 status = sane_read (pSource->deviceHandle, buffer,
416 sizeof (buffer), &buff_len);
417 if (status == SANE_STATUS_GOOD)
419 /* FIXME: put code for converting the image data into DIB here */
422 else if (status != SANE_STATUS_EOF)
424 WARN("sane_read: %s\n", sane_strstatus (status));
425 sane_cancel (pSource->deviceHandle);
426 pSource->twCC = TWCC_OPERATIONERROR;
429 } while (status == SANE_STATUS_GOOD);
431 sane_cancel (pSource->deviceHandle);
432 ReleaseDC (pSource->hwndOwner, dc);
433 *pHandle = (TW_UINT32)hDIB;
434 twRC = TWRC_XFERDONE;
435 pSource->twCC = TWCC_SUCCESS;
436 pSource->currentState = 7;
442 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
443 TW_UINT16 TWAIN_JPEGCompressionGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
451 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
452 TW_UINT16 TWAIN_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
461 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
462 TW_UINT16 TWAIN_JPEGCompressionReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
470 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
471 TW_UINT16 TWAIN_JPEGCompressionSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
479 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
480 TW_UINT16 TWAIN_Palette8Get (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
488 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
489 TW_UINT16 TWAIN_Palette8GetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
497 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
498 TW_UINT16 TWAIN_Palette8Reset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
506 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
507 TW_UINT16 TWAIN_Palette8Set (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
515 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
516 TW_UINT16 TWAIN_RGBResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
524 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
525 TW_UINT16 TWAIN_RGBResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,