lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.26k stars 1.3k forks source link

Clarification needed: Magick formats support #347

Closed oaleynik closed 8 years ago

oaleynik commented 8 years ago

Hey @lovell!

Just wondering, if libvips compiled with the --with-imagemagick flag, does it mean that sharp should be able to read (at least) all of the file formats listed here http://www.imagemagick.org/script/formats.php?

I did the simple test. From the list of the magick formats I took RWs and using PNG 100x100 image as input I generated set of 80 images.

echo {AAI,ART,AVS,BMP,BMP2,BMP3,CIN,CLIPBOARD,DCX,DDS,DIB,DPX,EPDF,EPI,EPS,EPSF,EPSI,EPT,EXR,FAX,FITS,FPX,GIF,HDR,HRZ,INLINE,J2C,J2K,JBIG,JNG,JP2,JPEG,JPT,MIFF,MNG,MPC,MPR,MTV,OTB,P7,PALM,PBM,PCD,PCDS,PCX,PDB,PDF,PFM,PGM,PICON,PICT,PNG00,PNG24,PNG32,PNG48,PNG64,PNG8,PNM,PPM,PS,PS2,PS3,PSB,PSD,PTIF,RFG,SGI,SUN,SVG,TGA,TIFF,TXT,VICAR,VIFF,WBMP,WEBP,X,XBM,XPM,XWD} | xargs -n 1 -I {} convert image.png -format {} image.{}

Running identify * gives the following results:

