user: Add an missing element to the hbmmenus array.
[wine] / dlls / twain / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "twain_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 TWAIN_CIEColorGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
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 TWAIN_ExtImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
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 TWAIN_GrayResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
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 TWAIN_GrayResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
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 TWAIN_ImageFileXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
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 TWAIN_ImageInfoGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
81                               TW_MEMREF pData)
82 {
83 #ifndef HAVE_SANE
84     return TWRC_FAILURE;
85 #else
86     TW_UINT16 twRC = TWRC_SUCCESS;
87     pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
88     activeDS *pSource = TWAIN_LookupSource (pDest);
89     SANE_Status status;
90
91     TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
92
93     if (!pSource)
94     {
95         twRC = TWRC_FAILURE;
96         DSM_twCC = TWCC_BADDEST;
97     }
98     else if (pSource->currentState != 6 && pSource->currentState != 7)
99     {
100         twRC = TWRC_FAILURE;
101         pSource->twCC = TWCC_SEQERROR;
102     }
103     else
104     {
105         if (pSource->currentState == 6)
106         {
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");
111         }
112
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;
119
120         TRACE("Bits per Sample %i\n",pSource->sane_param.depth);
121         TRACE("Frame Format %i\n",pSource->sane_param.format);
122
123         if (pSource->sane_param.format == SANE_FRAME_RGB )
124         {
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;
133         }
134         else if (pSource->sane_param.format == SANE_FRAME_GRAY)
135         {
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;
142         }
143         else
144         {
145             ERR("Unhandled source frame type %i\n",pSource->sane_param.format);
146             twRC = TWRC_FAILURE;
147             pSource->twCC = TWCC_SEQERROR;
148         }
149     }
150
151     return twRC;
152 #endif
153 }
154
155 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
156 TW_UINT16 TWAIN_ImageLayoutGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
157                                 TW_MEMREF pData)
158 {
159     FIXME ("stub!\n");
160
161     return TWRC_FAILURE;
162 }
163
164 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
165 TW_UINT16 TWAIN_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
166                                        TW_MEMREF pData)
167 {
168     FIXME ("stub!\n");
169
170     return TWRC_FAILURE;
171 }
172
173 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
174 TW_UINT16 TWAIN_ImageLayoutReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
175                                   TW_MEMREF pData)
176 {
177     FIXME ("stub!\n");
178
179     return TWRC_FAILURE;
180 }
181
182 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
183 TW_UINT16 TWAIN_ImageLayoutSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
184                                 TW_MEMREF pData)
185 {
186     FIXME ("stub!\n");
187
188     return TWRC_FAILURE;
189 }
190
191 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
192 TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
193                                  TW_MEMREF pData)
194 {
195 #ifndef HAVE_SANE
196     return TWRC_FAILURE;
197 #else
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;
202
203     TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
204
205     if (!pSource)
206     {
207         twRC = TWRC_FAILURE;
208         DSM_twCC = TWCC_NODS;
209     }
210     else if (pSource->currentState < 6 || pSource->currentState > 7)
211     {
212         twRC = TWRC_FAILURE;
213         pSource->twCC = TWCC_SEQERROR;
214     }
215     else
216     {
217         LPBYTE buffer;
218         int buff_len = 0;
219         int consumed_len = 0;
220         LPBYTE ptr;
221         int rows;
222
223         /* Transfer an image from the source to the application */
224         if (pSource->currentState == 6)
225         {
226
227             /* trigger scanning dialog */
228             pSource->progressWnd = ScanningDialogBox(NULL,0);
229
230             ScanningDialogBox(pSource->progressWnd,0);
231
232             status = sane_start (pSource->deviceHandle);
233             if (status != SANE_STATUS_GOOD)
234             {
235                 WARN("sane_start: %s\n", sane_strstatus (status));
236                 sane_cancel (pSource->deviceHandle);
237                 pSource->twCC = TWCC_OPERATIONERROR;
238                 return TWRC_FAILURE;
239             }
240
241             status = sane_get_parameters (pSource->deviceHandle,
242                     &pSource->sane_param);
243             pSource->sane_param_valid = TRUE;
244
245             if (status != SANE_STATUS_GOOD)
246             {
247                 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
248                 sane_cancel (pSource->deviceHandle);
249                 pSource->twCC = TWCC_OPERATIONERROR;
250                 return TWRC_FAILURE;
251             }
252
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);
257
258             pSource->currentState = 7;
259         }
260
261         /* access memory buffer */
262         if (pImageMemXfer->Memory.Length < pSource->sane_param.bytes_per_line)
263         {
264             sane_cancel (pSource->deviceHandle);
265             pSource->twCC = TWCC_BADVALUE;
266             return TWRC_FAILURE;
267         }
268
269         if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
270         {
271             FIXME("Memory Handle, may not be locked correctly\n");
272             buffer = LocalLock(pImageMemXfer->Memory.TheMem);
273         }
274         else
275             buffer = pImageMemXfer->Memory.TheMem;
276        
277         memset(buffer,0,pImageMemXfer->Memory.Length);
278
279         ptr = buffer;
280         consumed_len = 0;
281         rows = pImageMemXfer->Memory.Length / pSource->sane_param.bytes_per_line;
282
283         /* must fill full lines */
284         while (consumed_len < (pSource->sane_param.bytes_per_line*rows) && 
285                 status == SANE_STATUS_GOOD)
286         {
287             status = sane_read (pSource->deviceHandle, ptr, 
288                     (pSource->sane_param.bytes_per_line*rows) - consumed_len ,
289                     &buff_len);
290             consumed_len += buff_len;
291             ptr += buff_len;
292         }
293
294         if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
295         {
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;
303
304             ScanningDialogBox(pSource->progressWnd, consumed_len);
305
306             if (status == SANE_STATUS_EOF)
307             {
308                 ScanningDialogBox(pSource->progressWnd, -1);
309                 TRACE("sane_read: %s\n", sane_strstatus (status));
310                 sane_cancel (pSource->deviceHandle);
311                 twRC = TWRC_XFERDONE;
312             }
313             pSource->twCC = TWRC_SUCCESS;
314         }
315         else if (status != SANE_STATUS_EOF)
316         {
317             ScanningDialogBox(pSource->progressWnd, -1);
318             WARN("sane_read: %s\n", sane_strstatus (status));
319             sane_cancel (pSource->deviceHandle);
320             pSource->twCC = TWCC_OPERATIONERROR;
321             twRC = TWRC_FAILURE;
322         }
323     }
324
325     if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
326         LocalUnlock(pImageMemXfer->Memory.TheMem);
327     
328     return twRC;
329 #endif
330 }
331
332 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
333 TW_UINT16 TWAIN_ImageNativeXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
334                                     TW_MEMREF pData)
335 {
336 #ifndef HAVE_SANE
337     return TWRC_FAILURE;
338 #else
339     TW_UINT16 twRC = TWRC_SUCCESS;
340     pTW_UINT32 pHandle = (pTW_UINT32) pData;
341     activeDS *pSource = TWAIN_LookupSource (pDest);
342     SANE_Status status;
343     SANE_Byte buffer[32*1024];
344     int buff_len;
345     HBITMAP hDIB;
346     BITMAPINFO bmpInfo;
347     VOID *pBits;
348     HDC dc;
349
350     TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
351
352     if (!pSource)
353     {
354         twRC = TWRC_FAILURE;
355         DSM_twCC = TWCC_NODS;
356     }
357     else if (pSource->currentState != 6)
358     {
359         twRC = TWRC_FAILURE;
360         pSource->twCC = TWCC_SEQERROR;
361     }
362     else
363     {
364         /* Transfer an image from the source to the application */
365         status = sane_start (pSource->deviceHandle);
366         if (status != SANE_STATUS_GOOD)
367         {
368             WARN("sane_start: %s\n", sane_strstatus (status));
369             sane_cancel (pSource->deviceHandle);
370             pSource->twCC = TWCC_OPERATIONERROR;
371             return TWRC_FAILURE;
372         }
373
374         status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
375         pSource->sane_param_valid = TRUE;
376         if (status != SANE_STATUS_GOOD)
377         {
378             WARN("sane_get_parameters: %s\n", sane_strstatus (status));
379             sane_cancel (pSource->deviceHandle);
380             pSource->twCC = TWCC_OPERATIONERROR;
381             return TWRC_FAILURE;
382         }
383
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);
388
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);
406         if (!hDIB)
407         {
408             sane_cancel (pSource->deviceHandle);
409             pSource->twCC = TWCC_LOWMEMORY;
410             return TWRC_FAILURE;
411         }
412
413         do
414         {
415             status = sane_read (pSource->deviceHandle, buffer,
416                                 sizeof (buffer),  &buff_len);
417             if (status == SANE_STATUS_GOOD)
418             {
419                 /* FIXME: put code for converting the image data into DIB here */
420
421             }
422             else if (status != SANE_STATUS_EOF)
423             {
424                 WARN("sane_read: %s\n", sane_strstatus (status));
425                 sane_cancel (pSource->deviceHandle);
426                 pSource->twCC = TWCC_OPERATIONERROR;
427                 return TWRC_FAILURE;
428             }
429         } while (status == SANE_STATUS_GOOD);
430
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;
437     }
438     return twRC;
439 #endif
440 }
441
442 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
443 TW_UINT16 TWAIN_JPEGCompressionGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
444                                     TW_MEMREF pData)
445 {
446     FIXME ("stub!\n");
447
448     return TWRC_FAILURE;
449 }
450
451 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
452 TW_UINT16 TWAIN_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
453                                            pTW_IDENTITY pDest,
454                                            TW_MEMREF pData)
455 {
456     FIXME ("stub!\n");
457
458     return TWRC_FAILURE;
459 }
460
461 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
462 TW_UINT16 TWAIN_JPEGCompressionReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
463                                       TW_MEMREF pData)
464 {
465     FIXME ("stub!\n");
466
467     return TWRC_FAILURE;
468 }
469
470 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
471 TW_UINT16 TWAIN_JPEGCompressionSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
472                                     TW_MEMREF pData)
473 {
474     FIXME ("stub!\n");
475
476     return TWRC_FAILURE;
477 }
478
479 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
480 TW_UINT16 TWAIN_Palette8Get (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
481                              TW_MEMREF pData)
482 {
483     FIXME ("stub!\n");
484
485     return TWRC_FAILURE;
486 }
487
488 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
489 TW_UINT16 TWAIN_Palette8GetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
490                                     TW_MEMREF pData)
491 {
492     FIXME ("stub!\n");
493
494     return TWRC_FAILURE;
495 }
496
497 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
498 TW_UINT16 TWAIN_Palette8Reset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
499                                TW_MEMREF pData)
500 {
501     FIXME ("stub!\n");
502
503     return TWRC_FAILURE;
504 }
505
506 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
507 TW_UINT16 TWAIN_Palette8Set (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
508                              TW_MEMREF pData)
509 {
510     FIXME ("stub!\n");
511
512     return TWRC_FAILURE;
513 }
514
515 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
516 TW_UINT16 TWAIN_RGBResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
517                                   TW_MEMREF pData)
518 {
519     FIXME ("stub!\n");
520
521     return TWRC_FAILURE;
522 }
523
524 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
525 TW_UINT16 TWAIN_RGBResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
526                                 TW_MEMREF pData)
527 {
528     FIXME ("stub!\n");
529
530     return TWRC_FAILURE;
531 }