mirror of
https://github.com/soukoku/ntwain.git
synced 2025-12-20 03:59:56 +08:00
#74 expose memory transfer data as-is.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -156,3 +156,4 @@ $RECYCLE.BIN/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/packages
|
/packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
|
/.vs
|
||||||
|
|||||||
@@ -71,8 +71,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="ModernWpf.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=c99d0cfbea7491ef, processorArchitecture=MSIL">
|
<Reference Include="ModernWpf.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=c99d0cfbea7491ef, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\packages\ModernWpf.Core.2.0.0-alpha94\lib\net40-Client\ModernWpf.Core.dll</HintPath>
|
<HintPath>..\..\packages\ModernWpf.Core.2.0.0-alpha96\lib\net40-Client\ModernWpf.Core.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
|||||||
@@ -274,7 +274,8 @@ namespace Sample.WPF
|
|||||||
|
|
||||||
void _session_TransferReady(object sender, TransferReadyEventArgs e)
|
void _session_TransferReady(object sender, TransferReadyEventArgs e)
|
||||||
{
|
{
|
||||||
if (_session.CurrentSource.Capabilities.ICapXferMech.GetCurrent() == XferMech.File)
|
var mech = _session.CurrentSource.Capabilities.ICapXferMech.GetCurrent();
|
||||||
|
if (mech == XferMech.File)
|
||||||
{
|
{
|
||||||
var formats = _session.CurrentSource.Capabilities.ICapImageFileFormat.GetValues();
|
var formats = _session.CurrentSource.Capabilities.ICapImageFileFormat.GetValues();
|
||||||
var wantFormat = formats.Contains(FileFormat.Tiff) ? FileFormat.Tiff : FileFormat.Bmp;
|
var wantFormat = formats.Contains(FileFormat.Tiff) ? FileFormat.Tiff : FileFormat.Bmp;
|
||||||
@@ -286,6 +287,11 @@ namespace Sample.WPF
|
|||||||
};
|
};
|
||||||
var rc = _session.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
|
var rc = _session.CurrentSource.DGControl.SetupFileXfer.Set(fileSetup);
|
||||||
}
|
}
|
||||||
|
else if (mech == XferMech.Memory)
|
||||||
|
{
|
||||||
|
// ?
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetUniqueName(string dir, string name, string ext)
|
string GetUniqueName(string dir, string name, string ext)
|
||||||
@@ -315,19 +321,28 @@ namespace Sample.WPF
|
|||||||
ImageSource GenerateThumbnail(DataTransferredEventArgs e)
|
ImageSource GenerateThumbnail(DataTransferredEventArgs e)
|
||||||
{
|
{
|
||||||
BitmapSource img = null;
|
BitmapSource img = null;
|
||||||
if (e.NativeData != IntPtr.Zero)
|
|
||||||
|
switch (e.TransferType)
|
||||||
{
|
{
|
||||||
using (var stream = e.GetNativeImageStream())
|
case XferMech.Native:
|
||||||
{
|
using (var stream = e.GetNativeImageStream())
|
||||||
if (stream != null)
|
|
||||||
{
|
{
|
||||||
img = stream.ConvertToWpfBitmap(300, 0);
|
if (stream != null)
|
||||||
|
{
|
||||||
|
img = stream.ConvertToWpfBitmap(300, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
case XferMech.File:
|
||||||
else if (!string.IsNullOrEmpty(e.FileDataPath))
|
img = new BitmapImage(new Uri(e.FileDataPath));
|
||||||
{
|
if (img.CanFreeze)
|
||||||
img = new BitmapImage(new Uri(e.FileDataPath));
|
{
|
||||||
|
img.Freeze();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XferMech.Memory:
|
||||||
|
// TODO: build current image from multiple data-xferred event
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (img != null)
|
//if (img != null)
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
<package id="Microsoft.WindowsAPICodePack-Core" version="1.1.0.2" targetFramework="net4-client" />
|
<package id="Microsoft.WindowsAPICodePack-Core" version="1.1.0.2" targetFramework="net4-client" />
|
||||||
<package id="Microsoft.WindowsAPICodePack-Shell" version="1.1.0.0" targetFramework="net4-client" />
|
<package id="Microsoft.WindowsAPICodePack-Shell" version="1.1.0.0" targetFramework="net4-client" />
|
||||||
<package id="ModernWpf" version="2.0.0-alpha94" targetFramework="net40-client" />
|
<package id="ModernWpf" version="2.0.0-alpha94" targetFramework="net40-client" />
|
||||||
<package id="ModernWpf.Core" version="2.0.0-alpha94" targetFramework="net40-client" />
|
<package id="ModernWpf.Core" version="2.0.0-alpha96" targetFramework="net40-client" />
|
||||||
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net40-client" />
|
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net40-client" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -1921,9 +1921,9 @@ namespace NTwain.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the form of the acquired data being passed from the Source to the application.
|
/// Describes the form of the acquired data being passed from the Source to the application in memory transfer mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
partial class TWImageMemXfer
|
public partial class TWImageMemXfer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The compression method used to process the data being transferred.
|
/// The compression method used to process the data being transferred.
|
||||||
@@ -1965,7 +1965,7 @@ namespace NTwain.Data
|
|||||||
/// buffer, the actual size of the buffer, in bytes, and where the buffer is
|
/// buffer, the actual size of the buffer, in bytes, and where the buffer is
|
||||||
/// located in memory.
|
/// located in memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TWMemory Memory { get { return _memory; } internal set { _memory = value; } }
|
internal TWMemory Memory { get { return _memory; } set { _memory = value; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -25,17 +25,19 @@ namespace NTwain
|
|||||||
/// <param name="nativeData">The native data.</param>
|
/// <param name="nativeData">The native data.</param>
|
||||||
public DataTransferredEventArgs(DataSource source, IntPtr nativeData)
|
public DataTransferredEventArgs(DataSource source, IntPtr nativeData)
|
||||||
{
|
{
|
||||||
|
TransferType = XferMech.Native;
|
||||||
DataSource = source;
|
DataSource = source;
|
||||||
NativeData = nativeData;
|
NativeData = nativeData;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs"/> class.
|
/// Initializes a new instance of the <see cref="DataTransferredEventArgs" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The source.</param>
|
/// <param name="source">The source.</param>
|
||||||
/// <param name="fileDataPath">The file data path.</param>
|
/// <param name="fileDataPath">The file data path.</param>
|
||||||
/// <param name="imageFileFormat">The image file format.</param>
|
/// <param name="imageFileFormat">The image file format.</param>
|
||||||
public DataTransferredEventArgs(DataSource source, string fileDataPath, FileFormat imageFileFormat)
|
public DataTransferredEventArgs(DataSource source, string fileDataPath, FileFormat imageFileFormat)
|
||||||
{
|
{
|
||||||
|
TransferType = XferMech.File;
|
||||||
DataSource = source;
|
DataSource = source;
|
||||||
FileDataPath = fileDataPath;
|
FileDataPath = fileDataPath;
|
||||||
ImageFileFormat = imageFileFormat;
|
ImageFileFormat = imageFileFormat;
|
||||||
@@ -44,15 +46,26 @@ namespace NTwain
|
|||||||
/// Initializes a new instance of the <see cref="DataTransferredEventArgs" /> class.
|
/// Initializes a new instance of the <see cref="DataTransferredEventArgs" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source">The source.</param>
|
/// <param name="source">The source.</param>
|
||||||
|
/// <param name="memoryInfo">The memory information.</param>
|
||||||
/// <param name="memoryData">The memory data.</param>
|
/// <param name="memoryData">The memory data.</param>
|
||||||
public DataTransferredEventArgs(DataSource source, byte[] memoryData)
|
public DataTransferredEventArgs(DataSource source, TWImageMemXfer memoryInfo, byte[] memoryData)
|
||||||
{
|
{
|
||||||
|
TransferType = XferMech.Memory;
|
||||||
DataSource = source;
|
DataSource = source;
|
||||||
|
MemoryInfo = memoryInfo;
|
||||||
MemoryData = memoryData;
|
MemoryData = memoryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets pointer to the complete data if the transfer was native.
|
/// Gets the type of the transfer mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The type of the transfer.
|
||||||
|
/// </value>
|
||||||
|
public XferMech TransferType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the raw pointer to the complete data if <see cref="TransferType"/> is <see cref="XferMech.Native"/>.
|
||||||
/// The data will be freed once the event handler ends
|
/// The data will be freed once the event handler ends
|
||||||
/// so consumers must complete whatever processing before then.
|
/// so consumers must complete whatever processing before then.
|
||||||
/// For image type this data is DIB (Windows) or TIFF (Linux).
|
/// For image type this data is DIB (Windows) or TIFF (Linux).
|
||||||
@@ -63,6 +76,7 @@ namespace NTwain
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the file path to the complete data if the transfer was file or memory-file.
|
/// Gets the file path to the complete data if the transfer was file or memory-file.
|
||||||
|
/// This is only available if <see cref="TransferType"/> is <see cref="XferMech.File"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// The file path.
|
/// The file path.
|
||||||
@@ -71,12 +85,22 @@ namespace NTwain
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the file format if applicable.
|
/// Gets the file format if applicable.
|
||||||
|
/// This is only available if <see cref="TransferType"/> is <see cref="XferMech.Memory"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// The file format.
|
/// The file format.
|
||||||
/// </value>
|
/// </value>
|
||||||
public FileFormat ImageFileFormat { get; private set; }
|
public FileFormat ImageFileFormat { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the info object if the transfer was memory.
|
||||||
|
/// This is only available if <see cref="TransferType"/> is <see cref="XferMech.Memory"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The memory information.
|
||||||
|
/// </value>
|
||||||
|
public TWImageMemXfer MemoryInfo { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the raw memory data if the transfer was memory.
|
/// Gets the raw memory data if the transfer was memory.
|
||||||
/// Consumer application will need to do the parsing based on the values
|
/// Consumer application will need to do the parsing based on the values
|
||||||
@@ -166,7 +190,7 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
retVal = ImageTools.GetTiffStream(NativeData);
|
retVal = ImageTools.GetTiffStream(NativeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return retVal; ;
|
return retVal; ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace NTwain.Internals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc != ReturnCode.Success && session.StopOnTransferError)
|
if (rc != ReturnCode.Success && session.StopOnTransferError)
|
||||||
{
|
{
|
||||||
// end xfer without setting rc to exit (good/bad?)
|
// end xfer without setting rc to exit (good/bad?)
|
||||||
@@ -234,7 +234,7 @@ namespace NTwain.Internals
|
|||||||
{
|
{
|
||||||
lockedPtr = PlatformInfo.Current.MemoryManager.Lock(dataPtr);
|
lockedPtr = PlatformInfo.Current.MemoryManager.Lock(dataPtr);
|
||||||
}
|
}
|
||||||
DoImageXferredEventRoutine(session, lockedPtr, null, null, (FileFormat)0);
|
DoImageXferredEventRoutine(session, lockedPtr, null, null, null, (FileFormat)0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -276,7 +276,7 @@ namespace NTwain.Internals
|
|||||||
var xrc = session.DGImage.ImageFileXfer.Get();
|
var xrc = session.DGImage.ImageFileXfer.Get();
|
||||||
if (xrc == ReturnCode.XferDone)
|
if (xrc == ReturnCode.XferDone)
|
||||||
{
|
{
|
||||||
DoImageXferredEventRoutine(session, IntPtr.Zero, null, filePath, setupInfo.Format);
|
DoImageXferredEventRoutine(session, IntPtr.Zero, null, null, filePath, setupInfo.Format);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -304,50 +304,37 @@ namespace NTwain.Internals
|
|||||||
TheMem = PlatformInfo.Current.MemoryManager.Allocate(memInfo.Preferred)
|
TheMem = PlatformInfo.Current.MemoryManager.Allocate(memInfo.Preferred)
|
||||||
};
|
};
|
||||||
|
|
||||||
// do the unthinkable and keep all xferred batches in memory,
|
|
||||||
// possibly defeating the purpose of mem xfer
|
do
|
||||||
// unless compression is used.
|
|
||||||
// todo: use array instead of memory stream?
|
|
||||||
using (MemoryStream xferredData = new MemoryStream())
|
|
||||||
{
|
{
|
||||||
do
|
xrc = session.DGImage.ImageMemXfer.Get(xferInfo);
|
||||||
|
|
||||||
|
if (xrc == ReturnCode.Success ||
|
||||||
|
xrc == ReturnCode.XferDone)
|
||||||
{
|
{
|
||||||
xrc = session.DGImage.ImageMemXfer.Get(xferInfo);
|
if (session.State != 7) { session.ChangeState(7, true); }
|
||||||
|
|
||||||
if (xrc == ReturnCode.Success ||
|
// optimize and allocate buffer only once instead of inside the loop?
|
||||||
xrc == ReturnCode.XferDone)
|
byte[] buffer = new byte[(int)xferInfo.BytesWritten];
|
||||||
|
|
||||||
|
IntPtr lockPtr = IntPtr.Zero;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
session.ChangeState(7, true);
|
lockPtr = PlatformInfo.Current.MemoryManager.Lock(xferInfo.Memory.TheMem);
|
||||||
// optimize and allocate buffer only once instead of inside the loop?
|
Marshal.Copy(lockPtr, buffer, 0, buffer.Length);
|
||||||
byte[] buffer = new byte[(int)xferInfo.BytesWritten];
|
}
|
||||||
|
finally
|
||||||
IntPtr lockPtr = IntPtr.Zero;
|
{
|
||||||
try
|
if (lockPtr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
lockPtr = PlatformInfo.Current.MemoryManager.Lock(xferInfo.Memory.TheMem);
|
PlatformInfo.Current.MemoryManager.Unlock(xferInfo.Memory.TheMem);
|
||||||
Marshal.Copy(lockPtr, buffer, 0, buffer.Length);
|
|
||||||
xferredData.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (lockPtr != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
PlatformInfo.Current.MemoryManager.Unlock(xferInfo.Memory.TheMem);
|
|
||||||
//PlatformInfo.Current.MemoryManager.Unlock(lockPtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (xrc == ReturnCode.Success);
|
DoImageXferredEventRoutine(session, IntPtr.Zero, xferInfo, buffer, null, (FileFormat)0);
|
||||||
|
}
|
||||||
|
} while (xrc == ReturnCode.Success);
|
||||||
|
|
||||||
if (xrc == ReturnCode.XferDone)
|
HandleReturnCode(session, xrc);
|
||||||
{
|
|
||||||
DoImageXferredEventRoutine(session, IntPtr.Zero, xferredData.ToArray(), null, (FileFormat)0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HandleReturnCode(session, xrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -449,13 +436,13 @@ namespace NTwain.Internals
|
|||||||
|
|
||||||
if (File.Exists(finalFile))
|
if (File.Exists(finalFile))
|
||||||
{
|
{
|
||||||
DoImageXferredEventRoutine(session, IntPtr.Zero, null, finalFile, fileInfo.Format);
|
DoImageXferredEventRoutine(session, IntPtr.Zero, null, null, finalFile, fileInfo.Format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return xrc;
|
return xrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, byte[] dataArray, string filePath, FileFormat format)
|
static void DoImageXferredEventRoutine(ITwainSessionInternal session, IntPtr dataPtr, TWImageMemXfer memInfo, byte[] memData, string filePath, FileFormat format)
|
||||||
{
|
{
|
||||||
DataTransferredEventArgs args = null;
|
DataTransferredEventArgs args = null;
|
||||||
|
|
||||||
@@ -463,9 +450,9 @@ namespace NTwain.Internals
|
|||||||
{
|
{
|
||||||
args = new DataTransferredEventArgs(session.CurrentSource, dataPtr);
|
args = new DataTransferredEventArgs(session.CurrentSource, dataPtr);
|
||||||
}
|
}
|
||||||
else if (dataArray != null)
|
else if (memData != null)
|
||||||
{
|
{
|
||||||
args = new DataTransferredEventArgs(session.CurrentSource, dataArray);
|
args = new DataTransferredEventArgs(session.CurrentSource, memInfo, memData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace NTwain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The build release version number.
|
/// The build release version number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string Build = "3.3.9.5"; // change this for each nuget release
|
public const string Build = "3.4.0"; // change this for each nuget release
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user