mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 21:32:45 +00:00
172 lines
4.0 KiB
C
172 lines
4.0 KiB
C
/* Copyright (C) 2010-2015 The RetroArch team
|
|
*
|
|
* ---------------------------------------------------------------------------------------
|
|
* The following license statement only applies to this file (rpng.c).
|
|
* ---------------------------------------------------------------------------------------
|
|
*
|
|
* 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 _RPNG_COMMON_H
|
|
#define _RPNG_COMMON_H
|
|
|
|
#include <retro_inline.h>
|
|
#include <formats/rpng.h>
|
|
#include <stdint.h>
|
|
|
|
#undef GOTO_END_ERROR
|
|
#define GOTO_END_ERROR() do { \
|
|
fprintf(stderr, "[RPNG]: Error in line %d.\n", __LINE__); \
|
|
ret = false; \
|
|
goto end; \
|
|
} while(0)
|
|
|
|
#ifndef ARRAY_SIZE
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
#endif
|
|
|
|
static const uint8_t png_magic[8] = {
|
|
0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a,
|
|
};
|
|
|
|
enum png_chunk_type
|
|
{
|
|
PNG_CHUNK_NOOP = 0,
|
|
PNG_CHUNK_ERROR,
|
|
PNG_CHUNK_IHDR,
|
|
PNG_CHUNK_IDAT,
|
|
PNG_CHUNK_PLTE,
|
|
PNG_CHUNK_IEND
|
|
};
|
|
|
|
enum png_line_filter
|
|
{
|
|
PNG_FILTER_NONE = 0,
|
|
PNG_FILTER_SUB,
|
|
PNG_FILTER_UP,
|
|
PNG_FILTER_AVERAGE,
|
|
PNG_FILTER_PAETH
|
|
};
|
|
|
|
enum png_ihdr_color_type
|
|
{
|
|
PNG_IHDR_COLOR_GRAY = 0,
|
|
PNG_IHDR_COLOR_RGB = 2,
|
|
PNG_IHDR_COLOR_PLT = 3,
|
|
PNG_IHDR_COLOR_GRAY_ALPHA = 4,
|
|
PNG_IHDR_COLOR_RGBA = 6
|
|
};
|
|
|
|
struct adam7_pass
|
|
{
|
|
unsigned x;
|
|
unsigned y;
|
|
unsigned stride_x;
|
|
unsigned stride_y;
|
|
};
|
|
|
|
struct idat_buffer
|
|
{
|
|
uint8_t *data;
|
|
size_t size;
|
|
};
|
|
|
|
struct png_chunk
|
|
{
|
|
uint32_t size;
|
|
char type[4];
|
|
uint8_t *data;
|
|
};
|
|
|
|
struct png_ihdr
|
|
{
|
|
uint32_t width;
|
|
uint32_t height;
|
|
uint8_t depth;
|
|
uint8_t color_type;
|
|
uint8_t compression;
|
|
uint8_t filter;
|
|
uint8_t interlace;
|
|
};
|
|
|
|
struct rpng_process_t
|
|
{
|
|
bool initialized;
|
|
bool inflate_initialized;
|
|
bool adam7_pass_initialized;
|
|
bool pass_initialized;
|
|
uint32_t *data;
|
|
uint32_t *palette;
|
|
struct png_ihdr ihdr;
|
|
uint8_t *prev_scanline;
|
|
uint8_t *decoded_scanline;
|
|
uint8_t *inflate_buf;
|
|
size_t restore_buf_size;
|
|
size_t adam7_restore_buf_size;
|
|
size_t data_restore_buf_size;
|
|
size_t inflate_buf_size;
|
|
unsigned bpp;
|
|
unsigned pitch;
|
|
unsigned h;
|
|
struct
|
|
{
|
|
unsigned width;
|
|
unsigned height;
|
|
size_t size;
|
|
unsigned pos;
|
|
} pass;
|
|
void *stream;
|
|
zlib_file_handle_t handle;
|
|
};
|
|
|
|
struct rpng
|
|
{
|
|
struct rpng_process_t process;
|
|
bool has_ihdr;
|
|
bool has_idat;
|
|
bool has_iend;
|
|
bool has_plte;
|
|
struct idat_buffer idat_buf;
|
|
struct png_ihdr ihdr;
|
|
uint8_t *buff_data;
|
|
uint32_t palette[256];
|
|
};
|
|
|
|
/* Paeth prediction filter. */
|
|
static INLINE int paeth(int a, int b, int c)
|
|
{
|
|
int p = a + b - c;
|
|
int pa = abs(p - a);
|
|
int pb = abs(p - b);
|
|
int pc = abs(p - c);
|
|
|
|
if (pa <= pb && pa <= pc)
|
|
return a;
|
|
else if (pb <= pc)
|
|
return b;
|
|
return c;
|
|
}
|
|
|
|
static INLINE uint32_t dword_be(const uint8_t *buf)
|
|
{
|
|
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
|
|
}
|
|
|
|
int rpng_load_image_argb_process_inflate_init(rpng_t *rpng,
|
|
uint32_t **data, unsigned *width, unsigned *height);
|
|
|
|
#endif
|