stash
[wine/wine64.git] / dlls / sane.ds / ds_image.c
blob9a88bb5dcb75bb9a170312adddf8d5e99436d87a
1 /*
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
20 #include "config.h"
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "twain.h"
29 #include "sane_i.h"
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,
36 TW_MEMREF pData)
38 FIXME ("stub!\n");
40 return TWRC_FAILURE;
43 /* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
44 TW_UINT16 SANE_ExtImageInfoGet (pTW_IDENTITY pOrigin,
45 TW_MEMREF pData)
47 FIXME ("stub!\n");
49 return TWRC_FAILURE;
52 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
53 TW_UINT16 SANE_GrayResponseReset (pTW_IDENTITY pOrigin,
54 TW_MEMREF pData)
56 FIXME ("stub!\n");
58 return TWRC_FAILURE;
61 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
62 TW_UINT16 SANE_GrayResponseSet (pTW_IDENTITY pOrigin,
63 TW_MEMREF pData)
65 FIXME ("stub!\n");
67 return TWRC_FAILURE;
70 /* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
71 TW_UINT16 SANE_ImageFileXferGet (pTW_IDENTITY pOrigin,
72 TW_MEMREF pData)
74 FIXME ("stub!\n");
76 return TWRC_FAILURE;
79 /* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
80 TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
81 TW_MEMREF pData)
83 #ifndef SONAME_LIBSANE
84 return TWRC_FAILURE;
85 #else
86 TW_UINT16 twRC = TWRC_SUCCESS;
87 pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
88 SANE_Status status;
90 TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
92 if (activeDS.currentState != 6 && activeDS.currentState != 7)
94 twRC = TWRC_FAILURE;
95 activeDS.twCC = TWCC_SEQERROR;
97 else
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;
109 return TWRC_FAILURE;
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;
144 else
146 ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
147 twRC = TWRC_FAILURE;
148 activeDS.twCC = TWCC_SEQERROR;
152 return twRC;
153 #endif
156 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
157 TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin,
158 TW_MEMREF pData)
160 FIXME ("stub!\n");
162 return TWRC_FAILURE;
165 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
166 TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin,
167 TW_MEMREF pData)
169 FIXME ("stub!\n");
171 return TWRC_FAILURE;
174 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
175 TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin,
176 TW_MEMREF pData)
178 FIXME ("stub!\n");
180 return TWRC_FAILURE;
183 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
184 TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin,
185 TW_MEMREF pData)
187 FIXME ("stub!\n");
189 return TWRC_FAILURE;
192 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
193 TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
194 TW_MEMREF pData)
196 #ifndef SONAME_LIBSANE
197 return TWRC_FAILURE;
198 #else
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)
207 twRC = TWRC_FAILURE;
208 activeDS.twCC = TWCC_SEQERROR;
210 else
212 LPBYTE buffer;
213 int buff_len = 0;
214 int consumed_len = 0;
215 LPBYTE ptr;
216 int rows;
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;
233 return TWRC_FAILURE;
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;
245 return TWRC_FAILURE;
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;
261 return TWRC_FAILURE;
264 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
266 FIXME("Memory Handle, may not be locked correctly\n");
267 buffer = LocalLock(pImageMemXfer->Memory.TheMem);
269 else
270 buffer = pImageMemXfer->Memory.TheMem;
272 memset(buffer,0,pImageMemXfer->Memory.Length);
274 ptr = buffer;
275 consumed_len = 0;
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 ,
284 &buff_len);
285 consumed_len += buff_len;
286 ptr += 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;
316 twRC = TWRC_FAILURE;
320 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
321 LocalUnlock(pImageMemXfer->Memory.TheMem);
323 return twRC;
324 #endif
327 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
328 TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
329 TW_MEMREF pData)
331 #ifndef SONAME_LIBSANE
332 return TWRC_FAILURE;
333 #else
334 TW_UINT16 twRC = TWRC_SUCCESS;
335 pTW_UINT32 pHandle = (pTW_UINT32) pData;
336 SANE_Status status;
337 SANE_Byte buffer[32*1024];
338 int buff_len;
339 HBITMAP hDIB;
340 BITMAPINFO bmpInfo;
341 VOID *pBits;
342 HDC dc;
344 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
346 if (activeDS.currentState != 6)
348 twRC = TWRC_FAILURE;
349 activeDS.twCC = TWCC_SEQERROR;
351 else
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;
360 return TWRC_FAILURE;
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;
370 return TWRC_FAILURE;
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);
395 if (!hDIB)
397 psane_cancel (activeDS.deviceHandle);
398 activeDS.twCC = TWCC_LOWMEMORY;
399 return TWRC_FAILURE;
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;
416 return TWRC_FAILURE;
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;
427 return twRC;
428 #endif
431 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
432 TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin,
433 TW_MEMREF pData)
435 FIXME ("stub!\n");
437 return TWRC_FAILURE;
440 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
441 TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
443 TW_MEMREF pData)
445 FIXME ("stub!\n");
447 return TWRC_FAILURE;
450 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
451 TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin,
452 TW_MEMREF pData)
454 FIXME ("stub!\n");
456 return TWRC_FAILURE;
459 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
460 TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin,
461 TW_MEMREF pData)
463 FIXME ("stub!\n");
465 return TWRC_FAILURE;
468 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
469 TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin,
470 TW_MEMREF pData)
472 FIXME ("stub!\n");
474 return TWRC_FAILURE;
477 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
478 TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin,
479 TW_MEMREF pData)
481 FIXME ("stub!\n");
483 return TWRC_FAILURE;
486 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
487 TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin,
488 TW_MEMREF pData)
490 FIXME ("stub!\n");
492 return TWRC_FAILURE;
495 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
496 TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin,
497 TW_MEMREF pData)
499 FIXME ("stub!\n");
501 return TWRC_FAILURE;
504 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
505 TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin,
506 TW_MEMREF pData)
508 FIXME ("stub!\n");
510 return TWRC_FAILURE;
513 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
514 TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin,
515 TW_MEMREF pData)
517 FIXME ("stub!\n");
519 return TWRC_FAILURE;