Added saving resources version on unpacking .res file, added packing .res file, closes #1
parent
a6f36424e8
commit
fa2cbebad2
|
@ -0,0 +1,38 @@
|
|||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources.Models;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class Extractor
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly FileDescriptor _descriptor;
|
||||
|
||||
public Extractor(FileDescriptor descriptor)
|
||||
{
|
||||
_descriptor = descriptor;
|
||||
}
|
||||
|
||||
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 fileName = Path.Combine(outputDirectory, $"{i}.png");
|
||||
Logger.Debug("Extracting {0}...", fileName);
|
||||
_descriptor.Images[i].Save(fileName, ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +1,20 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources.Models;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class ResourcesFileReader
|
||||
public class FileReader
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly BinaryReader _binaryReader;
|
||||
private readonly Stream _stream;
|
||||
|
||||
public ResourcesFileReader(Stream stream)
|
||||
public static FileDescriptor Read(Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_binaryReader = new BinaryReader(stream);
|
||||
}
|
||||
var binaryReader = new BinaryReader(stream);
|
||||
|
||||
public Bitmap[] Read()
|
||||
{
|
||||
Logger.Trace("Reading resources header");
|
||||
var header = ResourcesHeader.ReadFrom(_binaryReader);
|
||||
var header = Header.ReadFrom(binaryReader);
|
||||
Logger.Trace("Resources header was read:");
|
||||
Logger.Trace("Signature: {0}, Version: {1}, ResourcesCount: {2}, IsValid: {3}",
|
||||
header.Signature, header.Version, header.ResourcesCount, header.IsValid
|
||||
|
@ -30,7 +23,11 @@ namespace Resources
|
|||
if (!header.IsValid)
|
||||
throw new ArgumentException("Invalid resources header");
|
||||
|
||||
return new ResourcesReader(_stream).Read(header.ResourcesCount);
|
||||
return new FileDescriptor
|
||||
{
|
||||
Version = header.Version,
|
||||
Images = new Reader(stream).Read(header.ResourcesCount)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources.Models;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class FileWriter
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly BinaryWriter _binaryWriter;
|
||||
private readonly Stream _stream;
|
||||
|
||||
public FileWriter(Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_binaryWriter = new BinaryWriter(stream);
|
||||
}
|
||||
|
||||
public void Write(FileDescriptor descriptor)
|
||||
{
|
||||
if (descriptor.Version == null)
|
||||
throw new ArgumentException("Res file version required");
|
||||
|
||||
var header = new Header
|
||||
{
|
||||
ResourcesCount = (uint) descriptor.Images.Count,
|
||||
Version = descriptor.Version.Value
|
||||
};
|
||||
Logger.Trace("Writing resources header...");
|
||||
Logger.Trace("Signature: {0}, Version: {1}, ResourcesCount: {2}, IsValid: {3}",
|
||||
header.Signature, header.Version, header.ResourcesCount, header.IsValid
|
||||
);
|
||||
header.WriteTo(_binaryWriter);
|
||||
|
||||
Logger.Trace("Writing images...");
|
||||
new Writer(_stream).Write(descriptor.Images);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using System.Drawing;
|
||||
|
||||
namespace Resources.Dithering
|
||||
namespace Resources.Image
|
||||
{
|
||||
public class ColorError
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
using System.Drawing;
|
||||
using NLog;
|
||||
|
||||
namespace Resources.Dithering
|
||||
namespace Resources.Image
|
||||
{
|
||||
public class FloydSteinbergDitherer
|
||||
{
|
|
@ -2,10 +2,11 @@
|
|||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources.Utils;
|
||||
|
||||
namespace Resources
|
||||
namespace Resources.Image
|
||||
{
|
||||
public class ImageReader
|
||||
public class Reader
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -18,7 +19,7 @@ namespace Resources
|
|||
private bool _transparency;
|
||||
private ushort _width;
|
||||
|
||||
public ImageReader(Stream stream)
|
||||
public Reader(Stream stream)
|
||||
{
|
||||
_reader = new BinaryReader(stream);
|
||||
}
|
|
@ -4,11 +4,11 @@ using System.Drawing;
|
|||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources.Dithering;
|
||||
using Resources.Utils;
|
||||
|
||||
namespace Resources
|
||||
namespace Resources.Image
|
||||
{
|
||||
public class ImageWriter
|
||||
public class Writer
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly byte[] Signature = {(byte) 'B', (byte) 'M', (byte) 'd', 0};
|
||||
|
@ -24,7 +24,7 @@ namespace Resources
|
|||
private ushort _transparency;
|
||||
private ushort _width;
|
||||
|
||||
public ImageWriter(Stream stream)
|
||||
public Writer(Stream stream)
|
||||
{
|
||||
_writer = new BinaryWriter(stream);
|
||||
_palette = new List<Color>();
|
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Resources.Models
|
||||
{
|
||||
public class FileDescriptor
|
||||
{
|
||||
public byte? Version { get; set; }
|
||||
public List<Bitmap> Images { get; set; } = new List<Bitmap>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Resources.Models
|
||||
{
|
||||
public class Header
|
||||
{
|
||||
public const int HeaderSize = 20;
|
||||
private const string ResSignature = "HMRES";
|
||||
|
||||
public string Signature { get; private set; } = ResSignature;
|
||||
public byte Version { get; set; }
|
||||
public uint ResourcesCount { get; set; }
|
||||
|
||||
public bool IsValid => Signature == ResSignature;
|
||||
|
||||
public void WriteTo(BinaryWriter writer)
|
||||
{
|
||||
var buffer = new byte[HeaderSize];
|
||||
for (var i = 0; i < buffer.Length; i++) buffer[i] = 0xff;
|
||||
|
||||
Encoding.ASCII.GetBytes(ResSignature).CopyTo(buffer, 0);
|
||||
buffer[5] = Version;
|
||||
BitConverter.GetBytes(ResourcesCount).CopyTo(buffer, 16);
|
||||
writer.Write(buffer);
|
||||
}
|
||||
|
||||
public static Header ReadFrom(BinaryReader reader)
|
||||
{
|
||||
var buffer = reader.ReadBytes(HeaderSize);
|
||||
return new Header
|
||||
{
|
||||
Signature = Encoding.ASCII.GetString(buffer, 0, 5),
|
||||
Version = buffer[5],
|
||||
ResourcesCount = BitConverter.ToUInt32(buffer, 16)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.2")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.2")]
|
||||
[assembly: AssemblyVersion("1.0.0.3")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.3")]
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class ResourcesReader
|
||||
public class Reader
|
||||
{
|
||||
private const int OffsetTableItemLength = 4;
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
@ -13,13 +14,13 @@ namespace Resources
|
|||
private readonly BinaryReader _binaryReader;
|
||||
private readonly Stream _stream;
|
||||
|
||||
public ResourcesReader(Stream stream)
|
||||
public Reader(Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_binaryReader = new BinaryReader(_stream);
|
||||
}
|
||||
|
||||
public Bitmap[] Read(uint imagesTableLength)
|
||||
public List<Bitmap> Read(uint imagesTableLength)
|
||||
{
|
||||
var offsetsTableLength = (int) (imagesTableLength * OffsetTableItemLength);
|
||||
Logger.Trace("Reading resources offsets table with {0} elements ({1} bytes)",
|
||||
|
@ -29,18 +30,20 @@ namespace Resources
|
|||
var imagesOffset = _stream.Position;
|
||||
|
||||
Logger.Debug("Reading {0} images...", imagesTableLength);
|
||||
var images = new Bitmap[imagesTableLength];
|
||||
var images = new List<Bitmap>((int) imagesTableLength);
|
||||
for (var i = 0; i < imagesTableLength; i++)
|
||||
{
|
||||
var imageOffset = BitConverter.ToUInt32(imagesOffsets, i * OffsetTableItemLength) + imagesOffset;
|
||||
if (_stream.Position != imageOffset)
|
||||
var imageOffset = BitConverter.ToUInt32(imagesOffsets, i * OffsetTableItemLength);
|
||||
var realOffset = imageOffset + imagesOffset;
|
||||
Logger.Trace("Image {0} offset is {1}...", i, imageOffset);
|
||||
if (_stream.Position != realOffset)
|
||||
{
|
||||
var bytesGap = imageOffset - _stream.Position;
|
||||
var bytesGap = realOffset - _stream.Position;
|
||||
Logger.Warn("Found {0} bytes gap before resource number {1}", bytesGap, i);
|
||||
_stream.Seek(imageOffset, SeekOrigin.Begin);
|
||||
_stream.Seek(realOffset, SeekOrigin.Begin);
|
||||
}
|
||||
Logger.Debug("Reading image {0}...", i);
|
||||
images[i] = new ImageReader(_stream).Read();
|
||||
images.Add(new Image.Reader(_stream).Read());
|
||||
}
|
||||
return images;
|
||||
}
|
|
@ -44,20 +44,24 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BitReader.cs" />
|
||||
<Compile Include="BitWriter.cs" />
|
||||
<Compile Include="Dithering\ColorError.cs" />
|
||||
<Compile Include="Dithering\FloydSteinbergDitherer.cs" />
|
||||
<Compile Include="ImageWriter.cs" />
|
||||
<Compile Include="ResourcesExtractor.cs" />
|
||||
<Compile Include="ResourcesHeader.cs" />
|
||||
<Compile Include="ImageReader.cs" />
|
||||
<Compile Include="ResourcesFileReader.cs" />
|
||||
<Compile Include="Models\FileDescriptor.cs" />
|
||||
<Compile Include="Utils\BitReader.cs" />
|
||||
<Compile Include="Utils\BitWriter.cs" />
|
||||
<Compile Include="Image\ColorError.cs" />
|
||||
<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\Header.cs" />
|
||||
<Compile Include="Image\Reader.cs" />
|
||||
<Compile Include="FileReader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ResourcesReader.cs" />
|
||||
<Compile Include="Reader.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,29 +0,0 @@
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class ResourcesExtractor
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly Bitmap[] _images;
|
||||
|
||||
public ResourcesExtractor(Bitmap[] images)
|
||||
{
|
||||
_images = images;
|
||||
}
|
||||
|
||||
public void Extract(string outputDirectory)
|
||||
{
|
||||
for (var i = 0; i < _images.Length; i++)
|
||||
{
|
||||
var fileName = Path.Combine(outputDirectory, $"{i}.png");
|
||||
Logger.Debug("Exporting {0}...", fileName);
|
||||
_images[i].Save(fileName, ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class ResourcesHeader
|
||||
{
|
||||
public const int HeaderSize = 20;
|
||||
private const string ResHeaderSignature = "HMRES";
|
||||
private readonly byte[] _header;
|
||||
|
||||
public ResourcesHeader(byte[] header)
|
||||
{
|
||||
_header = header;
|
||||
}
|
||||
|
||||
public string Signature => Encoding.ASCII.GetString(_header, 0, 5);
|
||||
public bool IsValid => Signature == ResHeaderSignature;
|
||||
public uint Version => _header[5];
|
||||
public uint ResourcesCount => BitConverter.ToUInt32(_header, 16);
|
||||
|
||||
public static ResourcesHeader ReadFrom(BinaryReader reader)
|
||||
{
|
||||
var buffer = reader.ReadBytes(HeaderSize);
|
||||
return new ResourcesHeader(buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Resources
|
||||
namespace Resources.Utils
|
||||
{
|
||||
public class BitReader
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Resources
|
||||
namespace Resources.Utils
|
||||
{
|
||||
public class BitWriter
|
||||
{
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
public class Writer
|
||||
{
|
||||
private const int OffsetTableItemLength = 4;
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly Stream _stream;
|
||||
|
||||
public Writer(Stream stream)
|
||||
{
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
public void Write(List<Bitmap> images)
|
||||
{
|
||||
var offsetsTable = new byte[images.Count * OffsetTableItemLength];
|
||||
var encodedImages = new MemoryStream[images.Count];
|
||||
|
||||
var offset = (uint) 0;
|
||||
for (var i = 0; i < images.Count; i++)
|
||||
{
|
||||
Logger.Trace("Image {0} offset is {1}...", i, offset);
|
||||
var offsetBytes = BitConverter.GetBytes(offset);
|
||||
offsetBytes.CopyTo(offsetsTable, i * OffsetTableItemLength);
|
||||
|
||||
var encodedImage = new MemoryStream();
|
||||
Logger.Debug("Encoding image {0}...", i);
|
||||
new Image.Writer(encodedImage).Write(images[i]);
|
||||
offset += (uint) encodedImage.Length;
|
||||
encodedImages[i] = encodedImage;
|
||||
}
|
||||
|
||||
Logger.Trace("Writing images offsets table");
|
||||
_stream.Write(offsetsTable, 0, offsetsTable.Length);
|
||||
|
||||
Logger.Debug("Writing images");
|
||||
foreach (var encodedImage in encodedImages)
|
||||
{
|
||||
encodedImage.Seek(0, SeekOrigin.Begin);
|
||||
encodedImage.CopyTo(_stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,13 +20,9 @@ namespace WatchFace.Parser.Models
|
|||
var buffer = new byte[HeaderSize];
|
||||
for (var i = 0; i < buffer.Length; i++) buffer[i] = 0xff;
|
||||
|
||||
var signature = Encoding.ASCII.GetBytes(Signature);
|
||||
var unknown = BitConverter.GetBytes(Unknown);
|
||||
var parametersSize = BitConverter.GetBytes(ParametersSize);
|
||||
|
||||
signature.CopyTo(buffer, 0);
|
||||
unknown.CopyTo(buffer, 32);
|
||||
parametersSize.CopyTo(buffer, 36);
|
||||
Encoding.ASCII.GetBytes(Signature).CopyTo(buffer, 0);
|
||||
BitConverter.GetBytes(Unknown).CopyTo(buffer, 32);
|
||||
BitConverter.GetBytes(ParametersSize).CopyTo(buffer, 36);
|
||||
stream.Write(buffer, 0, HeaderSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.2")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.2")]
|
||||
[assembly: AssemblyVersion("1.0.0.3")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.3")]
|
|
@ -2,7 +2,6 @@
|
|||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources;
|
||||
using WatchFace.Parser.Models;
|
||||
|
||||
namespace WatchFace.Parser
|
||||
|
@ -19,7 +18,7 @@ namespace WatchFace.Parser
|
|||
}
|
||||
|
||||
public List<Parameter> Parameters { get; private set; }
|
||||
public Bitmap[] Images { get; private set; }
|
||||
public List<Bitmap> Images { get; private set; }
|
||||
|
||||
public void Read()
|
||||
{
|
||||
|
@ -47,7 +46,7 @@ namespace WatchFace.Parser
|
|||
Logger.Trace("Watch face parameters locations were read:");
|
||||
|
||||
Parameters = ReadParameters(parametrsTableLength, parametersLocations);
|
||||
Images = new ResourcesReader(_stream).Read((uint) imagesCount);
|
||||
Images = new Resources.Reader(_stream).Read((uint) imagesCount);
|
||||
}
|
||||
|
||||
private List<Parameter> ReadParameters(long coordinatesTableSize, ICollection<Parameter> parametersDescriptors)
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace WatchFace.Parser.Utils
|
|||
|
||||
var fileName = Path.Combine(_imagesDirectory, $"{index}.png");
|
||||
var newImageIndex = Images.Count;
|
||||
Logger.Trace("Loading {0} image from file {1}", newImageIndex, fileName);
|
||||
Images.Add((Bitmap) Image.FromFile(fileName));
|
||||
_mapping[index] = newImageIndex;
|
||||
return newImageIndex;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Resources;
|
||||
using WatchFace.Parser.Models;
|
||||
using WatchFace.Parser.Utils;
|
||||
|
||||
|
@ -24,7 +22,10 @@ namespace WatchFace.Parser
|
|||
|
||||
public void Write(WatchFace watchFace)
|
||||
{
|
||||
Logger.Trace("Building parameters for watch face...");
|
||||
var descriptor = ParametersConverter.Build(watchFace);
|
||||
|
||||
Logger.Trace("Encoding parameters...");
|
||||
var encodedParameters = new Dictionary<byte, MemoryStream>(descriptor.Count);
|
||||
foreach (var parameter in descriptor)
|
||||
{
|
||||
|
@ -34,9 +35,9 @@ namespace WatchFace.Parser
|
|||
encodedParameters[parameter.Id] = memoryStream;
|
||||
}
|
||||
|
||||
Logger.Trace("Encoding offsets and lengths...");
|
||||
var parametersPositions = new List<Parameter>(descriptor.Count + 1);
|
||||
var offset = (long) 0;
|
||||
|
||||
foreach (var encodedParameter in encodedParameters)
|
||||
{
|
||||
var encodedParameterId = encodedParameter.Key;
|
||||
|
@ -58,6 +59,7 @@ namespace WatchFace.Parser
|
|||
foreach (var parametersPosition in parametersPositions)
|
||||
parametersPosition.Write(encodedParametersPositions);
|
||||
|
||||
Logger.Trace("Writing header...");
|
||||
var header = new Header
|
||||
{
|
||||
ParametersSize = (uint) encodedParametersPositions.Length,
|
||||
|
@ -65,43 +67,19 @@ namespace WatchFace.Parser
|
|||
};
|
||||
header.WriteTo(_stream);
|
||||
|
||||
Logger.Trace("Writing parameters offsets and lengths...");
|
||||
encodedParametersPositions.Seek(0, SeekOrigin.Begin);
|
||||
encodedParametersPositions.WriteTo(_stream);
|
||||
|
||||
Logger.Trace("Writing parameters...");
|
||||
foreach (var encodedParameter in encodedParameters)
|
||||
{
|
||||
var stream = encodedParameter.Value;
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
stream.WriteTo(_stream);
|
||||
}
|
||||
WriteImages();
|
||||
}
|
||||
|
||||
public void WriteImages()
|
||||
{
|
||||
var offsetsTable = new byte[_images.Count * 4];
|
||||
var encodedImages = new MemoryStream[_images.Count];
|
||||
|
||||
var offset = (uint) 0;
|
||||
for (var i = 0; i < _images.Count; i++)
|
||||
{
|
||||
var offsetBytes = BitConverter.GetBytes(offset);
|
||||
offsetBytes.CopyTo(offsetsTable, i * 4);
|
||||
|
||||
var encodedImage = new MemoryStream();
|
||||
Logger.Debug("Writing image {0}...", i);
|
||||
new ImageWriter(encodedImage).Write(_images[i]);
|
||||
offset += (uint) encodedImage.Length;
|
||||
encodedImages[i] = encodedImage;
|
||||
}
|
||||
|
||||
_stream.Write(offsetsTable, 0, offsetsTable.Length);
|
||||
|
||||
foreach (var encodedImage in encodedImages)
|
||||
{
|
||||
encodedImage.Seek(0, SeekOrigin.Begin);
|
||||
encodedImage.CopyTo(_stream);
|
||||
}
|
||||
Logger.Trace("Writing images...");
|
||||
new Resources.Writer(_stream).Write(_images);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -6,8 +7,10 @@ using NLog;
|
|||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using Resources;
|
||||
using WatchFace.Parser;
|
||||
using Resources.Models;
|
||||
using WatchFace.Parser.Utils;
|
||||
using Reader = WatchFace.Parser.Reader;
|
||||
using Writer = WatchFace.Parser.Writer;
|
||||
|
||||
namespace WatchFace
|
||||
{
|
||||
|
@ -22,12 +25,13 @@ namespace WatchFace
|
|||
if (args.Length == 0 || args[0] == null)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"{0}.exe unpacks and packs Amazfit Bip downloadable watch faces and unpacks res files.", AppName);
|
||||
"{0}.exe unpacks and packs Amazfit Bip downloadable watch faces and resource files.", AppName);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage examples:");
|
||||
Console.WriteLine(" {0}.exe watchface.bin - unpacks watchface images and config", AppName);
|
||||
Console.WriteLine(" {0}.exe watchface.res - unpacks resource file images", AppName);
|
||||
Console.WriteLine(" {0}.exe watchface.json - packs config and referenced images to bin file", AppName);
|
||||
Console.WriteLine(" {0}.exe watchface.bin - unpacks watchface images and config", AppName);
|
||||
Console.WriteLine(" {0}.exe watchface.json - packs config and referenced images to bin file", AppName);
|
||||
Console.WriteLine(" {0}.exe mili_chaohu.res - unpacks resource file images", AppName);
|
||||
Console.WriteLine(" {0}.exe mili_chaohu - packs folder content to res file", AppName);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,9 +40,24 @@ namespace WatchFace
|
|||
|
||||
foreach (var inputFileName in args)
|
||||
{
|
||||
if (!File.Exists(inputFileName))
|
||||
var isDirectory = Directory.Exists(inputFileName);
|
||||
var isFile = File.Exists(inputFileName);
|
||||
if (!isDirectory && !isFile)
|
||||
{
|
||||
Console.WriteLine("File '{0}' doesn't exists.", inputFileName);
|
||||
Console.WriteLine("File or directory '{0}' doesn't exists.", inputFileName);
|
||||
continue;
|
||||
}
|
||||
if (isDirectory)
|
||||
{
|
||||
Console.WriteLine("Processing directory '{0}'", inputFileName);
|
||||
try
|
||||
{
|
||||
PackResources(inputFileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Fatal(e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -105,23 +124,57 @@ namespace WatchFace
|
|||
if (watchFace == null) return;
|
||||
|
||||
Logger.Debug("Exporting resources to '{0}'", outputDirectory);
|
||||
new ResourcesExtractor(reader.Images).Extract(outputDirectory);
|
||||
var reDescriptor = new FileDescriptor {Images = reader.Images};
|
||||
new Extractor(reDescriptor).Extract(outputDirectory);
|
||||
ExportConfig(watchFace, Path.Combine(outputDirectory, $"{baseName}.json"));
|
||||
}
|
||||
|
||||
private static void PackResources(string inputDirectory)
|
||||
{
|
||||
var outputDirectory = Path.GetDirectoryName(inputDirectory);
|
||||
var baseName = Path.GetFileName(inputDirectory);
|
||||
var outputFileName = Path.Combine(outputDirectory, $"{baseName}_packed.res");
|
||||
var logFileName = Path.Combine(outputDirectory, $"{baseName}_packed.log");
|
||||
SetupLogger(logFileName);
|
||||
|
||||
var versionFileName = Path.Combine(inputDirectory, "version");
|
||||
var resDescriptor = new FileDescriptor();
|
||||
using (var stream = File.OpenRead(versionFileName))
|
||||
using (var reader = new BinaryReader(stream))
|
||||
{
|
||||
resDescriptor.Version = reader.ReadByte();
|
||||
}
|
||||
var i = 0;
|
||||
var images = new List<Bitmap>();
|
||||
while (true)
|
||||
{
|
||||
var fileName = Path.Combine(inputDirectory, $"{i}.png");
|
||||
if (!File.Exists(fileName)) break;
|
||||
|
||||
images.Add((Bitmap) Image.FromFile(fileName));
|
||||
i++;
|
||||
}
|
||||
resDescriptor.Images = images;
|
||||
|
||||
using (var stream = File.OpenWrite(outputFileName))
|
||||
{
|
||||
new FileWriter(stream).Write(resDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnpackResources(string inputFileName)
|
||||
{
|
||||
var outputDirectory = CreateOutputDirectory(inputFileName);
|
||||
var baseName = Path.GetFileNameWithoutExtension(inputFileName);
|
||||
SetupLogger(Path.Combine(outputDirectory, $"{baseName}.log"));
|
||||
|
||||
Bitmap[] images;
|
||||
FileDescriptor resDescriptor;
|
||||
using (var stream = File.OpenRead(inputFileName))
|
||||
{
|
||||
images = new ResourcesFileReader(stream).Read();
|
||||
resDescriptor = FileReader.Read(stream);
|
||||
}
|
||||
|
||||
new ResourcesExtractor(images).Extract(outputDirectory);
|
||||
new Extractor(resDescriptor).Extract(outputDirectory);
|
||||
}
|
||||
|
||||
private static void WriteWatchFace(string outputFileName, string imagesDirectory, Parser.WatchFace watchFace)
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.2")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.2")]
|
||||
[assembly: AssemblyVersion("1.0.0.3")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.3")]
|
Loading…
Reference in New Issue