webp_to_sdl.c (2819B)
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 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; 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