image.AAI AAI 100x100 100x100+0+0 8-bit sRGB 40KB 0.000u 0:00.000
image.ART ART 100x100 100x100+0+0 1-bit sRGB 2c 1.41KB 0.000u 0:00.000
image.AVS AVS 100x100 100x100+0+0 8-bit sRGB 40KB 0.000u 0:00.000
image.BMP BMP 100x100 100x100+0+0 8-bit sRGB 40.1KB 0.000u 0:00.000
image.BMP2 BMP2 100x100 100x100+0+0 8-bit sRGB 30KB 0.000u 0:00.000
image.BMP3 BMP3 100x100 100x100+0+0 8-bit sRGB 30.1KB 0.000u 0:00.000
image.CIN CIN 100x100 100x100+0+0 8-bit sRGB 32KB 0.000u 0:00.000
image.CLIPBOARD PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.DCX DCX 100x100 100x100+0+0 8-bit sRGB 6.23KB 0.000u 0:00.000
image.DDS DDS 100x100 100x100+0+0 8-bit sRGB 10.1KB 0.000u 0:00.000
image.DIB DIB 100x100 100x100+0+0 8-bit sRGB 40KB 0.000u 0:00.000
image.DPX DPX 100x100 100x100+0+0 16-bit RGB 48.2KB 0.000u 0:00.000
image.EPDF PDF 100x100 100x100+0+0 16-bit Bilevel Gray 1.36KB 0.000u 0:00.000
image.EPI PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.EPS PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.EPSF PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.EPSI PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.EPT EPT 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.EXR PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.FAX FAX 2592x3508 2592x3508+0+0 8-bit sRGB 2c 465B 0.000u 0:00.000
image.FITS[0] FITS 100x100 100x100+0+0 8-bit Grayscale Gray 34.6KB 0.000u 0:00.000
image.FITS[1] FITS 100x100 100x100+0+0 8-bit Grayscale Gray 34.6KB 0.000u 0:00.000
image.FITS[2] FITS 100x100 100x100+0+0 8-bit Grayscale Gray 34.6KB 0.000u 0:00.000
image.FPX PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.GIF GIF 100x100 100x100+0+0 8-bit sRGB 8c 261B 0.000u 0:00.000
image.HDR HDR 100x100 100x100+0+0 16-bit RGB 1.81KB 0.000u 0:00.000
image.HRZ HRZ 256x240 256x240+0+0 8-bit sRGB 184KB 0.000u 0:00.000
image.INLINE PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.J2C PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.J2K PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.JBIG PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.JNG JNG 100x100 100x100+0+0 16-bit sRGB 533B 0.000u 0:00.000
image.JP2 PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.JPEG JPEG 100x100 100x100+0+0 8-bit sRGB 626B 0.000u 0:00.000
image.JPT PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.MIFF MIFF 100x100 100x100+0+0 8-bit Palette sRGB 6c 10.9KB 0.000u 0:00.000
image.MNG MNG 100x100 100x100+0+0 8-bit sRGB 5c 309B 0.000u 0:00.000
image.MPC MPC 100x100 100x100+0+0 8-bit sRGB 6c 894B 0.000u 0:00.000
image.MPR PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.MTV MTV 100x100 100x100+0+0 8-bit sRGB 30KB 0.000u 0:00.000
image.OTB OTB 100x100 100x100+0+0 16-bit sRGB 2c 1.3KB 0.000u 0:00.000
image.P7 PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.PALM PALM 100x100 100x100+0+0 8-bit sRGB 16c 5.02KB 0.000u 0:00.000
image.PBM PBM 100x100 100x100+0+0 1-bit Bilevel Gray 1.31KB 0.000u 0:00.000
image.PCD PCD 768x512 768x512+0+0 8-bit YCC 788KB 0.000u 0:00.000
image.PCDS PCD 768x512 768x512+0+0 8-bit YCC 788KB 0.000u 0:00.000
image.PCX PCX 100x100 100x100+0+0 8-bit sRGB 256c 1.44KB 0.000u 0:00.000
image.PDB PDB 112x100 112x100+0+0 8-bit sRGB 16c 5.8KB 0.000u 0:00.000
image.PDF PDF 100x100 100x100+0+0 16-bit Bilevel Gray 1.36KB 0.000u 0:00.000
image.PFM PFM 100x100 100x100+0+0 32-bit TrueColor sRGB 120KB 0.000u 0:00.000
image.PGM PGM 100x100 100x100+0+0 8-bit Grayscale Gray 10KB 0.000u 0:00.000
image.PICON XPM 48x48 48x48+0+0 8-bit sRGB 30c 3.04KB 0.000u 0:00.000
image.PICT PICT 100x100 100x100+0+0 8-bit sRGB 1.18KB 0.000u 0:00.000
image.PNG00 PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.PNG24 PNG 100x100 100x100+0+0 8-bit sRGB 625B 0.000u 0:00.000
image.PNG32 PNG 100x100 100x100+0+0 8-bit sRGB 656B 0.000u 0:00.000
image.PNG48 PNG 100x100 100x100+0+0 16-bit sRGB 709B 0.000u 0:00.000
image.PNG64 PNG 100x100 100x100+0+0 16-bit sRGB 721B 0.000u 0:00.000
image.PNG8 PNG 100x100 100x100+0+0 8-bit sRGB 5c 425B 0.000u 0:00.000
image.PNM PPM 100x100 100x100+0+0 8-bit sRGB 30KB 0.000u 0:00.000
image.PPM PPM 100x100 100x100+0+0 8-bit sRGB 30KB 0.000u 0:00.000
image.PS PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.PS2 PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.PS3 PS 100x100 100x100+0+0 16-bit sRGB 541B 0.000u 0:00.000
image.PSB PSD 100x100 100x100+0+0 8-bit sRGB 256c 10.8KB 0.000u 0:00.000
image.PSD PSD 100x100 100x100+0+0 8-bit sRGB 256c 10.8KB 0.000u 0:00.000
image.PTIF[0] TIFF 100x100 100x100+0+0 8-bit sRGB 16c 960B 0.000u 0:00.000
image.PTIF[1] TIFF 50x50 50x50+0+0 8-bit sRGB 960B 0.000u 0:00.000
image.RFG PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.SGI SGI 100x100 100x100+0+0 8-bit sRGB 4.31KB 0.000u 0:00.000
image.SUN SUN 100x100 100x100+0+0 8-bit sRGB 6c 10.1KB 0.000u 0:00.000
image.SVG SVG 100x100 100x100+0+0 16-bit sRGB 1.08KB 0.000u 0:00.000
image.TGA TGA 100x100 100x100+0+0 8-bit sRGB 6c 10KB 0.000u 0:00.000
image.TIFF TIFF 100x100 100x100+0+0 8-bit sRGB 16c 518B 0.000u 0:00.000
image.TXT TXT 100x100 100x100+0+0 8-bit sRGB 538KB 0.000u 0:00.000
image.VICAR VICAR 100x100 100x100+0+0 8-bit sRGB 14.1KB 0.000u 0:00.000
image.VIFF VIFF 100x100 100x100+0+0 16-bit sRGB 6c 11KB 0.000u 0:00.000
image.WBMP WBMP 100x100 100x100+0+0 16-bit sRGB 2c 1.3KB 0.000u 0:00.000
Decoded /var/tmp/magick-31780XAkadkWpfoBk. Dimensions: 100 x 100 . Format: lossy. Now saving...
Saved file /var/tmp/magick-317809VEaZ8r2WOuG
image.WEBP PAM 100x100 100x100+0+0 8-bit TrueColor sRGB 40.1KB 0.000u 0:00.000
image.X PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.XBM XBM 100x100 100x100+0+0 8-bit sRGB 2c 8.21KB 0.000u 0:00.000
image.XPM XPM 100x100 100x100+0+0 8-bit sRGB 6c 10.6KB 0.000u 0:00.000
image.XWD PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000
image.png PNG 100x100 100x100+0+0 8-bit sRGB 6c 431B 0.000u 0:00.000

