Add WebP image format support (Bug#51296)
* configure.ac (--with-webp): New option. (HAVE_WEBP): New variable. (emacs_config_features): Add webp. * src/image.c (enum webp_keyword_index) [HAVE_WEBP]: New enum. (webp_format) [HAVE_WEBP]: New variable. (webp_image_p, init_webp_functions, webp_load) [HAVE_WEBP]: New functions for WebP support. (image_types) [HAVE_WEBP]: Define WebP format. (syms_of_image) <Qwebp> [HAVE_WEBP]: New DEFSYM. Add image type Qwebp. * src/Makefile.in (LIBIMAGE): Add WEBP_LIBS. * lisp/files.el (auto-mode-alist): * lisp/image-file.el (image-file-name-extensions): * lisp/image.el (image-type-header-regexps) (image-type-file-name-regexps, image-type-auto-detectable): Add WebP support. * lisp/term/w32-win.el (dynamic-library-alist): Add the libwebp DLL. * INSTALL: * admin/CPP-DEFINES: * doc/lispref/display.texi (Image Formats, Other Image Types): * nt/INSTALL: Document WebP support. * test/lisp/image-tests.el (image-find-image) (image-type-from-file-name): Expand tests. * test/src/image-tests.el (image-tests--files): Add WebP. (image-tests-image-size/webp, image-tests-image-mask-p/webp) (image-tests-image-metadata/webp): New tests. * test/data/image/black.webp: New file.
This commit is contained in:
parent
938f10c601
commit
bc2a5c1127
15 changed files with 363 additions and 15 deletions
2
INSTALL
2
INSTALL
|
@ -187,6 +187,7 @@ X11 is being used.
|
|||
X libtiff for TIFF: http://www.simplesystems.org/libtiff/
|
||||
X libgif for GIF: http://giflib.sourceforge.net/
|
||||
librsvg2 for SVG: https://wiki.gnome.org/Projects/LibRsvg
|
||||
libwebp for WebP: https://developers.google.com/speed/webp/
|
||||
|
||||
If you supply the appropriate --without-LIB option, 'configure' will
|
||||
omit the corresponding library from Emacs, even if that makes for a
|
||||
|
@ -313,6 +314,7 @@ or more of these options:
|
|||
--without-gif for GIF image support
|
||||
--without-png for PNG image support
|
||||
--without-rsvg for SVG image support
|
||||
--without-webp for WebP image support
|
||||
|
||||
Although ImageMagick support is disabled by default due to security
|
||||
and stability concerns, you can enable it with --with-imagemagick.
|
||||
|
|
|
@ -287,6 +287,7 @@ HAVE_UTIMENSAT
|
|||
HAVE_UTMP_H
|
||||
HAVE_VFORK
|
||||
HAVE_VFORK_H
|
||||
HAVE_WEBP
|
||||
HAVE_WCHAR_H
|
||||
HAVE_WCHAR_T
|
||||
HAVE_WINDOW_SYSTEM
|
||||
|
|
28
configure.ac
28
configure.ac
|
@ -447,6 +447,7 @@ OPTION_DEFAULT_ON([tiff],[don't compile with TIFF image support])
|
|||
OPTION_DEFAULT_ON([gif],[don't compile with GIF image support])
|
||||
OPTION_DEFAULT_ON([png],[don't compile with PNG image support])
|
||||
OPTION_DEFAULT_ON([rsvg],[don't compile with SVG image support])
|
||||
OPTION_DEFAULT_ON([webp],[don't compile with WebP image support])
|
||||
OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support])
|
||||
OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support])
|
||||
OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing])
|
||||
|
@ -2588,6 +2589,28 @@ if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" =
|
|||
fi
|
||||
fi
|
||||
|
||||
### Use -lwebp if available, unless '--with-webp=no'
|
||||
### mingw32 doesn't use -lwebp, since it loads the library dynamically.
|
||||
HAVE_WEBP=no
|
||||
if test "${with_webp}" != "no"; then
|
||||
if test "$opsys" = mingw32; then
|
||||
AC_CHECK_HEADER([webp/decode.h], [HAVE_WEBP=yes])
|
||||
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
|
||||
|| test "${HAVE_NS}" = "yes"; then
|
||||
WEBP_REQUIRED=0.6.0
|
||||
WEBP_MODULE="libwebp >= $WEBP_REQUIRED"
|
||||
|
||||
EMACS_CHECK_MODULES([WEBP], [$WEBP_MODULE])
|
||||
AC_SUBST(WEBP_CFLAGS)
|
||||
AC_SUBST(WEBP_LIBS)
|
||||
|
||||
if test $HAVE_WEBP = yes; then
|
||||
AC_DEFINE(HAVE_WEBP, 1, [Define to 1 if using libwebp.])
|
||||
CFLAGS="$CFLAGS $WEBP_CFLAGS"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
HAVE_IMAGEMAGICK=no
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then
|
||||
if test "${with_imagemagick}" != "no"; then
|
||||
|
@ -5882,8 +5905,8 @@ emacs_config_features=
|
|||
for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
|
||||
HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \
|
||||
M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PNG RSVG SECCOMP \
|
||||
SOUND THREADS TIFF \
|
||||
TOOLKIT_SCROLL_BARS UNEXEC X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \
|
||||
SOUND THREADS TIFF TOOLKIT_SCROLL_BARS \
|
||||
UNEXEC WEBP X11 XAW3D XDBE XFT XIM XPM XWIDGETS X_TOOLKIT \
|
||||
ZLIB; do
|
||||
|
||||
case $opt in
|
||||
|
@ -5928,6 +5951,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
|
|||
Does Emacs use a gif library? ${HAVE_GIF} $LIBGIF
|
||||
Does Emacs use a png library? ${HAVE_PNG} $LIBPNG
|
||||
Does Emacs use -lrsvg-2? ${HAVE_RSVG}
|
||||
Does Emacs use -lwebp? ${HAVE_WEBP}
|
||||
Does Emacs use cairo? ${HAVE_CAIRO}
|
||||
Does Emacs use -llcms2? ${HAVE_LCMS2}
|
||||
Does Emacs use imagemagick? ${HAVE_IMAGEMAGICK}
|
||||
|
|
|
@ -5264,13 +5264,13 @@ to modify the set of known names for these dynamic libraries.
|
|||
Supported image formats (and the required support libraries) include
|
||||
PBM and XBM (which do not depend on support libraries and are always
|
||||
available), XPM (@code{libXpm}), GIF (@code{libgif} or
|
||||
@code{libungif}), JPEG (@code{libjpeg}), TIFF
|
||||
(@code{libtiff}), PNG (@code{libpng}), and SVG (@code{librsvg}).
|
||||
@code{libungif}), JPEG (@code{libjpeg}), TIFF (@code{libtiff}), PNG
|
||||
(@code{libpng}), SVG (@code{librsvg}), and WebP (@code{libwebp}).
|
||||
|
||||
Each of these image formats is associated with an @dfn{image type
|
||||
symbol}. The symbols for the above formats are, respectively,
|
||||
@code{pbm}, @code{xbm}, @code{xpm}, @code{gif},
|
||||
@code{jpeg}, @code{tiff}, @code{png}, and @code{svg}.
|
||||
@code{pbm}, @code{xbm}, @code{xpm}, @code{gif}, @code{jpeg},
|
||||
@code{tiff}, @code{png}, @code{svg}, and @code{webp}.
|
||||
|
||||
Furthermore, if you build Emacs with ImageMagick
|
||||
(@code{libMagickWand}) support, Emacs can display any image format
|
||||
|
@ -6274,6 +6274,9 @@ Image type @code{png}.
|
|||
@item TIFF
|
||||
Image type @code{tiff}.
|
||||
Supports the @code{:index} property. @xref{Multi-Frame Images}.
|
||||
|
||||
@item WebP
|
||||
Image type @code{webp}.
|
||||
@end table
|
||||
|
||||
@node Defining Images
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -61,6 +61,12 @@ Emacs previously didn't distinguish between the "regular" weight and
|
|||
the "medium" weight, but it now also supports the (heavier) "medium"
|
||||
weight.
|
||||
|
||||
+++
|
||||
** Support for the WebP image format.
|
||||
This support is built by default when the libwebp library is
|
||||
available. To disable it, use the '--without-webp' configure flag.
|
||||
Image specifiers can now use ':type webp'.
|
||||
|
||||
|
||||
* Editing Changes in Emacs 29.1
|
||||
|
||||
|
|
|
@ -2758,6 +2758,7 @@ since only a single case-insensitive search through the alist is made."
|
|||
("\\.gif\\'" . image-mode)
|
||||
("\\.png\\'" . image-mode)
|
||||
("\\.jpe?g\\'" . image-mode)
|
||||
("\\.webp\\'" . image-mode)
|
||||
("\\.te?xt\\'" . text-mode)
|
||||
("\\.[tT]e[xX]\\'" . tex-mode)
|
||||
("\\.ins\\'" . tex-mode) ;Installation files for TeX packages.
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
;;;###autoload
|
||||
(defcustom image-file-name-extensions
|
||||
(purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg"))
|
||||
(purecopy '("png" "jpeg" "jpg" "gif" "tiff" "tif" "xbm" "xpm" "pbm" "pgm" "ppm" "pnm" "svg" "webp"))
|
||||
"A list of image-file filename extensions.
|
||||
Filenames having one of these extensions are considered image files,
|
||||
in addition to those matching `image-file-name-regexps'.
|
||||
|
|
|
@ -48,6 +48,7 @@ static \\(unsigned \\)?char \\1_bits" . xbm)
|
|||
("\\`\\(?:MM\0\\*\\|II\\*\0\\)" . tiff)
|
||||
("\\`[\t\n\r ]*%!PS" . postscript)
|
||||
("\\`\xff\xd8" . jpeg) ; used to be (image-jpeg-p . jpeg)
|
||||
("\\`RIFF....WEBPVP8" . webp)
|
||||
(,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)")
|
||||
(comment-re (concat "\\(?:!--" incomment-re "*-->[ \t\r\n]*<\\)")))
|
||||
(concat "\\(?:<\\?xml[ \t\r\n]+[^>]*>\\)?[ \t\r\n]*<"
|
||||
|
@ -67,6 +68,7 @@ a non-nil value, TYPE is the image's type.")
|
|||
'(("\\.png\\'" . png)
|
||||
("\\.gif\\'" . gif)
|
||||
("\\.jpe?g\\'" . jpeg)
|
||||
("\\.webp\\'" . webp)
|
||||
("\\.bmp\\'" . bmp)
|
||||
("\\.xpm\\'" . xpm)
|
||||
("\\.pbm\\'" . pbm)
|
||||
|
@ -92,6 +94,7 @@ be of image type IMAGE-TYPE.")
|
|||
(jpeg . maybe)
|
||||
(tiff . maybe)
|
||||
(svg . maybe)
|
||||
(webp . maybe)
|
||||
(postscript . nil))
|
||||
"Alist of (IMAGE-TYPE . AUTODETECT) pairs used to auto-detect image files.
|
||||
\(See `image-type-auto-detected-p').
|
||||
|
|
|
@ -274,6 +274,7 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
|
|||
'(gif "libgif-6.dll" "giflib5.dll" "gif.dll")
|
||||
'(gif "libgif-5.dll" "giflib4.dll" "libungif4.dll" "libungif.dll")))
|
||||
'(svg "librsvg-2-2.dll")
|
||||
'(libwebp "libwebp-7.dll" "libwebp.dll")
|
||||
'(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
|
||||
'(glib "libglib-2.0-0.dll")
|
||||
'(gio "libgio-2.0-0.dll")
|
||||
|
|
|
@ -488,6 +488,7 @@ build will run on Windows 9X and newer systems).
|
|||
Does Emacs use a gif library? yes
|
||||
Does Emacs use a png library? yes
|
||||
Does Emacs use -lrsvg-2? yes
|
||||
Does Emacs use -lwebp? yes
|
||||
Does Emacs use cairo? no
|
||||
Does Emacs use -llcms2? yes
|
||||
Does Emacs use imagemagick? no
|
||||
|
@ -597,8 +598,8 @@ build will run on Windows 9X and newer systems).
|
|||
* Optional image library support
|
||||
|
||||
In addition to its "native" image formats (pbm and xbm), Emacs can
|
||||
handle other image types: xpm, tiff, gif, png, jpeg and experimental
|
||||
support for svg.
|
||||
handle other image types: xpm, tiff, gif, png, jpeg, webp and
|
||||
experimental support for svg.
|
||||
|
||||
To build Emacs with support for them, the corresponding headers must
|
||||
be in the include path and libraries should be where the linker
|
||||
|
@ -736,6 +737,10 @@ build will run on Windows 9X and newer systems).
|
|||
without it by specifying the --without-rsvg switch to the configure
|
||||
script.
|
||||
|
||||
For WebP images you will need libwebp:
|
||||
|
||||
https://developers.google.com/speed/webp/
|
||||
|
||||
Binaries for the other image libraries can be found on the
|
||||
ezwinports site or at the GnuWin32 project (the latter are generally
|
||||
very old, so not recommended). Note specifically that, due to some
|
||||
|
|
|
@ -124,7 +124,7 @@ LIB_MATH=@LIB_MATH@
|
|||
## -lpthread, or empty.
|
||||
LIB_PTHREAD=@LIB_PTHREAD@
|
||||
|
||||
LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@
|
||||
LIBIMAGE=@LIBTIFF@ @LIBJPEG@ @LIBPNG@ @LIBGIF@ @LIBXPM@ @WEBP_LIBS@
|
||||
|
||||
XCB_LIBS=@XCB_LIBS@
|
||||
XFT_LIBS=@XFT_LIBS@
|
||||
|
|
281
src/image.c
281
src/image.c
|
@ -8739,8 +8739,280 @@ gif_load (struct frame *f, struct image *img)
|
|||
#endif /* HAVE_GIF */
|
||||
|
||||
|
||||
#ifdef HAVE_WEBP
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
WebP
|
||||
***********************************************************************/
|
||||
|
||||
#include "webp/decode.h"
|
||||
|
||||
/* Indices of image specification fields in webp_format, below. */
|
||||
|
||||
enum webp_keyword_index
|
||||
{
|
||||
WEBP_TYPE,
|
||||
WEBP_DATA,
|
||||
WEBP_FILE,
|
||||
WEBP_ASCENT,
|
||||
WEBP_MARGIN,
|
||||
WEBP_RELIEF,
|
||||
WEBP_ALGORITHM,
|
||||
WEBP_HEURISTIC_MASK,
|
||||
WEBP_MASK,
|
||||
WEBP_BACKGROUND,
|
||||
WEBP_LAST
|
||||
};
|
||||
|
||||
/* Vector of image_keyword structures describing the format
|
||||
of valid user-defined image specifications. */
|
||||
|
||||
static const struct image_keyword webp_format[WEBP_LAST] =
|
||||
{
|
||||
{":type", IMAGE_SYMBOL_VALUE, 1},
|
||||
{":data", IMAGE_STRING_VALUE, 0},
|
||||
{":file", IMAGE_STRING_VALUE, 0},
|
||||
{":ascent", IMAGE_ASCENT_VALUE, 0},
|
||||
{":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
|
||||
{":relief", IMAGE_INTEGER_VALUE, 0},
|
||||
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
|
||||
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
|
||||
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
|
||||
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
|
||||
};
|
||||
|
||||
/* Return true if OBJECT is a valid WebP image specification. */
|
||||
|
||||
static bool
|
||||
webp_image_p (Lisp_Object object)
|
||||
{
|
||||
struct image_keyword fmt[WEBP_LAST];
|
||||
memcpy (fmt, webp_format, sizeof fmt);
|
||||
|
||||
if (!parse_image_spec (object, fmt, WEBP_LAST, Qwebp))
|
||||
return false;
|
||||
|
||||
/* Must specify either the :data or :file keyword. */
|
||||
return fmt[WEBP_FILE].count + fmt[WEBP_DATA].count == 1;
|
||||
}
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
|
||||
/* WebP library details. */
|
||||
|
||||
DEF_DLL_FN (int, WebPGetInfo, (const uint8_t *, size_t, int *, int *));
|
||||
DEF_DLL_FN (VP8StatusCode, WebPGetFeatures, (const uint8_t *, size_t, WebPBitstreamFeatures *));
|
||||
DEF_DLL_FN (uint8_t *, WebPDecodeRGB, (const uint8_t *, size_t, int *, int *));
|
||||
DEF_DLL_FN (uint8_t *, WebPDecodeBGR, (const uint8_t *, size_t, int *, int *));
|
||||
DEF_DLL_FN (void, WebPFreeDecBuffer (WebPDecBuffer *));
|
||||
|
||||
static bool
|
||||
init_webp_functions (void)
|
||||
{
|
||||
HMODULE library;
|
||||
|
||||
if (!(library = w32_delayed_load (Qwebp)))
|
||||
return false;
|
||||
|
||||
LOAD_DLL_FN (library, WebPGetInfo);
|
||||
LOAD_DLL_FN (library, WebPGetFeatures);
|
||||
LOAD_DLL_FN (library, WebPDecodeRGBA);
|
||||
LOAD_DLL_FN (library, WebPDecodeRGB);
|
||||
LOAD_DLL_FN (library, WebPFree);
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef WebPGetInfo
|
||||
#undef WebPGetFeatures
|
||||
#undef WebPDecodeRGBA
|
||||
#undef WebPDecodeRGB
|
||||
#undef WebPFree
|
||||
|
||||
#define WebPGetInfo fn_WebPGetInfo
|
||||
#define WebPGetFeatures fn_WebPGetFeatures
|
||||
#define WebPDecodeRGBA fn_WebPDecodeRGBA
|
||||
#define WebPDecodeRGB fn_WebPDecodeRGB
|
||||
#define WebPFree fn_WebPFree
|
||||
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
/* Load WebP image IMG for use on frame F. Value is true if
|
||||
successful. */
|
||||
|
||||
static bool
|
||||
webp_load (struct frame *f, struct image *img)
|
||||
{
|
||||
ptrdiff_t size = 0;
|
||||
uint8_t *contents;
|
||||
Lisp_Object file;
|
||||
|
||||
/* Open the WebP file. */
|
||||
Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
|
||||
Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
|
||||
|
||||
if (NILP (specified_data))
|
||||
{
|
||||
int fd;
|
||||
file = image_find_image_fd (specified_file, &fd);
|
||||
if (!STRINGP (file))
|
||||
{
|
||||
image_error ("Cannot find image file `%s'", specified_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
contents = (uint8_t *) slurp_file (fd, &size);
|
||||
if (contents == NULL)
|
||||
{
|
||||
image_error ("Error loading WebP image `%s'", file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!STRINGP (specified_data))
|
||||
{
|
||||
image_error ("Invalid image data `%s'", specified_data);
|
||||
return false;
|
||||
}
|
||||
contents = SDATA (specified_data);
|
||||
size = SBYTES (specified_data);
|
||||
}
|
||||
|
||||
/* Validate the WebP image header. */
|
||||
if (!WebPGetInfo (contents, size, NULL, NULL))
|
||||
{
|
||||
if (!NILP (specified_data))
|
||||
image_error ("Not a WebP file: `%s'", file);
|
||||
else
|
||||
image_error ("Invalid header in WebP image data");
|
||||
goto webp_error1;
|
||||
}
|
||||
|
||||
/* Get WebP features. */
|
||||
WebPBitstreamFeatures features;
|
||||
VP8StatusCode result = WebPGetFeatures (contents, size, &features);
|
||||
switch (result)
|
||||
{
|
||||
case VP8_STATUS_OK:
|
||||
break;
|
||||
case VP8_STATUS_NOT_ENOUGH_DATA:
|
||||
case VP8_STATUS_OUT_OF_MEMORY:
|
||||
case VP8_STATUS_INVALID_PARAM:
|
||||
case VP8_STATUS_BITSTREAM_ERROR:
|
||||
case VP8_STATUS_UNSUPPORTED_FEATURE:
|
||||
case VP8_STATUS_SUSPENDED:
|
||||
case VP8_STATUS_USER_ABORT:
|
||||
default:
|
||||
/* Error out in all other cases. */
|
||||
if (!NILP (specified_data))
|
||||
image_error ("Error when interpreting WebP image data: `%s'", file);
|
||||
else
|
||||
image_error ("Error when interpreting WebP image data");
|
||||
goto webp_error1;
|
||||
}
|
||||
|
||||
/* Decode WebP data. */
|
||||
uint8_t *decoded;
|
||||
int width, height;
|
||||
if (features.has_alpha)
|
||||
/* Linear [r0, g0, b0, a0, r1, g1, b1, a1, ...] order. */
|
||||
decoded = WebPDecodeRGBA (contents, size, &width, &height);
|
||||
else
|
||||
/* Linear [r0, g0, b0, r1, g1, b1, ...] order. */
|
||||
decoded = WebPDecodeRGB (contents, size, &width, &height);
|
||||
|
||||
if (!(width <= INT_MAX && height <= INT_MAX
|
||||
&& check_image_size (f, width, height)))
|
||||
{
|
||||
image_size_error ();
|
||||
goto webp_error2;
|
||||
}
|
||||
|
||||
/* Create the x image and pixmap. */
|
||||
Emacs_Pix_Container ximg, mask_img;
|
||||
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, false))
|
||||
goto webp_error2;
|
||||
|
||||
/* Create an image and pixmap serving as mask if the WebP image
|
||||
contains an alpha channel. */
|
||||
if (features.has_alpha
|
||||
&& !image_create_x_image_and_pixmap (f, img, width, height, 1, &mask_img, true))
|
||||
{
|
||||
image_destroy_x_image (ximg);
|
||||
image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
|
||||
goto webp_error2;
|
||||
}
|
||||
|
||||
/* Fill the X image and mask from WebP data. */
|
||||
init_color_table ();
|
||||
|
||||
uint8_t *p = decoded;
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
int r = *p++ << 8;
|
||||
int g = *p++ << 8;
|
||||
int b = *p++ << 8;
|
||||
PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
|
||||
|
||||
/* An alpha channel associates variable transparency with an
|
||||
image. WebP allows up to 256 levels of partial transparency.
|
||||
We handle this like with PNG (which see), using the frame's
|
||||
background color to combine the image with. */
|
||||
if (features.has_alpha)
|
||||
{
|
||||
if (mask_img)
|
||||
PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COLOR_TABLE_SUPPORT
|
||||
/* Remember colors allocated for this image. */
|
||||
img->colors = colors_in_color_table (&img->ncolors);
|
||||
free_color_table ();
|
||||
#endif /* COLOR_TABLE_SUPPORT */
|
||||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
|
||||
/* Same for the mask. */
|
||||
if (mask_img)
|
||||
{
|
||||
/* Fill in the background_transparent field while we have the
|
||||
mask handy. Casting avoids a GCC warning. */
|
||||
image_background_transparent (img, f, (Emacs_Pix_Context)mask_img);
|
||||
|
||||
image_put_x_image (f, img, mask_img, 1);
|
||||
}
|
||||
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
|
||||
/* Clean up. */
|
||||
WebPFree (decoded);
|
||||
if (NILP (specified_data))
|
||||
xfree (contents);
|
||||
return true;
|
||||
|
||||
webp_error2:
|
||||
WebPFree (decoded);
|
||||
|
||||
webp_error1:
|
||||
if (NILP (specified_data))
|
||||
xfree (contents);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* HAVE_WEBP */
|
||||
|
||||
|
||||
#ifdef HAVE_IMAGEMAGICK
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
ImageMagick
|
||||
***********************************************************************/
|
||||
|
@ -10725,6 +10997,10 @@ static struct image_type const image_types[] =
|
|||
#if defined HAVE_XPM || defined HAVE_NS
|
||||
{ SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
|
||||
IMAGE_TYPE_INIT (init_xpm_functions) },
|
||||
#endif
|
||||
#if defined HAVE_WEBP
|
||||
{ SYMBOL_INDEX (Qwebp), webp_image_p, webp_load, image_clear_image,
|
||||
IMAGE_TYPE_INIT (init_webp_functions) },
|
||||
#endif
|
||||
{ SYMBOL_INDEX (Qxbm), xbm_image_p, xbm_load, image_clear_image },
|
||||
{ SYMBOL_INDEX (Qpbm), pbm_image_p, pbm_load, image_clear_image },
|
||||
|
@ -10891,6 +11167,11 @@ non-numeric, there is no explicit limit on the size of images. */);
|
|||
add_image_type (Qpng);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_WEBP)
|
||||
DEFSYM (Qwebp, "webp");
|
||||
add_image_type (Qwebp);
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_IMAGEMAGICK)
|
||||
DEFSYM (Qimagemagick, "imagemagick");
|
||||
add_image_type (Qimagemagick);
|
||||
|
|
BIN
test/data/image/black.webp
Normal file
BIN
test/data/image/black.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
|
@ -49,12 +49,14 @@
|
|||
(should (equal image '(image)))))
|
||||
|
||||
(ert-deftest image-find-image ()
|
||||
(find-image '((:type xpm :file "undo.xpm")))
|
||||
(find-image '((:type png :file "newsticker/rss-feed.png" :ascent center))))
|
||||
(should (listp (find-image '((:type xpm :file "undo.xpm")))))
|
||||
(should (listp (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center)))))
|
||||
(should-not (find-image '((:type png :file "does-not-exist-foo-bar.png")))))
|
||||
|
||||
(ert-deftest image-type-from-file-name ()
|
||||
(should (eq (image-type-from-file-name "foo.jpg") 'jpeg))
|
||||
(should (eq (image-type-from-file-name "foo.png") 'png)))
|
||||
(should (eq (image-type-from-file-name "foo.png") 'png))
|
||||
(should (eq (image-type-from-file-name "foo.webp") 'webp)))
|
||||
|
||||
(ert-deftest image-type/from-filename ()
|
||||
;; On emba, `image-types' and `image-load-path' do not exist.
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
(tiff . ,(expand-file-name
|
||||
"nextstep/GNUstep/Emacs.base/Resources/emacs.tiff"
|
||||
source-directory))
|
||||
(webp . ,(expand-file-name "test/data/image/black.webp"
|
||||
source-directory))
|
||||
(xbm . ,(find-image '((:file "gnus/gnus.xbm" :type xbm))))
|
||||
(xpm . ,(find-image '((:file "splash.xpm" :type xpm))))
|
||||
;; TODO: gif
|
||||
|
@ -86,6 +88,13 @@
|
|||
(should (floatp a))
|
||||
(should (floatp b)))))
|
||||
|
||||
(ert-deftest image-tests-image-size/webp ()
|
||||
(image-skip-unless 'webp)
|
||||
(pcase (image-size (create-image (cdr (assq 'webp image-tests--files))))
|
||||
(`(,a . ,b)
|
||||
(should (floatp a))
|
||||
(should (floatp b)))))
|
||||
|
||||
(ert-deftest image-tests-image-size/xbm ()
|
||||
(image-skip-unless 'xbm)
|
||||
(pcase (image-size (cdr (assq 'xbm image-tests--files)))
|
||||
|
@ -130,7 +139,12 @@
|
|||
(ert-deftest image-tests-image-mask-p/tiff ()
|
||||
(image-skip-unless 'tiff)
|
||||
(should-not (image-mask-p (create-image
|
||||
(cdr (assq 'tiff image-tests--files))))))
|
||||
(cdr (assq 'tiff image-tests--files))))))
|
||||
|
||||
(ert-deftest image-tests-image-mask-p/webp ()
|
||||
(image-skip-unless 'webp)
|
||||
(should-not (image-mask-p (create-image
|
||||
(cdr (assq 'webp image-tests--files))))))
|
||||
|
||||
(ert-deftest image-tests-image-mask-p/xbm ()
|
||||
(image-skip-unless 'xbm)
|
||||
|
@ -173,7 +187,12 @@
|
|||
(ert-deftest image-tests-image-metadata/tiff ()
|
||||
(image-skip-unless 'tiff)
|
||||
(should-not (image-metadata
|
||||
(create-image (cdr (assq 'tiff image-tests--files))))))
|
||||
(create-image (cdr (assq 'tiff image-tests--files))))))
|
||||
|
||||
(ert-deftest image-tests-image-metadata/webp ()
|
||||
(image-skip-unless 'webp)
|
||||
(should-not (image-metadata
|
||||
(create-image (cdr (assq 'webp image-tests--files))))))
|
||||
|
||||
(ert-deftest image-tests-image-metadata/xbm ()
|
||||
(image-skip-unless 'xbm)
|
||||
|
|
Loading…
Add table
Reference in a new issue