Mostly fix image serialization

This commit is contained in:
Ben Olden-Cooligan 2019-03-19 15:00:49 -04:00
parent a59019eb87
commit deb5b0335b
23 changed files with 285 additions and 128 deletions

View File

@ -27,7 +27,7 @@ namespace NAPS2.Images
double scaleFactor = Math.Min(outputSize / (double)storage.Height, outputSize / (double)storage.Width);
storage = Transform.Perform(storage, new ScaleTransform(scaleFactor));
}
return Transform.PerformAll(storage, snapshot.TransformList);
return Transform.PerformAll(storage, snapshot.Metadata.TransformList);
});
}
}

View File

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using NAPS2.Images.Storage;
using NAPS2.Images.Transforms;
using NAPS2.Recovery;
using NAPS2.Scan;
namespace NAPS2.Images
@ -14,7 +11,6 @@ namespace NAPS2.Images
{
private IImage thumbnail;
private int thumbnailState;
private int transformState;
private bool disposed;
private int snapshotCount;
@ -36,6 +32,14 @@ namespace NAPS2.Images
Metadata = metadata;
}
public ScannedImage(IStorage storage, string serializedMetadata, StorageConvertParams convertParams)
{
BackingStorage = StorageManager.ConvertToBacking(storage, convertParams);
Metadata = StorageManager.ImageMetadataFactory.CreateMetadata(BackingStorage);
Metadata.Deserialize(serializedMetadata);
Metadata.Commit();
}
public ScannedImage(IStorage storage, ScanBitDepth bitDepth, bool highQuality, int quality)
{
var convertParams = new StorageConvertParams { Lossless = highQuality, LossyQuality = quality };
@ -83,7 +87,7 @@ namespace NAPS2.Images
{
// Also updates the recovery index since they reference the same list
Transform.AddOrSimplify(Metadata.TransformList, transform);
transformState++;
Metadata.TransformState++;
}
Metadata.Commit();
ThumbnailInvalidated?.Invoke(this, new EventArgs());
@ -98,7 +102,7 @@ namespace NAPS2.Images
return;
}
Metadata.TransformList.Clear();
transformState++;
Metadata.TransformState++;
}
Metadata.Commit();
ThumbnailInvalidated?.Invoke(this, new EventArgs());
@ -118,12 +122,12 @@ namespace NAPS2.Images
{
thumbnail?.Dispose();
thumbnail = image;
thumbnailState = state ?? transformState;
thumbnailState = state ?? Metadata.TransformState;
}
ThumbnailChanged?.Invoke(this, new EventArgs());
}
public bool IsThumbnailDirty => thumbnailState != transformState;
public bool IsThumbnailDirty => thumbnailState != Metadata.TransformState;
public EventHandler ThumbnailChanged;
@ -139,9 +143,7 @@ namespace NAPS2.Images
public Snapshot Preserve() => new Snapshot(this);
[Serializable]
[KnownType("KnownTypes")]
public class Snapshot : IDisposable, ISerializable
public class Snapshot : IDisposable
{
private bool disposed;
@ -155,16 +157,13 @@ namespace NAPS2.Images
}
source.snapshotCount++;
Source = source;
TransformList = source.Metadata.TransformList.ToList();
TransformState = source.transformState;
Metadata = source.Metadata.Clone();
}
}
public ScannedImage Source { get; }
public List<Transform> TransformList { get; }
public int TransformState { get; }
public IImageMetadata Metadata { get; }
public void Dispose()
{
@ -179,29 +178,6 @@ namespace NAPS2.Images
}
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// TODO
//info.AddValue("RecoveryIndexImage", Source.RecoveryIndexImage);
info.AddValue("TransformList", TransformList);
info.AddValue("TransformState", TransformState);
}
private Snapshot(SerializationInfo info, StreamingContext context)
{
// TODO
//Source = new ScannedImage((RecoveryIndexImage)info.GetValue("RecoveryIndexImage", typeof(RecoveryIndexImage)));
TransformList = (List<Transform>)info.GetValue("TransformList", typeof(List<Transform>));
TransformState = (int)info.GetValue("TransformState", typeof(int));
}
// ReSharper disable once UnusedMember.Local
private static Type[] KnownTypes()
{
var transformTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsSubclassOf(typeof(Transform)));
return transformTypes.Concat(new[] { typeof(List<Transform>), typeof(RecoveryIndexImage) }).ToArray();
}
}
}
}

View File

