| // 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 "src/webp/config.h" | 
 | #endif | 
 |  | 
 | #if defined(WEBP_HAVE_SDL) | 
 |  | 
 | #include "webp_to_sdl.h" | 
 |  | 
 | #include <stdio.h> | 
 | #include "src/webp/decode.h" | 
 |  | 
 | #if defined(WEBP_HAVE_JUST_SDL_H) | 
 | #include <SDL.h> | 
 | #else | 
 | #include <SDL/SDL.h> | 
 | #endif | 
 |  | 
 | static int init_ok = 0; | 
 | 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; | 
 |   } | 
 |  | 
 |   if (!init_ok) { | 
 |     SDL_Init(SDL_INIT_VIDEO); | 
 |     init_ok = 1; | 
 |   } | 
 |  | 
 |   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_BlitSurface(surface, NULL, screen, NULL) || | 
 |       SDL_Flip(screen)) { | 
 |     goto Error; | 
 |   } | 
 |  | 
 |   ok = 1; | 
 |  | 
 |  Error: | 
 |   SDL_FreeSurface(surface); | 
 |   SDL_FreeSurface(screen); | 
 |   WebPFreeDecBuffer(output); | 
 |   return ok; | 
 | } | 
 |  | 
 | //------------------------------------------------------------------------------ | 
 |  | 
 | #endif  // WEBP_HAVE_SDL |