blob: 994f71e8b683d37204ddf28dd0c1e8e57d861e75 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
// Simple WP2-to-SDL wrapper. Useful for emscripten.
//
// Author: Skal (pascal.massimino@gmail.com)
#ifdef HAVE_CONFIG_H
#include "src/wp2/config.h"
#endif
#if defined(WP2_HAVE_SDL)
#include "./wp2_to_sdl.h"
#include <cstdio>
#include "wp2/decode.h"
#if defined(WP2_HAVE_JUST_SDL_H)
#include <SDL.h>
#else
#include <SDL/SDL.h>
#endif
static bool init_ok = false;
int WP2ToSDL(const char* const data, unsigned int data_size) {
int ok = 0;
if (!WP2CheckVersion()) return 0;
if (!init_ok) {
SDL_Init(SDL_INIT_VIDEO);
init_ok = true;
}
WP2::BitstreamFeatures bitstream;
if (bitstream.Read((const uint8_t*)data, data_size) != WP2_STATUS_OK) {
return 0;
}
SDL_Surface* const screen =
SDL_SetVideoMode(bitstream.width, bitstream.height, 32, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n",
bitstream.width, bitstream.height);
return 0;
}
SDL_Surface* const surface =
SDL_CreateRGBSurface(SDL_SWSURFACE,
bitstream.width, bitstream.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",
bitstream.width, bitstream.height);
return 0;
}
if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
const WP2SampleFormat format = WP2_BGRA_32;
#else
const WP2SampleFormat format = WP2_RGBA_32;
#endif
WP2Status status;
WP2::ArgbBuffer output(format);
status = output.SetExternal((uint32_t)surface->w, (uint32_t)surface->h,
(uint8_t*)surface->pixels,
(uint32_t)surface->pitch);
if (status == WP2_STATUS_OK) {
status = WP2::Decode((const uint8_t*)data, data_size, &output);
}
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
if (status != WP2_STATUS_OK) goto Error;
if (SDL_BlitSurface(surface, NULL, screen, NULL) || SDL_Flip(screen)) {
goto Error;
}
ok = 1;
Error:
SDL_FreeSurface(surface);
SDL_FreeSurface(screen);
return ok;
}
//------------------------------------------------------------------------------
#else
int WP2ToSDL(const char* const data, unsigned int data_size) {
(void)data;
(void)data_size;
return 0;
}
#endif // WP2_HAVE_SDL