View on GitHub

SARAFF SOFTWARE

All products / Saraff.Twain.DS / Contents

OnImageMemXfer

This operation is used to initiate the transfer of an image from the Source to the application via the Buffered Memory transfer mechanism.

This operation supports the transfer of successive blocks of image data (in strips or,optionally, tiles) from the Source into one or more main memory transfer buffers. These buffers (for strips) are allocated and owned by the application. For tiled transfers, the source allocates the buffers.

The application should repeatedly invoke this operation while TWRC_SUCCESS is returned by the Source.

Syntax

protected abstract ImageMemXfer OnImageMemXfer(long length, bool isMemFile)

Parameters

Return Value

Information about transmitting data.

Examples

public abstract class BitmapDataSource:ImageDataSource {
    private Bitmap _currentImage;
    private BitmapReader _bitmapReader;

    /// <summary>
    /// This operation is used to initiate the transfer of an image from the Source to the application via the
    /// Buffered Memory transfer mechanism.
    /// This operation supports the transfer of successive blocks of image data (in strips or,optionally,
    /// tiles) from the Source into one or more main memory transfer buffers. These buffers(for strips)
    /// are allocated and owned by the application. For tiled transfers, the source allocates the buffers.
    /// The application should repeatedly invoke this operation while TWRC_SUCCESS is returned by the Source.
    /// </summary>
    /// <param name="length">The length.</param>
    /// <param name="isMemFile">If set to <c>true</c> that transfer a MemFile.</param>
    /// <returns>
    /// Information about transmitting data.
    /// </returns>
    /// <exception cref="System.NotSupportedException"></exception>
    protected override ImageMemXfer OnImageMemXfer(long length, bool isMemFile) {
        if(!isMemFile) {
            return new ImageMemXfer {
                YOffset=(uint)this._BitmapReader.RowsOffset,
                XOffset=0U,
                BytesPerRow=(uint)this._BitmapReader.BitmapStream.BitmapData.Stride,
                Compression=this.XferEnvironment.ImageInfo.Compression,
                ImageData=this._BitmapReader.ReadRows((int)(length/this._BitmapReader.BitmapStream.BitmapData.Stride)),
                Columns=(uint)this._currentImage.Width,
                Rows=(uint)this._BitmapReader.RowsAffected,
                IsXferDone=this._BitmapReader.RowsOffset==this._BitmapReader.BitmapStream.BitmapData.Height
            };
        }
        throw new NotSupportedException();
    }

    /// <summary>
    /// Invoked to indicate that the Source has data that is ready to be transferred.
    /// </summary>
    protected override void OnXferReady() {
        if(this.XferEnvironment.PendingXfers==0) {
            this.XferEnvironment.PendingXfers=(ushort)Math.Abs((short)this[TwCap.XferCount].Value);
        }
        this._Acquire();

        base.OnXferReady();
    }

    /// <summary>
    /// Invoked at the end of every transfer to signal that the application has received all the data it expected.
    /// </summary>
    protected override void OnEndXfer() {
        this._Dispose();
        if(this.XferEnvironment.PendingXfers>0) {
            this._Acquire();
        }

        base.OnEndXfer();
    }

    /// <summary>
    /// Invoked when the pending transfers discarded.
    /// </summary>
    protected override void OnResetXfer() {
        this._Dispose();

        base.OnResetXfer();
    }

    private void _Dispose() {
        if(this._currentImage!=null) {
            this._currentImage.Dispose();
            this._currentImage=null;
        }
    }

    /// <summary>
    /// Acquire bitmap image.
    /// </summary>
    /// <returns>The bitmap image.</returns>
    protected abstract Bitmap Acquire();

    private void _Acquire() {
        this._BitmapReader=null;
        this._currentImage=this.Acquire();

        #region ImageInfo

        this.XferEnvironment.ImageInfo=new ImageInfo {
            BitsPerPixel=(short)Image.GetPixelFormatSize(this._currentImage.PixelFormat),
            BitsPerSample=new Dictionary<PixelFormat, short[]> {
                {PixelFormat.Format1bppIndexed,new short[] { 1 }},
                {PixelFormat.Format4bppIndexed,new short[] { 4 }},
                {PixelFormat.Format8bppIndexed,new short[] { 8 }},
                {PixelFormat.Format24bppRgb,new short[] { 8, 8, 8 }},
                {PixelFormat.Format48bppRgb,new short[] { 16, 16, 16 }}}[this._currentImage.PixelFormat],
            Compression=TwCompression.None,
            ImageLength=this._currentImage.Height,
            ImageWidth=this._currentImage.Width,
            PixelType=(TwPixelType)this[TwCap.IPixelType].Value,
            Planar=false,
            XResolution=this._currentImage.HorizontalResolution,
            YResolution=this._currentImage.VerticalResolution
        };

        #endregion
    }

    private BitmapReader _BitmapReader {
        get {
            return this._bitmapReader??(this._bitmapReader=this._currentImage.CreateReader(this.XferEnvironment.ImageInfo));
        }
        set {
            if(value!=null) {
                throw new ArgumentException();
            }
            if(this._bitmapReader!=null) {
                this._bitmapReader.Dispose();
                this._bitmapReader=null;
            }
        }
    }
}