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 TRACE("Getting parameters\n");
104 if (status
!= SANE_STATUS_GOOD
)
106 WARN("psane_get_parameters: %s\n", psane_strstatus (status
));
107 psane_cancel (activeDS
.deviceHandle
);
108 activeDS
.twCC
= TWCC_OPERATIONERROR
;
111 activeDS
.sane_param_valid
= TRUE
;
114 pImageInfo
->XResolution
.Whole
= -1;
115 pImageInfo
->XResolution
.Frac
= 0;
116 pImageInfo
->YResolution
.Whole
= -1;
117 pImageInfo
->YResolution
.Frac
= 0;
118 pImageInfo
->ImageWidth
= activeDS
.sane_param
.pixels_per_line
;
119 pImageInfo
->ImageLength
= activeDS
.sane_param
.lines
;
121 TRACE("Bits per Sample %i\n",activeDS
.sane_param
.depth
);
122 TRACE("Frame Format %i\n",activeDS
.sane_param
.format
);
124 if (activeDS
.sane_param
.format
== SANE_FRAME_RGB
)
126 pImageInfo
->BitsPerPixel
= activeDS
.sane_param
.depth
* 3;
127 pImageInfo
->Compression
= TWCP_NONE
;
128 pImageInfo
->Planar
= TRUE
;
129 pImageInfo
->SamplesPerPixel
= 3;
130 pImageInfo
->BitsPerSample
[0] = activeDS
.sane_param
.depth
;
131 pImageInfo
->BitsPerSample
[1] = activeDS
.sane_param
.depth
;
132 pImageInfo
->BitsPerSample
[2] = activeDS
.sane_param
.depth
;
133 pImageInfo
->PixelType
= TWPT_RGB
;
135 else if (activeDS
.sane_param
.format
== SANE_FRAME_GRAY
)
137 pImageInfo
->BitsPerPixel
= activeDS
.sane_param
.depth
;
138 pImageInfo
->Compression
= TWCP_NONE
;
139 pImageInfo
->Planar
= TRUE
;
140 pImageInfo
->SamplesPerPixel
= 1;
141 pImageInfo
->BitsPerSample
[0] = activeDS
.sane_param
.depth
;
142 pImageInfo
->PixelType
= TWPT_GRAY
;
146 ERR("Unhandled source frame type %i\n",activeDS
.sane_param
.format
);
148 activeDS
.twCC
= TWCC_SEQERROR
;
156 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
157 TW_UINT16
SANE_ImageLayoutGet (pTW_IDENTITY pOrigin
,
165 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
166 TW_UINT16
SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin
,
174 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
175 TW_UINT16
SANE_ImageLayoutReset (pTW_IDENTITY pOrigin
,
183 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
184 TW_UINT16
SANE_ImageLayoutSet (pTW_IDENTITY pOrigin
,
192 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
193 TW_UINT16
SANE_ImageMemXferGet (pTW_IDENTITY pOrigin
,
196 #ifndef SONAME_LIBSANE
199 TW_UINT16 twRC
= TWRC_SUCCESS
;
200 pTW_IMAGEMEMXFER pImageMemXfer
= (pTW_IMAGEMEMXFER
) pData
;
201 SANE_Status status
= SANE_STATUS_GOOD
;
203 TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
205 if (activeDS
.currentState
< 6 || activeDS
.currentState
> 7)
208 activeDS
.twCC
= TWCC_SEQERROR
;
214 int consumed_len
= 0;
218 /* Transfer an image from the source to the application */
219 if (activeDS
.currentState
== 6)
222 /* trigger scanning dialog */
223 activeDS
.progressWnd
= ScanningDialogBox(NULL
,0);
225 ScanningDialogBox(activeDS
.progressWnd
,0);
227 status
= psane_start (activeDS
.deviceHandle
);
228 if (status
!= SANE_STATUS_GOOD
)
230 WARN("psane_start: %s\n", psane_strstatus (status
));
231 psane_cancel (activeDS
.deviceHandle
);
232 activeDS
.twCC
= TWCC_OPERATIONERROR
;
236 status
= psane_get_parameters (activeDS
.deviceHandle
,
237 &activeDS
.sane_param
);
238 activeDS
.sane_param_valid
= TRUE
;
240 if (status
!= SANE_STATUS_GOOD
)
242 WARN("psane_get_parameters: %s\n", psane_strstatus (status
));
243 psane_cancel (activeDS
.deviceHandle
);
244 activeDS
.twCC
= TWCC_OPERATIONERROR
;
248 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
249 , activeDS
.sane_param
.pixels_per_line
, activeDS
.sane_param
.lines
,
250 activeDS
.sane_param
.depth
, activeDS
.sane_param
.format
,
251 activeDS
.sane_param
.last_frame
);
253 activeDS
.currentState
= 7;
256 /* access memory buffer */
257 if (pImageMemXfer
->Memory
.Length
< activeDS
.sane_param
.bytes_per_line
)
259 psane_cancel (activeDS
.deviceHandle
);
260 activeDS
.twCC
= TWCC_BADVALUE
;
264 if (pImageMemXfer
->Memory
.Flags
& TWMF_HANDLE
)
266 FIXME("Memory Handle, may not be locked correctly\n");
267 buffer
= LocalLock(pImageMemXfer
->Memory
.TheMem
);
270 buffer
= pImageMemXfer
->Memory
.TheMem
;
272 memset(buffer
,0,pImageMemXfer
->Memory
.Length
);
276 rows
= pImageMemXfer
->Memory
.Length
/ activeDS
.sane_param
.bytes_per_line
;
278 /* must fill full lines */
279 while (consumed_len
< (activeDS
.sane_param
.bytes_per_line
*rows
) &&
280 status
== SANE_STATUS_GOOD
)
282 status
= psane_read (activeDS
.deviceHandle
, ptr
,
283 (activeDS
.sane_param
.bytes_per_line
*rows
) - consumed_len
,
285 consumed_len
+= buff_len
;
289 if (status
== SANE_STATUS_GOOD
|| status
== SANE_STATUS_EOF
)
291 pImageMemXfer
->Compression
= TWCP_NONE
;
292 pImageMemXfer
->BytesPerRow
= activeDS
.sane_param
.bytes_per_line
;
293 pImageMemXfer
->Columns
= activeDS
.sane_param
.pixels_per_line
;
294 pImageMemXfer
->Rows
= rows
;
295 pImageMemXfer
->XOffset
= 0;
296 pImageMemXfer
->YOffset
= 0;
297 pImageMemXfer
->BytesWritten
= consumed_len
;
299 ScanningDialogBox(activeDS
.progressWnd
, consumed_len
);
301 if (status
== SANE_STATUS_EOF
)
303 ScanningDialogBox(activeDS
.progressWnd
, -1);
304 TRACE("psane_read: %s\n", psane_strstatus (status
));
305 psane_cancel (activeDS
.deviceHandle
);
306 twRC
= TWRC_XFERDONE
;
308 activeDS
.twCC
= TWRC_SUCCESS
;
310 else if (status
!= SANE_STATUS_EOF
)
312 ScanningDialogBox(activeDS
.progressWnd
, -1);
313 WARN("psane_read: %s\n", psane_strstatus (status
));
314 psane_cancel (activeDS
.deviceHandle
);
315 activeDS
.twCC
= TWCC_OPERATIONERROR
;
320 if (pImageMemXfer
->Memory
.Flags
& TWMF_HANDLE
)
321 LocalUnlock(pImageMemXfer
->Memory
.TheMem
);
327 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
328 TW_UINT16
SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin
,
331 #ifndef SONAME_LIBSANE
334 TW_UINT16 twRC
= TWRC_SUCCESS
;
335 pTW_UINT32 pHandle
= (pTW_UINT32
) pData
;
337 SANE_Byte buffer
[32*1024];
344 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
346 if (activeDS
.currentState
!= 6)
349 activeDS
.twCC
= TWCC_SEQERROR
;
353 /* Transfer an image from the source to the application */
354 status
= psane_start (activeDS
.deviceHandle
);
355 if (status
!= SANE_STATUS_GOOD
)
357 WARN("psane_start: %s\n", psane_strstatus (status
));
358 psane_cancel (activeDS
.deviceHandle
);
359 activeDS
.twCC
= TWCC_OPERATIONERROR
;
363 status
= psane_get_parameters (activeDS
.deviceHandle
, &activeDS
.sane_param
);
364 activeDS
.sane_param_valid
= TRUE
;
365 if (status
!= SANE_STATUS_GOOD
)
367 WARN("psane_get_parameters: %s\n", psane_strstatus (status
));
368 psane_cancel (activeDS
.deviceHandle
);
369 activeDS
.twCC
= TWCC_OPERATIONERROR
;
373 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
374 , activeDS
.sane_param
.pixels_per_line
, activeDS
.sane_param
.lines
,
375 activeDS
.sane_param
.depth
, activeDS
.sane_param
.format
,
376 activeDS
.sane_param
.last_frame
);
378 ZeroMemory (&bmpInfo
, sizeof (BITMAPINFO
));
379 bmpInfo
.bmiHeader
.biSize
= sizeof (BITMAPINFOHEADER
);
380 bmpInfo
.bmiHeader
.biWidth
= activeDS
.sane_param
.pixels_per_line
;
381 bmpInfo
.bmiHeader
.biHeight
= activeDS
.sane_param
.lines
;
382 bmpInfo
.bmiHeader
.biPlanes
= 1;
383 bmpInfo
.bmiHeader
.biBitCount
= activeDS
.sane_param
.depth
;
384 bmpInfo
.bmiHeader
.biCompression
= BI_RGB
;
385 bmpInfo
.bmiHeader
.biSizeImage
= 0;
386 bmpInfo
.bmiHeader
.biXPelsPerMeter
= 0;
387 bmpInfo
.bmiHeader
.biYPelsPerMeter
= 0;
388 bmpInfo
.bmiHeader
.biClrUsed
= 1;
389 bmpInfo
.bmiHeader
.biClrImportant
= 0;
390 bmpInfo
.bmiColors
[0].rgbBlue
= 128;
391 bmpInfo
.bmiColors
[0].rgbGreen
= 128;
392 bmpInfo
.bmiColors
[0].rgbRed
= 128;
393 hDIB
= CreateDIBSection ((dc
= GetDC(activeDS
.hwndOwner
)), &bmpInfo
,
394 DIB_RGB_COLORS
, &pBits
, 0, 0);
397 psane_cancel (activeDS
.deviceHandle
);
398 activeDS
.twCC
= TWCC_LOWMEMORY
;
404 status
= psane_read (activeDS
.deviceHandle
, buffer
,
405 sizeof (buffer
), &buff_len
);
406 if (status
== SANE_STATUS_GOOD
)
408 /* FIXME: put code for converting the image data into DIB here */
411 else if (status
!= SANE_STATUS_EOF
)
413 WARN("psane_read: %s\n", psane_strstatus (status
));
414 psane_cancel (activeDS
.deviceHandle
);
415 activeDS
.twCC
= TWCC_OPERATIONERROR
;
418 } while (status
== SANE_STATUS_GOOD
);
420 psane_cancel (activeDS
.deviceHandle
);
421 ReleaseDC (activeDS
.hwndOwner
, dc
);
422 *pHandle
= (TW_UINT32
)hDIB
;
423 twRC
= TWRC_XFERDONE
;
424 activeDS
.twCC
= TWCC_SUCCESS
;
425 activeDS
.currentState
= 7;
431 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
432 TW_UINT16
SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin
,
440 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
441 TW_UINT16
SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin
,
450 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
451 TW_UINT16
SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin
,
459 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
460 TW_UINT16
SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin
,
468 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
469 TW_UINT16
SANE_Palette8Get (pTW_IDENTITY pOrigin
,
477 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
478 TW_UINT16
SANE_Palette8GetDefault (pTW_IDENTITY pOrigin
,
486 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
487 TW_UINT16
SANE_Palette8Reset (pTW_IDENTITY pOrigin
,
495 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
496 TW_UINT16
SANE_Palette8Set (pTW_IDENTITY pOrigin
,
504 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
505 TW_UINT16
SANE_RGBResponseReset (pTW_IDENTITY pOrigin
,
513 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
514 TW_UINT16
SANE_RGBResponseSet (pTW_IDENTITY pOrigin
,