All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.bottlecaps.railroad.core.RsvgPngTranscoder Maven / Gradle / Ivy

package de.bottlecaps.railroad.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

import net.sf.saxon.Configuration;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XdmNode;

public class RsvgPngTranscoder implements PngTranscoder
{
  public static final String RSVG_CONVERT_PROPERTY = "rsvg.convert";
  public static final String RSVG_CONVERT_DEFAULT = "rsvg-convert";
  private String rsvgConvert = rsvgConvertPath();

  public static String rsvgConvertPath() {
    String rsvgPath = System.getProperty(RSVG_CONVERT_PROPERTY);
    return rsvgPath != null ? rsvgPath : RSVG_CONVERT_DEFAULT;
  }

  @Override
  public void transcode(XdmNode svg, OutputStream o) throws Exception {
    File pngFile = File.createTempFile(XhtmlToZip.class.getName() + "-", ".png");
    String pngFileName = pngFile.getAbsolutePath();
    String nativeFileName = pngFileName;

    // Avoid problems due to Windows file system redirection,
    // when running inside of a 64 bit container.

    if ("amd64".equals(System.getProperty("os.arch")))
    {
      nativeFileName = pngFileName.replaceFirst("\\\\[Ss][Yy][Ss][Tt][Ee][Mm]32\\\\", "\\\\sysnative\\\\");
    }

    try
    {
      String[] commandLine = {rsvgConvert, "-o", nativeFileName};
//    System.out.println("executing " + Arrays.toString(commandLine));
      Process proc = Runtime.getRuntime().exec(commandLine);

      OutputStream stdin = proc.getOutputStream();
      Serializer serializer = new Processor(new Configuration()).newSerializer(stdin);
      serializer.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "no");
      serializer.setOutputProperty(Serializer.Property.INDENT, "yes");
      serializer.serializeNode(svg);
      stdin.close();

      StreamCollector stderr = new StreamCollector(proc.getErrorStream());
      StreamCollector stdout = new StreamCollector(proc.getInputStream());

      try
      {
        int exitCode = proc.waitFor();
        if (exitCode != 0)
        {
          throw new RuntimeException(rsvgConvert + " returned exit code " + exitCode + ", " + stderr + " " + stdout);
        }
      }
      catch (InterruptedException e)
      {
        throw new RuntimeException(e.getMessage(), e);
      }

      try (FileInputStream fis = new FileInputStream(pngFile))
      {
        byte[] buffer = new byte[2 * 1024 * 1024];
        int size = 0;
        for (int n = 0; n >= 0; n = fis.read(buffer, size, buffer.length - size))
        {
          size += n;
          if (size == buffer.length)
          {
            for (; fis.read() >= 0; ) {}
            break;
          }
        }
        o.write(buffer, 0, size);
      }
    }
    finally
    {
      pngFile.delete();
    }
  }

  private static class StreamCollector extends Thread
  {
    InputStream stream;
    String string;

    public StreamCollector(InputStream s)
    {
      stream = s;
      string = null;
      start();
    }

    @Override
    public String toString()
    {
      if (string == null)
      {
        try
        {
          join();
        }
        catch (InterruptedException e)
        {
          throw new RuntimeException(e.getMessage(), e);
        }
      }
      return string;
    }

    @Override
    public void run()
    {
      try
      {
        byte[] buffer = new byte[2 * 1024 * 1024];
        int size = 0;
        for (int n = 0; n >= 0; n = stream.read(buffer, size, buffer.length - size))
        {
          size += n;
          if (size == buffer.length)
          {
            for (; stream.read() >= 0; ) {}
            break;
          }
        }
        string = new String(buffer, 0, size, StandardCharsets.UTF_8);
      }
      catch (IOException e)
      {
        throw new RuntimeException(e.getMessage(), e);
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy