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 == 1 /*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;
136 ERR("Unhandled source frame type\n");
138 pSource->twCC = TWCC_SEQERROR;
146 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
147 TW_UINT16 TWAIN_ImageLayoutGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
155 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
156 TW_UINT16 TWAIN_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
164 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
165 TW_UINT16 TWAIN_ImageLayoutReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
173 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
174 TW_UINT16 TWAIN_ImageLayoutSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
182 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
183 TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
189 TW_UINT16 twRC = TWRC_SUCCESS;
190 pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
191 activeDS *pSource = TWAIN_LookupSource (pDest);
192 SANE_Status status = SANE_STATUS_GOOD;
194 TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
199 DSM_twCC = TWCC_NODS;
201 else if (pSource->currentState < 6 || pSource->currentState > 7)
204 pSource->twCC = TWCC_SEQERROR;
210 int consumed_len = 0;
214 /* Transfer an image from the source to the application */
215 if (pSource->currentState == 6)
217 status = sane_start (pSource->deviceHandle);
218 if (status != SANE_STATUS_GOOD)
220 WARN("sane_start: %s\n", sane_strstatus (status));
221 sane_cancel (pSource->deviceHandle);
222 pSource->twCC = TWCC_OPERATIONERROR;
226 status = sane_get_parameters (pSource->deviceHandle,
227 &pSource->sane_param);
228 pSource->sane_param_valid = TRUE;
230 if (status != SANE_STATUS_GOOD)
232 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
233 sane_cancel (pSource->deviceHandle);
234 pSource->twCC = TWCC_OPERATIONERROR;
238 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
239 , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
240 pSource->sane_param.depth, pSource->sane_param.format,
241 pSource->sane_param.last_frame);
243 pSource->currentState = 7;
246 /* access memory buffer */
247 if (pImageMemXfer->Memory.Length < pSource->sane_param.bytes_per_line)
249 sane_cancel (pSource->deviceHandle);
250 pSource->twCC = TWCC_BADVALUE;
254 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
256 FIXME("Memory Handle, may not be locked correctly\n");
257 buffer = LocalLock(pImageMemXfer->Memory.TheMem);
260 buffer = pImageMemXfer->Memory.TheMem;
262 memset(buffer,0,pImageMemXfer->Memory.Length);
266 rows = pImageMemXfer->Memory.Length / pSource->sane_param.bytes_per_line;
268 /* must fill full lines */
269 while (consumed_len < (pSource->sane_param.bytes_per_line*rows) &&
270 status == SANE_STATUS_GOOD)
272 status = sane_read (pSource->deviceHandle, ptr,
273 (pSource->sane_param.bytes_per_line*rows) - consumed_len ,
275 consumed_len += buff_len;
279 if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
281 pImageMemXfer->Compression = TWCP_NONE;
282 pImageMemXfer->BytesPerRow = pSource->sane_param.bytes_per_line;
283 pImageMemXfer->Columns = pSource->sane_param.pixels_per_line;
284 pImageMemXfer->Rows = rows;
285 pImageMemXfer->XOffset = 0;
286 pImageMemXfer->YOffset = 0;
287 pImageMemXfer->BytesWritten = consumed_len;
289 if (status == SANE_STATUS_EOF)
291 TRACE("sane_read: %s\n", sane_strstatus (status));
292 sane_cancel (pSource->deviceHandle);
293 twRC = TWRC_XFERDONE;
295 pSource->twCC = TWRC_SUCCESS;
297 else if (status != SANE_STATUS_EOF)
299 WARN("sane_read: %s\n", sane_strstatus (status));
300 sane_cancel (pSource->deviceHandle);
301 pSource->twCC = TWCC_OPERATIONERROR;
306 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
307 LocalUnlock(pImageMemXfer->Memory.TheMem);
313 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
314 TW_UINT16 TWAIN_ImageNativeXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
320 TW_UINT16 twRC = TWRC_SUCCESS;
321 pTW_UINT32 pHandle = (pTW_UINT32) pData;
322 activeDS *pSource = TWAIN_LookupSource (pDest);
324 SANE_Byte buffer[32*1024];
331 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
336 DSM_twCC = TWCC_NODS;
338 else if (pSource->currentState != 6)
341 pSource->twCC = TWCC_SEQERROR;
345 /* Transfer an image from the source to the application */
346 status = sane_start (pSource->deviceHandle);
347 if (status != SANE_STATUS_GOOD)
349 WARN("sane_start: %s\n", sane_strstatus (status));
350 sane_cancel (pSource->deviceHandle);
351 pSource->twCC = TWCC_OPERATIONERROR;
355 status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
356 pSource->sane_param_valid = TRUE;
357 if (status != SANE_STATUS_GOOD)
359 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
360 sane_cancel (pSource->deviceHandle);
361 pSource->twCC = TWCC_OPERATIONERROR;
365 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
366 , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
367 pSource->sane_param.depth, pSource->sane_param.format,
368 pSource->sane_param.last_frame);
370 ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
371 bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
372 bmpInfo.bmiHeader.biWidth = pSource->sane_param.pixels_per_line;
373 bmpInfo.bmiHeader.biHeight = pSource->sane_param.lines;
374 bmpInfo.bmiHeader.biPlanes = 1;
375 bmpInfo.bmiHeader.biBitCount = pSource->sane_param.depth;
376 bmpInfo.bmiHeader.biCompression = BI_RGB;
377 bmpInfo.bmiHeader.biSizeImage = 0;
378 bmpInfo.bmiHeader.biXPelsPerMeter = 0;
379 bmpInfo.bmiHeader.biYPelsPerMeter = 0;
380 bmpInfo.bmiHeader.biClrUsed = 1;
381 bmpInfo.bmiHeader.biClrImportant = 0;
382 bmpInfo.bmiColors[0].rgbBlue = 128;
383 bmpInfo.bmiColors[0].rgbGreen = 128;
384 bmpInfo.bmiColors[0].rgbRed = 128;
385 hDIB = CreateDIBSection ((dc = GetDC(pSource->hwndOwner)), &bmpInfo,
386 DIB_RGB_COLORS, &pBits, 0, 0);
389 sane_cancel (pSource->deviceHandle);
390 pSource->twCC = TWCC_LOWMEMORY;
396 status = sane_read (pSource->deviceHandle, buffer,
397 sizeof (buffer), &buff_len);
398 if (status == SANE_STATUS_GOOD)
400 /* FIXME: put code for converting the image data into DIB here */
403 else if (status != SANE_STATUS_EOF)
405 WARN("sane_read: %s\n", sane_strstatus (status));
406 sane_cancel (pSource->deviceHandle);
407 pSource->twCC = TWCC_OPERATIONERROR;
410 } while (status == SANE_STATUS_GOOD);
412 sane_cancel (pSource->deviceHandle);
413 ReleaseDC (pSource->hwndOwner, dc);
414 *pHandle = (TW_UINT32)hDIB;
415 twRC = TWRC_XFERDONE;
416 pSource->twCC = TWCC_SUCCESS;
417 pSource->currentState = 7;
423 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
424 TW_UINT16 TWAIN_JPEGCompressionGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
432 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
433 TW_UINT16 TWAIN_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
442 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
443 TW_UINT16 TWAIN_JPEGCompressionReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
451 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
452 TW_UINT16 TWAIN_JPEGCompressionSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
460 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
461 TW_UINT16 TWAIN_Palette8Get (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
469 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
470 TW_UINT16 TWAIN_Palette8GetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
478 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
479 TW_UINT16 TWAIN_Palette8Reset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
487 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
488 TW_UINT16 TWAIN_Palette8Set (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
496 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
497 TW_UINT16 TWAIN_RGBResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
505 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
506 TW_UINT16 TWAIN_RGBResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,