So, ImageMagick can easily read metadata of all of the generated images. However, if run sharp through the set of the same images and try to get their metadata I have the following picture:

image.AAI      : null
image.ART      : null
image.AVS      : null
image.BMP      : 100x100
image.BMP2     : 100x100
image.BMP3     : 100x100
image.CIN      : null
image.CLIPBOARD: 100x100
image.DCX      : 100x100
image.DDS      : null
image.DIB      : 100x100
image.DPX      : 100x100
image.EPDF     : 100x100
image.EPI      : 100x100
image.EPS      : 100x100
image.EPSF     : 100x100
image.EPSI     : 100x100
image.EPT      : 100x100
image.EXR      : 100x100
image.FAX      : null
image.FITS     : 100x100
image.FPX      : 100x100
image.GIF      : 100x100
image.HDR      : null
image.HRZ      : null
image.INLINE   : 100x100
image.J2C      : 100x100
image.J2K      : 100x100
image.JBIG     : 100x100
image.JNG      : 100x100
image.JP2      : 100x100
image.JPEG     : 100x100
image.JPT      : 100x100
image.MIFF     : 100x100
image.MNG      : 100x100
image.MPC      : null
image.MPR      : 100x100
image.MTV      : null
image.OTB      : null
image.P7       : 100x100
image.PALM     : null
image.PBM      : 100x100
image.PCD      : 768x512
image.PCDS     : 768x512
image.PCX      : 100x100
image.PDB      : 112x100
image.PDF      : 100x100
image.PFM      : null
image.PGM      : 100x100
image.PICON    : 48x48
image.PICT     : 100x100
image.PNG00    : 100x100
image.PNG24    : 100x100
image.PNG32    : 100x100
image.PNG48    : 100x100
image.PNG64    : 100x100
image.PNG8     : 100x100
image.PNM      : 100x100
image.PPM      : 100x100
image.PS       : 100x100
image.PS2      : 100x100
image.PS3      : 100x100
image.PSB      : null
image.PSD      : 100x100
image.PTIF     : 100x100
image.RFG      : 100x100
image.SGI      : 100x100
image.SUN      : 100x100
image.SVG      : null
image.TGA      : null
image.TIFF     : 100x100
image.TXT      : null
image.VICAR    : 100x100
image.VIFF     : 100x100
image.WBMP     : null
image.WEBP     : null
image.X        : 100x100
image.XBM      : 100x100
image.XPM      : 100x100
image.XWD      : 100x100

Am I missing something and libvips requires some extra flags to be compiled with?

oaleynik commented 8 years ago

Tried to compile libvips with the all possible flags. The only change I see is webp format was read successfully.

oaleynik commented 8 years ago

Running vipsheader * gives interesting results:

