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)