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
,