1 // Copyright 2017 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 // Simple WebP-to-SDL wrapper. Useful for emscripten.
11 //
12 // Author: James Zern (jzern@google.com)
13
14 #ifdef HAVE_CONFIG_H
15 #include "src/webp/config.h"
16 #endif
17
18 #if defined(WEBP_HAVE_SDL)
19
20 #include "webp_to_sdl.h"
21
22 #include <stdio.h>
23 #include "src/webp/decode.h"
24
25 #if defined(WEBP_HAVE_JUST_SDL_H)
26 #include <SDL.h>
27 #else
28 #include <SDL/SDL.h>
29 #endif
30
31 static int init_ok = 0;
WebpToSDL(const char * data,unsigned int data_size)32 int WebpToSDL(const char* data, unsigned int data_size) {
33 int ok = 0;
34 VP8StatusCode status;
35 WebPDecoderConfig config;
36 WebPBitstreamFeatures* const input = &config.input;
37 WebPDecBuffer* const output = &config.output;
38 SDL_Surface* screen = NULL;
39 SDL_Surface* surface = NULL;
40
41 if (!WebPInitDecoderConfig(&config)) {
42 fprintf(stderr, "Library version mismatch!\n");
43 return 0;
44 }
45
46 if (!init_ok) {
47 SDL_Init(SDL_INIT_VIDEO);
48 init_ok = 1;
49 }
50
51 status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
52 if (status != VP8_STATUS_OK) goto Error;
53
54 screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE);
55 if (screen == NULL) {
56 fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n",
57 input->width, input->height);
58 goto Error;
59 }
60
61 surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
62 input->width, input->height, 32,
63 0x000000ffu, // R mask
64 0x0000ff00u, // G mask
65 0x00ff0000u, // B mask
66 0xff000000u); // A mask
67
68 if (surface == NULL) {
69 fprintf(stderr, "Unable to create %dx%d RGBA surface!\n",
70 input->width, input->height);
71 goto Error;
72 }
73 if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
74
75 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
76 output->colorspace = MODE_BGRA;
77 #else
78 output->colorspace = MODE_RGBA;
79 #endif
80 output->width = surface->w;
81 output->height = surface->h;
82 output->u.RGBA.rgba = surface->pixels;
83 output->u.RGBA.stride = surface->pitch;
84 output->u.RGBA.size = surface->pitch * surface->h;
85 output->is_external_memory = 1;
86
87 status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config);
88 if (status != VP8_STATUS_OK) {
89 fprintf(stderr, "Error decoding image (%d)\n", status);
90 goto Error;
91 }
92
93 if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
94 if (SDL_BlitSurface(surface, NULL, screen, NULL) ||
95 SDL_Flip(screen)) {
96 goto Error;
97 }
98
99 ok = 1;
100
101 Error:
102 SDL_FreeSurface(surface);
103 SDL_FreeSurface(screen);
104 WebPFreeDecBuffer(output);
105 return ok;
106 }
107
108 //------------------------------------------------------------------------------
109
110 #endif // WEBP_HAVE_SDL
111