kernel32: Use ntdll functions where possible to implement the pthread wrappers.
[wine/wine-kai.git] / dlls / sane.ds / ds_image.c
blobc3e70821d030658644689df17ee86d8eb90e28c5
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 activeDS.sane_param_valid = TRUE;
104 TRACE("Getting parameters\n");
107 pImageInfo->XResolution.Whole = -1;
108 pImageInfo->XResolution.Frac = 0;
109 pImageInfo->YResolution.Whole = -1;
110 pImageInfo->YResolution.Frac = 0;
111 pImageInfo->ImageWidth = activeDS.sane_param.pixels_per_line;
112 pImageInfo->ImageLength = activeDS.sane_param.lines;
114 TRACE("Bits per Sample %i\n",activeDS.sane_param.depth);
115 TRACE("Frame Format %i\n",activeDS.sane_param.format);
117 if (activeDS.sane_param.format == SANE_FRAME_RGB )
119 pImageInfo->BitsPerPixel = activeDS.sane_param.depth * 3;
120 pImageInfo->Compression = TWCP_NONE;
121 pImageInfo->Planar = TRUE;
122 pImageInfo->SamplesPerPixel = 3;
123 pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
124 pImageInfo->BitsPerSample[1] = activeDS.sane_param.depth;
125 pImageInfo->BitsPerSample[2] = activeDS.sane_param.depth;
126 pImageInfo->PixelType = TWPT_RGB;
128 else if (activeDS.sane_param.format == SANE_FRAME_GRAY)
130 pImageInfo->BitsPerPixel = activeDS.sane_param.depth;
131 pImageInfo->Compression = TWCP_NONE;
132 pImageInfo->Planar = TRUE;
133 pImageInfo->SamplesPerPixel = 1;
134 pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
135 pImageInfo->PixelType = TWPT_GRAY;
137 else
139 ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
140 twRC = TWRC_FAILURE;
141 activeDS.twCC = TWCC_SEQERROR;
145 return twRC;
146 #endif
149 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
150 TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin,
151 TW_MEMREF pData)
153 FIXME ("stub!\n");
155 return TWRC_FAILURE;
158 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
159 TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin,
160 TW_MEMREF pData)
162 FIXME ("stub!\n");
164 return TWRC_FAILURE;
167 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
168 TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin,
169 TW_MEMREF pData)
171 FIXME ("stub!\n");
173 return TWRC_FAILURE;
176 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
177 TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin,
178 TW_MEMREF pData)
180 FIXME ("stub!\n");
182 return TWRC_FAILURE;
185 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
186 TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
187 TW_MEMREF pData)
189 #ifndef SONAME_LIBSANE
190 return TWRC_FAILURE;
191 #else
192 TW_UINT16 twRC = TWRC_SUCCESS;
193 pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
194 SANE_Status status = SANE_STATUS_GOOD;
196 TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
198 if (activeDS.currentState < 6 || activeDS.currentState > 7)
200 twRC = TWRC_FAILURE;
201 activeDS.twCC = TWCC_SEQERROR;
203 else
205 LPBYTE buffer;
206 int buff_len = 0;
207 int consumed_len = 0;
208 LPBYTE ptr;
209 int rows;
211 /* Transfer an image from the source to the application */
212 if (activeDS.currentState == 6)
215 /* trigger scanning dialog */
216 activeDS.progressWnd = ScanningDialogBox(NULL,0);
218 ScanningDialogBox(activeDS.progressWnd,0);
220 status = psane_start (activeDS.deviceHandle);
221 if (status != SANE_STATUS_GOOD)
223 WARN("psane_start: %s\n", psane_strstatus (status));
224 psane_cancel (activeDS.deviceHandle);
225 activeDS.twCC = TWCC_OPERATIONERROR;
226 return TWRC_FAILURE;
229 status = psane_get_parameters (activeDS.deviceHandle,
230 &activeDS.sane_param);
231 activeDS.sane_param_valid = TRUE;
233 if (status != SANE_STATUS_GOOD)
235 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
236 psane_cancel (activeDS.deviceHandle);
237 activeDS.twCC = TWCC_OPERATIONERROR;
238 return TWRC_FAILURE;
241 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
242 , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
243 activeDS.sane_param.depth, activeDS.sane_param.format,
244 activeDS.sane_param.last_frame);
246 activeDS.currentState = 7;
249 /* access memory buffer */
250 if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
252 psane_cancel (activeDS.deviceHandle);
253 activeDS.twCC = TWCC_BADVALUE;
254 return TWRC_FAILURE;
257 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
259 FIXME("Memory Handle, may not be locked correctly\n");
260 buffer = LocalLock(pImageMemXfer->Memory.TheMem);
262 else
263 buffer = pImageMemXfer->Memory.TheMem;
265 memset(buffer,0,pImageMemXfer->Memory.Length);
267 ptr = buffer;
268 consumed_len = 0;
269 rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line;
271 /* must fill full lines */
272 while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) &&
273 status == SANE_STATUS_GOOD)
275 status = psane_read (activeDS.deviceHandle, ptr,
276 (activeDS.sane_param.bytes_per_line*rows) - consumed_len ,
277 &buff_len);
278 consumed_len += buff_len;
279 ptr += buff_len;
282 if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
284 pImageMemXfer->Compression = TWCP_NONE;
285 pImageMemXfer->BytesPerRow = activeDS.sane_param.bytes_per_line;
286 pImageMemXfer->Columns = activeDS.sane_param.pixels_per_line;
287 pImageMemXfer->Rows = rows;
288 pImageMemXfer->XOffset = 0;
289 pImageMemXfer->YOffset = 0;
290 pImageMemXfer->BytesWritten = consumed_len;
292 ScanningDialogBox(activeDS.progressWnd, consumed_len);
294 if (status == SANE_STATUS_EOF)
296 ScanningDialogBox(activeDS.progressWnd, -1);
297 TRACE("psane_read: %s\n", psane_strstatus (status));
298 psane_cancel (activeDS.deviceHandle);
299 twRC = TWRC_XFERDONE;
301 activeDS.twCC = TWRC_SUCCESS;
303 else if (status != SANE_STATUS_EOF)
305 ScanningDialogBox(activeDS.progressWnd, -1);
306 WARN("psane_read: %s\n", psane_strstatus (status));
307 psane_cancel (activeDS.deviceHandle);
308 activeDS.twCC = TWCC_OPERATIONERROR;
309 twRC = TWRC_FAILURE;
313 if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
314 LocalUnlock(pImageMemXfer->Memory.TheMem);
316 return twRC;
317 #endif
320 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
321 TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
322 TW_MEMREF pData)
324 #ifndef SONAME_LIBSANE
325 return TWRC_FAILURE;
326 #else
327 TW_UINT16 twRC = TWRC_SUCCESS;
328 pTW_UINT32 pHandle = (pTW_UINT32) pData;
329 SANE_Status status;
330 SANE_Byte buffer[32*1024];
331 int buff_len;
332 HBITMAP hDIB;
333 BITMAPINFO bmpInfo;
334 VOID *pBits;
335 HDC dc;
337 TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
339 if (activeDS.currentState != 6)
341 twRC = TWRC_FAILURE;
342 activeDS.twCC = TWCC_SEQERROR;
344 else
346 /* Transfer an image from the source to the application */
347 status = psane_start (activeDS.deviceHandle);
348 if (status != SANE_STATUS_GOOD)
350 WARN("psane_start: %s\n", psane_strstatus (status));
351 psane_cancel (activeDS.deviceHandle);
352 activeDS.twCC = TWCC_OPERATIONERROR;
353 return TWRC_FAILURE;
356 status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
357 activeDS.sane_param_valid = TRUE;
358 if (status != SANE_STATUS_GOOD)
360 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
361 psane_cancel (activeDS.deviceHandle);
362 activeDS.twCC = TWCC_OPERATIONERROR;
363 return TWRC_FAILURE;
366 TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
367 , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
368 activeDS.sane_param.depth, activeDS.sane_param.format,
369 activeDS.sane_param.last_frame);
371 ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
372 bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
373 bmpInfo.bmiHeader.biWidth = activeDS.sane_param.pixels_per_line;
374 bmpInfo.bmiHeader.biHeight = activeDS.sane_param.lines;
375 bmpInfo.bmiHeader.biPlanes = 1;
376 bmpInfo.bmiHeader.biBitCount = activeDS.sane_param.depth;
377 bmpInfo.bmiHeader.biCompression = BI_RGB;
378 bmpInfo.bmiHeader.biSizeImage = 0;
379 bmpInfo.bmiHeader.biXPelsPerMeter = 0;
380 bmpInfo.bmiHeader.biYPelsPerMeter = 0;
381 bmpInfo.bmiHeader.biClrUsed = 1;
382 bmpInfo.bmiHeader.biClrImportant = 0;
383 bmpInfo.bmiColors[0].rgbBlue = 128;
384 bmpInfo.bmiColors[0].rgbGreen = 128;
385 bmpInfo.bmiColors[0].rgbRed = 128;
386 hDIB = CreateDIBSection ((dc = GetDC(activeDS.hwndOwner)), &bmpInfo,
387 DIB_RGB_COLORS, &pBits, 0, 0);
388 if (!hDIB)
390 psane_cancel (activeDS.deviceHandle);
391 activeDS.twCC = TWCC_LOWMEMORY;
392 return TWRC_FAILURE;
397 status = psane_read (activeDS.deviceHandle, buffer,
398 sizeof (buffer), &buff_len);
399 if (status == SANE_STATUS_GOOD)
401 /* FIXME: put code for converting the image data into DIB here */
404 else if (status != SANE_STATUS_EOF)
406 WARN("psane_read: %s\n", psane_strstatus (status));
407 psane_cancel (activeDS.deviceHandle);
408 activeDS.twCC = TWCC_OPERATIONERROR;
409 return TWRC_FAILURE;
411 } while (status == SANE_STATUS_GOOD);
413 psane_cancel (activeDS.deviceHandle);
414 ReleaseDC (activeDS.hwndOwner, dc);
415 *pHandle = (TW_UINT32)hDIB;
416 twRC = TWRC_XFERDONE;
417 activeDS.twCC = TWCC_SUCCESS;
418 activeDS.currentState = 7;
420 return twRC;
421 #endif
424 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
425 TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin,
426 TW_MEMREF pData)
428 FIXME ("stub!\n");
430 return TWRC_FAILURE;
433 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
434 TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
436 TW_MEMREF pData)
438 FIXME ("stub!\n");
440 return TWRC_FAILURE;
443 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
444 TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin,
445 TW_MEMREF pData)
447 FIXME ("stub!\n");
449 return TWRC_FAILURE;
452 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
453 TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin,
454 TW_MEMREF pData)
456 FIXME ("stub!\n");
458 return TWRC_FAILURE;
461 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
462 TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin,
463 TW_MEMREF pData)
465 FIXME ("stub!\n");
467 return TWRC_FAILURE;
470 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
471 TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin,
472 TW_MEMREF pData)
474 FIXME ("stub!\n");
476 return TWRC_FAILURE;
479 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
480 TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin,
481 TW_MEMREF pData)
483 FIXME ("stub!\n");
485 return TWRC_FAILURE;
488 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
489 TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin,
490 TW_MEMREF pData)
492 FIXME ("stub!\n");
494 return TWRC_FAILURE;
497 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
498 TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin,
499 TW_MEMREF pData)
501 FIXME ("stub!\n");
503 return TWRC_FAILURE;
506 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
507 TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin,
508 TW_MEMREF pData)
510 FIXME ("stub!\n");
512 return TWRC_FAILURE;