78 lines
2.5 KiB
C#
78 lines
2.5 KiB
C#
using LibDgf.Aqualead.Image;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace LibDgf.Aqualead.Image.Conversion
|
|
{
|
|
public class PkmConverter : IAlImageConverter
|
|
{
|
|
public string FileExtension => ".pkm";
|
|
|
|
public void ConvertFromAl(AlImage image, Stream destStream)
|
|
{
|
|
List<byte[]> mips;
|
|
if (image.PixelFormat == "ETC1")
|
|
{
|
|
mips = image.Mipmaps;
|
|
}
|
|
else if (image.PixelFormat == "EC1A")
|
|
{
|
|
// Give first half of the mips
|
|
mips = new List<byte[]>();
|
|
byte[] newMip = new byte[image.Mipmaps[0].Length / 2];
|
|
Buffer.BlockCopy(image.Mipmaps[0], 0, newMip, 0, newMip.Length);
|
|
mips.Add(newMip);
|
|
}
|
|
else
|
|
{
|
|
throw new ArgumentException("Pixel format not supported.", nameof(image));
|
|
}
|
|
|
|
WritePkm(destStream, mips[0], image.Width, image.Height);
|
|
}
|
|
|
|
public void ConvertFromAlAlt(AlImage image, Stream destStream)
|
|
{
|
|
if (image.PixelFormat != "EC1A")
|
|
throw new ArgumentException("Pixel format does not have alternate representation.", nameof(image));
|
|
|
|
// Give second half of the mips
|
|
byte[] newMip = new byte[image.Mipmaps[0].Length / 2];
|
|
Buffer.BlockCopy(image.Mipmaps[0], newMip.Length, newMip, 0, newMip.Length);
|
|
|
|
WritePkm(destStream, newMip, image.Width, image.Height);
|
|
}
|
|
|
|
public bool CanConvert(string pixelFormat)
|
|
{
|
|
return pixelFormat == "EC1A" || pixelFormat == "ETC1";
|
|
}
|
|
|
|
public bool HasAlternativeFile(AlImage image)
|
|
{
|
|
return image.PixelFormat == "EC1A";
|
|
}
|
|
|
|
const ushort ETC1_RGB_NO_MIPMAPS = 0;
|
|
|
|
static void WritePkm(Stream stream, byte[] data, uint width, uint height)
|
|
{
|
|
BinaryWriter bw = new BinaryWriter(stream);
|
|
bw.Write("PKM 10".ToCharArray());
|
|
WriteBeUInt16(bw, ETC1_RGB_NO_MIPMAPS);
|
|
WriteBeUInt16(bw, (ushort)((width + 3) & ~3));
|
|
WriteBeUInt16(bw, (ushort)((height + 3) & ~3));
|
|
WriteBeUInt16(bw, (ushort)width);
|
|
WriteBeUInt16(bw, (ushort)height);
|
|
bw.Write(data);
|
|
}
|
|
|
|
static void WriteBeUInt16(BinaryWriter bw, ushort value)
|
|
{
|
|
bw.Write((byte)(value >> 8));
|
|
bw.Write((byte)value);
|
|
}
|
|
}
|
|
}
|