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 ([email protected])
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
24 #include "src/webp/decode.h"
25
26 #if defined(WEBP_HAVE_JUST_SDL_H)
27 #include <SDL.h>
28 #else
29 #include <SDL2/SDL.h>
30 #endif
31
32 static int init_ok = 0;
WebPToSDL(const char * data,unsigned int data_size)33 int WebPToSDL(const char* data, unsigned int data_size) {
34 int ok = 0;
35 VP8StatusCode status;
36 WebPBitstreamFeatures input;
37 uint8_t* output = NULL;
38 SDL_Window* window = NULL;
39 SDL_Renderer* renderer = NULL;
40 SDL_Texture* texture = NULL;
41 int width, height;
42
43 if (!init_ok) {
44 SDL_Init(SDL_INIT_VIDEO);
45 init_ok = 1;
46 }
47
48 status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &input);
49 if (status != VP8_STATUS_OK) goto Error;
50 width = input.width;
51 height = input.height;
52
53 SDL_CreateWindowAndRenderer(width, height, 0, &window, &renderer);
54 if (window == NULL || renderer == NULL) {
55 fprintf(stderr, "Unable to create window or renderer!\n");
56 goto Error;
57 }
58 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
59 "linear"); // make the scaled rendering look smoother.
60 SDL_RenderSetLogicalSize(renderer, width, height);
61
62 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
63 SDL_TEXTUREACCESS_STREAMING, width, height);
64 if (texture == NULL) {
65 fprintf(stderr, "Unable to create %dx%d RGBA texture!\n", width, height);
66 goto Error;
67 }
68
69 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
70 output = WebPDecodeBGRA((const uint8_t*)data, (size_t)data_size, &width,
71 &height);
72 #else
73 output = WebPDecodeRGBA((const uint8_t*)data, (size_t)data_size, &width,
74 &height);
75 #endif
76 if (output == NULL) {
77 fprintf(stderr, "Error decoding image (%d)\n", status);
78 goto Error;
79 }
80
81 SDL_UpdateTexture(texture, NULL, output, width * sizeof(uint32_t));
82 SDL_RenderClear(renderer);
83 SDL_RenderCopy(renderer, texture, NULL, NULL);
84 SDL_RenderPresent(renderer);
85 ok = 1;
86
87 Error:
88 // We should call SDL_DestroyWindow(window) but that makes .js fail.
89 SDL_DestroyRenderer(renderer);
90 SDL_DestroyTexture(texture);
91 WebPFree(output);
92 return ok;
93 }
94
95 //------------------------------------------------------------------------------
96
97 #endif // WEBP_HAVE_SDL
98