~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/sane.ds/ds_image.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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_IMAGEINFO/MSG_GET */
 35 TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, 
 36                               TW_MEMREF pData)
 37 {
 38 #ifndef SONAME_LIBSANE
 39     return TWRC_FAILURE;
 40 #else
 41     TW_UINT16 twRC = TWRC_SUCCESS;
 42     pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
 43     SANE_Status status;
 44     SANE_Int resolution;
 45 
 46     TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
 47 
 48     if (activeDS.currentState != 6 && activeDS.currentState != 7)
 49     {
 50         twRC = TWRC_FAILURE;
 51         activeDS.twCC = TWCC_SEQERROR;
 52     }
 53     else
 54     {
 55         if (activeDS.currentState == 6)
 56         {
 57             /* return general image description information about the image about to be transferred */
 58             status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
 59             TRACE("Getting parameters\n");
 60             if (status != SANE_STATUS_GOOD)
 61             {
 62                 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
 63                 psane_cancel (activeDS.deviceHandle);
 64                 activeDS.sane_started = FALSE;
 65                 activeDS.twCC = TWCC_OPERATIONERROR;
 66                 return TWRC_FAILURE;
 67             }
 68             activeDS.sane_param_valid = TRUE;
 69         }
 70 
 71         if (sane_option_get_int(activeDS.deviceHandle, "resolution", &resolution) == SANE_STATUS_GOOD)
 72             pImageInfo->XResolution.Whole = pImageInfo->YResolution.Whole = resolution;
 73         else
 74             pImageInfo->XResolution.Whole = pImageInfo->YResolution.Whole = -1;
 75         pImageInfo->XResolution.Frac = 0;
 76         pImageInfo->YResolution.Frac = 0;
 77         pImageInfo->ImageWidth = activeDS.sane_param.pixels_per_line;
 78         pImageInfo->ImageLength = activeDS.sane_param.lines;
 79 
 80         TRACE("Bits per Sample %i\n",activeDS.sane_param.depth);
 81         TRACE("Frame Format %i\n",activeDS.sane_param.format);
 82 
 83         if (activeDS.sane_param.format == SANE_FRAME_RGB )
 84         {
 85             pImageInfo->BitsPerPixel = activeDS.sane_param.depth * 3;
 86             pImageInfo->Compression = TWCP_NONE;
 87             pImageInfo->Planar = TRUE;
 88             pImageInfo->SamplesPerPixel = 3;
 89             pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
 90             pImageInfo->BitsPerSample[1] = activeDS.sane_param.depth;
 91             pImageInfo->BitsPerSample[2] = activeDS.sane_param.depth;
 92             pImageInfo->PixelType = TWPT_RGB;
 93         }
 94         else if (activeDS.sane_param.format == SANE_FRAME_GRAY)
 95         {
 96             pImageInfo->BitsPerPixel = activeDS.sane_param.depth;
 97             pImageInfo->Compression = TWCP_NONE;
 98             pImageInfo->Planar = TRUE;
 99             pImageInfo->SamplesPerPixel = 1;
100             pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
101             if (activeDS.sane_param.depth == 1)
102                 pImageInfo->PixelType = TWPT_BW;
103             else
104                 pImageInfo->PixelType = TWPT_GRAY;
105         }
106         else
107         {
108             ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
109             twRC = TWRC_FAILURE;
110             activeDS.twCC = TWCC_SEQERROR;
111         }
112     }
113 
114     return twRC;
115 #endif
116 }
117 
118 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
119 TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin,
120                                 TW_MEMREF pData)
121 {
122 #ifndef SONAME_LIBSANE
123     return TWRC_FAILURE;
124 #else
125     TW_IMAGELAYOUT *img = (TW_IMAGELAYOUT *) pData;
126     SANE_Fixed tlx_current;
127     SANE_Fixed tly_current;
128     SANE_Fixed brx_current;
129     SANE_Fixed bry_current;
130     SANE_Status status;
131 
132     TRACE("DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET\n");
133 
134     status = sane_option_probe_scan_area(activeDS.deviceHandle, "tl-x", &tlx_current, NULL, NULL, NULL, NULL);
135     if (status == SANE_STATUS_GOOD)
136         status = sane_option_probe_scan_area(activeDS.deviceHandle, "tl-y", &tly_current, NULL, NULL, NULL, NULL);
137 
138     if (status == SANE_STATUS_GOOD)
139         status = sane_option_probe_scan_area(activeDS.deviceHandle, "br-x", &brx_current, NULL, NULL, NULL, NULL);
140 
141     if (status == SANE_STATUS_GOOD)
142         status = sane_option_probe_scan_area(activeDS.deviceHandle, "br-y", &bry_current, NULL, NULL, NULL, NULL);
143 
144     if (status != SANE_STATUS_GOOD)
145     {
146         activeDS.twCC = sane_status_to_twcc(status);
147         return TWRC_FAILURE;
148     }
149 
150     convert_sane_res_to_twain(SANE_UNFIX(tlx_current), SANE_UNIT_MM, &img->Frame.Left, TWUN_INCHES);
151     convert_sane_res_to_twain(SANE_UNFIX(tly_current), SANE_UNIT_MM, &img->Frame.Top, TWUN_INCHES);
152     convert_sane_res_to_twain(SANE_UNFIX(brx_current), SANE_UNIT_MM, &img->Frame.Right, TWUN_INCHES);
153     convert_sane_res_to_twain(SANE_UNFIX(bry_current), SANE_UNIT_MM, &img->Frame.Bottom, TWUN_INCHES);
154 
155     img->DocumentNumber = 1;
156     img->PageNumber = 1;
157     img->FrameNumber = 1;
158 
159     activeDS.twCC = TWCC_SUCCESS;
160     return TWRC_SUCCESS;
161 #endif
162 }
163 
164 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
165 TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, 
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 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin, 
175                                   TW_MEMREF pData)
176 {
177     FIXME ("stub!\n");
178 
179     return TWRC_FAILURE;
180 }
181 
182 #ifdef SONAME_LIBSANE
183 static TW_UINT16 set_one_imagecoord(const char *option_name, TW_FIX32 val, BOOL *changed)
184 {
185     double d = val.Whole + ((double) val.Frac / 65536.0);
186     int set_status = 0;
187     SANE_Status status;
188     status = sane_option_set_fixed(activeDS.deviceHandle, option_name,
189              SANE_FIX((d * 254) / 10), &set_status);
190     if (status != SANE_STATUS_GOOD)
191     {
192         activeDS.twCC = sane_status_to_twcc(status);
193         return TWRC_FAILURE;
194     }
195     if (set_status & SANE_INFO_INEXACT)
196         *changed = TRUE;
197     return TWRC_SUCCESS;
198 }
199 #endif
200 
201 /* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
202 TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin,
203                                 TW_MEMREF pData)
204 {
205 #ifndef SONAME_LIBSANE
206     return TWRC_FAILURE;
207 #else
208     TW_IMAGELAYOUT *img = (TW_IMAGELAYOUT *) pData;
209     BOOL changed = FALSE;
210     TW_UINT16 twrc;
211 
212     TRACE("DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET\n");
213     TRACE("Frame: [Left %x.%x|Top %x.%x|Right %x.%x|Bottom %x.%x]\n",
214             img->Frame.Left.Whole, img->Frame.Left.Frac,
215             img->Frame.Top.Whole, img->Frame.Top.Frac,
216             img->Frame.Right.Whole, img->Frame.Right.Frac,
217             img->Frame.Bottom.Whole, img->Frame.Bottom.Frac);
218 
219     twrc = set_one_imagecoord("tl-x", img->Frame.Left, &changed);
220     if (twrc != TWRC_SUCCESS)
221         return (twrc);
222 
223     twrc = set_one_imagecoord("tl-y", img->Frame.Top, &changed);
224     if (twrc != TWRC_SUCCESS)
225         return (twrc);
226 
227     twrc = set_one_imagecoord("br-x", img->Frame.Right, &changed);
228     if (twrc != TWRC_SUCCESS)
229         return (twrc);
230 
231     twrc = set_one_imagecoord("br-y", img->Frame.Bottom, &changed);
232     if (twrc != TWRC_SUCCESS)
233         return (twrc);
234 
235     activeDS.twCC = TWCC_SUCCESS;
236     return changed ? TWRC_CHECKSTATUS : TWRC_SUCCESS;
237 #endif
238 }
239 
240 /* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
241 TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, 
242                                  TW_MEMREF pData)
243 {
244 #ifndef SONAME_LIBSANE
245     return TWRC_FAILURE;
246 #else
247     TW_UINT16 twRC = TWRC_SUCCESS;
248     pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
249     SANE_Status status = SANE_STATUS_GOOD;
250 
251     TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");
252 
253     if (activeDS.currentState < 6 || activeDS.currentState > 7)
254     {
255         twRC = TWRC_FAILURE;
256         activeDS.twCC = TWCC_SEQERROR;
257     }
258     else
259     {
260         LPBYTE buffer;
261         int buff_len = 0;
262         int consumed_len = 0;
263         LPBYTE ptr;
264         int rows;
265 
266         /* Transfer an image from the source to the application */
267         if (activeDS.currentState == 6)
268         {
269 
270             /* trigger scanning dialog */
271             activeDS.progressWnd = ScanningDialogBox(NULL,0);
272 
273             ScanningDialogBox(activeDS.progressWnd,0);
274 
275             if (! activeDS.sane_started)
276             {
277                 status = psane_start (activeDS.deviceHandle);
278                 if (status != SANE_STATUS_GOOD)
279                 {
280                     WARN("psane_start: %s\n", psane_strstatus (status));
281                     psane_cancel (activeDS.deviceHandle);
282                     activeDS.twCC = TWCC_OPERATIONERROR;
283                     return TWRC_FAILURE;
284                 }
285                 activeDS.sane_started = TRUE;
286             }
287 
288             status = psane_get_parameters (activeDS.deviceHandle,
289                     &activeDS.sane_param);
290             activeDS.sane_param_valid = TRUE;
291 
292             if (status != SANE_STATUS_GOOD)
293             {
294                 WARN("psane_get_parameters: %s\n", psane_strstatus (status));
295                 psane_cancel (activeDS.deviceHandle);
296                 activeDS.sane_started = FALSE;
297                 activeDS.twCC = TWCC_OPERATIONERROR;
298                 return TWRC_FAILURE;
299             }
300 
301             TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
302               , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
303               activeDS.sane_param.depth, activeDS.sane_param.format,
304               activeDS.sane_param.last_frame);
305 
306             activeDS.currentState = 7;
307         }
308 
309         /* access memory buffer */
310         if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
311         {
312             psane_cancel (activeDS.deviceHandle);
313             activeDS.sane_started = FALSE;
314             activeDS.twCC = TWCC_BADVALUE;
315             return TWRC_FAILURE;
316         }
317 
318         if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
319         {
320             FIXME("Memory Handle, may not be locked correctly\n");
321             buffer = LocalLock(pImageMemXfer->Memory.TheMem);
322         }
323         else
324             buffer = pImageMemXfer->Memory.TheMem;
325        
326         memset(buffer,0,pImageMemXfer->Memory.Length);
327 
328         ptr = buffer;
329         consumed_len = 0;
330         rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line;
331 
332         /* must fill full lines */
333         while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) && 
334                 status == SANE_STATUS_GOOD)
335         {
336             status = psane_read (activeDS.deviceHandle, ptr,
337                     (activeDS.sane_param.bytes_per_line*rows) - consumed_len ,
338                     &buff_len);
339             consumed_len += buff_len;
340             ptr += buff_len;
341         }
342 
343         if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
344         {
345             pImageMemXfer->Compression = TWCP_NONE;
346             pImageMemXfer->BytesPerRow = activeDS.sane_param.bytes_per_line;
347             pImageMemXfer->Columns = activeDS.sane_param.pixels_per_line;
348             pImageMemXfer->Rows = rows;
349             pImageMemXfer->XOffset = 0;
350             pImageMemXfer->YOffset = 0;
351             pImageMemXfer->BytesWritten = consumed_len;
352 
353             ScanningDialogBox(activeDS.progressWnd, consumed_len);
354 
355             if (status == SANE_STATUS_EOF)
356             {
357                 ScanningDialogBox(activeDS.progressWnd, -1);
358                 TRACE("psane_read: %s\n", psane_strstatus (status));
359                 psane_cancel (activeDS.deviceHandle);
360                 activeDS.sane_started = FALSE;
361                 twRC = TWRC_XFERDONE;
362             }
363             activeDS.twCC = TWRC_SUCCESS;
364         }
365         else if (status != SANE_STATUS_EOF)
366         {
367             ScanningDialogBox(activeDS.progressWnd, -1);
368             WARN("psane_read: %s\n", psane_strstatus (status));
369             psane_cancel (activeDS.deviceHandle);
370             activeDS.sane_started = FALSE;
371             activeDS.twCC = TWCC_OPERATIONERROR;
372             twRC = TWRC_FAILURE;
373         }
374     }
375 
376     if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
377         LocalUnlock(pImageMemXfer->Memory.TheMem);
378     
379     return twRC;
380 #endif
381 }
382 
383 #ifdef SONAME_LIBSANE
384 static SANE_Status read_one_line(SANE_Handle h, BYTE *line, int len)
385 {
386     int read_len;
387     SANE_Status status;
388 
389     for (;;)
390     {
391         read_len = 0;
392         status = psane_read (activeDS.deviceHandle, line, len, &read_len);
393         if (status != SANE_STATUS_GOOD)
394             break;
395 
396         if (read_len == len)
397             break;
398 
399         line += read_len;
400         len -= read_len;
401     }
402 
403     return status;
404 }
405 #endif
406 
407 /* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
408 TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, 
409                                     TW_MEMREF pData)
410 {
411 #ifndef SONAME_LIBSANE
412     return TWRC_FAILURE;
413 #else
414     TW_UINT16 twRC = TWRC_SUCCESS;
415     pTW_UINT32 pHandle = (pTW_UINT32) pData;
416     SANE_Status status;
417     HANDLE hDIB;
418     BITMAPINFOHEADER *header = NULL;
419     int dib_bytes;
420     int dib_bytes_per_line;
421     BYTE *line;
422     RGBQUAD *colors;
423     int color_size = 0;
424     int i;
425     BYTE *p;
426 
427     TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");
428 
429     if (activeDS.currentState != 6)
430     {
431         twRC = TWRC_FAILURE;
432         activeDS.twCC = TWCC_SEQERROR;
433     }
434     else
435     {
436         /* Transfer an image from the source to the application */
437         if (! activeDS.sane_started)
438         {
439             status = psane_start (activeDS.deviceHandle);
440             if (status != SANE_STATUS_GOOD)
441             {
442                 WARN("psane_start: %s\n", psane_strstatus (status));
443                 psane_cancel (activeDS.deviceHandle);
444                 activeDS.twCC = TWCC_OPERATIONERROR;
445                 return TWRC_FAILURE;
446             }
447             activeDS.sane_started = TRUE;
448         }
449 
450         status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
451         activeDS.sane_param_valid = TRUE;
452         if (status != SANE_STATUS_GOOD)
453         {
454             WARN("psane_get_parameters: %s\n", psane_strstatus (status));
455             psane_cancel (activeDS.deviceHandle);
456             activeDS.sane_started = FALSE;
457             activeDS.twCC = TWCC_OPERATIONERROR;
458             return TWRC_FAILURE;
459         }
460 
461         if (activeDS.sane_param.format == SANE_FRAME_GRAY)
462         {
463             if (activeDS.sane_param.depth == 8)
464                 color_size = (1 << 8) * sizeof(*colors);
465             else if (activeDS.sane_param.depth == 1)
466                 ;
467             else
468             {
469                 FIXME("For NATIVE, we support only 1 bit monochrome and 8 bit Grayscale, not %d\n", activeDS.sane_param.depth);
470                 psane_cancel (activeDS.deviceHandle);
471                 activeDS.sane_started = FALSE;
472                 activeDS.twCC = TWCC_OPERATIONERROR;
473                 return TWRC_FAILURE;
474             }
475         }
476         else if (activeDS.sane_param.format != SANE_FRAME_RGB)
477         {
478             FIXME("For NATIVE, we support only GRAY and RGB, not %d\n", activeDS.sane_param.format);
479             psane_cancel (activeDS.deviceHandle);
480             activeDS.sane_started = FALSE;
481             activeDS.twCC = TWCC_OPERATIONERROR;
482             return TWRC_FAILURE;
483         }
484 
485         TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d bpl=%d) from sane...\n"
486               , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
487               activeDS.sane_param.depth, activeDS.sane_param.format,
488               activeDS.sane_param.last_frame, activeDS.sane_param.bytes_per_line);
489 
490         dib_bytes_per_line = ((activeDS.sane_param.bytes_per_line + 3) / 4) * 4;
491         dib_bytes = activeDS.sane_param.lines * dib_bytes_per_line;
492 
493         hDIB = GlobalAlloc(GMEM_ZEROINIT, dib_bytes + sizeof(*header) + color_size);
494         if (hDIB)
495            header = GlobalLock(hDIB);
496 
497         if (!header)
498         {
499             psane_cancel (activeDS.deviceHandle);
500             activeDS.sane_started = FALSE;
501             activeDS.twCC = TWCC_LOWMEMORY;
502             if (hDIB)
503                 GlobalFree(hDIB);
504             return TWRC_FAILURE;
505         }
506 
507         header->biSize = sizeof (*header);
508         header->biWidth = activeDS.sane_param.pixels_per_line;
509         header->biHeight = activeDS.sane_param.lines;
510         header->biPlanes = 1;
511         header->biCompression = BI_RGB;
512         if (activeDS.sane_param.format == SANE_FRAME_RGB)
513             header->biBitCount = activeDS.sane_param.depth * 3;
514         if (activeDS.sane_param.format == SANE_FRAME_GRAY)
515             header->biBitCount = activeDS.sane_param.depth;
516         header->biSizeImage = dib_bytes;
517         header->biXPelsPerMeter = 0;
518         header->biYPelsPerMeter = 0;
519         header->biClrUsed = 0;
520         header->biClrImportant = 0;
521 
522         p = (BYTE *)(header + 1);
523 
524         if (color_size > 0)
525         {
526             colors = (RGBQUAD *) p;
527             p += color_size;
528             for (i = 0; i < (color_size / sizeof(*colors)); i++)
529                 colors[i].rgbBlue = colors[i].rgbRed = colors[i].rgbGreen = i;
530         }
531 
532 
533         /* Sane returns data in top down order.  Acrobat does best with
534            a bottom up DIB being returned.  */
535         line = p + (activeDS.sane_param.lines - 1) * dib_bytes_per_line;
536         for (i = activeDS.sane_param.lines - 1; i >= 0; i--)
537         {
538             activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd,
539                     ((activeDS.sane_param.lines - 1 - i) * 100)
540                             /
541                     (activeDS.sane_param.lines - 1));
542 
543             status = read_one_line(activeDS.deviceHandle, line,
544                             activeDS.sane_param.bytes_per_line);
545             if (status != SANE_STATUS_GOOD)
546                 break;
547 
548             line -= dib_bytes_per_line;
549         }
550         activeDS.progressWnd = ScanningDialogBox(activeDS.progressWnd, -1);
551 
552         GlobalUnlock(hDIB);
553 
554         if (status != SANE_STATUS_GOOD && status != SANE_STATUS_EOF)
555         {
556             WARN("psane_read: %s, reading line %d\n", psane_strstatus(status), i);
557             psane_cancel (activeDS.deviceHandle);
558             activeDS.sane_started = FALSE;
559             activeDS.twCC = TWCC_OPERATIONERROR;
560             GlobalFree(hDIB);
561             return TWRC_FAILURE;
562         }
563 
564         psane_cancel (activeDS.deviceHandle);
565         activeDS.sane_started = FALSE;
566         *pHandle = (UINT_PTR)hDIB;
567         twRC = TWRC_XFERDONE;
568         activeDS.twCC = TWCC_SUCCESS;
569         activeDS.currentState = 7;
570     }
571     return twRC;
572 #endif
573 }
574 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.