From d09574bb1f5e309f7df1d7b8da9075ca65237ed7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 22 Feb 2015 04:56:18 +0100 Subject: [PATCH] Move files around --- Makefile.common | 2 + gfx/drivers/gl.c | 2 +- gfx/gl_common.h | 2 +- gfx/image/image.c | 69 +---- gfx/image/image_nbio.c | 238 ++++++++++++++++++ griffin/griffin.c | 1 + input/input_overlay.h | 2 +- libretro-common/formats/tga/tga_decode.c | 89 +++++++ .../include/formats}/image.h | 8 +- libretro-common/include/formats/mpng.h | 55 ---- libretro-common/include/formats/tga.h | 49 ++++ 11 files changed, 384 insertions(+), 133 deletions(-) create mode 100644 gfx/image/image_nbio.c create mode 100644 libretro-common/formats/tga/tga_decode.c rename {gfx/image => libretro-common/include/formats}/image.h (91%) delete mode 100644 libretro-common/include/formats/mpng.h create mode 100644 libretro-common/include/formats/tga.h diff --git a/Makefile.common b/Makefile.common index dfb3c1c091..74cc2d771d 100644 --- a/Makefile.common +++ b/Makefile.common @@ -565,6 +565,8 @@ ifeq ($(HAVE_7ZIP),1) OBJ += $(7ZOBJ) endif + OBJ += libretro-common/formats/tga/tga_decode.o + ifeq ($(HAVE_ZLIB), 1) ZLIB_OBJS = decompress/zip_support.o OBJ += libretro-common/formats/png/rpng_decode_fnbio.o \ diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 1a4ee5d64c..15364005e4 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -22,7 +22,7 @@ #include "../../driver.h" #include "../../performance.h" #include -#include "../image/image.h" +#include #include #include "../../libretro.h" diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 33a5b39451..9d96d5f55e 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -22,7 +22,7 @@ #include #include #include "font_gl_driver.h" -#include "image/image.h" +#include #include "video_shader_driver.h" #ifdef HAVE_CONFIG_H diff --git a/gfx/image/image.c b/gfx/image/image.c index 9942cb512c..edce9c8505 100644 --- a/gfx/image/image.c +++ b/gfx/image/image.c @@ -18,7 +18,7 @@ #include "../../config.h" #endif -#include "image.h" +#include #ifdef _XBOX1 #include "../d3d/d3d_wrapper.h" #endif @@ -48,73 +48,6 @@ #include #endif -static bool rtga_image_load_shift(uint8_t *buf, - struct texture_image *out_img, - unsigned a_shift, unsigned r_shift, - unsigned g_shift, unsigned b_shift) -{ - unsigned i, bits, size, bits_mul; - uint8_t info[6]; - unsigned width = 0; - unsigned height = 0; - const uint8_t *tmp = NULL; - - if (buf[2] != 2) - { - RARCH_ERR("TGA image is not uncompressed RGB.\n"); - return false; - } - - memcpy(info, buf + 12, 6); - - width = info[0] + ((unsigned)info[1] * 256); - height = info[2] + ((unsigned)info[3] * 256); - bits = info[4]; - - RARCH_LOG("Loaded TGA: (%ux%u @ %u bpp)\n", width, height, bits); - - size = width * height * sizeof(uint32_t); - out_img->pixels = (uint32_t*)malloc(size); - out_img->width = width; - out_img->height = height; - - if (!out_img->pixels) - { - RARCH_ERR("Failed to allocate TGA pixels.\n"); - return false; - } - - tmp = buf + 18; - bits_mul = 3; - - if (bits != 32 && bits != 24) - { - RARCH_ERR("Bit depth of TGA image is wrong. Only 32-bit and 24-bit supported.\n"); - free(out_img->pixels); - out_img->pixels = NULL; - return false; - } - - if (bits == 32) - bits_mul = 4; - - for (i = 0; i < width * height; i++) - { - uint32_t b = tmp[i * bits_mul + 0]; - uint32_t g = tmp[i * bits_mul + 1]; - uint32_t r = tmp[i * bits_mul + 2]; - uint32_t a = tmp[i * bits_mul + 3]; - - if (bits == 24) - a = 0xff; - - out_img->pixels[i] = (a << a_shift) | - (r << r_shift) | (g << g_shift) | (b << b_shift); - } - - return true; -} - #ifdef HAVE_ZLIB #ifdef HAVE_NONBLOCKING_TEST static bool rpng_load_image_argb_nonblocking( diff --git a/gfx/image/image_nbio.c b/gfx/image/image_nbio.c new file mode 100644 index 0000000000..bf04775800 --- /dev/null +++ b/gfx/image/image_nbio.c @@ -0,0 +1,238 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "image.h" + +#include +#include +#include +#include "../../general.h" +#include "../../file_ops.h" +#include + +#ifdef HAVE_ZLIB +static bool rpng_load_image_argb_nonblocking( + const char *path, uint32_t **data, + unsigned *width, unsigned *height) +{ + bool ret = true; + struct rpng_t *rpng = rpng_nbio_load_image_argb_init(path); + + if (!rpng) + { + ret = false; + goto end; + } + + while (!nbio_iterate((struct nbio_t*)rpng->userdata)); + + if (!rpng_nbio_load_image_argb_start(rpng)) + { + ret = false; + goto end; + } + + while (rpng_nbio_load_image_argb_iterate( + rpng->buff_data, rpng)) + { + rpng->buff_data += 4 + 4 + rpng->chunk.size + 4; + } + +#if 0 + fprintf(stderr, "has_ihdr: %d\n", rpng->has_ihdr); + fprintf(stderr, "has_idat: %d\n", rpng->has_idat); + fprintf(stderr, "has_iend: %d\n", rpng->has_iend); +#endif + + if (!rpng->has_ihdr || !rpng->has_idat || !rpng->has_iend) + { + ret = false; + goto end; + } + + rpng_nbio_load_image_argb_process(rpng, data, width, height); + +end: + rpng_nbio_load_image_free(rpng); + rpng = NULL; + if (!ret) + free(*data); + + return ret; +} + +static bool rpng_image_load_argb_shift(const char *path, + struct texture_image *out_img, + unsigned a_shift, unsigned r_shift, + unsigned g_shift, unsigned b_shift) +{ + bool ret = rpng_load_image_argb_nonblocking(path, + &out_img->pixels, &out_img->width, &out_img->height); + + if (!ret) + return false; + + /* This is quite uncommon. */ + if (a_shift != 24 || r_shift != 16 || g_shift != 8 || b_shift != 0) + { + uint32_t i; + uint32_t num_pixels = out_img->width * out_img->height; + uint32_t *pixels = (uint32_t*)out_img->pixels; + + for (i = 0; i < num_pixels; i++) + { + uint32_t col = pixels[i]; + uint8_t a = (uint8_t)(col >> 24); + uint8_t r = (uint8_t)(col >> 16); + uint8_t g = (uint8_t)(col >> 8); + uint8_t b = (uint8_t)(col >> 0); + pixels[i] = (a << a_shift) | + (r << r_shift) | (g << g_shift) | (b << b_shift); + } + } + + return true; +} +#endif + +#ifdef GEKKO + +#define GX_BLIT_LINE_32(off) \ +{ \ + const uint16_t *tmp_src = src; \ + uint16_t *tmp_dst = dst; \ + for (unsigned x = 0; x < width2 >> 3; x++, tmp_src += 8, tmp_dst += 32) \ + { \ + tmp_dst[ 0 + off] = tmp_src[0]; \ + tmp_dst[ 16 + off] = tmp_src[1]; \ + tmp_dst[ 1 + off] = tmp_src[2]; \ + tmp_dst[ 17 + off] = tmp_src[3]; \ + tmp_dst[ 2 + off] = tmp_src[4]; \ + tmp_dst[ 18 + off] = tmp_src[5]; \ + tmp_dst[ 3 + off] = tmp_src[6]; \ + tmp_dst[ 19 + off] = tmp_src[7]; \ + } \ + src += tmp_pitch; \ +} + +static bool rpng_gx_convert_texture32(struct texture_image *image) +{ + unsigned tmp_pitch, width2, i; + const uint16_t *src; + uint16_t *dst; + /* Memory allocation in libogc is extremely primitive so try + * to avoid gaps in memory when converting by copying over to + * a temporary buffer first, then converting over into + * main buffer again. */ + void *tmp = malloc(image->width * image->height * sizeof(uint32_t)); + + if (!tmp) + { + RARCH_ERR("Failed to create temp buffer for conversion.\n"); + return false; + } + + memcpy(tmp, image->pixels, image->width * image->height * sizeof(uint32_t)); + tmp_pitch = (image->width * sizeof(uint32_t)) >> 1; + + image->width &= ~3; + image->height &= ~3; + + width2 = image->width << 1; + + src = (uint16_t *) tmp; + dst = (uint16_t *) image->pixels; + + for (i = 0; i < image->height; i += 4, dst += 4 * width2) + { + GX_BLIT_LINE_32(0) + GX_BLIT_LINE_32(4) + GX_BLIT_LINE_32(8) + GX_BLIT_LINE_32(12) + } + + free(tmp); + return true; +} + +#endif + +void texture_image_free(struct texture_image *img) +{ + if (!img) + return; + + if (img->pixels) + free(img->pixels); + memset(img, 0, sizeof(*img)); +} + +bool texture_image_load(struct texture_image *out_img, const char *path) +{ + /* This interface "leak" is very ugly. FIXME: Fix this properly ... */ + bool ret = false; + bool use_rgba = driver.gfx_use_rgba; + unsigned a_shift = 24; + unsigned r_shift = use_rgba ? 0 : 16; + unsigned g_shift = 8; + unsigned b_shift = use_rgba ? 16 : 0; + + if (strstr(path, ".tga")) + { + void *raw_buf = NULL; + uint8_t *buf = NULL; + ssize_t len; + bool ret = read_file(path, &raw_buf, &len); + + if (!ret || len < 0) + { + RARCH_ERR("Failed to read image: %s.\n", path); + return false; + } + + buf = (uint8_t*)raw_buf; + + ret = rtga_image_load_shift(buf, out_img, + a_shift, r_shift, g_shift, b_shift); + + if (buf) + free(buf); + } +#ifdef HAVE_ZLIB + else if (strstr(path, ".png")) + { + ret = rpng_image_load_argb_shift(path, out_img, + a_shift, r_shift, g_shift, b_shift); + } +#endif + +#ifdef GEKKO + if (ret) + { + if (!rpng_gx_convert_texture32(out_img)) + { + texture_image_free(out_img); + return false; + } + } +#endif + + return ret; +} diff --git a/griffin/griffin.c b/griffin/griffin.c index f53e652046..c80173e92f 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -174,6 +174,7 @@ VIDEO IMAGE #include "../gfx/image/image.c" +#include "../libretro-common/formats/tga/tga_decode.c" #include "../libretro-common/formats/png/rpng_decode_fbio.c" #include "../libretro-common/formats/png/rpng_decode_fnbio.c" #include "../libretro-common/formats/png/rpng_encode.c" diff --git a/input/input_overlay.h b/input/input_overlay.h index 348e6feec7..b0f9f40843 100644 --- a/input/input_overlay.h +++ b/input/input_overlay.h @@ -20,7 +20,7 @@ #include #include #include "../libretro.h" -#include "../gfx/image/image.h" +#include #include #ifdef __cplusplus diff --git a/libretro-common/formats/tga/tga_decode.c b/libretro-common/formats/tga/tga_decode.c new file mode 100644 index 0000000000..75f43cfa08 --- /dev/null +++ b/libretro-common/formats/tga/tga_decode.c @@ -0,0 +1,89 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2015 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include + +bool rtga_image_load_shift(uint8_t *buf, + void *data, + unsigned a_shift, unsigned r_shift, + unsigned g_shift, unsigned b_shift) +{ + unsigned i, bits, size, bits_mul; + uint8_t info[6]; + unsigned width = 0; + unsigned height = 0; + const uint8_t *tmp = NULL; + struct texture_image *out_img = (struct texture_image*)data; + + if (buf[2] != 2) + { + fprintf(stderr, "TGA image is not uncompressed RGB.\n"); + return false; + } + + memcpy(info, buf + 12, 6); + + width = info[0] + ((unsigned)info[1] * 256); + height = info[2] + ((unsigned)info[3] * 256); + bits = info[4]; + + fprintf(stderr, "Loaded TGA: (%ux%u @ %u bpp)\n", width, height, bits); + + size = width * height * sizeof(uint32_t); + out_img->pixels = (uint32_t*)malloc(size); + out_img->width = width; + out_img->height = height; + + if (!out_img->pixels) + { + fprintf(stderr, "Failed to allocate TGA pixels.\n"); + return false; + } + + tmp = buf + 18; + bits_mul = 3; + + if (bits != 32 && bits != 24) + { + fprintf(stderr, "Bit depth of TGA image is wrong. Only 32-bit and 24-bit supported.\n"); + free(out_img->pixels); + out_img->pixels = NULL; + return false; + } + + if (bits == 32) + bits_mul = 4; + + for (i = 0; i < width * height; i++) + { + uint32_t b = tmp[i * bits_mul + 0]; + uint32_t g = tmp[i * bits_mul + 1]; + uint32_t r = tmp[i * bits_mul + 2]; + uint32_t a = tmp[i * bits_mul + 3]; + + if (bits == 24) + a = 0xff; + + out_img->pixels[i] = (a << a_shift) | + (r << r_shift) | (g << g_shift) | (b << b_shift); + } + + return true; +} diff --git a/gfx/image/image.h b/libretro-common/include/formats/image.h similarity index 91% rename from gfx/image/image.h rename to libretro-common/include/formats/image.h index 65342b1294..0f67f474bf 100644 --- a/gfx/image/image.h +++ b/libretro-common/include/formats/image.h @@ -21,13 +21,7 @@ #include #include - -#ifdef _WIN32 -#include "../drivers_context/win32_common.h" -#ifdef _XBOX1 -#include "../d3d/d3d_defines.h" -#endif -#endif +#include struct texture_image { diff --git a/libretro-common/include/formats/mpng.h b/libretro-common/include/formats/mpng.h deleted file mode 100644 index 83fd5052a1..0000000000 --- a/libretro-common/include/formats/mpng.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _MPNG_FORMAT_H -#define _MPNG_FORMAT_H - -enum video_format -{ - /* these three are same values and order as in libretro - do not change */ - FMT_XRGB1555, - FMT_XRGB8888, - FMT_RGB565, - - FMT_NONE, - - FMT_RGB888, - FMT_ARGB1555, - FMT_ARGB8888, -}; - -struct mpng_image -{ - unsigned int width; - unsigned int height; - void * pixels; - - /* Small, or even large, - * amounts of padding between each scanline is fine. - * However, each scanline is packed. - * The pitch is in bytes. - */ - unsigned int pitch; - - enum video_format format; -}; - -static inline uint8_t videofmt_byte_per_pixel(enum video_format fmt) -{ - static const uint8_t table[]={2, 4, 2, 0, 3, 2, 4}; - return table[fmt]; -} - -#ifdef __cplusplus -extern "C" { -#endif - -/* Valid formats: 888, (8)888, 8888 - * If there is transparency, 8888 is mandatory. */ -bool png_decode(const void * pngdata, - size_t pnglen, - struct mpng_image *img, - enum video_format format); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libretro-common/include/formats/tga.h b/libretro-common/include/formats/tga.h new file mode 100644 index 0000000000..fa3a9c816c --- /dev/null +++ b/libretro-common/include/formats/tga.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (rpng.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LIBRETRO_SDK_FORMAT_RTGA_H__ +#define __LIBRETRO_SDK_FORMAT_RTGA_H__ + +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +bool rtga_image_load_shift(uint8_t *buf, + void *data, + unsigned a_shift, unsigned r_shift, + unsigned g_shift, unsigned b_shift); + +#ifdef __cplusplus +} +#endif + +#endif +