@ -7,21 +7,31 @@ namespace NAPS2.Images.Storage
{
public class FileStorage : IStorage
{
public FileStorage(string fullPath)
private readonly bool shared;
public FileStorage(string fullPath) : this(fullPath, false)
{
}
public FileStorage(string fullPath, bool shared)
{
FullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath));
this.shared = shared;
}
public string FullPath { get; }
public void Dispose()
{
try
{
File.Delete(FullPath);
}
catch (IOException)
if (!shared)
{
try
{
File.Delete(FullPath);
}
catch (IOException)
{
}
}
}
}

View File

@ -10,6 +10,8 @@ namespace NAPS2.Images.Storage
{
List<Transform> TransformList { get; set; }
int TransformState { get; set; }
int Index { get; set; }
ScanBitDepth BitDepth { get; set; }
@ -23,5 +25,7 @@ namespace NAPS2.Images.Storage
string Serialize();
void Deserialize(string serializedData);
IImageMetadata Clone();
}
}

View File

@ -8,7 +8,7 @@ namespace NAPS2.Images.Storage
public class OwnershipConverters
{
[StorageConverter]
public FileStorage ConvertToFile(UnownedTransferStorage input, StorageConvertParams convertParams)
public FileStorage ConvertToFile(UnownedFileStorage input, StorageConvertParams convertParams)
{
string newPath = FileStorageManager.Current.NextFilePath();
File.Copy(input.FilePath, newPath);

View File

@ -27,6 +27,8 @@ namespace NAPS2.Images.Storage
set => indexImage.TransformList = value;
}
public int TransformState { get; set; }
public int Index
{
get => rsm.Index.Images.IndexOf(indexImage);
@ -61,6 +63,16 @@ namespace NAPS2.Images.Storage
public void Deserialize(string serializedData) => indexImage = serializedData.FromXml<RecoveryIndexImage>();
public IImageMetadata Clone() =>
new StubImageMetadata
{
TransformList = TransformList.ToList(),
TransformState = TransformState,
Index = Index,
BitDepth = BitDepth,
Lossless = Lossless
};
public void Dispose()
{
rsm.Index.Images.Remove(indexImage);

View File

@ -11,6 +11,8 @@ namespace NAPS2.Images.Storage
{
public List<Transform> TransformList { get; set; } = new List<Transform>();
public int TransformState { get; set; }
public int Index { get; set; }
public ScanBitDepth BitDepth { get; set; }
@ -37,6 +39,16 @@ namespace NAPS2.Images.Storage
Lossless = other.Lossless;
}
public IImageMetadata Clone() =>
new StubImageMetadata
{
TransformList = TransformList.ToList(),
TransformState = TransformState,
Index = Index,
BitDepth = BitDepth,
Lossless = Lossless
};
public void Dispose()
{
}

View File

@ -8,14 +8,14 @@ namespace NAPS2.Images.Storage
/// Represents an image received across the wire where we must copy the backing
/// file before it can be used.
/// </summary>
public class UnownedTransferStorage : IStorage
public class UnownedFileStorage : IStorage
{
static UnownedTransferStorage()
static UnownedFileStorage()
{
StorageManager.RegisterConverters(new OwnershipConverters());
}
public UnownedTransferStorage(string filePath)
public UnownedFileStorage(string filePath)
{
FilePath = filePath ?? throw new ArgumentNullException(nameof(filePath));
}

View File

@ -78,7 +78,7 @@ namespace NAPS2.Images
{
outputSize = UserConfig.Current.ThumbnailSize;
}
using (var bitmap = await imageRenderer.Render(snapshot, snapshot.TransformList.Count == 0 ? 0 : outputSize * OVERSAMPLE))
using (var bitmap = await imageRenderer.Render(snapshot, snapshot.Metadata.TransformList.Count == 0 ? 0 : outputSize * OVERSAMPLE))
{
return Transform.Perform(bitmap, new ThumbnailTransform(outputSize));
}

View File

@ -2,29 +2,31 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NAPS2.Recovery;
using Google.Protobuf;
using NAPS2.Images;
using NAPS2.Serialization;
namespace NAPS2.ImportExport
{
[Serializable]
public class DirectImageTransfer
{
public DirectImageTransfer(IEnumerable<ScannedImage> selectedImages)
public DirectImageTransfer(IEnumerable<ScannedImage> images)
{
ProcessID = Process.GetCurrentProcess().Id;
// TODO
//ImageRecovery = selectedImages.Select(x => x.RecoveryIndexImage).ToArray();
//if (ImageRecovery.Length > 0)
//{
// RecoveryFolder = RecoveryImage.RecoveryFolder.FullName;
//}
var serializedImages = images.Select(x => SerializedImageHelper.Serialize(x, new SerializedImageHelper.SerializeOptions()));
SerializedImages = serializedImages.Select(x => x.ToByteArray()).ToList();
}
public DirectImageTransfer(IEnumerable<ScannedImage.Snapshot> snapshots)
{
ProcessID = Process.GetCurrentProcess().Id;
var serializedImages = snapshots.Select(x => SerializedImageHelper.Serialize(x, new SerializedImageHelper.SerializeOptions()));
SerializedImages = serializedImages.Select(x => x.ToByteArray()).ToList();
}
public int ProcessID { get; }
public RecoveryIndexImage[] ImageRecovery { get; }
public string RecoveryFolder { get; }
public List<byte[]> SerializedImages { get; }
}
}

View File

@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Google.Protobuf;
using NAPS2.Lang.Resources;
using NAPS2.Logging;
using NAPS2.Operation;
using NAPS2.Images;
using NAPS2.Images.Storage;
using NAPS2.Images.Transforms;
using NAPS2.Serialization;
namespace NAPS2.ImportExport
{
@ -29,25 +31,19 @@ namespace NAPS2.ImportExport
Status = new OperationStatus
{
StatusText = copy ? MiscResources.Copying : MiscResources.Importing,
MaxProgress = data.ImageRecovery.Length
MaxProgress = data.SerializedImages.Count
};
RunAsync(async () =>
{
Exception error = null;
foreach (var ir in data.ImageRecovery)
foreach (var serializedImageBytes in data.SerializedImages)
{
try
{
ScannedImage img;
using (var storage = StorageManager.ConvertToImage(new FileStorage(Path.Combine(data.RecoveryFolder, ir.FileName)), new StorageConvertParams()))
{
img = new ScannedImage(storage, ir.BitDepth, ir.HighQuality, -1);
}
foreach (var transform in ir.TransformList)
{
img.AddTransform(transform);
}
var serializedImage = new SerializedImage();
serializedImage.MergeFrom(serializedImageBytes);
ScannedImage img = SerializedImageHelper.Deserialize(serializedImage, new SerializedImageHelper.DeserializeOptions());
// TODO: Don't bother, here, in recovery, etc.
img.SetThumbnail(Transform.Perform(await imageRenderer.Render(img), new ThumbnailTransform()));
imageCallback(img);
@ -66,7 +62,7 @@ namespace NAPS2.ImportExport
}
if (error != null)
{
Log.ErrorException(string.Format(MiscResources.ImportErrorCouldNot, data.RecoveryFolder), error);
Log.ErrorException(string.Format(MiscResources.ImportErrorCouldNot, "<data>"), error);
}
return true;
});

View File

@ -138,7 +138,7 @@ namespace NAPS2.ImportExport.Pdf
progressCallback(progress, snapshots.Count);
foreach (var snapshot in snapshots)
{
if (snapshot.Source.BackingStorage is FileStorage fileStorage && IsPdfFile(fileStorage) && !snapshot.TransformList.Any())
if (snapshot.Source.BackingStorage is FileStorage fileStorage && IsPdfFile(fileStorage) && !snapshot.Metadata.TransformList.Any())
{
CopyPdfPageToDoc(document, fileStorage);
}
@ -182,7 +182,7 @@ namespace NAPS2.ImportExport.Pdf
PdfPage page;
bool importedPdfPassThrough = false;
if (snapshot.Source.BackingStorage is FileStorage fileStorage && IsPdfFile(fileStorage) && !snapshot.TransformList.Any())
if (snapshot.Source.BackingStorage is FileStorage fileStorage && IsPdfFile(fileStorage) && !snapshot.Metadata.TransformList.Any())
{
importedPdfPassThrough = true;
page = CopyPdfPageToDoc(document, fileStorage);

View File

@ -193,7 +193,7 @@
<Compile Include="Images\ScannedImageSink.cs" />
<Compile Include="Images\Storage\OwnershipConverters.cs" />
<Compile Include="Images\Storage\PdfConverters.cs" />
<Compile Include="Images\Storage\UnownedTransferStorage.cs" />
<Compile Include="Images\Storage\UnownedFileStorage.cs" />
<Compile Include="Images\Storage\PdfStorage.cs" />
<Compile Include="ImportExport\Email\Mapi\IMapiWrapper.cs" />
<Compile Include="ImportExport\Email\Mapi\MapiWrapper.cs" />
@ -287,6 +287,7 @@
<Compile Include="Scan\Wia\WiaConfiguration.cs" />
<Compile Include="Scan\Wia\WiaScanErrors.cs" />
<Compile Include="Scan\Wia\WiaScanOperation.cs" />
<Compile Include="Serialization\SerializedImageHelper.cs" />
<Compile Include="Update\UpdateOperation.cs" />
<Compile Include="Update\UpdateInfo.cs" />
<Compile Include="Update\UpdateChecker.cs" />
@ -297,6 +298,7 @@
<Compile Include="Platform\IRuntimeCompat.cs" />
<Compile Include="Platform\MonoRuntimeCompat.cs" />
<Compile Include="Util\ExpFallback.cs" />
<Compile Include="WinForms\ImageClipboard.cs" />
<Compile Include="Worker\GrpcHelper.cs" />
<Compile Include="Util\IInvoker.cs" />
<Compile Include="Util\ImageExtensions.cs" />
@ -6203,6 +6205,7 @@
<None Include="naps2-public.cer" />
<None Include="Icons\accept-small.png" />
<None Include="packages.config" />
<ProtoBuf Include="Serialization\common.proto" />
<Protobuf Include="Worker\worker.proto" />
</ItemGroup>
<ItemGroup>

View File

@ -10,7 +10,7 @@ namespace NAPS2.Ocr
public OcrRequestParams(ScannedImage.Snapshot snapshot, IOcrEngine ocrEngine, OcrParams ocrParams)
{
ScannedImage = snapshot.Source;
TransformState = snapshot.TransformList.Count == 0 ? -1 : snapshot.TransformState;
TransformState = snapshot.Metadata.TransformList.Count == 0 ? -1 : snapshot.Metadata.TransformState;
Engine = ocrEngine;
OcrParams = ocrParams;
}

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Google.Protobuf;
using NAPS2.Images;
using NAPS2.Images.Storage;
namespace NAPS2.Serialization
{
public static class SerializedImageHelper
{
public static SerializedImage Serialize(ScannedImage image, SerializeOptions options) =>
Serialize(image, image.Metadata, options);
public static SerializedImage Serialize(ScannedImage.Snapshot snapshot, SerializeOptions options) =>
Serialize(snapshot.Source, snapshot.Metadata, options);
private static SerializedImage Serialize(ScannedImage image, IImageMetadata metadata, SerializeOptions options)
{
MemoryStream thumbStream = null;
var thumb = image.GetThumbnail();
if (thumb != null && options.IncludeThumbnail)
{
thumbStream = StorageManager.Convert<MemoryStreamStorage>(thumb, new StorageConvertParams { Lossless = true }).Stream;
}
var fileStorage = image.BackingStorage as FileStorage;
if (fileStorage == null && options.RequireFileStorage)
{
throw new InvalidOperationException("FileStorage is required for serialization.");
}
MemoryStream imageStream = null;
if (fileStorage == null)
{
imageStream = StorageManager.Convert<MemoryStreamStorage>(image.BackingStorage, new StorageConvertParams()).Stream;
}
var result = new SerializedImage
{
TransferOwnership = options.TransferOwnership,
MetadataXml = image.Metadata.Serialize(),
Thumbnail = thumbStream != null ? ByteString.FromStream(thumbStream) : ByteString.Empty,
RenderedFilePath = options.RenderedFilePath
};
if (fileStorage != null)
{
result.FilePath = fileStorage.FullPath;
}
else
{
result.FileContent = ByteString.FromStream(imageStream);
}
return result;
}
public static ScannedImage Deserialize(SerializedImage serializedImage, DeserializeOptions options)
{
IStorage storage;
if (!string.IsNullOrEmpty(serializedImage.FilePath))
{
if (serializedImage.TransferOwnership)
{
storage = new FileStorage(serializedImage.FilePath);
}
else if (options.ShareFileStorage)
{
storage = new FileStorage(serializedImage.FilePath, true);
}
else
{
// TODO: With this logic centralized, maybe we can remove UnownedFileStorage and just move the file copy logic here?
storage = new UnownedFileStorage(serializedImage.FilePath);
}
}
else
{
var memoryStream = new MemoryStream(serializedImage.FileContent.ToByteArray());
storage = new MemoryStreamStorage(memoryStream);
}
var scannedImage = new ScannedImage(storage, serializedImage.MetadataXml, new StorageConvertParams());
var thumbnail = serializedImage.Thumbnail.ToByteArray();
if (thumbnail.Length > 0)
{
var thumbnailStorage = new MemoryStreamStorage(new MemoryStream(thumbnail));
scannedImage.SetThumbnail(StorageManager.ConvertToImage(thumbnailStorage, new StorageConvertParams()));
}
return scannedImage;
}
public class SerializeOptions
{
public bool TransferOwnership { get; set; }
public bool IncludeThumbnail { get; set; }
public bool RequireFileStorage { get; set; }
public string RenderedFilePath { get; set; }
}
public class DeserializeOptions
{
/// <summary>
/// If true, the deserializer guarantees that the file storage will not be used for longer than the duration of the RPC call.
/// In this way, files can be reused even if ownership isn't transferred to the callee.
/// </summary>
public bool ShareFileStorage { get; set; }
}
}
}

View File

@ -0,0 +1,20 @@
syntax = "proto3";
package NAPS2.Serialization;
message Error {
string type = 1;
string message = 2;
string stackTrace = 3;
}
message SerializedImage {
bool transferOwnership = 1;
oneof image {
string filePath = 2;
bytes fileContent = 3;
}
string metadataXml = 4;
bytes thumbnail = 5;
string renderedFilePath = 6;
}

View File

@ -1885,7 +1885,7 @@ namespace NAPS2.WinForms
continue;
}
next.SetThumbnail(thumb, snapshot.TransformState);
next.SetThumbnail(thumb, snapshot.Metadata.TransformState);
}
fallback.Reset();
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NAPS2.Images;
namespace NAPS2.WinForms
{
public class ImageClipboard
{
private readonly BitmapRenderer bitmapRenderer;
public ImageClipboard()
{
bitmapRenderer = new BitmapRenderer();
}
public ImageClipboard(BitmapRenderer bitmapRenderer)
{
this.bitmapRenderer = bitmapRenderer;
}
}
}

View File

@ -5,6 +5,7 @@ using System.Reflection;
using System.Threading.Tasks;
using Grpc.Core;
using NAPS2.Scan.Exceptions;
using NAPS2.Serialization;
using NAPS2.Util;
namespace NAPS2.Worker

View File

@ -1,16 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using NAPS2.Images;
using NAPS2.Images.Storage;
using NAPS2.ImportExport.Email;
using NAPS2.ImportExport.Email.Mapi;
using NAPS2.Scan;
using NAPS2.Scan.Wia;
using NAPS2.Serialization;
using NAPS2.Util;
namespace NAPS2.Worker
@ -65,17 +64,8 @@ namespace NAPS2.Worker
{
var resp = streamingCall.ResponseStream.Current;
GrpcHelper.HandleErrors(resp.Error);
var storage = new FileStorage(resp.FilePath);
var metadata = StorageManager.ImageMetadataFactory.CreateMetadata(storage);
metadata.Deserialize(resp.MetadataXml);
var scannedImage = new ScannedImage(storage, metadata, new StorageConvertParams());
var thumbnail = resp.Thumbnail.ToByteArray();
if (thumbnail.Length > 0)
{
var thumbnailStorage = new MemoryStreamStorage(new MemoryStream(thumbnail));
scannedImage.SetThumbnail(StorageManager.ConvertToImage(thumbnailStorage, new StorageConvertParams()));
}
imageCallback?.Invoke(scannedImage, resp.RenderedFilePath);
var scannedImage = SerializedImageHelper.Deserialize(resp.Image, new SerializedImageHelper.DeserializeOptions());
imageCallback?.Invoke(scannedImage, resp.Image.RenderedFilePath);
}
}
@ -91,7 +81,10 @@ namespace NAPS2.Worker
{
var req = new RenderThumbnailRequest
{
SnapshotXml = snapshot.ToXml(),
Image = SerializedImageHelper.Serialize(snapshot, new SerializedImageHelper.SerializeOptions
{
RequireFileStorage = true
}),
Size = size
};
var resp = client.RenderThumbnail(req);

View File

@ -14,6 +14,7 @@ using NAPS2.Scan;
using NAPS2.Scan.Twain;
using NAPS2.Scan.Wia;
using NAPS2.Scan.Wia.Native;
using NAPS2.Serialization;
using NAPS2.Util;
namespace NAPS2.Worker
@ -109,12 +110,19 @@ namespace NAPS2.Worker
GrpcHelper.WrapFunc(
async () =>
{
var thumbnail = await thumbnailRenderer.Render(request.SnapshotXml.FromXml<ScannedImage.Snapshot>(), request.Size);
var stream = StorageManager.Convert<MemoryStreamStorage>(thumbnail, new StorageConvertParams { Lossless = true }).Stream;
return new RenderThumbnailResponse
var deserializeOptions = new SerializedImageHelper.DeserializeOptions
{
Thumbnail = ByteString.FromStream(stream)
ShareFileStorage = true
};
using (var image = SerializedImageHelper.Deserialize(request.Image, deserializeOptions))
{
var thumbnail = await thumbnailRenderer.Render(image, request.Size);
var stream = StorageManager.Convert<MemoryStreamStorage>(thumbnail, new StorageConvertParams { Lossless = true }).Stream;
return new RenderThumbnailResponse
{
Thumbnail = ByteString.FromStream(stream)
};
}
},
err => new RenderThumbnailResponse { Error = err });
@ -132,22 +140,14 @@ namespace NAPS2.Worker
public override void PutImage(ScannedImage image)
{
// TODO: Ideally this shouldn't be inheriting ScannedImageSink, some other cleaner mechanism
MemoryStream stream = null;
var thumb = image.GetThumbnail();
if (thumb != null)
{
stream = StorageManager.Convert<MemoryStreamStorage>(thumb, new StorageConvertParams { Lossless = true }).Stream;
}
if (!(image.BackingStorage is FileStorage fileStorage))
{
throw new InvalidOperationException("The worker can only be used with IFileStorage backing storage.");
}
callback.WriteAsync(new TwainScanResponse
{
FilePath = fileStorage.FullPath,
MetadataXml = image.Metadata.Serialize(),
Thumbnail = stream != null ? ByteString.FromStream(stream) : ByteString.Empty,
RenderedFilePath = imagePathDict.Get(image) ?? ""
Image = SerializedImageHelper.Serialize(image, new SerializedImageHelper.SerializeOptions
{
TransferOwnership = true,
IncludeThumbnail = true,
RenderedFilePath = imagePathDict.Get(image) ?? ""
})
});
}
}

View File

@ -2,6 +2,8 @@
package NAPS2.Worker;
import "Serialization/common.proto";
service GrpcWorkerService {
rpc Init (InitRequest) returns (InitResponse) {}
rpc Wia10NativeUi (Wia10NativeUiRequest) returns (Wia10NativeUiResponse) {}
@ -11,18 +13,12 @@ service GrpcWorkerService {
rpc RenderThumbnail (RenderThumbnailRequest) returns (RenderThumbnailResponse) {}
}
message Error {
string type = 1;
string message = 2;
string stackTrace = 3;
}
message InitRequest {
string recoveryFolderPath = 1;
}
message InitResponse {
Error error = 1;
NAPS2.Serialization.Error error = 1;
}
message Wia10NativeUiRequest {
@ -31,7 +27,7 @@ message Wia10NativeUiRequest {
}
message Wia10NativeUiResponse {
Error error = 1;
NAPS2.Serialization.Error error = 1;
string wiaConfigurationXml = 2;
}
@ -40,7 +36,7 @@ message TwainGetDeviceListRequest {
}
message TwainGetDeviceListResponse {
Error error = 1;
NAPS2.Serialization.Error error = 1;
string deviceListXml = 2;
}
@ -52,11 +48,8 @@ message TwainScanRequest {
}
message TwainScanResponse {
Error error = 1;
string filePath = 2;
string metadataXml = 3;
bytes thumbnail = 4;
string renderedFilePath = 5;
NAPS2.Serialization.Error error = 1;
NAPS2.Serialization.SerializedImage image = 2;
}
message SendMapiEmailRequest {
@ -64,16 +57,16 @@ message SendMapiEmailRequest {
}
message SendMapiEmailResponse {
Error error = 1;
NAPS2.Serialization.Error error = 1;
string returnCodeXml = 2;
}
message RenderThumbnailRequest {
string snapshotXml = 1;
NAPS2.Serialization.SerializedImage image = 1;
int32 size = 2;
}
message RenderThumbnailResponse {
Error error = 1;
NAPS2.Serialization.Error error = 1;
bytes thumbnail = 2;
}

View File

@ -11,5 +11,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwnd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jpegs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lineart/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lossless/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mapi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pdfs/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>