OverviewFilesCommitsIssuesDocsReleasesPeers

ifsrenderer-linux / IFSEngine / Serialization / FlameFormatExporter.cs

76 lines · csharp ref:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

using IFSEngine.Model;

namespace IFSEngine.Serialization;

/// <summary>
/// Exports palette collections to flame format files (*.gradient / *.ugr).
/// </summary>
public static class FlameFormatExporter
{
    private const int SampleCount = 400;

    /// <summary>
    /// Export a palette collection as a flame format file.
    /// </summary>
    /// <param name="collection">The collection to export.</param>
    /// <param name="filePath">Output file path.</param>
    /// <exception cref="InvalidOperationException">Thrown when the collection has no palettes.</exception>
    public static async Task ExportCollectionAsync(PaletteCollection collection, string filePath)
    {
        if (collection.Palettes.Count == 0)
            throw new InvalidOperationException("Cannot export an empty collection.");

        var sb = new StringBuilder();

        foreach (var palette in collection.Palettes)
        {
            sb.Append($"{{ title=\"{EscapeFlameString(palette.Name)}\" rotation=0");

            // Sample the gradient at 400 positions
            for (int i = 0; i < SampleCount; i++)
            {
                double position = (double)i / (SampleCount - 1);
                Vector4 color = palette.SampleGradient(position);

                // Convert to BGR integer (flame format stores color as BGR packed int)
                int b = (byte)(color.Z * 255);
                int g = (byte)(color.Y * 255);
                int r = (byte)(color.X * 255);
                int packedColor = r | (g << 8) | (b << 16);

                sb.Append($" index={i} color={packedColor}");
            }

            sb.Append("} ");
        }

        await File.WriteAllTextAsync(filePath, sb.ToString(), Encoding.UTF8);
    }

    /// <summary>
    /// Export a single palette as a flame format file.
    /// </summary>
    public static async Task ExportPaletteAsync(ColorPalette palette, string filePath)
    {
        var collection = new PaletteCollection
        {
            Name = palette.Name,
            Palettes = [palette]
        };
        await ExportCollectionAsync(collection, filePath);
    }

    private static string EscapeFlameString(string input)
    {
        return input.Replace("\\", "\\\\").Replace("\"", "\\\"");
    }
}