xref: /aosp_15_r20/external/webp/extras/webp_to_sdl.c (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
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