sane.ds: Check dead stored status (llvm/clang).
[wine] / dlls / sane.ds / ds_image.c
1 /*
2  * Copyright 2000 Corel Corporation
3  * Copyright 2006 CodeWeavers, Aric Stewart
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include "config.h"
21
22 #include <stdarg.h>
23
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"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
33
34 /* DG_IMAGE/DAT_CIECOLOR/MSG_GET */
35 TW_UINT16 SANE_CIEColorGet (pTW_IDENTITY pOrigin, 
36                              TW_MEMREF pData)
37 {
38     FIXME ("stub!\n");
39
40     return TWRC_FAILURE;
41 }
42
43 /* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
44 TW_UINT16 SANE_ExtImageInfoGet (pTW_IDENTITY pOrigin, 
45                                  TW_MEMREF pData)
46 {
47     FIXME ("stub!\n");
48
49     return TWRC_FAILURE;
50 }
51
52 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
53 TW_UINT16 SANE_GrayResponseReset (pTW_IDENTITY pOrigin, 
54                                    TW_MEMREF pData)
55 {
56     FIXME ("stub!\n");
57
58     return TWRC_FAILURE;
59 }
60
61 /* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
62 TW_UINT16 SANE_GrayResponseSet (pTW_IDENTITY pOrigin, 
63                                  TW_MEMREF pData)
64 {
65     FIXME ("stub!\n");
66
67     return TWRC_FAILURE;
68 }
69
70 /* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
71 TW_UINT16 SANE_ImageFileXferGet (pTW_IDENTITY pOrigin, 
72                                   TW_MEMREF pData)
73 {
74     FIXME ("stub!\n");
75
76     return TWRC_FAILURE;
77 }
78
79 /* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
80 TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, 
81                               TW_MEMREF pData)
82 {
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;
89
90     TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
91
92     if (activeDS.currentState != 6 && activeDS.currentState != 7)
93     {
94         twRC = TWRC_FAILURE;
95         activeDS.twCC = TWCC_SEQERROR;
96     }
97     else
98     {
99         if (activeDS.currentState == 6)
100         {
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)
105             {
106                 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
107                 psane_cancel (activeDS.deviceHandle);
108                 activeDS.twCC = TWCC_OPERATIONERROR;
109                 return TWRC_FAILURE;
110             }
111             activeDS.sane_param_valid = TRUE;
112         }
113
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;
120
121         TRACE("Bits per Sample %i\n",activeDS.sane_param.depth);
122         TRACE("Frame Format %i\n",activeDS.sane_param.format);
123
124         if (activeDS.sane_param.format == SANE_FRAME_RGB )
125         {
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;
134         }
135         else if (activeDS.sane_param.format == SANE_FRAME_GRAY)
136         {
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;
143         }
144         else
145         {
146             ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
147             twRC = TWRC_FAILURE;
148             activeDS.twCC = TWCC_SEQERROR;
149         }
150     }
151
152     return twRC;
153 #endif
154 }
155
156 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
157 TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin, 
158                                 TW_MEMREF pData)
159 {
160     FIXME ("stub!\n");
161
162     return TWRC_FAILURE;
163 }
164
165 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
166 TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, 
167                                        TW_MEMREF pData)
168 {
169     FIXME ("stub!\n");
170
171     return TWRC_FAILURE;
172 }
173
174 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
175 TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin, 
176                                   TW_MEMREF pData)
177 {
178     FIXME ("stub!\n");
179
180     return TWRC_FAILURE;
181 }
182
183 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
184 TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin, 
185                                 TW_MEMREF pData)
186 {
187     FIXME ("stub!\n");
188
189     return TWRC_FAILURE;
190 }
191
192 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
193 TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, 
194                                  TW_MEMREF pData)
195 {
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;
202
203     TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
204
205     if (activeDS.currentState < 6 || activeDS.currentState > 7)
206     {
207         twRC = TWRC_FAILURE;
208         activeDS.twCC = TWCC_SEQERROR;
209     }
210     else
211     {
212         LPBYTE buffer;
213         int buff_len = 0;
214         int consumed_len = 0;
215         LPBYTE ptr;
216         int rows;
217
218         /* Transfer an image from the source to the application */
219         if (activeDS.currentState == 6)
220         {
221
222             /* trigger scanning dialog */
223             activeDS.progressWnd = ScanningDialogBox(NULL,0);
224
225             ScanningDialogBox(activeDS.progressWnd,0);
226
227             status = psane_start (activeDS.deviceHandle);
228             if (status != SANE_STATUS_GOOD)
229             {
230                 WARN("psane_start: %s\n", psane_strstatus (status));
231                 psane_cancel (activeDS.deviceHandle);
232                 activeDS.twCC = TWCC_OPERATIONERROR;
233                 return TWRC_FAILURE;
234             }
235
236             status = psane_get_parameters (activeDS.deviceHandle,
237                     &activeDS.sane_param);
238             activeDS.sane_param_valid = TRUE;
239
240             if (status != SANE_STATUS_GOOD)
241             {
242                 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
243                 psane_cancel (activeDS.deviceHandle);
244                 activeDS.twCC = TWCC_OPERATIONERROR;
245                 return TWRC_FAILURE;
246             }
247
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);
252
253             activeDS.currentState = 7;
254         }
255
256         /* access memory buffer */
257         if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
258         {
259             psane_cancel (activeDS.deviceHandle);
260             activeDS.twCC = TWCC_BADVALUE;
261             return TWRC_FAILURE;
262         }
263
264         if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
265         {
266             FIXME("Memory Handle, may not be locked correctly\n");
267             buffer = LocalLock(pImageMemXfer->Memory.TheMem);
268         }
269         else
270             buffer = pImageMemXfer->Memory.TheMem;
271        
272         memset(buffer,0,pImageMemXfer->Memory.Length);
273
274         ptr = buffer;
275         consumed_len = 0;
276         rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line;
277
278         /* must fill full lines */
279         while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) && 
280                 status == SANE_STATUS_GOOD)
281         {
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;
287         }
288
289         if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
290         {
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;
298
299             ScanningDialogBox(activeDS.progressWnd, consumed_len);
300
301             if (status == SANE_STATUS_EOF)
302             {
303                 ScanningDialogBox(activeDS.progressWnd, -1);
304                 TRACE("psane_read: %s\n", psane_strstatus (status));
305                 psane_cancel (activeDS.deviceHandle);
306                 twRC = TWRC_XFERDONE;
307             }
308             activeDS.twCC = TWRC_SUCCESS;
309         }
310         else if (status != SANE_STATUS_EOF)
311         {
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;
317         }
318     }
319
320     if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
321         LocalUnlock(pImageMemXfer->Memory.TheMem);
322     
323     return twRC;
324 #endif
325 }
326
327 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
328 TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, 
329                                     TW_MEMREF pData)
330 {
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;
343
344     TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
345
346     if (activeDS.currentState != 6)
347     {
348         twRC = TWRC_FAILURE;
349         activeDS.twCC = TWCC_SEQERROR;
350     }
351     else
352     {
353         /* Transfer an image from the source to the application */
354         status = psane_start (activeDS.deviceHandle);
355         if (status != SANE_STATUS_GOOD)
356         {
357             WARN("psane_start: %s\n", psane_strstatus (status));
358             psane_cancel (activeDS.deviceHandle);
359             activeDS.twCC = TWCC_OPERATIONERROR;
360             return TWRC_FAILURE;
361         }
362
363         status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
364         activeDS.sane_param_valid = TRUE;
365         if (status != SANE_STATUS_GOOD)
366         {
367             WARN("psane_get_parameters: %s\n", psane_strstatus (status));
368             psane_cancel (activeDS.deviceHandle);
369             activeDS.twCC = TWCC_OPERATIONERROR;
370             return TWRC_FAILURE;
371         }
372
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);
377
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)
396         {
397             psane_cancel (activeDS.deviceHandle);
398             activeDS.twCC = TWCC_LOWMEMORY;
399             return TWRC_FAILURE;
400         }
401
402         do
403         {
404             status = psane_read (activeDS.deviceHandle, buffer,
405                                 sizeof (buffer),  &buff_len);
406             if (status == SANE_STATUS_GOOD)
407             {
408                 /* FIXME: put code for converting the image data into DIB here */
409
410             }
411             else if (status != SANE_STATUS_EOF)
412             {
413                 WARN("psane_read: %s\n", psane_strstatus (status));
414                 psane_cancel (activeDS.deviceHandle);
415                 activeDS.twCC = TWCC_OPERATIONERROR;
416                 return TWRC_FAILURE;
417             }
418         } while (status == SANE_STATUS_GOOD);
419
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;
426     }
427     return twRC;
428 #endif
429 }
430
431 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
432 TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin, 
433                                     TW_MEMREF pData)
434 {
435     FIXME ("stub!\n");
436
437     return TWRC_FAILURE;
438 }
439
440 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
441 TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
442                                            
443                                            TW_MEMREF pData)
444 {
445     FIXME ("stub!\n");
446
447     return TWRC_FAILURE;
448 }
449
450 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
451 TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin, 
452                                       TW_MEMREF pData)
453 {
454     FIXME ("stub!\n");
455
456     return TWRC_FAILURE;
457 }
458
459 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
460 TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin, 
461                                     TW_MEMREF pData)
462 {
463     FIXME ("stub!\n");
464
465     return TWRC_FAILURE;
466 }
467
468 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
469 TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin, 
470                              TW_MEMREF pData)
471 {
472     FIXME ("stub!\n");
473
474     return TWRC_FAILURE;
475 }
476
477 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
478 TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin, 
479                                     TW_MEMREF pData)
480 {
481     FIXME ("stub!\n");
482
483     return TWRC_FAILURE;
484 }
485
486 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
487 TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin, 
488                                TW_MEMREF pData)
489 {
490     FIXME ("stub!\n");
491
492     return TWRC_FAILURE;
493 }
494
495 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
496 TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin, 
497                              TW_MEMREF pData)
498 {
499     FIXME ("stub!\n");
500
501     return TWRC_FAILURE;
502 }
503
504 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
505 TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin, 
506                                   TW_MEMREF pData)
507 {
508     FIXME ("stub!\n");
509
510     return TWRC_FAILURE;
511 }
512
513 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
514 TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin, 
515                                 TW_MEMREF pData)
516 {
517     FIXME ("stub!\n");
518
519     return TWRC_FAILURE;
520 }