protected void TransferPictures()
        {
            // see http://www.twain.org/wp-content/uploads/2017/03/TWAIN-2.4-Specification.pdf
            // page (3-20)

            if (DataSource.SourceId.Id == 0)
            {
                return;
            }

            PendingXfers pendingTransfer = new PendingXfers();
            TwainResult  result;

            try
            {
                do
                {
                    pendingTransfer.Count = 0;     // the Twain source will fill this in during DsPendingTransfer
                    IntPtr hbitmap = IntPtr.Zero;

                    // Get the image info
                    ImageInfo imageInfo = new ImageInfo();
                    result = Twain32Native.DsImageInfo(
                        ApplicationId,
                        DataSource.SourceId,
                        DataGroup.Image,
                        DataArgumentType.ImageInfo,
                        Message.Get,
                        imageInfo);

                    if (result != TwainResult.Success)
                    {
                        DataSource.Close();
                        break;
                    }
                    Bitmap bitmap;
                    try {
                        // Transfer the image from the device
                        result = Twain32Native.DsImageTransfer(
                            ApplicationId,
                            DataSource.SourceId,
                            DataGroup.Image,
                            DataArgumentType.ImageNativeXfer,
                            Message.Get,
                            ref hbitmap);

                        if (result != TwainResult.XferDone)
                        {
                            DataSource.Close();
                            break;
                        }
                        if (hbitmap == IntPtr.Zero)
                        {
                            throw new TwainException("Transfer complete, but bitmap pointer is still null.");
                        }

                        bitmap = BitmapRenderer.NewBitmapFromHBitmap(hbitmap);
                    } finally {
                        if (hbitmap != IntPtr.Zero)
                        {
                            Kernel32Native.GlobalFree(hbitmap);
                            hbitmap = IntPtr.Zero;
                        }
                    }

                    // End pending transfers
                    result = Twain32Native.DsPendingTransfer(
                        ApplicationId,
                        DataSource.SourceId,
                        DataGroup.Control,
                        DataArgumentType.PendingXfers,
                        Message.EndXfer,
                        pendingTransfer);

                    if (result != TwainResult.Success)
                    {
                        DataSource.Close();
                        break;
                    }

                    // fire the transfer event...
                    TransferImageEventArgs args = new TransferImageEventArgs(bitmap, pendingTransfer.Count != 0, 1.0f);
                    TransferImage(this, args);
                    if (!args.ContinueScanning)
                    {
                        break;
                    }
                }while (pendingTransfer.Count != 0);
            }
            finally
            {
                // Reset any pending transfers
                result = Twain32Native.DsPendingTransfer(
                    ApplicationId,
                    DataSource.SourceId,
                    DataGroup.Control,
                    DataArgumentType.PendingXfers,
                    Message.Reset,
                    pendingTransfer);
            }
        }