// 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