comctl32: A couple fixes for tab icon offsets.
[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 == 1 /*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
135         {
136             ERR("Unhandled source frame type\n");
137             twRC = TWRC_FAILURE;
138             pSource->twCC = TWCC_SEQERROR;
139         }
140     }
141
142     return twRC;
143 #endif
144 }
145
146 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
147 TW_UINT16 TWAIN_ImageLayoutGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
148                                 TW_MEMREF pData)
149 {
150     FIXME ("stub!\n");
151
152     return TWRC_FAILURE;
153 }
154
155 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
156 TW_UINT16 TWAIN_ImageLayoutGetDefault (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_RESET */
165 TW_UINT16 TWAIN_ImageLayoutReset (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_SET */
174 TW_UINT16 TWAIN_ImageLayoutSet (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_IMAGEMEMXFER/MSG_GET */
183 TW_UINT16 TWAIN_ImageMemXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
184                                  TW_MEMREF pData)
185 {
186 #ifndef HAVE_SANE
187     return TWRC_FAILURE;
188 #else
189     TW_UINT16 twRC = TWRC_SUCCESS;
190     pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
191     activeDS *pSource = TWAIN_LookupSource (pDest);
192     SANE_Status status = SANE_STATUS_GOOD;
193
194     TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
195
196     if (!pSource)
197     {
198         twRC = TWRC_FAILURE;
199         DSM_twCC = TWCC_NODS;
200     }
201     else if (pSource->currentState < 6 || pSource->currentState > 7)
202     {
203         twRC = TWRC_FAILURE;
204         pSource->twCC = TWCC_SEQERROR;
205     }
206     else
207     {
208         LPBYTE buffer;
209         int buff_len = 0;
210         int consumed_len = 0;
211         LPBYTE ptr;
212         int rows;
213
214         /* Transfer an image from the source to the application */
215         if (pSource->currentState == 6)
216         {
217             status = sane_start (pSource->deviceHandle);
218             if (status != SANE_STATUS_GOOD)
219             {
220                 WARN("sane_start: %s\n", sane_strstatus (status));
221                 sane_cancel (pSource->deviceHandle);
222                 pSource->twCC = TWCC_OPERATIONERROR;
223                 return TWRC_FAILURE;
224             }
225
226             status = sane_get_parameters (pSource->deviceHandle,
227                     &pSource->sane_param);
228             pSource->sane_param_valid = TRUE;
229
230             if (status != SANE_STATUS_GOOD)
231             {
232                 WARN("sane_get_parameters: %s\n", sane_strstatus (status));
233                 sane_cancel (pSource->deviceHandle);
234                 pSource->twCC = TWCC_OPERATIONERROR;
235                 return TWRC_FAILURE;
236             }
237
238             TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
239               , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
240               pSource->sane_param.depth, pSource->sane_param.format,
241               pSource->sane_param.last_frame);
242
243             pSource->currentState = 7;
244         }
245
246         /* access memory buffer */
247         if (pImageMemXfer->Memory.Length < pSource->sane_param.bytes_per_line)
248         {
249             sane_cancel (pSource->deviceHandle);
250             pSource->twCC = TWCC_BADVALUE;
251             return TWRC_FAILURE;
252         }
253
254         if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
255         {
256             FIXME("Memory Handle, may not be locked correctly\n");
257             buffer = LocalLock(pImageMemXfer->Memory.TheMem);
258         }
259         else
260             buffer = pImageMemXfer->Memory.TheMem;
261        
262         memset(buffer,0,pImageMemXfer->Memory.Length);
263
264         ptr = buffer;
265         consumed_len = 0;
266         rows = pImageMemXfer->Memory.Length / pSource->sane_param.bytes_per_line;
267
268         /* must fill full lines */
269         while (consumed_len < (pSource->sane_param.bytes_per_line*rows) && 
270                 status == SANE_STATUS_GOOD)
271         {
272             status = sane_read (pSource->deviceHandle, ptr, 
273                     (pSource->sane_param.bytes_per_line*rows) - consumed_len ,
274                     &buff_len);
275             consumed_len += buff_len;
276             ptr += buff_len;
277         }
278
279         if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
280         {
281             pImageMemXfer->Compression = TWCP_NONE;
282             pImageMemXfer->BytesPerRow = pSource->sane_param.bytes_per_line;
283             pImageMemXfer->Columns = pSource->sane_param.pixels_per_line;
284             pImageMemXfer->Rows = rows;
285             pImageMemXfer->XOffset = 0;
286             pImageMemXfer->YOffset = 0;
287             pImageMemXfer->BytesWritten = consumed_len;
288
289             if (status == SANE_STATUS_EOF)
290             {
291                 TRACE("sane_read: %s\n", sane_strstatus (status));
292                 sane_cancel (pSource->deviceHandle);
293                 twRC = TWRC_XFERDONE;
294             }
295             pSource->twCC = TWRC_SUCCESS;
296         }
297         else if (status != SANE_STATUS_EOF)
298         {
299             WARN("sane_read: %s\n", sane_strstatus (status));
300             sane_cancel (pSource->deviceHandle);
301             pSource->twCC = TWCC_OPERATIONERROR;
302             twRC = TWRC_FAILURE;
303         }
304     }
305
306     if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
307         LocalUnlock(pImageMemXfer->Memory.TheMem);
308     
309     return twRC;
310 #endif
311 }
312
313 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
314 TW_UINT16 TWAIN_ImageNativeXferGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
315                                     TW_MEMREF pData)
316 {
317 #ifndef HAVE_SANE
318     return TWRC_FAILURE;
319 #else
320     TW_UINT16 twRC = TWRC_SUCCESS;
321     pTW_UINT32 pHandle = (pTW_UINT32) pData;
322     activeDS *pSource = TWAIN_LookupSource (pDest);
323     SANE_Status status;
324     SANE_Byte buffer[32*1024];
325     int buff_len;
326     HBITMAP hDIB;
327     BITMAPINFO bmpInfo;
328     VOID *pBits;
329     HDC dc;
330
331     TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
332
333     if (!pSource)
334     {
335         twRC = TWRC_FAILURE;
336         DSM_twCC = TWCC_NODS;
337     }
338     else if (pSource->currentState != 6)
339     {
340         twRC = TWRC_FAILURE;
341         pSource->twCC = TWCC_SEQERROR;
342     }
343     else
344     {
345         /* Transfer an image from the source to the application */
346         status = sane_start (pSource->deviceHandle);
347         if (status != SANE_STATUS_GOOD)
348         {
349             WARN("sane_start: %s\n", sane_strstatus (status));
350             sane_cancel (pSource->deviceHandle);
351             pSource->twCC = TWCC_OPERATIONERROR;
352             return TWRC_FAILURE;
353         }
354
355         status = sane_get_parameters (pSource->deviceHandle, &pSource->sane_param);
356         pSource->sane_param_valid = TRUE;
357         if (status != SANE_STATUS_GOOD)
358         {
359             WARN("sane_get_parameters: %s\n", sane_strstatus (status));
360             sane_cancel (pSource->deviceHandle);
361             pSource->twCC = TWCC_OPERATIONERROR;
362             return TWRC_FAILURE;
363         }
364
365         TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
366               , pSource->sane_param.pixels_per_line, pSource->sane_param.lines,
367               pSource->sane_param.depth, pSource->sane_param.format,
368               pSource->sane_param.last_frame);
369
370         ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
371         bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
372         bmpInfo.bmiHeader.biWidth = pSource->sane_param.pixels_per_line;
373         bmpInfo.bmiHeader.biHeight = pSource->sane_param.lines;
374         bmpInfo.bmiHeader.biPlanes = 1;
375         bmpInfo.bmiHeader.biBitCount = pSource->sane_param.depth;
376         bmpInfo.bmiHeader.biCompression = BI_RGB;
377         bmpInfo.bmiHeader.biSizeImage = 0;
378         bmpInfo.bmiHeader.biXPelsPerMeter = 0;
379         bmpInfo.bmiHeader.biYPelsPerMeter = 0;
380         bmpInfo.bmiHeader.biClrUsed = 1;
381         bmpInfo.bmiHeader.biClrImportant = 0;
382         bmpInfo.bmiColors[0].rgbBlue = 128;
383         bmpInfo.bmiColors[0].rgbGreen = 128;
384         bmpInfo.bmiColors[0].rgbRed = 128;
385         hDIB = CreateDIBSection ((dc = GetDC(pSource->hwndOwner)), &bmpInfo,
386                                  DIB_RGB_COLORS, &pBits, 0, 0);
387         if (!hDIB)
388         {
389             sane_cancel (pSource->deviceHandle);
390             pSource->twCC = TWCC_LOWMEMORY;
391             return TWRC_FAILURE;
392         }
393
394         do
395         {
396             status = sane_read (pSource->deviceHandle, buffer,
397                                 sizeof (buffer),  &buff_len);
398             if (status == SANE_STATUS_GOOD)
399             {
400                 /* FIXME: put code for converting the image data into DIB here */
401
402             }
403             else if (status != SANE_STATUS_EOF)
404             {
405                 WARN("sane_read: %s\n", sane_strstatus (status));
406                 sane_cancel (pSource->deviceHandle);
407                 pSource->twCC = TWCC_OPERATIONERROR;
408                 return TWRC_FAILURE;
409             }
410         } while (status == SANE_STATUS_GOOD);
411
412         sane_cancel (pSource->deviceHandle);
413         ReleaseDC (pSource->hwndOwner, dc);
414         *pHandle = (TW_UINT32)hDIB;
415         twRC = TWRC_XFERDONE;
416         pSource->twCC = TWCC_SUCCESS;
417         pSource->currentState = 7;
418     }
419     return twRC;
420 #endif
421 }
422
423 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
424 TW_UINT16 TWAIN_JPEGCompressionGet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
425                                     TW_MEMREF pData)
426 {
427     FIXME ("stub!\n");
428
429     return TWRC_FAILURE;
430 }
431
432 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
433 TW_UINT16 TWAIN_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
434                                            pTW_IDENTITY pDest,
435                                            TW_MEMREF pData)
436 {
437     FIXME ("stub!\n");
438
439     return TWRC_FAILURE;
440 }
441
442 /* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
443 TW_UINT16 TWAIN_JPEGCompressionReset (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_SET */
452 TW_UINT16 TWAIN_JPEGCompressionSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
453                                     TW_MEMREF pData)
454 {
455     FIXME ("stub!\n");
456
457     return TWRC_FAILURE;
458 }
459
460 /* DG_IMAGE/DAT_PALETTE8/MSG_GET */
461 TW_UINT16 TWAIN_Palette8Get (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
462                              TW_MEMREF pData)
463 {
464     FIXME ("stub!\n");
465
466     return TWRC_FAILURE;
467 }
468
469 /* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
470 TW_UINT16 TWAIN_Palette8GetDefault (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
471                                     TW_MEMREF pData)
472 {
473     FIXME ("stub!\n");
474
475     return TWRC_FAILURE;
476 }
477
478 /* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
479 TW_UINT16 TWAIN_Palette8Reset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
480                                TW_MEMREF pData)
481 {
482     FIXME ("stub!\n");
483
484     return TWRC_FAILURE;
485 }
486
487 /* DG_IMAGE/DAT_PALETTE8/MSG_SET */
488 TW_UINT16 TWAIN_Palette8Set (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
489                              TW_MEMREF pData)
490 {
491     FIXME ("stub!\n");
492
493     return TWRC_FAILURE;
494 }
495
496 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
497 TW_UINT16 TWAIN_RGBResponseReset (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
498                                   TW_MEMREF pData)
499 {
500     FIXME ("stub!\n");
501
502     return TWRC_FAILURE;
503 }
504
505 /* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
506 TW_UINT16 TWAIN_RGBResponseSet (pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
507                                 TW_MEMREF pData)
508 {
509     FIXME ("stub!\n");
510
511     return TWRC_FAILURE;
512 }