vipsheader: VipsForeignLoad: "image.AAI" is not a known file format
image.ART: 100x100 uchar, 1 band, rgb, magickload
image.AVS: 100x100 uchar, 3 bands, rgb, magickload
image.BMP: 100x100 uchar, 3 bands, rgb, magickload
image.BMP2: 100x100 uchar, 3 bands, rgb, magickload
image.BMP3: 100x100 uchar, 3 bands, rgb, magickload
vipsheader: magick2vips: unable to read file "image.CIN"
libMagick error: Unexpected end-of-file image.CIN
image.CLIPBOARD: 100x100 uchar, 3 bands, srgb, pngload
image.DCX: 100x100 uchar, 3 bands, rgb, magickload
vipsheader: VipsForeignLoad: "image.DDS" is not a known file format
image.DIB: 100x100 uchar, 3 bands, rgb, magickload
image.DPX: 100x100 uchar, 4 bands, rgb, magickload
image.EPDF: 100x100 uchar, 3 bands, rgb, magickload
image.EPI: 100x100 uchar, 3 bands, rgb, magickload
image.EPS: 100x100 uchar, 3 bands, rgb, magickload
image.EPSF: 100x100 uchar, 3 bands, rgb, magickload
image.EPSI: 100x100 uchar, 3 bands, rgb, magickload
image.EPT: 100x100 uchar, 3 bands, rgb, magickload
image.EXR: 100x100 uchar, 3 bands, srgb, pngload
image.FAX: 2592x100 uchar, 1 band, rgb, magickload
image.FITS: 100x100 uchar, 3 bands, rgb, fitsload
image.FPX: 100x100 uchar, 3 bands, srgb, pngload
image.GIF: 100x100 uchar, 3 bands, rgb, magickload
image.HDR: 100x100, rad, radload
image.HRZ: 256x240 uchar, 3 bands, rgb, magickload
image.INLINE: 100x100 uchar, 3 bands, srgb, pngload
image.J2C: 100x100 uchar, 3 bands, srgb, pngload
image.J2K: 100x100 uchar, 3 bands, srgb, pngload
image.JBIG: 100x100 uchar, 3 bands, srgb, pngload
image.JNG: 100x100 ushort, 3 bands, rgb16, magickload
image.JP2: 100x100 uchar, 3 bands, srgb, pngload
image.JPEG: 100x100 uchar, 3 bands, srgb, jpegload
image.JPT: 100x100 uchar, 3 bands, srgb, pngload
image.MIFF: 100x100 uchar, 3 bands, rgb, magickload
image.MNG: 100x100 uchar, 3 bands, rgb, magickload
vipsheader: VipsForeignLoad: "image.MPC" is not a known file format
image.MPR: 100x100 uchar, 3 bands, srgb, pngload
image.MTV: 100x100 uchar, 3 bands, rgb, magickload
image.OTB: 100x100 ushort, 1 band, rgb16, magickload
image.P7: 100x100 uchar, 3 bands, srgb, pngload
image.PALM: 100x100 uchar, 1 band, rgb, magickload
image.PBM: 100x100 uchar, 1 band, b-w, ppmload
image.PCD: 768x512 uchar, 3 bands, rgb, magickload
image.PCDS: 768x512 uchar, 3 bands, rgb, magickload
image.PCX: 100x100 uchar, 3 bands, rgb, magickload
image.PDB: 112x100 uchar, 1 band, rgb, magickload
image.PDF: 100x100 uchar, 3 bands, rgb, magickload
image.PFM: 100x100 float, 3 bands, srgb, ppmload
image.PGM: 100x100 uchar, 1 band, b-w, ppmload
image.PICON: 48x48 uchar, 3 bands, rgb, magickload
image.PICT: 100x100 ushort, 3 bands, rgb16, magickload
image.PNG00: 100x100 uchar, 3 bands, srgb, pngload
image.PNG24: 100x100 uchar, 3 bands, srgb, pngload
image.PNG32: 100x100 uchar, 4 bands, srgb, pngload
image.PNG48: 100x100 ushort, 3 bands, rgb16, pngload
image.PNG64: 100x100 ushort, 4 bands, rgb16, pngload
image.PNG8: 100x100 uchar, 3 bands, srgb, pngload
image.PNM: 100x100 uchar, 3 bands, srgb, ppmload
image.PPM: 100x100 uchar, 3 bands, srgb, ppmload
image.PS: 100x100 uchar, 3 bands, rgb, magickload
image.PS2: 100x100 uchar, 3 bands, rgb, magickload
image.PS3: 100x100 uchar, 3 bands, rgb, magickload
vipsheader: VipsForeignLoad: "image.PSB" is not a known file format
image.PSD: 100x100 uchar, 3 bands, rgb, magickload
vips warning: tiff2vips: no resolution information for TIFF image "image.PTIF" -- defaulting to 1 pixel per mm
image.PTIF: 100x100 uchar, 3 bands, srgb, tiffload
image.RFG: 100x100 uchar, 3 bands, srgb, pngload
image.SGI: 100x100 uchar, 3 bands, rgb, magickload
image.SUN: 100x100 uchar, 3 bands, rgb, magickload
vipsheader: VipsForeignLoad: "image.SVG" is not a known file format
image.TGA: 100x100 uchar, 3 bands, rgb, magickload
vips warning: tiff2vips: no resolution information for TIFF image "image.TIFF" -- defaulting to 1 pixel per mm
image.TIFF: 100x100 uchar, 3 bands, srgb, tiffload
image.TXT: 100x100 ushort, 3 bands, rgb16, magickload
image.VICAR: 100x100 uchar, 1 band, rgb, magickload
image.VIFF: 100x100 ushort, 3 bands, rgb16, magickload
image.WBMP: 100x100 ushort, 1 band, rgb16, magickload
image.WEBP: 100x100 uchar, 3 bands, srgb, webpload
image.X: 100x100 uchar, 3 bands, srgb, pngload
image.XBM: 100x100 uchar, 1 band, rgb, magickload
image.XPM: 100x100 uchar, 3 bands, rgb, magickload
image.XWD: 100x100 uchar, 3 bands, srgb, pngload
lovell commented 8 years ago

