ds_image.c 15.2 KB
Newer Older
1 2
/*
 * Copyright 2000 Corel Corporation
3
 * Copyright 2006 CodeWeavers, Aric Stewart
4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 21
 */

#include "config.h"

22 23 24
#include <stdarg.h>

#include "windef.h"
25 26 27 28
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "twain.h"
29
#include "sane_i.h"
30 31 32 33 34
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(twain);

/* DG_IMAGE/DAT_CIECOLOR/MSG_GET */
35
TW_UINT16 SANE_CIEColorGet (pTW_IDENTITY pOrigin, 
36 37 38 39 40 41 42 43
                             TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_EXTIMAGEINFO/MSG_GET */
44
TW_UINT16 SANE_ExtImageInfoGet (pTW_IDENTITY pOrigin, 
45 46 47 48 49 50 51 52
                                 TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_RESET */
53
TW_UINT16 SANE_GrayResponseReset (pTW_IDENTITY pOrigin, 
54 55 56 57 58 59 60 61
                                   TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_GRAYRESPONSE/MSG_SET */
62
TW_UINT16 SANE_GrayResponseSet (pTW_IDENTITY pOrigin, 
63 64 65 66 67 68 69 70
                                 TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGEFILEXFER/MSG_GET */
71
TW_UINT16 SANE_ImageFileXferGet (pTW_IDENTITY pOrigin, 
72 73 74 75 76 77 78 79
                                  TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGEINFO/MSG_GET */
80
TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin, 
81 82 83 84 85 86 87 88 89 90 91
                              TW_MEMREF pData)
{
#ifndef HAVE_SANE
    return TWRC_FAILURE;
#else
    TW_UINT16 twRC = TWRC_SUCCESS;
    pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
    SANE_Status status;

    TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");

92
    if (activeDS.currentState != 6 && activeDS.currentState != 7)
93 94
    {
        twRC = TWRC_FAILURE;
95
        activeDS.twCC = TWCC_SEQERROR;
96 97 98
    }
    else
    {
99
        if (activeDS.currentState == 6)
100
        {
101
            /* return general image description information about the image about to be transferred */
102 103
            status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
            activeDS.sane_param_valid = TRUE;
104
            TRACE("Getting parameters\n");
105 106 107 108 109 110
        }

        pImageInfo->XResolution.Whole = -1;
        pImageInfo->XResolution.Frac = 0;
        pImageInfo->YResolution.Whole = -1;
        pImageInfo->YResolution.Frac = 0;
111 112
        pImageInfo->ImageWidth = activeDS.sane_param.pixels_per_line;
        pImageInfo->ImageLength = activeDS.sane_param.lines;
113

114 115
        TRACE("Bits per Sample %i\n",activeDS.sane_param.depth);
        TRACE("Frame Format %i\n",activeDS.sane_param.format);
116

117
        if (activeDS.sane_param.format == SANE_FRAME_RGB )
118
        {
119
            pImageInfo->BitsPerPixel = activeDS.sane_param.depth * 3;
120
            pImageInfo->Compression = TWCP_NONE;
121
            pImageInfo->Planar = TRUE;
122
            pImageInfo->SamplesPerPixel = 3;
123 124 125
            pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
            pImageInfo->BitsPerSample[1] = activeDS.sane_param.depth;
            pImageInfo->BitsPerSample[2] = activeDS.sane_param.depth;
126
            pImageInfo->PixelType = TWPT_RGB;
127
        }
128
        else if (activeDS.sane_param.format == SANE_FRAME_GRAY)
129
        {
130
            pImageInfo->BitsPerPixel = activeDS.sane_param.depth;
131 132 133
            pImageInfo->Compression = TWCP_NONE;
            pImageInfo->Planar = TRUE;
            pImageInfo->SamplesPerPixel = 1;
134
            pImageInfo->BitsPerSample[0] = activeDS.sane_param.depth;
135 136
            pImageInfo->PixelType = TWPT_GRAY;
        }
137
        else
138
        {
139
            ERR("Unhandled source frame type %i\n",activeDS.sane_param.format);
140
            twRC = TWRC_FAILURE;
141
            activeDS.twCC = TWCC_SEQERROR;
142 143 144 145 146 147 148 149
        }
    }

    return twRC;
#endif
}

/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET */
150
TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin, 
151 152 153 154 155 156 157 158
                                TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_GETDEFAULT */
159
TW_UINT16 SANE_ImageLayoutGetDefault (pTW_IDENTITY pOrigin, 
160 161 162 163 164 165 166 167
                                       TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_RESET */
168
TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin, 
169 170 171 172 173 174 175 176
                                  TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGELAYOUT/MSG_SET */
177
TW_UINT16 SANE_ImageLayoutSet (pTW_IDENTITY pOrigin, 
178 179 180 181 182 183 184 185
                                TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET */
186
TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin, 
187 188
                                 TW_MEMREF pData)
{
189
#ifndef HAVE_SANE
190
    return TWRC_FAILURE;
191 192 193 194 195 196 197
#else
    TW_UINT16 twRC = TWRC_SUCCESS;
    pTW_IMAGEMEMXFER pImageMemXfer = (pTW_IMAGEMEMXFER) pData;
    SANE_Status status = SANE_STATUS_GOOD;

    TRACE ("DG_IMAGE/DAT_IMAGEMEMXFER/MSG_GET\n");

198
    if (activeDS.currentState < 6 || activeDS.currentState > 7)
199 200
    {
        twRC = TWRC_FAILURE;
201
        activeDS.twCC = TWCC_SEQERROR;
202 203 204 205 206 207 208 209 210 211
    }
    else
    {
        LPBYTE buffer;
        int buff_len = 0;
        int consumed_len = 0;
        LPBYTE ptr;
        int rows;

        /* Transfer an image from the source to the application */
212
        if (activeDS.currentState == 6)
213
        {
214 215

            /* trigger scanning dialog */
216
            activeDS.progressWnd = ScanningDialogBox(NULL,0);
217

218
            ScanningDialogBox(activeDS.progressWnd,0);
219

220
            status = sane_start (activeDS.deviceHandle);
221 222 223
            if (status != SANE_STATUS_GOOD)
            {
                WARN("sane_start: %s\n", sane_strstatus (status));
224 225
                sane_cancel (activeDS.deviceHandle);
                activeDS.twCC = TWCC_OPERATIONERROR;
226 227 228
                return TWRC_FAILURE;
            }

229 230 231
            status = sane_get_parameters (activeDS.deviceHandle,
                    &activeDS.sane_param);
            activeDS.sane_param_valid = TRUE;
232 233 234 235

            if (status != SANE_STATUS_GOOD)
            {
                WARN("sane_get_parameters: %s\n", sane_strstatus (status));
236 237
                sane_cancel (activeDS.deviceHandle);
                activeDS.twCC = TWCC_OPERATIONERROR;
238 239 240 241
                return TWRC_FAILURE;
            }

            TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
242 243 244
              , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
              activeDS.sane_param.depth, activeDS.sane_param.format,
              activeDS.sane_param.last_frame);
245

246
            activeDS.currentState = 7;
247 248 249
        }

        /* access memory buffer */
250
        if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
251
        {
252 253
            sane_cancel (activeDS.deviceHandle);
            activeDS.twCC = TWCC_BADVALUE;
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
            return TWRC_FAILURE;
        }

        if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
        {
            FIXME("Memory Handle, may not be locked correctly\n");
            buffer = LocalLock(pImageMemXfer->Memory.TheMem);
        }
        else
            buffer = pImageMemXfer->Memory.TheMem;
       
        memset(buffer,0,pImageMemXfer->Memory.Length);

        ptr = buffer;
        consumed_len = 0;
269
        rows = pImageMemXfer->Memory.Length / activeDS.sane_param.bytes_per_line;
270 271

        /* must fill full lines */
272
        while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) && 
273 274
                status == SANE_STATUS_GOOD)
        {
275 276
            status = sane_read (activeDS.deviceHandle, ptr, 
                    (activeDS.sane_param.bytes_per_line*rows) - consumed_len ,
277 278 279 280 281 282 283 284
                    &buff_len);
            consumed_len += buff_len;
            ptr += buff_len;
        }

        if (status == SANE_STATUS_GOOD || status == SANE_STATUS_EOF)
        {
            pImageMemXfer->Compression = TWCP_NONE;
285 286
            pImageMemXfer->BytesPerRow = activeDS.sane_param.bytes_per_line;
            pImageMemXfer->Columns = activeDS.sane_param.pixels_per_line;
287 288 289 290 291
            pImageMemXfer->Rows = rows;
            pImageMemXfer->XOffset = 0;
            pImageMemXfer->YOffset = 0;
            pImageMemXfer->BytesWritten = consumed_len;

292
            ScanningDialogBox(activeDS.progressWnd, consumed_len);
293

294 295
            if (status == SANE_STATUS_EOF)
            {
296
                ScanningDialogBox(activeDS.progressWnd, -1);
297
                TRACE("sane_read: %s\n", sane_strstatus (status));
298
                sane_cancel (activeDS.deviceHandle);
299 300
                twRC = TWRC_XFERDONE;
            }
301
            activeDS.twCC = TWRC_SUCCESS;
302 303 304
        }
        else if (status != SANE_STATUS_EOF)
        {
305
            ScanningDialogBox(activeDS.progressWnd, -1);
306
            WARN("sane_read: %s\n", sane_strstatus (status));
307 308
            sane_cancel (activeDS.deviceHandle);
            activeDS.twCC = TWCC_OPERATIONERROR;
309 310 311 312 313 314 315 316 317
            twRC = TWRC_FAILURE;
        }
    }

    if (pImageMemXfer->Memory.Flags & TWMF_HANDLE)
        LocalUnlock(pImageMemXfer->Memory.TheMem);
    
    return twRC;
#endif
318 319 320
}

/* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */
321
TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin, 
322 323 324 325 326 327 328 329 330 331 332 333 334 335
                                    TW_MEMREF pData)
{
#ifndef HAVE_SANE
    return TWRC_FAILURE;
#else
    TW_UINT16 twRC = TWRC_SUCCESS;
    pTW_UINT32 pHandle = (pTW_UINT32) pData;
    SANE_Status status;
    SANE_Byte buffer[32*1024];
    int buff_len;
    HBITMAP hDIB;
    BITMAPINFO bmpInfo;
    VOID *pBits;
    HDC dc;
336

337 338
    TRACE("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET\n");

339
    if (activeDS.currentState != 6)
340 341
    {
        twRC = TWRC_FAILURE;
342
        activeDS.twCC = TWCC_SEQERROR;
343 344 345 346
    }
    else
    {
        /* Transfer an image from the source to the application */
347
        status = sane_start (activeDS.deviceHandle);
348 349 350
        if (status != SANE_STATUS_GOOD)
        {
            WARN("sane_start: %s\n", sane_strstatus (status));
351 352
            sane_cancel (activeDS.deviceHandle);
            activeDS.twCC = TWCC_OPERATIONERROR;
353 354
            return TWRC_FAILURE;
        }
355

356 357
        status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
        activeDS.sane_param_valid = TRUE;
358 359 360
        if (status != SANE_STATUS_GOOD)
        {
            WARN("sane_get_parameters: %s\n", sane_strstatus (status));
361 362
            sane_cancel (activeDS.deviceHandle);
            activeDS.twCC = TWCC_OPERATIONERROR;
363 364 365 366
            return TWRC_FAILURE;
        }

        TRACE("Acquiring image %dx%dx%d bits (format=%d last=%d) from sane...\n"
367 368 369
              , activeDS.sane_param.pixels_per_line, activeDS.sane_param.lines,
              activeDS.sane_param.depth, activeDS.sane_param.format,
              activeDS.sane_param.last_frame);
370 371 372

        ZeroMemory (&bmpInfo, sizeof (BITMAPINFO));
        bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
373 374
        bmpInfo.bmiHeader.biWidth = activeDS.sane_param.pixels_per_line;
        bmpInfo.bmiHeader.biHeight = activeDS.sane_param.lines;
375
        bmpInfo.bmiHeader.biPlanes = 1;
376
        bmpInfo.bmiHeader.biBitCount = activeDS.sane_param.depth;
377 378 379 380 381 382 383 384 385
        bmpInfo.bmiHeader.biCompression = BI_RGB;
        bmpInfo.bmiHeader.biSizeImage = 0;
        bmpInfo.bmiHeader.biXPelsPerMeter = 0;
        bmpInfo.bmiHeader.biYPelsPerMeter = 0;
        bmpInfo.bmiHeader.biClrUsed = 1;
        bmpInfo.bmiHeader.biClrImportant = 0;
        bmpInfo.bmiColors[0].rgbBlue = 128;
        bmpInfo.bmiColors[0].rgbGreen = 128;
        bmpInfo.bmiColors[0].rgbRed = 128;
386
        hDIB = CreateDIBSection ((dc = GetDC(activeDS.hwndOwner)), &bmpInfo,
387 388 389
                                 DIB_RGB_COLORS, &pBits, 0, 0);
        if (!hDIB)
        {
390 391
            sane_cancel (activeDS.deviceHandle);
            activeDS.twCC = TWCC_LOWMEMORY;
392 393
            return TWRC_FAILURE;
        }
394

395 396
        do
        {
397
            status = sane_read (activeDS.deviceHandle, buffer,
398 399 400
                                sizeof (buffer),  &buff_len);
            if (status == SANE_STATUS_GOOD)
            {
401
                /* FIXME: put code for converting the image data into DIB here */
402 403 404 405 406

            }
            else if (status != SANE_STATUS_EOF)
            {
                WARN("sane_read: %s\n", sane_strstatus (status));
407 408
                sane_cancel (activeDS.deviceHandle);
                activeDS.twCC = TWCC_OPERATIONERROR;
409 410 411
                return TWRC_FAILURE;
            }
        } while (status == SANE_STATUS_GOOD);
412

413 414
        sane_cancel (activeDS.deviceHandle);
        ReleaseDC (activeDS.hwndOwner, dc);
Michael Stefaniuc's avatar
Michael Stefaniuc committed
415
        *pHandle = (TW_UINT32)hDIB;
416
        twRC = TWRC_XFERDONE;
417 418
        activeDS.twCC = TWCC_SUCCESS;
        activeDS.currentState = 7;
419 420 421 422 423 424
    }
    return twRC;
#endif
}

/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GET */
425
TW_UINT16 SANE_JPEGCompressionGet (pTW_IDENTITY pOrigin, 
426 427 428 429 430 431 432 433
                                    TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_GETDEFAULT */
434 435
TW_UINT16 SANE_JPEGCompressionGetDefault (pTW_IDENTITY pOrigin,
                                           
436 437 438 439 440 441 442 443
                                           TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_RESET */
444
TW_UINT16 SANE_JPEGCompressionReset (pTW_IDENTITY pOrigin, 
445 446 447 448 449 450 451 452
                                      TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_JPEGCOMPRESSION/MSG_SET */
453
TW_UINT16 SANE_JPEGCompressionSet (pTW_IDENTITY pOrigin, 
454 455 456 457 458 459 460 461
                                    TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_PALETTE8/MSG_GET */
462
TW_UINT16 SANE_Palette8Get (pTW_IDENTITY pOrigin, 
463 464 465 466 467 468 469 470
                             TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_PALETTE8/MSG_GETDEFAULT */
471
TW_UINT16 SANE_Palette8GetDefault (pTW_IDENTITY pOrigin, 
472 473 474 475 476 477 478 479
                                    TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_PALETTE8/MSG_RESET */
480
TW_UINT16 SANE_Palette8Reset (pTW_IDENTITY pOrigin, 
481 482 483 484 485 486 487 488
                               TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_PALETTE8/MSG_SET */
489
TW_UINT16 SANE_Palette8Set (pTW_IDENTITY pOrigin, 
490 491 492 493 494 495 496 497
                             TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_RGBRESPONSE/MSG_RESET */
498
TW_UINT16 SANE_RGBResponseReset (pTW_IDENTITY pOrigin, 
499 500 501 502 503 504 505 506
                                  TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}

/* DG_IMAGE/DAT_RGBRESPONSE/MSG_SET */
507
TW_UINT16 SANE_RGBResponseSet (pTW_IDENTITY pOrigin, 
508 509 510 511 512 513
                                TW_MEMREF pData)
{
    FIXME ("stub!\n");

    return TWRC_FAILURE;
}