ImageMagick6 icon indicating copy to clipboard operation
ImageMagick6 copied to clipboard

Inkscape SVG processing broken with MagickReadImageBlob

Open Danack opened this issue 3 years ago • 0 comments

ImageMagick version

6-6.9.12-58

Operating system

Linux

Operating system, version and so on

Debian

Description

I have an SVG that is processed successfully when read with MagickReadImage(). I have Inkscape installed and ImageMagick is successfully delegating the image processing to it.

When processing the same image with MagickReadImageBlob it fails to be processed by Inkscape.

From looking at the output of strace, by running strace -f -v -s 1024 ./test > strace_output.txt 2>&1, I think the problem is that:

  1. ImageMagick symlinks the directory.
[pid   232] symlink("/var/app/bugs/gh551/", "/tmp/magick-sMox8_sIP_c_AtemZ9uRqYUwd4Gkq5yL") = 0
  1. ImageMagick invokes inkscape with that symlinked directory as the filename.
[pid   238] execve("/bin/sh", ["sh", "-c", "'inkscape' '/tmp/magick-sMox8_sIP_c_AtemZ9uRqYUwd4Gkq5yL' --export-filename='/tmp/magick-Vw4zM-TKHyiX7SIalXaQ7aaYOZhAb5zL.png' --export-dpi='96' --export-background='rgb(100%,100%,100%)' --export-background-opacity='1' > '/tmp/magick-f_1o0qhhHqyqsUXt4wI9Dsg2EGyRo7XI' 2>&1"], ["HOSTNAME=09f1b8b41433", "PWD=/var/app/bugs/gh551", "HOME=/root", "TERM=xterm", "SHLVL=1", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "OLDPWD=/var/app/bugs", "_=/usr/bin/strace"] <unfinished ...>
  1. Inkscape tries to open the 'file' to read it, but it's a directory, so it can't read any data.
[pid   239] access("/tmp/magick-sMox8_sIP_c_AtemZ9uRqYUwd4Gkq5yL", F_OK) = 0
[pid   239] openat(AT_FDCWD, "/tmp/magick-sMox8_sIP_c_AtemZ9uRqYUwd4Gkq5yL", O_RDONLY) = 5
[pid   239] fstat(5, {st_dev=makedev(0, 0x75), st_ino=8633408362, st_mode=S_IFDIR|0755, st_nlink=14, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=448, st_atime=1658435866 /* 2022-07-21T20:37:46.152274720+0000 */, st_atime_nsec=152274720, st_mtime=1658435865 /* 2022-07-21T20:37:45.626572031+0000 */, st_mtime_nsec=626572031, st_ctime=1658435865 /* 2022-07-21T20:37:45.626572031+0000 */, st_ctime_nsec=626572031}) = 0
[pid   239] read(5, 0x5607b62e7f00, 4096) = -1 EISDIR (Is a directory)
[pid   239] read(5, 0x5607b62e7f00, 4096) = -1 EISDIR (Is a directory)
[pid   239] write(2, "/tmp/magick-sMox8_sIP_c_AtemZ9uRqYUwd4Gkq5yL:1: ", 48) = 48
[pid   239] write(2, "parser ", 7)      = 7
[pid   239] write(2, "error : ", 8)     = 8
[pid   239] write(2, "Document is empty\n", 18) = 18

Steps to Reproduce

This code reproduces the problem:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <wand/MagickWand.h>

// strace -f -s 256 ./test > strace_output_c_api.txt 2>&1
// strace -f -s 256 convert source.svg output_convert.png > strace_convert.txt 2>&1

int main(int argc,char **argv) {
  MagickWand *magick_wand;
  MagickBooleanType status;

  MagickWandGenesis();

  // Read from file.
  magick_wand = NewMagickWand();
  status = MagickReadImage(magick_wand, "./source.svg");
  if (status == MagickFalse) {
    printf("Failed to MagickReadImage");
    return -1;
  }

  MagickSetImageFormat(magick_wand, "png");

  status = MagickWriteImages(magick_wand, "./output_from_file.png", MagickTrue);
  if (status == MagickFalse) {
        printf("Failed to MagickWriteImages");
        return -1;
  }

  // Read from blob
  magick_wand = NewMagickWand();

  FILE *f = fopen("./source.svg", "rb");
  fseek(f, 0, SEEK_END);
  long fsize = ftell(f);
  fseek(f, 0, SEEK_SET);  /* same as rewind(f); */

  char *string = malloc(fsize + 1);
  int count = fread(string, fsize, 1, f);
  fclose(f);

  if (count != 1) {
    printf("Failed to read source file.\n");
    exit(-1);
  }

  printf("About to MagickReadImageBlob\n.");

  status = MagickReadImageBlob(
    magick_wand,
    string,
    fsize
  );

  if (status == MagickFalse) {
    printf("Failed to MagickReadImage");
    return -1;
  }

  MagickSetImageFormat(magick_wand, "png");

  status = MagickWriteImages(magick_wand, "./output_from_blob.png", MagickTrue);
  if (status == MagickFalse) {
    printf("Failed to MagickWriteImages");
    return -1;
  }

  printf("Fin.\n");

  MagickWandTerminus();

  return(0);
}

Images

Source image 'source.svg' source

output_from_file.png output_from_file

output_from_blob.png output_from_blob - it is falling back to the built-in ImageMagick SVG processing, which doesn't like this source image much.

Danack avatar Jul 21 '22 21:07 Danack