Added support for packing a new format of .res-file (fixes #18)

fonts_experiment 1.0.2.8
Valeriy Mironov 2018-02-02 01:23:37 +02:00
parent 2398ab8086
commit e906ed4ff2
8 changed files with 122 additions and 26 deletions

View File

@ -18,16 +18,6 @@ namespace Resources
public void Extract(string outputDirectory)
{
if (_descriptor.Version != null)
{
var fileName = Path.Combine(outputDirectory, "version");
using (var stream = File.OpenWrite(fileName))
using (var writer = new BinaryWriter(stream))
{
writer.Write(_descriptor.Version.Value);
}
}
for (var i = 0; i < _descriptor.Images.Count; i++)
{
var numericPart = i.ToString().PadLeft(ImageLoader.NumericPartLength, '0');

View File

@ -36,7 +36,10 @@ namespace Resources
return new FileDescriptor
{
HasNewHeader = header is NewHeader,
ResourcesCount = header.ResourcesCount,
Version = header.Version,
Unknown = (header as NewHeader)?.Unknown,
Images = new Reader(stream).Read(header.ResourcesCount)
};
}

View File

@ -23,9 +23,20 @@ namespace Resources
if (descriptor.Version == null)
throw new ArgumentException("Res file version required");
if (descriptor.HasNewHeader)
WriteNewHeader(descriptor);
else
WriteOldHeader(descriptor);
Logger.Trace("Writing images...");
new Writer(_stream).Write(descriptor.Images);
}
private void WriteOldHeader(FileDescriptor descriptor)
{
var header = new Header
{
ResourcesCount = (uint) descriptor.Images.Count,
ResourcesCount = (uint)descriptor.Images.Count,
Version = descriptor.Version.Value
};
Logger.Trace("Writing resources header...");
@ -33,9 +44,22 @@ namespace Resources
header.Signature, header.Version, header.ResourcesCount
);
header.WriteTo(_binaryWriter);
Logger.Trace("Writing images...");
new Writer(_stream).Write(descriptor.Images);
}
private void WriteNewHeader(FileDescriptor descriptor)
{
var header = new NewHeader
{
ResourcesCount = descriptor.ResourcesCount.Value,
Version = descriptor.Version.Value,
Unknown = descriptor.Unknown.Value
};
Logger.Trace("Writing resources header...");
Logger.Trace("Signature: {0}, Version: {1}, ResourcesCount: {2}, Unknown: {3}",
header.Signature, header.Version, header.ResourcesCount, header.Unknown
);
header.WriteTo(_binaryWriter);
}
}
}

View File

@ -1,11 +1,17 @@
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.Serialization;
namespace Resources.Models
{
public class FileDescriptor
{
public bool HasNewHeader { get; set; }
public uint? ResourcesCount { get; set; }
public uint? Unknown { get; set; }
public byte? Version { get; set; }
[IgnoreDataMember]
public List<Bitmap> Images { get; set; } = new List<Bitmap>();
}
}

View File

@ -13,7 +13,7 @@ namespace Resources.Models
public byte Version { get; set; }
public uint ResourcesCount { get; set; }
public void WriteTo(BinaryWriter writer)
public virtual void WriteTo(BinaryWriter writer)
{
var buffer = new byte[HeaderSize];
for (var i = 0; i < buffer.Length; i++) buffer[i] = 0xff;

View File

@ -9,8 +9,14 @@ namespace Resources.Models
public new const int HeaderSize = 0x24;
public new const string ResSignature = "NERES";
public NewHeader()
{
Signature = ResSignature;
}
public uint Unknown { get; set; }
public new void WriteTo(BinaryWriter writer)
public override void WriteTo(BinaryWriter writer)
{
var buffer = new byte[HeaderSize];
for (var i = 0; i < buffer.Length; i++) buffer[i] = 0xff;

View File

@ -40,6 +40,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -47,6 +48,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extractor.cs" />
<Compile Include="ImageLoader.cs" />
<Compile Include="Models\FileDescriptor.cs" />
<Compile Include="Models\Header.cs" />
@ -56,7 +58,6 @@
<Compile Include="Image\FloydSteinbergDitherer.cs" />
<Compile Include="Image\Writer.cs" />
<Compile Include="Writer.cs" />
<Compile Include="Extractor.cs" />
<Compile Include="FileWriter.cs" />
<Compile Include="Models\NewHeader.cs" />
<Compile Include="Image\Reader.cs" />

View File

@ -50,6 +50,7 @@ namespace WatchFace
Console.WriteLine("File or directory '{0}' doesn't exists.", inputFileName);
continue;
}
if (isDirectory)
{
Console.WriteLine("Processing directory '{0}'", inputFileName);
@ -61,6 +62,7 @@ namespace WatchFace
{
Logger.Fatal(e);
}
continue;
}
@ -99,7 +101,7 @@ namespace WatchFace
var outputFileName = Path.Combine(outputDirectory, baseName + "_packed.bin");
SetupLogger(Path.ChangeExtension(outputFileName, ".log"));
var watchFace = ReadConfig(inputFileName);
var watchFace = ReadWatchFaceConfig(inputFileName);
if (watchFace == null) return;
var imagesDirectory = Path.GetDirectoryName(inputFileName);
@ -137,7 +139,7 @@ namespace WatchFace
Logger.Debug("Exporting resources to '{0}'", outputDirectory);
var reDescriptor = new FileDescriptor {Images = reader.Images};
new Extractor(reDescriptor).Extract(outputDirectory);
ExportConfig(watchFace, Path.Combine(outputDirectory, $"{baseName}.json"));
ExportWatchFaceConfig(watchFace, Path.Combine(outputDirectory, $"{baseName}.json"));
}
private static void PackResources(string inputDirectory)
@ -148,16 +150,32 @@ namespace WatchFace
var logFileName = Path.Combine(outputDirectory, $"{baseName}_packed.log");
SetupLogger(logFileName);
FileDescriptor resDescriptor;
var headerFileName = Path.Combine(inputDirectory, "header.json");
var versionFileName = Path.Combine(inputDirectory, "version");
var resDescriptor = new FileDescriptor();
using (var stream = File.OpenRead(versionFileName))
using (var reader = new BinaryReader(stream))
if (File.Exists(headerFileName))
{
resDescriptor.Version = reader.ReadByte();
resDescriptor = ReadResConfig(headerFileName);
}
else if (File.Exists(versionFileName))
{
resDescriptor = new FileDescriptor();
using (var stream = File.OpenRead(versionFileName))
using (var reader = new BinaryReader(stream))
{
resDescriptor.Version = reader.ReadByte();
}
}
else
{
throw new ArgumentException(
"File 'header.json' or 'version' should exists in the folder with unpacked images. Res-file couldn't be created"
);
}
var i = 0;
var images = new List<Bitmap>();
while (true)
while (resDescriptor.ResourcesCount == null || i < resDescriptor.ResourcesCount.Value)
{
try
{
@ -169,8 +187,13 @@ namespace WatchFace
Logger.Info("All images with sequenced names are loaded. Latest loaded image: {0}", i - 1);
break;
}
i++;
}
if (resDescriptor.ResourcesCount != null && resDescriptor.ResourcesCount.Value != images.Count)
throw new ArgumentException($"The .res-file should contain {resDescriptor.ResourcesCount.Value} images but was loaded {images.Count} images.");
resDescriptor.Images = images;
using (var stream = File.OpenWrite(outputFileName))
@ -191,6 +214,7 @@ namespace WatchFace
resDescriptor = FileReader.Read(stream);
}
ExportResConfig(resDescriptor, Path.Combine(outputDirectory, "header.json"));
new Extractor(resDescriptor).Extract(outputDirectory);
}
@ -271,7 +295,7 @@ namespace WatchFace
return unpackedPath;
}
private static Parser.WatchFace ReadConfig(string jsonFileName)
private static Parser.WatchFace ReadWatchFaceConfig(string jsonFileName)
{
Logger.Debug("Reading config...");
try
@ -294,7 +318,30 @@ namespace WatchFace
}
}
private static void ExportConfig(Parser.WatchFace watchFace, string jsonFileName)
private static FileDescriptor ReadResConfig(string jsonFileName)
{
Logger.Debug("Reading resources config...");
try
{
using (var fileStream = File.OpenRead(jsonFileName))
using (var reader = new StreamReader(fileStream))
{
return JsonConvert.DeserializeObject<FileDescriptor>(reader.ReadToEnd(),
new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Error,
NullValueHandling = NullValueHandling.Ignore
});
}
}
catch (Exception e)
{
Logger.Fatal(e);
return null;
}
}
private static void ExportWatchFaceConfig(Parser.WatchFace watchFace, string jsonFileName)
{
Logger.Debug("Exporting config...");
try
@ -313,6 +360,25 @@ namespace WatchFace
}
}
private static void ExportResConfig(FileDescriptor resDescriptor, string jsonFileName)
{
Logger.Debug("Exporting resources config...");
try
{
using (var fileStream = File.OpenWrite(jsonFileName))
using (var writer = new StreamWriter(fileStream))
{
writer.Write(JsonConvert.SerializeObject(resDescriptor, Formatting.Indented,
new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}));
writer.Flush();
}
}
catch (Exception e)
{
Logger.Fatal(e);
}
}
private static void SetupLogger(string logFileName)
{
var config = new LoggingConfiguration();