1

I am using the Windows libvips CLI to convert images from HEIC to PNG format. I want to pipe the converted output to another process without writing to disk. This can be achieved by writing to stdout (i.e. typing only the file extension as output file):

vips copy input.heic .png

However, if I write to a file instead:

vips copy input.heic output.png

and compare the stdout byte stream to the contents of output.png, they are somewhat different. Indeed, writing stdout to a file results in a corrupted PNG.

Further analysis made me realise that the difference between stdout and output.png is a large number of randomly placed CR characters in stdout that are not present in the file. Everything else is identical.

Is there any way to get the right byte stream in stdout as it was read from output.png?

Alreiber
  • 19
  • 4

1 Answers1

0

It looks like you've hit a bug --- Windows creates stdin and stdout in text mode, so when libvips writes to stdout, any newline characters will be automatically expanded to newline + carriage return.

When running on win, libvips probably needs to call _setmode(1, O_BINARY); to force binary mode before writing image data. I've pushed a patch to libvips 8.10 and credited you. This fix will be in 8.10.3, due in a week or two.

jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • You are totally right. I have searched the byte stream for `LF` and there is always a `CR` preceding. As a temporary patch I have replaced all those `CRLF` with `LF` and now the byte stream matches the `output.png` read. Thanks! – Alreiber Nov 26 '20 at 20:18
  • You could also use something like python -- you can write a 5 line program to open a file descriptor in binary mode and write to that, It would be safer than changing all cr-lf pairs. Sample code here: https://libvips.github.io/libvips/2019/11/29/True-streaming-for-libvips.html – jcupitt Nov 27 '20 at 09:13