Hello, when the call to metadata() produced null, were these same errors also provided?

oaleynik commented 8 years ago

@lovell yes, for CIN format error is Input buffer has corrupt header. All others has Input buffer contains unsupported image format error

oaleynik commented 8 years ago

vipsheader were not able to read CIN format too (throws libMagick error: Unexpected end-of-file image.CIN)

For others vipsheader were not able to read headers just for 5 formats:

vipsheader: VipsForeignLoad: "image.AAI" is not a known file format
vipsheader: VipsForeignLoad: "image.DDS" is not a known file format
vipsheader: VipsForeignLoad: "image.MPC" is not a known file format
vipsheader: VipsForeignLoad: "image.PSB" is not a known file format
vipsheader: VipsForeignLoad: "image.SVG" is not a known file format
oaleynik commented 8 years ago

Just to clarify - null in the output above is not the actual output by sharp. I mark images with null, when sharp was not able to get image metadata.

lovell commented 8 years ago

I notice libvips uses fitsload and ppmload for some of those formats. If you have a genuine need for those formats then we'll need to modify sharp to detect/support those loaders.

For those formats where magickload was attempted, if you reverse the script that created these images, can they be to convert-ed back to a valid PNG? For example the vector SVG format is supported but the input file you've auto-generated could be empty.

It's also worth checking the "L" column in the output of convert -list format as convert support for some of these formats is considered Unstable.

oaleynik commented 8 years ago

If reverse script and try to convert generated files back to PNG imagemagick's convert stops without any errors at about 1/3 of the full set of images. GraphicsMagick completes them all. SVGs and most of the null formats were converted back successfully, however it has troubles with some of them:

gm convert: No decode delegate for this image format (assets/image.AAI).
gm convert: invalid chromaticities (reversed/assets/image.BMP.png).
gm convert: Unexpected end-of-file (assets/image.CIN).
gm convert: No decode delegate for this image format (assets/image.DDS).
gm convert: No decode delegate for this image format (assets/image.HDR).
gm convert: Unable to open cache (assets/image.MPC) [No such file or directory].
gm convert: No decode delegate for this image format (assets/image.PFM).
gm convert: Improper image header (assets/image.PSB).
gm convert: No decode delegate for this image format (assets/image.WEBP).

Related to the convert -list format: I don't have the "L" column. I use ImageMagick 6.9.3-0 Q16 x86_64 2016-01-08

oaleynik commented 8 years ago

So, it looks like I just misunderstood the phrase: This module supports reading JPEG, PNG, WebP, TIFF, OpenSlide, GIF and other libmagick-supported formats. It is not super critical for now, but would be helpful to have clarification regarding magick formats in documentation :) Thanks @lovell for quick response! Closing this for now.

lovell commented 8 years ago

Commit 906fb67 on the mind branch (v0.13.0) adds support for a few extra formats on your megalist when using libvips compiled with PPM and FITS.

oaleynik commented 8 years ago

Thank you @lovell! I just checked - FITS and PPM has no issues with mind branch. I dig into the sources of vips and libmagick. Wanna get better understanding how they work together so if I will need other format in sharp I can add it on my own and send PR :)