From 6524fcd614e944f1027b05297a79c106a3006a13 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Mon, 30 Jan 2017 13:33:35 +0100 Subject: [PATCH] vwebp_sdl: simple viewer based on SDL Uses WebPToSDL() generic function defined in vwebp_sdl.[ch]. This function is not included in the libextras library, because it would bring in an SDL dependency. Probably too heavy for now. WebPToSDL() is separate, because it will be called used by the javascript version of libwebp (through emscripten build rules) Change-Id: Ic85b36f8ce4784f46023656278f6480be6802834 --- Makefile.vc | 5 ++- configure.ac | 40 +++++++++++++++++ extras/Makefile.am | 16 +++++-- extras/vwebp_sdl.c | 96 +++++++++++++++++++++++++++++++++++++++ extras/webp_to_sdl.c | 105 +++++++++++++++++++++++++++++++++++++++++++ extras/webp_to_sdl.h | 22 +++++++++ makefile.unix | 9 +++- 7 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 extras/vwebp_sdl.c create mode 100755 extras/webp_to_sdl.c create mode 100644 extras/webp_to_sdl.h diff --git a/Makefile.vc b/Makefile.vc index ca0955ca..db4cbb9c 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -344,7 +344,7 @@ all: ex OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \ $(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \ - $(DIRBIN)\webp_quality.exe + $(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \ ex: $(OUT_LIBS) $(OUT_EXAMPLES) all: ex $(EXTRA_EXAMPLES) @@ -366,6 +366,9 @@ $(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX) $(DIRBIN)\gif2webp.exe: $(LIBWEBP) $(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS) $(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) +$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\examples\vwebp_sdl.obj +$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\examples\webp_to_sdl.obj +$(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP) $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX) $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP) $(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX) diff --git a/configure.ac b/configure.ac index 400bdc12..04cde761 100644 --- a/configure.ac +++ b/configure.ac @@ -428,6 +428,44 @@ AS_IF([test "x$enable_gl" != "xno"], [ ]) AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"]) +dnl === check for SDL support === + +AC_ARG_ENABLE([sdl], + AS_HELP_STRING([--disable-sdl], + [Disable detection of SDL support + @<:@default=auto@:>@])) +AS_IF([test "x$enable_sdl" != "xno"], [ + CLEAR_LIBVARS([SDL]) + WITHLIB_OPTION([sdl], [SDL]) + + $sdl_header = "no"; + LIBCHECK_PROLOGUE([SDL]) + AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL_SDL.h"], + [AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"], + [AC_MSG_WARN(SDL library not available - no sdl.h)])]) + if test x"$sdl_header" != "xno" ; then + AC_CHECK_LIB(SDL, SDL_Init, + [SDL_LIBS="-lSDL" + SDL_INCLUDES="-DWEBP_HAVE_SDL" + AC_DEFINE(WEBP_HAVE_SDL, [1], + [Set to 1 if SDL library is installed]) + sdl_support=yes + ], + AC_MSG_WARN(Optional SDL library not found), + [$MATH_LIBS]), + if test x"$sdl_header" == "xSDL.h" ; then + SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H" + fi + fi + LIBCHECK_EPILOGUE([SDL]) + + if test "$sdl_support" = "yes" ; then + build_vwebp_sdl=yes + fi +]) + +AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"]) + dnl === check for PNG support === AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png], @@ -718,4 +756,6 @@ gif2webp : ${build_gif2webp-no} img2webp : ${build_img2webp-no} webpmux : ${enable_libwebpmux-no} vwebp : ${build_vwebp-no} +SDL support : ${sdl_support-no} +vwebp_sdl : ${build_vwebp_sdl-no} ]) diff --git a/extras/Makefile.am b/extras/Makefile.am index 28ec20b1..6edfbacf 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -11,10 +11,14 @@ libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS) libwebpextras_la_LDFLAGS = -lm libwebpextras_la_LIBADD = ../src/libwebp.la -noinst_PROGRAMS = get_disto webp_quality +noinst_PROGRAMS = +noinst_PROGRAMS += get_disto webp_quality +if BUILD_VWEBP_SDL + noinst_PROGRAMS += vwebp_sdl +endif -get_disto_SOURCES = get_disto.c -get_disto_CPPFLAGS = $(AM_CPPFLAGS) +get_disto_SOURCES = get_disto.c +get_disto_CPPFLAGS = $(AM_CPPFLAGS) get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la get_disto_LDADD += ../src/libwebp.la get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS) @@ -24,3 +28,9 @@ webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) webp_quality_LDADD = ../imageio/libimageio_util.la webp_quality_LDADD += ./libwebpextras.la webp_quality_LDADD += ../src/libwebp.la + +vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h +vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES) +vwebp_sdl_LDADD = ../imageio/libimageio_util.la +vwebp_sdl_LDADD += ../src/libwebp.la +vwebp_sdl_LDADD += $(SDL_LIBS) diff --git a/extras/vwebp_sdl.c b/extras/vwebp_sdl.c new file mode 100644 index 00000000..700929f0 --- /dev/null +++ b/extras/vwebp_sdl.c @@ -0,0 +1,96 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// Simple SDL-based WebP file viewer. +// Does not support animation, just static images. +// +// Press 'q' to exit. +// +// Author: James Zern (jzern@google.com) + +#include + +#ifdef HAVE_CONFIG_H +#include "webp/config.h" +#endif + +#if defined(WEBP_HAVE_SDL) + +#include "webp_to_sdl.h" +#include "webp/decode.h" +#include "../imageio/imageio_util.h" + +#if defined(WEBP_HAVE_JUST_SDL_H) +#include +#else +#include +#endif + +static void ProcessEvents(void) { + int done = 0; + SDL_Event event; + while (!done && SDL_WaitEvent(&event)) { + switch (event.type) { + case SDL_KEYUP: + switch (event.key.keysym.sym) { + case SDLK_q: done = 1; break; + default: break; + } + break; + default: break; + } + } +} + +int main(int argc, char* argv[]) { + int c; + int ok = 0; + for (c = 1; c < argc; ++c) { + const char* file = NULL; + const uint8_t* webp = NULL; + size_t webp_size = 0; + if (!strcmp(argv[c], "-h")) { + printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]); + return 0; + } else { + file = argv[c]; + } + if (file == NULL) continue; + if (!ImgIoUtilReadFile(file, &webp, &webp_size)) { + fprintf(stderr, "Error opening file: %s\n", file); + goto Error; + } + if (webp_size != (size_t)(int)webp_size) { + fprintf(stderr, "File too large.\n"); + goto Error; + } + ok = WebpToSDL((const char*)webp, (int)webp_size); + free((void*)webp); + if (!ok) { + fprintf(stderr, "Error decoding file %s\n", file); + goto Error; + } + ProcessEvents(); + } + ok = 1; + + Error: + SDL_Quit(); + return ok ? 0 : 1; +} + +#else // !WEBP_HAVE_SDL + +int main(int argc, const char *argv[]) { + fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]); + (void)argc; + return 0; +} + +#endif diff --git a/extras/webp_to_sdl.c b/extras/webp_to_sdl.c new file mode 100755 index 00000000..b47c1e6e --- /dev/null +++ b/extras/webp_to_sdl.c @@ -0,0 +1,105 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// Simple WebP-to-SDL wrapper. Useful for emscripten. +// +// Author: James Zern (jzern@google.com) + +#ifdef HAVE_CONFIG_H +#include "webp/config.h" +#endif + +#if defined(WEBP_HAVE_SDL) + +#include "webp_to_sdl.h" + +#include +#include "webp/decode.h" + +#if defined(WEBP_HAVE_JUST_SDL_H) +#include +#else +#include +#endif + +int WebpToSDL(const char* data, unsigned int data_size) { + int ok = 0; + VP8StatusCode status; + WebPDecoderConfig config; + WebPBitstreamFeatures* const input = &config.input; + WebPDecBuffer* const output = &config.output; + SDL_Surface* screen = NULL; + SDL_Surface* surface = NULL; + + if (!WebPInitDecoderConfig(&config)) { + fprintf(stderr, "Library version mismatch!\n"); + return 1; + } + + SDL_Init(SDL_INIT_VIDEO); + + status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input); + if (status != VP8_STATUS_OK) goto Error; + + screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE); + if (screen == NULL) { + fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n", + input->width, input->height); + goto Error; + } + + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + input->width, input->height, 32, + 0x000000ffu, // R mask + 0x0000ff00u, // G mask + 0x00ff0000u, // B mask + 0xff000000u); // A mask + if (surface == NULL) { + fprintf(stderr, "Unable to create %dx%d RGBA surface!\n", + input->width, input->height); + goto Error; + } + if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + output->colorspace = MODE_BGRA; +#else + output->colorspace = MODE_RGBA; +#endif + output->width = surface->w; + output->height = surface->h; + output->u.RGBA.rgba = surface->pixels; + output->u.RGBA.stride = surface->pitch; + output->u.RGBA.size = surface->pitch * surface->h; + output->is_external_memory = 1; + + status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config); + if (status != VP8_STATUS_OK) { + fprintf(stderr, "Error decoding image (%d)\n", status); + goto Error; + } + + if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); + if (SDL_FillRect(screen, &screen->clip_rect, 0xffffffff) || + SDL_BlitSurface(surface, NULL, screen, NULL) || + SDL_Flip(screen)) { + goto Error; + } + + ok = 1; + + Error: + SDL_FreeSurface(surface); + SDL_FreeSurface(screen); + return ok; +} + +//------------------------------------------------------------------------------ + +#endif // WEBP_HAVE_SDL diff --git a/extras/webp_to_sdl.h b/extras/webp_to_sdl.h new file mode 100644 index 00000000..1b5ea980 --- /dev/null +++ b/extras/webp_to_sdl.h @@ -0,0 +1,22 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// Simple WebP-to-SDL wrapper. Useful for emscripten. +// +// Author: James Zern (jzern@google.com) + +#ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_ +#define WEBP_EXTRAS_WEBP_TO_SDL_H_ + +// Exports the method WebpToSDL(const char* data, int data_size) which decodes +// a WebP bitstream into an RGBA SDL surface. +// Return false on failure. +extern int WebpToSDL(const char* data, unsigned int data_size); + +#endif // WEBP_EXTRAS_WEBP_TO_SDL_H_ diff --git a/makefile.unix b/makefile.unix index 47b8c65f..09eb2c58 100644 --- a/makefile.unix +++ b/makefile.unix @@ -329,7 +329,7 @@ EXTRA_LIB = extras/libwebpextras.a OUT_EXAMPLES = examples/cwebp examples/dwebp EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \ examples/anim_diff examples/img2webp -OTHER_EXAMPLES = extras/get_disto extras/webp_quality +OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES) ifeq ($(MAKECMDGOALS),clean) @@ -420,6 +420,13 @@ extras/webp_quality: extras/webp_quality.o extras/webp_quality: imageio/libimageio_util.a extras/webp_quality: $(EXTRA_LIB) src/libwebp.a +extras/vwebp_sdl: extras/vwebp_sdl.o +extras/vwebp_sdl: extras/webp_to_sdl.o +extras/vwebp_sdl: imageio/libimageio_util.a +extras/vwebp_sdl: src/libwebp.a +extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL +extras/vwebp_sdl: -lSDL + $(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES): $(CC) -o $@ $^ $(LDFLAGS)