mirror of
https://github.com/joel16/VITAlbum.git
synced 2024-11-26 21:10:25 +00:00
Initial commit
This commit is contained in:
commit
18cd52564e
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
111
CMakeLists.txt
Normal file
111
CMakeLists.txt
Normal file
@ -0,0 +1,111 @@
|
||||
## This file is a quick tutorial on writing CMakeLists for targeting the Vita
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
## This includes the Vita toolchain, must go before project definition
|
||||
# It is a convenience so you do not have to type
|
||||
# -DCMAKE_TOOLCHAIN_FILE=$VITASDK/share/vita.toolchain.cmake for cmake. It is
|
||||
# highly recommended that you include this block for all projects.
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
if(DEFINED ENV{VITASDK})
|
||||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
|
||||
else()
|
||||
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
## Define project parameters here
|
||||
# Name of the project
|
||||
project(VITAlbum)
|
||||
# This line adds Vita helper macros, must go after project definition in order
|
||||
# to build Vita specific artifacts (self/vpk).
|
||||
include("${VITASDK}/share/vita.cmake" REQUIRED)
|
||||
|
||||
## Configuration options for this app
|
||||
# Display name (under bubble in LiveArea)
|
||||
set(VITA_APP_NAME "VITAlbum")
|
||||
# Unique ID must be exactly 9 characters. Recommended: XXXXYYYYY where X =
|
||||
# unique string of developer and Y = a unique number for this app
|
||||
set(VITA_TITLEID "VITALBUM0")
|
||||
# Optional version string to show in LiveArea's more info screen
|
||||
set(VITA_VERSION "01.00")
|
||||
|
||||
## Flags and includes for building
|
||||
# Note that we make sure not to overwrite previous flags
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -mtune=cortex-a9 -mfpu=neon -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -std=gnu++17")
|
||||
# Optional. You can specify more param.sfo flags this way.
|
||||
set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1")
|
||||
|
||||
# Add any additional include paths here
|
||||
include_directories(
|
||||
libs/imgui
|
||||
libs/libnsbmp
|
||||
libs/libnsgif
|
||||
libs/libtiff
|
||||
libs
|
||||
include
|
||||
)
|
||||
|
||||
# Add any additional library paths here
|
||||
# ${CMAKE_CURRENT_BINARY_DIR} lets you use any library currently being built
|
||||
link_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/libs/lib
|
||||
)
|
||||
|
||||
## Build and link
|
||||
# Add all the files needed to compile here
|
||||
add_executable(${PROJECT_NAME}
|
||||
libs/imgui/imgui.cpp
|
||||
libs/imgui/imgui_draw.cpp
|
||||
libs/imgui/imgui_impl_vitagl.cpp
|
||||
libs/imgui/imgui_vita_touch.cpp
|
||||
libs/imgui/imgui_widgets.cpp
|
||||
libs/libnsbmp/libnsbmp.c
|
||||
libs/libnsgif/libnsgif.c
|
||||
libs/libnsgif/lzw.c
|
||||
source/fs.cpp
|
||||
source/gui.cpp
|
||||
source/log.cpp
|
||||
source/main.cpp
|
||||
source/textures.cpp
|
||||
source/utils.cpp
|
||||
)
|
||||
|
||||
# Library to link to (drop the prefix). This will mostly be stubs.
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
tiff
|
||||
webp
|
||||
jpeg
|
||||
pthread
|
||||
lzma
|
||||
z
|
||||
vitaGL
|
||||
mathneon
|
||||
SceCommonDialog_stub
|
||||
SceLibKernel_stub
|
||||
SceDisplay_stub
|
||||
SceGxm_stub
|
||||
SceSysmodule_stub
|
||||
SceCtrl_stub
|
||||
SceTouch_stub
|
||||
m
|
||||
SceAppMgr_stub
|
||||
SceAppUtil_stub
|
||||
)
|
||||
|
||||
## Create Vita files
|
||||
vita_create_self(${PROJECT_NAME}.self ${PROJECT_NAME} UNSAFE)
|
||||
# The FILE directive lets you add additional files to the VPK, the syntax is
|
||||
# FILE src_path dst_path_in_vpk. In this case, we add the LiveArea paths.
|
||||
vita_create_vpk(${PROJECT_NAME}.vpk ${VITA_TITLEID} ${PROJECT_NAME}.self
|
||||
VERSION ${VITA_VERSION}
|
||||
NAME ${VITA_APP_NAME}
|
||||
FILE sce_sys/icon0.png sce_sys/icon0.png
|
||||
FILE sce_sys/livearea/contents/bg.png sce_sys/livearea/contents/bg.png
|
||||
FILE sce_sys/livearea/contents/startup.png sce_sys/livearea/contents/startup.png
|
||||
FILE sce_sys/livearea/contents/template.xml sce_sys/livearea/contents/template.xml
|
||||
FILE res/file.png res/file.png
|
||||
FILE res/folder.png res/folder.png
|
||||
FILE res/image.png res/image.png
|
||||
)
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Joel
|
||||
|
||||
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.
|
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# VITAAlbum
|
||||
|
||||
A simple file browser for PS Vita homebrew that is used for viewing various image formats.
|
||||
|
||||
# Supported Formats:
|
||||
- BMP
|
||||
- GIF
|
||||
- ICO
|
||||
- JPG/JPEG
|
||||
- PCX
|
||||
- PNG
|
||||
- PGM/PPM
|
||||
- TGA
|
||||
- TIFF
|
||||
- WEBP
|
||||
|
||||
# Todo:
|
||||
- Ability to resize images.
|
||||
- Load animated GIFs.
|
||||
|
||||
# Credits:
|
||||
- Rinnegatamante for [vitaGL](https://github.com/Rinnegatamante/vitaGL)
|
||||
- Rinnegatamante for [imgui-vita](https://github.com/Rinnegatamante/imgui-vita)
|
||||
- ocornut and contributors for [upstream imgui](https://github.com/ocornut/imgui)
|
||||
- stb_image contributors [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h)
|
||||
- dr-soft for [dr_pcx](https://github.com/dr-soft/dr_pcx)
|
||||
- libwebp contributors for [libwebp](https://developers.google.com/speed/webp)
|
||||
- libtiff contributors for [libtiff](http://www.libtiff.org/)
|
||||
- libnsbmp contributors for [libnsbmp](https://www.netsurf-browser.org/projects/libnsbmp/)
|
||||
- libnsgif contributors for [libnsgif](https://www.netsurf-browser.org/projects/libnsgif/)
|
||||
- [vitasdk](https://github.com/vitasdk)
|
793
include/dr_pcx.h
Normal file
793
include/dr_pcx.h
Normal file
@ -0,0 +1,793 @@
|
||||
// PCX image loader. Public domain. See "unlicense" statement at the end of this file.
|
||||
// dr_pcx - v0.3.1 - 2018-09-11
|
||||
//
|
||||
// David Reid - mackron@gmail.com
|
||||
|
||||
// USAGE
|
||||
//
|
||||
// dr_pcx is a single-file library. To use it, do something like the following in one .c file.
|
||||
// #define DR_PCX_IMPLEMENTATION
|
||||
// #include "dr_pcx.h"
|
||||
//
|
||||
// You can then #include this file in other parts of the program as you would with any other header file. Do something like
|
||||
// the following to load and decode an image:
|
||||
//
|
||||
// int width;
|
||||
// int height;
|
||||
// int components
|
||||
// drpcx_uint8* pImageData = drpcx_load_file("my_image.pcx", DRPCX_FALSE, &width, &height, &components, 0);
|
||||
// if (pImageData == NULL) {
|
||||
// // Failed to load image.
|
||||
// }
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// drpcx_free(pImageData);
|
||||
//
|
||||
// The boolean parameter (second argument in the above example) is whether or not the image should be flipped upside down.
|
||||
//
|
||||
//
|
||||
//
|
||||
// OPTIONS
|
||||
// #define these options before including this file.
|
||||
//
|
||||
// #define DR_PCX_NO_STDIO
|
||||
// Disable drpcx_load_file().
|
||||
//
|
||||
//
|
||||
//
|
||||
// QUICK NOTES
|
||||
// - 2-bpp/4-plane and 4-bpp/1-plane formats have not been tested.
|
||||
|
||||
#ifndef dr_pcx_h
|
||||
#define dr_pcx_h
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
typedef signed char drpcx_int8;
|
||||
typedef unsigned char drpcx_uint8;
|
||||
typedef signed short drpcx_int16;
|
||||
typedef unsigned short drpcx_uint16;
|
||||
typedef signed int drpcx_int32;
|
||||
typedef unsigned int drpcx_uint32;
|
||||
typedef signed __int64 drpcx_int64;
|
||||
typedef unsigned __int64 drpcx_uint64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef int8_t drpcx_int8;
|
||||
typedef uint8_t drpcx_uint8;
|
||||
typedef int16_t drpcx_int16;
|
||||
typedef uint16_t drpcx_uint16;
|
||||
typedef int32_t drpcx_int32;
|
||||
typedef uint32_t drpcx_uint32;
|
||||
typedef int64_t drpcx_int64;
|
||||
typedef uint64_t drpcx_uint64;
|
||||
#endif
|
||||
typedef drpcx_uint8 drpcx_bool8;
|
||||
typedef drpcx_uint32 drpcx_bool32;
|
||||
#define DRPCX_TRUE 1
|
||||
#define DRPCX_FALSE 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Callback for when data is read. Return value is the number of bytes actually read.
|
||||
typedef size_t (* drpcx_read_proc)(void* userData, void* bufferOut, size_t bytesToRead);
|
||||
|
||||
|
||||
// Loads a PCX file using the given callbacks.
|
||||
drpcx_uint8* drpcx_load(drpcx_read_proc onRead, void* pUserData, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents);
|
||||
|
||||
// Frees memory returned by drpcx_load() and family.
|
||||
void drpcx_free(void* pReturnValueFromLoad);
|
||||
|
||||
|
||||
#ifndef DR_PCX_NO_STDIO
|
||||
// Loads an PCX file from an actual file.
|
||||
drpcx_uint8* drpcx_load_file(const char* filename, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents);
|
||||
#endif
|
||||
|
||||
// Helper for loading an PCX file from a block of memory.
|
||||
drpcx_uint8* drpcx_load_memory(const void* data, size_t dataSize, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // dr_pcx_h
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef DR_PCX_IMPLEMENTATION
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef DR_PCX_NO_STDIO
|
||||
#include <stdio.h>
|
||||
|
||||
static size_t drpcx__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
|
||||
{
|
||||
return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData);
|
||||
}
|
||||
|
||||
drpcx_uint8* drpcx_load_file(const char* filename, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents)
|
||||
{
|
||||
FILE* pFile;
|
||||
#ifdef _MSC_VER
|
||||
if (fopen_s(&pFile, filename, "rb") != 0) {
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
pFile = fopen(filename, "rb");
|
||||
if (pFile == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
drpcx_uint8* pImageData = drpcx_load(drpcx__on_read_stdio, pFile, flipped, x, y, internalComponents, desiredComponents);
|
||||
|
||||
fclose(pFile);
|
||||
return pImageData;
|
||||
}
|
||||
#endif // DR_PCX_NO_STDIO
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// A pointer to the beginning of the data. We use a char as the type here for easy offsetting.
|
||||
const unsigned char* data;
|
||||
size_t dataSize;
|
||||
size_t currentReadPos;
|
||||
} drpcx_memory;
|
||||
|
||||
static size_t drpcx__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead)
|
||||
{
|
||||
drpcx_memory* memory = (drpcx_memory*)pUserData;
|
||||
assert(memory != NULL);
|
||||
assert(memory->dataSize >= memory->currentReadPos);
|
||||
|
||||
size_t bytesRemaining = memory->dataSize - memory->currentReadPos;
|
||||
if (bytesToRead > bytesRemaining) {
|
||||
bytesToRead = bytesRemaining;
|
||||
}
|
||||
|
||||
if (bytesToRead > 0) {
|
||||
memcpy(bufferOut, memory->data + memory->currentReadPos, bytesToRead);
|
||||
memory->currentReadPos += bytesToRead;
|
||||
}
|
||||
|
||||
return bytesToRead;
|
||||
}
|
||||
|
||||
drpcx_uint8* drpcx_load_memory(const void* data, size_t dataSize, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents)
|
||||
{
|
||||
drpcx_memory memory;
|
||||
memory.data = (const unsigned char*)data;
|
||||
memory.dataSize = dataSize;
|
||||
memory.currentReadPos = 0;
|
||||
return drpcx_load(drpcx__on_read_memory, &memory, flipped, x, y, internalComponents, desiredComponents);
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
drpcx_uint8 header;
|
||||
drpcx_uint8 version;
|
||||
drpcx_uint8 encoding;
|
||||
drpcx_uint8 bpp;
|
||||
drpcx_uint16 left;
|
||||
drpcx_uint16 top;
|
||||
drpcx_uint16 right;
|
||||
drpcx_uint16 bottom;
|
||||
drpcx_uint16 hres;
|
||||
drpcx_uint16 vres;
|
||||
drpcx_uint8 palette16[48];
|
||||
drpcx_uint8 reserved1;
|
||||
drpcx_uint8 bitPlanes;
|
||||
drpcx_uint16 bytesPerLine;
|
||||
drpcx_uint16 paletteType;
|
||||
drpcx_uint16 screenSizeH;
|
||||
drpcx_uint16 screenSizeV;
|
||||
drpcx_uint8 reserved2[54];
|
||||
} drpcx_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
drpcx_read_proc onRead;
|
||||
void* pUserData;
|
||||
drpcx_bool32 flipped;
|
||||
drpcx_header header;
|
||||
|
||||
drpcx_uint32 width;
|
||||
drpcx_uint32 height;
|
||||
drpcx_uint32 components; // 3 = RGB; 4 = RGBA. Only 3 and 4 are supported.
|
||||
drpcx_uint8* pImageData;
|
||||
} drpcx;
|
||||
|
||||
|
||||
static drpcx_uint8 drpcx__read_byte(drpcx* pPCX)
|
||||
{
|
||||
drpcx_uint8 byte = 0;
|
||||
pPCX->onRead(pPCX->pUserData, &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
static drpcx_uint8* drpcx__row_ptr(drpcx* pPCX, drpcx_uint32 row)
|
||||
{
|
||||
drpcx_uint32 stride = pPCX->width * pPCX->components;
|
||||
|
||||
drpcx_uint8* pRow = pPCX->pImageData;
|
||||
if (pPCX->flipped) {
|
||||
pRow += (pPCX->height - row - 1) * stride;
|
||||
} else {
|
||||
pRow += row * stride;
|
||||
}
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
||||
static drpcx_uint8 drpcx__rle(drpcx* pPCX, drpcx_uint8* pRLEValueOut)
|
||||
{
|
||||
drpcx_uint8 rleCount;
|
||||
drpcx_uint8 rleValue;
|
||||
|
||||
rleValue = drpcx__read_byte(pPCX);
|
||||
if ((rleValue & 0xC0) == 0xC0) {
|
||||
rleCount = rleValue & 0x3F;
|
||||
rleValue = drpcx__read_byte(pPCX);
|
||||
} else {
|
||||
rleCount = 1;
|
||||
}
|
||||
|
||||
|
||||
*pRLEValueOut = rleValue;
|
||||
return rleCount;
|
||||
}
|
||||
|
||||
|
||||
drpcx_bool32 drpcx__decode_1bit(drpcx* pPCX)
|
||||
{
|
||||
drpcx_uint8 rleCount = 0;
|
||||
drpcx_uint8 rleValue = 0;
|
||||
|
||||
switch (pPCX->header.bitPlanes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
for (int bit = 0; (bit < 8) && ((x*8 + bit) < pPCX->width); ++bit) {
|
||||
drpcx_uint8 mask = (1 << (7 - bit));
|
||||
drpcx_uint8 paletteIndex = (rleValue & mask) >> (7 - bit);
|
||||
|
||||
pRow[0] = paletteIndex * 255;
|
||||
pRow[1] = paletteIndex * 255;
|
||||
pRow[2] = paletteIndex * 255;
|
||||
pRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
|
||||
} break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
for (drpcx_uint32 c = 0; c < pPCX->header.bitPlanes; ++c) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
for (int bit = 0; (bit < 8) && ((x*8 + bit) < pPCX->width); ++bit) {
|
||||
drpcx_uint8 mask = (1 << (7 - bit));
|
||||
drpcx_uint8 paletteIndex = (rleValue & mask) >> (7 - bit);
|
||||
|
||||
pRow[0] |= ((paletteIndex & 0x01) << c);
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->width; ++x) {
|
||||
drpcx_uint8 paletteIndex = pRow[0];
|
||||
for (drpcx_uint32 c = 0; c < pPCX->components; ++c) {
|
||||
pRow[c] = pPCX->header.palette16[paletteIndex*3 + c];
|
||||
}
|
||||
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
}
|
||||
|
||||
default: return DRPCX_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
drpcx_bool32 drpcx__decode_2bit(drpcx* pPCX)
|
||||
{
|
||||
drpcx_uint8 rleCount = 0;
|
||||
drpcx_uint8 rleValue = 0;
|
||||
|
||||
switch (pPCX->header.bitPlanes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
drpcx_uint8 paletteCGA[48];
|
||||
paletteCGA[ 0] = 0x00; paletteCGA[ 1] = 0x00; paletteCGA[ 2] = 0x00; // #000000
|
||||
paletteCGA[ 3] = 0x00; paletteCGA[ 4] = 0x00; paletteCGA[ 5] = 0xAA; // #0000AA
|
||||
paletteCGA[ 6] = 0x00; paletteCGA[ 7] = 0xAA; paletteCGA[ 8] = 0x00; // #00AA00
|
||||
paletteCGA[ 9] = 0x00; paletteCGA[10] = 0xAA; paletteCGA[11] = 0xAA; // #00AAAA
|
||||
paletteCGA[12] = 0xAA; paletteCGA[13] = 0x00; paletteCGA[14] = 0x00; // #AA0000
|
||||
paletteCGA[15] = 0xAA; paletteCGA[16] = 0x00; paletteCGA[17] = 0xAA; // #AA00AA
|
||||
paletteCGA[18] = 0xAA; paletteCGA[19] = 0x55; paletteCGA[20] = 0x00; // #AA5500
|
||||
paletteCGA[21] = 0xAA; paletteCGA[22] = 0xAA; paletteCGA[23] = 0xAA; // #AAAAAA
|
||||
paletteCGA[24] = 0x55; paletteCGA[25] = 0x55; paletteCGA[26] = 0x55; // #555555
|
||||
paletteCGA[27] = 0x55; paletteCGA[28] = 0x55; paletteCGA[29] = 0xFF; // #5555FF
|
||||
paletteCGA[30] = 0x55; paletteCGA[31] = 0xFF; paletteCGA[32] = 0x55; // #55FF55
|
||||
paletteCGA[33] = 0x55; paletteCGA[34] = 0xFF; paletteCGA[35] = 0xFF; // #55FFFF
|
||||
paletteCGA[36] = 0xFF; paletteCGA[37] = 0x55; paletteCGA[38] = 0x55; // #FF5555
|
||||
paletteCGA[39] = 0xFF; paletteCGA[40] = 0x55; paletteCGA[41] = 0xFF; // #FF55FF
|
||||
paletteCGA[42] = 0xFF; paletteCGA[43] = 0xFF; paletteCGA[44] = 0x55; // #FFFF55
|
||||
paletteCGA[45] = 0xFF; paletteCGA[46] = 0xFF; paletteCGA[47] = 0xFF; // #FFFFFF
|
||||
|
||||
drpcx_uint8 cgaBGColor = pPCX->header.palette16[0] >> 4;
|
||||
drpcx_uint8 i = (pPCX->header.palette16[3] & 0x20) >> 5;
|
||||
drpcx_uint8 p = (pPCX->header.palette16[3] & 0x40) >> 6;
|
||||
//drpcx_uint8 c = (pPCX->header.palette16[3] & 0x80) >> 7; // Color or monochrome. How is monochrome handled?
|
||||
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
for (int bit = 0; bit < 4; ++bit) {
|
||||
if (x*4 + bit < pPCX->width) {
|
||||
drpcx_uint8 mask = (3 << ((3 - bit) * 2));
|
||||
drpcx_uint8 paletteIndex = (rleValue & mask) >> ((3 - bit) * 2);
|
||||
|
||||
drpcx_uint8 cgaIndex;
|
||||
if (paletteIndex == 0) { // Background.
|
||||
cgaIndex = cgaBGColor;
|
||||
} else { // Foreground
|
||||
cgaIndex = (((paletteIndex << 1) + p) + (i << 3));
|
||||
}
|
||||
|
||||
pRow[0] = paletteCGA[cgaIndex*3 + 0];
|
||||
pRow[1] = paletteCGA[cgaIndex*3 + 1];
|
||||
pRow[2] = paletteCGA[cgaIndex*3 + 2];
|
||||
pRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: According to http://www.fysnet.net/pcxfile.htm, we should use the palette at the end of the file
|
||||
// instead of the standard CGA palette if the version is equal to 5. With my test files the palette
|
||||
// at the end of the file does not exist. Research this one.
|
||||
if (pPCX->header.version == 5) {
|
||||
drpcx_uint8 paletteMarker = drpcx__read_byte(pPCX);
|
||||
if (paletteMarker == 0x0C) {
|
||||
// TODO: Implement Me.
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
};
|
||||
|
||||
case 4:
|
||||
{
|
||||
// NOTE: This is completely untested. If anybody knows where I can get a test file please let me know or send it through to me!
|
||||
// TODO: Test Me.
|
||||
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
for (drpcx_uint32 c = 0; c < pPCX->header.bitPlanes; ++c) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
for (int bitpair = 0; (bitpair < 4) && ((x*4 + bitpair) < pPCX->width); ++bitpair) {
|
||||
drpcx_uint8 mask = (4 << (3 - bitpair));
|
||||
drpcx_uint8 paletteIndex = (rleValue & mask) >> (3 - bitpair);
|
||||
|
||||
pRow[0] |= ((paletteIndex & 0x03) << (c*2));
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->width; ++x) {
|
||||
drpcx_uint8 paletteIndex = pRow[0];
|
||||
for (drpcx_uint32 c = 0; c < pPCX->header.bitPlanes; ++c) {
|
||||
pRow[c] = pPCX->header.palette16[paletteIndex*3 + c];
|
||||
}
|
||||
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
};
|
||||
|
||||
default: return DRPCX_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
drpcx_bool32 drpcx__decode_4bit(drpcx* pPCX)
|
||||
{
|
||||
// NOTE: This is completely untested. If anybody knows where I can get a test file please let me know or send it through to me!
|
||||
// TODO: Test Me.
|
||||
|
||||
if (pPCX->header.bitPlanes > 1) {
|
||||
return DRPCX_FALSE;
|
||||
}
|
||||
|
||||
drpcx_uint8 rleCount = 0;
|
||||
drpcx_uint8 rleValue = 0;
|
||||
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
for (drpcx_uint32 c = 0; c < pPCX->header.bitPlanes; ++c) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
for (int nibble = 0; (nibble < 2) && ((x*2 + nibble) < pPCX->width); ++nibble)
|
||||
{
|
||||
drpcx_uint8 mask = (4 << (1 - nibble));
|
||||
drpcx_uint8 paletteIndex = (rleValue & mask) >> (1 - nibble);
|
||||
|
||||
pRow[0] |= ((paletteIndex & 0x0F) << (c*4));
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->width; ++x) {
|
||||
drpcx_uint8 paletteIndex = pRow[0];
|
||||
for (drpcx_uint32 c = 0; c < pPCX->components; ++c) {
|
||||
pRow[c] = pPCX->header.palette16[paletteIndex*3 + c];
|
||||
}
|
||||
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
}
|
||||
|
||||
drpcx_bool32 drpcx__decode_8bit(drpcx* pPCX)
|
||||
{
|
||||
drpcx_uint8 rleCount = 0;
|
||||
drpcx_uint8 rleValue = 0;
|
||||
drpcx_uint32 stride = pPCX->width * pPCX->components;
|
||||
|
||||
switch (pPCX->header.bitPlanes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
if (x < pPCX->width) {
|
||||
pRow[0] = rleValue;
|
||||
pRow[1] = rleValue;
|
||||
pRow[2] = rleValue;
|
||||
pRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we can know if we are dealing with a palette or a grayscale image by checking the next byte. If it's equal to 0x0C, we
|
||||
// need to do a simple palette lookup.
|
||||
drpcx_uint8 paletteMarker = drpcx__read_byte(pPCX);
|
||||
if (paletteMarker == 0x0C) {
|
||||
// A palette is present - we need to do a second pass.
|
||||
drpcx_uint8 palette256[768];
|
||||
if (pPCX->onRead(pPCX->pUserData, palette256, sizeof(palette256)) != sizeof(palette256)) {
|
||||
return DRPCX_FALSE;
|
||||
}
|
||||
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
drpcx_uint8* pRow = pPCX->pImageData + (y * stride);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->width; ++x) {
|
||||
drpcx_uint8 index = pRow[0];
|
||||
pRow[0] = palette256[index*3 + 0];
|
||||
pRow[1] = palette256[index*3 + 1];
|
||||
pRow[2] = palette256[index*3 + 2];
|
||||
pRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
}
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
for (drpcx_uint32 y = 0; y < pPCX->height; ++y) {
|
||||
for (drpcx_uint32 c = 0; c < pPCX->components; ++c) {
|
||||
drpcx_uint8* pRow = drpcx__row_ptr(pPCX, y);
|
||||
for (drpcx_uint32 x = 0; x < pPCX->header.bytesPerLine; ++x) {
|
||||
if (rleCount == 0) {
|
||||
rleCount = drpcx__rle(pPCX, &rleValue);
|
||||
}
|
||||
rleCount -= 1;
|
||||
|
||||
if (x < pPCX->width) {
|
||||
pRow[c] = rleValue;
|
||||
pRow += pPCX->components;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return DRPCX_TRUE;
|
||||
}
|
||||
|
||||
drpcx_uint8* drpcx_load(drpcx_read_proc onRead, void* pUserData, drpcx_bool32 flipped, int* x, int* y, int* internalComponents, int desiredComponents)
|
||||
{
|
||||
if (onRead == NULL) return NULL;
|
||||
if (desiredComponents > 4) return NULL;
|
||||
|
||||
drpcx pcx;
|
||||
pcx.onRead = onRead;
|
||||
pcx.pUserData = pUserData;
|
||||
pcx.flipped = flipped;
|
||||
if (onRead(pUserData, &pcx.header, sizeof(pcx.header)) != sizeof(pcx.header)) {
|
||||
return NULL; // Failed to read the header.
|
||||
}
|
||||
|
||||
if (pcx.header.header != 10) {
|
||||
return NULL; // Not a PCX file.
|
||||
}
|
||||
|
||||
if (pcx.header.encoding != 1) {
|
||||
return NULL; // Not supporting non-RLE encoding. Would assume a value of 0 indicates raw, unencoded, but that is apparently never used.
|
||||
}
|
||||
|
||||
if (pcx.header.bpp != 1 && pcx.header.bpp != 2 && pcx.header.bpp != 4 && pcx.header.bpp != 8) {
|
||||
return NULL; // Unsupported pixel format.
|
||||
}
|
||||
|
||||
|
||||
if (pcx.header.left > pcx.header.right) {
|
||||
drpcx_uint16 temp = pcx.header.left;
|
||||
pcx.header.left = pcx.header.right;
|
||||
pcx.header.right = temp;
|
||||
}
|
||||
if (pcx.header.top > pcx.header.bottom) {
|
||||
drpcx_uint16 temp = pcx.header.top;
|
||||
pcx.header.top = pcx.header.bottom;
|
||||
pcx.header.bottom = temp;
|
||||
}
|
||||
|
||||
pcx.width = pcx.header.right - pcx.header.left + 1;
|
||||
pcx.height = pcx.header.bottom - pcx.header.top + 1;
|
||||
pcx.components = (pcx.header.bpp == 8 && pcx.header.bitPlanes == 4) ? 4 : 3;
|
||||
|
||||
size_t dataSize = pcx.width * pcx.height * pcx.components;
|
||||
pcx.pImageData = (drpcx_uint8*)calloc(1, dataSize); // <-- Clearing to zero is important! Required for proper decoding.
|
||||
if (pcx.pImageData == NULL) {
|
||||
return NULL; // Failed to allocate memory.
|
||||
}
|
||||
|
||||
drpcx_bool32 result = DRPCX_FALSE;
|
||||
switch (pcx.header.bpp)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
result = drpcx__decode_1bit(&pcx);
|
||||
} break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
result = drpcx__decode_2bit(&pcx);
|
||||
} break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
result = drpcx__decode_4bit(&pcx);
|
||||
} break;
|
||||
|
||||
case 8:
|
||||
{
|
||||
result = drpcx__decode_8bit(&pcx);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
free(pcx.pImageData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// There's an annoying amount of branching when loading PCX files so for simplicity I'm doing the component conversion as
|
||||
// a second pass.
|
||||
if (desiredComponents == 0) desiredComponents = pcx.components;
|
||||
if (desiredComponents != (int)pcx.components) {
|
||||
drpcx_uint8* pNewImageData = (drpcx_uint8*)malloc(pcx.width * pcx.height * desiredComponents);
|
||||
if (pNewImageData == NULL) {
|
||||
free(pcx.pImageData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drpcx_uint8* pSrcData = pcx.pImageData;
|
||||
drpcx_uint8* pDstData = pNewImageData;
|
||||
if (desiredComponents < (int)pcx.components) {
|
||||
// We're reducing the number of components. Just drop the excess.
|
||||
for (drpcx_uint32 i = 0; i < pcx.width*pcx.height; ++i) {
|
||||
for (int c = 0; c < desiredComponents; ++c) {
|
||||
pDstData[c] = pSrcData[c];
|
||||
}
|
||||
|
||||
pSrcData += pcx.components;
|
||||
pDstData += desiredComponents;
|
||||
}
|
||||
} else {
|
||||
// We're increasing the number of components. Always ensure the alpha channel is set to 0xFF.
|
||||
if (pcx.components == 1) {
|
||||
for (drpcx_uint32 i = 0; i < pcx.width*pcx.height; ++i) {
|
||||
for (int c = 0; c < desiredComponents; ++c) {
|
||||
pDstData[c] = pSrcData[0];
|
||||
}
|
||||
|
||||
pSrcData += pcx.components;
|
||||
pDstData += desiredComponents;
|
||||
}
|
||||
} else if (pcx.components == 2) {
|
||||
for (drpcx_uint32 i = 0; i < pcx.width*pcx.height; ++i) {
|
||||
pDstData[0] = pSrcData[0];
|
||||
pDstData[1] = pSrcData[1];
|
||||
pDstData[2] = 0x00;
|
||||
if (desiredComponents == 4) pDstData[3] = 0xFF;
|
||||
|
||||
pSrcData += pcx.components;
|
||||
pDstData += desiredComponents;
|
||||
}
|
||||
} else {
|
||||
assert(pcx.components == 3);
|
||||
assert(desiredComponents == 4);
|
||||
for (drpcx_uint32 i = 0; i < pcx.width*pcx.height; ++i) {
|
||||
pDstData[0] = pSrcData[0];
|
||||
pDstData[1] = pSrcData[1];
|
||||
pDstData[2] = pSrcData[2];
|
||||
pDstData[3] = 0xFF;
|
||||
|
||||
pSrcData += pcx.components;
|
||||
pDstData += desiredComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pcx.pImageData);
|
||||
pcx.pImageData = pNewImageData;
|
||||
}
|
||||
|
||||
if (x) *x = pcx.width;
|
||||
if (y) *y = pcx.height;
|
||||
if (internalComponents) *internalComponents = pcx.components;
|
||||
return pcx.pImageData;
|
||||
}
|
||||
|
||||
void drpcx_free(void* pReturnValueFromLoad)
|
||||
{
|
||||
free(pReturnValueFromLoad);
|
||||
}
|
||||
|
||||
#endif // DR_PCX_IMPLEMENTATION
|
||||
|
||||
|
||||
// REVISION HISTORY
|
||||
//
|
||||
// v0.3.1 - 2018-09-11
|
||||
// - Styling fixes.
|
||||
// - Fix a typo.
|
||||
//
|
||||
// v0.3 - 2018-02-08
|
||||
// - API CHANGE: Rename dr_* types to drpcx_*.
|
||||
//
|
||||
// v0.2c - 2018-02-07
|
||||
// - Fix a crash.
|
||||
//
|
||||
// v0.2b - 2018-02-02
|
||||
// - Fix compilation error.
|
||||
//
|
||||
// v0.2a - 2017-07-16
|
||||
// - Change underlying type for booleans to unsigned.
|
||||
//
|
||||
// v0.2 - 2016-10-28
|
||||
// - API CHANGE: Add a parameter to drpcx_load() and family to control the number of output components.
|
||||
// - Use custom sized types rather than built-in ones to improve support for older MSVC compilers.
|
||||
//
|
||||
// v0.1c - 2016-10-23
|
||||
// - A minor change to drpcx_bool8 and drpcx_bool32 types.
|
||||
//
|
||||
// v0.1b - 2016-10-11
|
||||
// - Use drpcx_bool32 instead of the built-in "bool" type. The reason for this change is that it helps maintain API/ABI consistency
|
||||
// between C and C++ builds.
|
||||
//
|
||||
// v0.1a - 2016-09-18
|
||||
// - Change date format to ISO 8601 (YYYY-MM-DD)
|
||||
//
|
||||
// v0.1 - 2016-05-04
|
||||
// - Initial versioned release.
|
||||
|
||||
|
||||
// TODO
|
||||
// - Test 2-bpp/4-plane and 4-bpp/1-plane formats.
|
||||
|
||||
|
||||
/*
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
19
include/fs.h
Normal file
19
include/fs.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _VITASTUDIO_FS_H_
|
||||
#define _VITASTUDIO_FS_H_
|
||||
|
||||
#include <psp2/io/dirent.h>
|
||||
#include <psp2/types.h>
|
||||
#include <string>
|
||||
|
||||
namespace FS {
|
||||
extern std::string CWD;
|
||||
int GetFileSize(const std::string &path, SceOff *size);
|
||||
std::string GetFileExt(const std::string &filename);
|
||||
SceOff GetDirList(const std::string &path, SceIoDirent **entriesp);
|
||||
SceOff ChangeDirNext(const std::string &path, SceIoDirent **entries);
|
||||
SceOff ChangeDirPrev(SceIoDirent **entries);
|
||||
const std::string BuildPath(SceIoDirent *entry);
|
||||
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size);
|
||||
}
|
||||
|
||||
#endif
|
8
include/gui.h
Normal file
8
include/gui.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _VITASTUDIO_GUI_H_
|
||||
#define _VITASTUDIO_GUI_H_
|
||||
|
||||
namespace GUI {
|
||||
void MainMenu(void);
|
||||
}
|
||||
|
||||
#endif
|
10
include/log.h
Normal file
10
include/log.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _VITASTUDIO_LOG_H_
|
||||
#define _VITASTUDIO_LOG_H_
|
||||
|
||||
namespace Log {
|
||||
int OpenHande(void);
|
||||
int CloseHandle(void);
|
||||
int Debug(const char *format, ...);
|
||||
}
|
||||
|
||||
#endif
|
7656
include/stb_image.h
Normal file
7656
include/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
2631
include/stb_image_resize.h
Normal file
2631
include/stb_image_resize.h
Normal file
File diff suppressed because it is too large
Load Diff
28
include/textures.h
Normal file
28
include/textures.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _VITASTUDIO_TEXTURES_H_
|
||||
#define _VITASTUDIO_TEXTURES_H_
|
||||
|
||||
#include <vitaGL.h>
|
||||
#include <string>
|
||||
|
||||
typedef struct {
|
||||
GLuint id = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
} Tex;
|
||||
|
||||
extern Tex folder_texture, file_texture, image_texture;
|
||||
|
||||
namespace Textures {
|
||||
bool LoadImageFile(const std::string &path, Tex *texture);
|
||||
bool LoadImageBMP(const std::string &path, Tex *texture);
|
||||
bool LoadImageGIF(const std::string &path, Tex *texture, unsigned int *frames);
|
||||
bool LoadImageICO(const std::string &path, Tex *texture);
|
||||
bool LoadImagePCX(const std::string &path, Tex *texture);
|
||||
bool LoadImageTIFF(const std::string &path, Tex *texture);
|
||||
bool LoadImageWEBP(const std::string &path, Tex *texture);
|
||||
void Free(Tex *texture);
|
||||
void Init(void);
|
||||
void Exit(void);
|
||||
}
|
||||
|
||||
#endif
|
24
include/utils.h
Normal file
24
include/utils.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _VITASTUDIO_UTILS_H_
|
||||
#define _VITASTUDIO_UTILS_H_
|
||||
|
||||
#include <psp2/ctrl.h>
|
||||
|
||||
/// Checks whether a result code indicates success.
|
||||
#define R_SUCCEEDED(res) ((res)>=0)
|
||||
/// Checks whether a result code indicates failure.
|
||||
#define R_FAILED(res) ((res)<0)
|
||||
/// Returns the level of a result code.
|
||||
|
||||
extern int SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
|
||||
extern unsigned int pressed;
|
||||
|
||||
namespace Utils {
|
||||
int InitAppUtil(void);
|
||||
int EndAppUtil(void);
|
||||
void ReadControls(void);
|
||||
int GetEnterButton(void);
|
||||
int GetCancelButton(void);
|
||||
void GetSizeString(char *string, double size);
|
||||
}
|
||||
|
||||
#endif
|
21
libs/imgui/LICENSE.txt
Normal file
21
libs/imgui/LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2020 Omar Cornut
|
||||
|
||||
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.
|
108
libs/imgui/imconfig.h
Normal file
108
libs/imgui/imconfig.h
Normal file
@ -0,0 +1,108 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h)
|
||||
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
|
||||
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include
|
||||
// the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support full unicode code points.
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library.
|
||||
// Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
10625
libs/imgui/imgui.cpp
Normal file
10625
libs/imgui/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2392
libs/imgui/imgui.h
Normal file
2392
libs/imgui/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
3647
libs/imgui/imgui_draw.cpp
Normal file
3647
libs/imgui/imgui_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
490
libs/imgui/imgui_impl_vitagl.cpp
Normal file
490
libs/imgui/imgui_impl_vitagl.cpp
Normal file
@ -0,0 +1,490 @@
|
||||
// Implemented features:
|
||||
// [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vitaGL.h>
|
||||
#include <math.h>
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_vitagl.h"
|
||||
#include "imgui_vita_touch.h"
|
||||
|
||||
#define lerp(value, from_max, to_max) ((((value*10) * (to_max*10))/(from_max*10))/10)
|
||||
|
||||
// Data
|
||||
static uint64_t g_Time = 0;
|
||||
static bool g_MousePressed[3] = { false, false, false };
|
||||
static GLuint g_FontTexture = 0;
|
||||
static SceCtrlData g_OldPad;
|
||||
static int hires_x = 0;
|
||||
static int hires_y = 0;
|
||||
|
||||
static float *startVertex = nullptr;
|
||||
static float *startTexCoord = nullptr;
|
||||
static uint8_t *startColor = nullptr;
|
||||
static float *gVertexBuffer = nullptr;
|
||||
static float *gTexCoordBuffer = nullptr;
|
||||
static uint8_t *gColorBuffer = nullptr;
|
||||
static uint16_t *gIndexBuffer = nullptr;
|
||||
static uint32_t gCounter = 0;
|
||||
|
||||
static bool touch_usage = false;
|
||||
static bool mousestick_usage = true;
|
||||
static bool gamepad_usage = false;
|
||||
static bool shaders_usage = false;
|
||||
|
||||
#ifdef ENABLE_IMGUI_LOG
|
||||
void LOG(const char *format, ...) {
|
||||
__gnuc_va_list arg;
|
||||
int done;
|
||||
va_start(arg, format);
|
||||
char msg[512];
|
||||
done = vsprintf(msg, format, arg);
|
||||
va_end(arg);
|
||||
int i;
|
||||
sprintf(msg, "%s\n", msg);
|
||||
FILE* log = fopen("ux0:/data/imgui.log", "a+");
|
||||
if (log != NULL) {
|
||||
fwrite(msg, 1, strlen(msg), log);
|
||||
fclose(log);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// OpenGL2 Render function.
|
||||
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
|
||||
void ImGui_ImplVitaGL_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
||||
|
||||
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
//glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
||||
glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
||||
|
||||
float *vp = gVertexBuffer;
|
||||
float *tp = gTexCoordBuffer;
|
||||
uint8_t *cp = gColorBuffer;
|
||||
uint8_t *indices = (uint8_t*)idx_buffer;
|
||||
if (sizeof(ImDrawIdx) == 2){
|
||||
for (int idx=0; idx < pcmd->ElemCount; idx++){
|
||||
uint16_t index = *((uint16_t*)(indices + sizeof(ImDrawIdx) * idx));
|
||||
float *vertices = (float*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos) + sizeof(ImDrawVert) * index);
|
||||
float *texcoords = (float*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv) + sizeof(ImDrawVert) * index);
|
||||
uint8_t *colors = (uint8_t*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col) + sizeof(ImDrawVert) * index);
|
||||
gVertexBuffer[0] = vertices[0];
|
||||
gVertexBuffer[1] = vertices[1];
|
||||
gVertexBuffer[2] = 0.0f;
|
||||
gTexCoordBuffer[0] = texcoords[0];
|
||||
gTexCoordBuffer[1] = texcoords[1];
|
||||
gColorBuffer[0] = colors[0];
|
||||
gColorBuffer[1] = colors[1];
|
||||
gColorBuffer[2] = colors[2];
|
||||
gColorBuffer[3] = colors[3];
|
||||
gVertexBuffer += 3;
|
||||
gTexCoordBuffer += 2;
|
||||
gColorBuffer += 4;
|
||||
}
|
||||
}else{
|
||||
for (int idx=0; idx < pcmd->ElemCount; idx++){
|
||||
uint16_t index = *((uint16_t*)(indices + sizeof(ImDrawIdx) * idx));
|
||||
float *vertices = (float*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos) + sizeof(ImDrawVert) * index);
|
||||
float *texcoords = (float*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv) + sizeof(ImDrawVert) * index);
|
||||
uint8_t *colors = (uint8_t*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col) + sizeof(ImDrawVert) * index);
|
||||
gVertexBuffer[0] = vertices[0];
|
||||
gVertexBuffer[1] = vertices[1];
|
||||
gVertexBuffer[2] = 0.0f;
|
||||
gTexCoordBuffer[0] = texcoords[0];
|
||||
gTexCoordBuffer[1] = texcoords[1];
|
||||
gColorBuffer[0] = colors[0];
|
||||
gColorBuffer[1] = colors[1];
|
||||
gColorBuffer[2] = colors[2];
|
||||
gColorBuffer[3] = colors[3];
|
||||
gVertexBuffer += 3;
|
||||
gTexCoordBuffer += 2;
|
||||
gColorBuffer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (shaders_usage){
|
||||
vglVertexAttribPointerMapped(0, vp);
|
||||
vglVertexAttribPointerMapped(1, tp);
|
||||
vglVertexAttribPointerMapped(2, cp);
|
||||
}else{
|
||||
vglVertexPointerMapped(vp);
|
||||
vglTexCoordPointerMapped(tp);
|
||||
vglColorPointerMapped(GL_UNSIGNED_BYTE, cp);
|
||||
}
|
||||
vglDrawObjects(GL_TRIANGLES, pcmd->ElemCount, GL_TRUE);
|
||||
}
|
||||
idx_buffer += pcmd->ElemCount;
|
||||
gCounter += pcmd->ElemCount;
|
||||
if (gCounter > 0x99900){
|
||||
gVertexBuffer = startVertex;
|
||||
gColorBuffer = startColor;
|
||||
gTexCoordBuffer = startTexCoord;
|
||||
gCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified state
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
//glPopAttrib();
|
||||
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
}
|
||||
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
bool ImGui_ImplVitaGL_ProcessEvent(SceCtrlData *pad)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
/*switch (event->type)
|
||||
{
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if (event->wheel.x > 0) io.MouseWheelH += 1;
|
||||
if (event->wheel.x < 0) io.MouseWheelH -= 1;
|
||||
if (event->wheel.y > 0) io.MouseWheel += 1;
|
||||
if (event->wheel.y < 0) io.MouseWheel -= 1;
|
||||
return true;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true;
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true;
|
||||
if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true;
|
||||
return true;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
io.AddInputCharactersUTF8(event->text.text);
|
||||
return true;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
int key = event->key.keysym.scancode;
|
||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
||||
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
|
||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
||||
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
|
||||
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui_ImplVitaGL_CreateDeviceObjects()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
GLint last_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGenTextures(1, &g_FontTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
|
||||
|
||||
// Restore state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_InvalidateDeviceObjects()
|
||||
{
|
||||
if (g_FontTexture)
|
||||
{
|
||||
glDeleteTextures(1, &g_FontTexture);
|
||||
ImGui::GetIO().Fonts->TexID = 0;
|
||||
g_FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplVitaGL_Init()
|
||||
{
|
||||
|
||||
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
|
||||
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
|
||||
|
||||
// Setup back-end capabilities flags
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseDrawCursor = true;
|
||||
|
||||
// Initializing buffers
|
||||
startVertex = (float*)malloc(sizeof(float) * 0x100000 * 3);
|
||||
startTexCoord = (float*)malloc(sizeof(float) * 0x100000 * 2);
|
||||
startColor = (uint8_t*)malloc(sizeof(uint8_t) * 0x100000 * 4);
|
||||
gIndexBuffer = (uint16_t*)malloc(sizeof(uint16_t) * 0x5000);
|
||||
|
||||
gVertexBuffer = startVertex;
|
||||
gColorBuffer = startColor;
|
||||
gTexCoordBuffer = startTexCoord;
|
||||
|
||||
for (uint16_t i = 0; i < 0x5000; i++) {
|
||||
gIndexBuffer[i] = i;
|
||||
}
|
||||
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||
/*io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
||||
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
|
||||
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;*/
|
||||
|
||||
io.ClipboardUserData = NULL;
|
||||
|
||||
ImGui_ImplVitaGL_InitTouch();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_Shutdown()
|
||||
{
|
||||
// Destroy buffers
|
||||
free(gVertexBuffer);
|
||||
free(gTexCoordBuffer);
|
||||
free(gColorBuffer);
|
||||
free(gIndexBuffer);
|
||||
|
||||
// Destroy OpenGL objects
|
||||
ImGui_ImplVitaGL_InvalidateDeviceObjects();
|
||||
}
|
||||
|
||||
int mx, my;
|
||||
|
||||
void IN_RescaleAnalog(int *x, int *y, int dead) {
|
||||
|
||||
float analogX = (float) *x;
|
||||
float analogY = (float) *y;
|
||||
float deadZone = (float) dead;
|
||||
float maximum = 32768.0f;
|
||||
float magnitude = sqrt(analogX * analogX + analogY * analogY);
|
||||
if (magnitude >= deadZone)
|
||||
{
|
||||
float scalingFactor = maximum / magnitude * (magnitude - deadZone) / (maximum - deadZone);
|
||||
*x = (int) (analogX * scalingFactor);
|
||||
*y = (int) (analogY * scalingFactor);
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_PollLeftStick(SceCtrlData *pad, int *x, int *y)
|
||||
{
|
||||
sceCtrlPeekBufferPositive(0, pad, 1);
|
||||
int lx = (pad->lx - 127) * 256;
|
||||
int ly = (pad->ly - 127) * 256;
|
||||
IN_RescaleAnalog(&lx, &ly, 7680);
|
||||
hires_x += lx;
|
||||
hires_y += ly;
|
||||
if (hires_x != 0 || hires_y != 0) {
|
||||
// slow down pointer, could be made user-adjustable
|
||||
int slowdown = 2048;
|
||||
*x += hires_x / slowdown;
|
||||
*y += hires_y / slowdown;
|
||||
hires_x %= slowdown;
|
||||
hires_y %= slowdown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ImGui_ImplVitaGL_NewFrame()
|
||||
{
|
||||
|
||||
if (!g_FontTexture)
|
||||
ImGui_ImplVitaGL_CreateDeviceObjects();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
w = display_w = viewport[2];
|
||||
h = display_h = viewport[3];
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
|
||||
|
||||
static uint64_t frequency = 1000000;
|
||||
uint64_t current_time = sceKernelGetProcessTimeWide();
|
||||
io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
// Touch for mouse emulation
|
||||
if (touch_usage){
|
||||
double scale_x = 960.0 / io.DisplaySize.x;
|
||||
double scale_y = 544.0 / io.DisplaySize.y;
|
||||
double offset_x = 0;
|
||||
double offset_y = 0;
|
||||
ImGui_ImplVitaGL_PollTouch(offset_x, offset_y, scale_x, scale_y, &mx, &my, g_MousePressed);
|
||||
}
|
||||
|
||||
// Keypad navigation
|
||||
if (gamepad_usage){
|
||||
SceCtrlData pad;
|
||||
int lstick_x, lstick_y = 0;
|
||||
ImGui_ImplVitaGL_PollLeftStick(&pad, &lstick_x, &lstick_y);
|
||||
io.NavInputs[ImGuiNavInput_Activate] = (pad.buttons & SCE_CTRL_CROSS) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_Cancel] = (pad.buttons & SCE_CTRL_CIRCLE) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_Input] = (pad.buttons & SCE_CTRL_TRIANGLE) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_Menu] = (pad.buttons & SCE_CTRL_SQUARE) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_DpadLeft] = (pad.buttons & SCE_CTRL_LEFT) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_DpadRight] = (pad.buttons & SCE_CTRL_RIGHT) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_DpadUp] = (pad.buttons & SCE_CTRL_UP) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_DpadDown] = (pad.buttons & SCE_CTRL_DOWN) ? 1.0f : 0.0f;
|
||||
|
||||
if (io.NavInputs[ImGuiNavInput_Menu] == 1.0f) {
|
||||
io.NavInputs[ImGuiNavInput_FocusPrev] = (pad.buttons & SCE_CTRL_LTRIGGER) ? 1.0f : 0.0f;
|
||||
io.NavInputs[ImGuiNavInput_FocusNext] = (pad.buttons & SCE_CTRL_RTRIGGER) ? 1.0f : 0.0f;
|
||||
if (lstick_x < 0) io.NavInputs[ImGuiNavInput_LStickLeft] = (float)(-lstick_x/16);
|
||||
if (lstick_x > 0) io.NavInputs[ImGuiNavInput_LStickRight] = (float)(lstick_x/16);
|
||||
if (lstick_y < 0) io.NavInputs[ImGuiNavInput_LStickUp] = (float)(-lstick_y/16);
|
||||
if (lstick_y > 0) io.NavInputs[ImGuiNavInput_LStickDown] = (float)(lstick_y/16);
|
||||
}
|
||||
}
|
||||
|
||||
// Keys for mouse emulation
|
||||
/*if (mousestick_usage && !(io.NavInputs[ImGuiNavInput_Menu] == 1.0f)){
|
||||
SceCtrlData pad;
|
||||
ImGui_ImplVitaGL_PollLeftStick(&pad, &mx, &my);
|
||||
if ((pad.buttons & SCE_CTRL_LTRIGGER) != (g_OldPad.buttons & SCE_CTRL_LTRIGGER))
|
||||
g_MousePressed[0] = pad.buttons & SCE_CTRL_LTRIGGER;
|
||||
if ((pad.buttons & SCE_CTRL_RTRIGGER) != (g_OldPad.buttons & SCE_CTRL_RTRIGGER))
|
||||
g_MousePressed[1] = pad.buttons & SCE_CTRL_RTRIGGER;
|
||||
g_OldPad = pad;
|
||||
}
|
||||
|
||||
// Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler)
|
||||
//Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my);
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
io.MouseDown[0] = g_MousePressed[0];
|
||||
io.MouseDown[1] = g_MousePressed[1];
|
||||
io.MouseDown[2] = g_MousePressed[2];
|
||||
|
||||
if (mx < 0) mx = 0;
|
||||
else if (mx > 960) mx = 960;
|
||||
if (my < 0) my = 0;
|
||||
else if (my > 544) my = 544;
|
||||
io.MousePos = ImVec2((float)mx, (float)my);*/
|
||||
|
||||
// Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application.
|
||||
ImGui::NewFrame();
|
||||
|
||||
vglIndexPointerMapped(gIndexBuffer);
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_TouchUsage(bool val){
|
||||
touch_usage = val;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_UseIndirectFrontTouch(bool val){
|
||||
ImGui_ImplVitaGL_PrivateSetIndirectFrontTouch(val);
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_UseRearTouch(bool val){
|
||||
ImGui_ImplVitaGL_PrivateSetRearTouch(val);
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_MouseStickUsage(bool val){
|
||||
mousestick_usage = val;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_GamepadUsage(bool val){
|
||||
gamepad_usage = val;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_UseCustomShader(bool val){
|
||||
shaders_usage = val;
|
||||
}
|
24
libs/imgui/imgui_impl_vitagl.h
Normal file
24
libs/imgui/imgui_impl_vitagl.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Implemented features:
|
||||
// [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
|
||||
|
||||
#include <vitasdk.h>
|
||||
|
||||
IMGUI_API bool ImGui_ImplVitaGL_Init();
|
||||
IMGUI_API void ImGui_ImplVitaGL_Shutdown();
|
||||
IMGUI_API void ImGui_ImplVitaGL_NewFrame();
|
||||
IMGUI_API void ImGui_ImplVitaGL_RenderDrawData(ImDrawData* draw_data);
|
||||
IMGUI_API bool ImGui_ImplVitaGL_ProcessEvent(SceCtrlData* pad);
|
||||
|
||||
// Use if you want to reset your rendering device without losing ImGui state.
|
||||
IMGUI_API void ImGui_ImplVitaGL_InvalidateDeviceObjects();
|
||||
IMGUI_API bool ImGui_ImplVitaGL_CreateDeviceObjects();
|
||||
|
||||
void ImGui_ImplVitaGL_TouchUsage(bool val);
|
||||
// indirect front touch enabled: drag pointer with finger
|
||||
// indirect front touch disabled: pointer jumps to finger
|
||||
void ImGui_ImplVitaGL_UseIndirectFrontTouch(bool val);
|
||||
void ImGui_ImplVitaGL_UseRearTouch(bool val); // turn rear panel touch on or off
|
||||
void ImGui_ImplVitaGL_MouseStickUsage(bool val); // Left mouse stick and trigger buttons control mouse pointer
|
||||
// GamepadUsage uses the Vita buttons to navigate and interact with UI elements
|
||||
void ImGui_ImplVitaGL_GamepadUsage(bool val);
|
||||
void ImGui_ImplVitaGL_UseCustomShader(bool val);
|
2063
libs/imgui/imgui_internal.h
Normal file
2063
libs/imgui/imgui_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
6
libs/imgui/imgui_vita.h
Normal file
6
libs/imgui/imgui_vita.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _IMGUI_VITA_
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_vitagl.h"
|
||||
|
||||
#endif
|
479
libs/imgui/imgui_vita_touch.cpp
Normal file
479
libs/imgui/imgui_vita_touch.cpp
Normal file
@ -0,0 +1,479 @@
|
||||
//
|
||||
// Created by rsn8887 on 02/05/18.
|
||||
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
#include <psp2/touch.h>
|
||||
#include <psp2/display.h>
|
||||
#include "imgui_vita_touch.h"
|
||||
#include <string.h>
|
||||
//#include "math.h"
|
||||
|
||||
#define SDL_BUTTON_LEFT 0
|
||||
#define SDL_BUTTON_RIGHT 1
|
||||
typedef int Uint8;
|
||||
|
||||
|
||||
static int *touchmouse_x;
|
||||
static int *touchmouse_y;
|
||||
static bool *touchmouse_button;
|
||||
|
||||
static SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM];
|
||||
static SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM];
|
||||
|
||||
static SceTouchPanelInfo panelinfo[SCE_TOUCH_PORT_MAX_NUM];
|
||||
|
||||
static float aAWidth[SCE_TOUCH_PORT_MAX_NUM];
|
||||
static float aAHeight[SCE_TOUCH_PORT_MAX_NUM];
|
||||
static float dispWidth[SCE_TOUCH_PORT_MAX_NUM];
|
||||
static float dispHeight[SCE_TOUCH_PORT_MAX_NUM];
|
||||
static float forcerange[SCE_TOUCH_PORT_MAX_NUM];
|
||||
|
||||
static bool rear_touch = false; // rear panel on or off
|
||||
static bool indirect_front_touch = false; // front panel indirect mode (drag pointer) or direct mode (pointer jumps to finger)
|
||||
|
||||
static float pointer_speed_factor = 1.0; // pointer speed factor for indirect touch
|
||||
static double offset_x = 0.0;
|
||||
static double offset_y = 0.0;
|
||||
static double scale_x = 1.0;
|
||||
static double scale_y = 1.0;
|
||||
static int hires_dx;
|
||||
static int hires_dy;
|
||||
|
||||
typedef enum TouchEventType {
|
||||
FINGERDOWN,
|
||||
FINGERUP,
|
||||
FINGERMOTION,
|
||||
} TouchEventType;
|
||||
|
||||
typedef struct {
|
||||
TouchEventType type;
|
||||
SceUInt64 timestamp;
|
||||
int touchId;
|
||||
int fingerId;
|
||||
float x;
|
||||
float y;
|
||||
float dx;
|
||||
float dy;
|
||||
} FingerType;
|
||||
|
||||
typedef struct {
|
||||
TouchEventType type;
|
||||
FingerType tfinger;
|
||||
} TouchEvent;
|
||||
|
||||
enum {
|
||||
MAX_NUM_FINGERS = 3, // number of fingers to track per panel
|
||||
MAX_TAP_TIME = 250, // taps longer than this will not result in mouse click events
|
||||
MAX_TAP_MOTION_DISTANCE = 10, // max distance finger motion in Vita screen pixels to be considered a tap
|
||||
SIMULATED_CLICK_DURATION = 50, // time in ms how long simulated mouse clicks should be
|
||||
}; // track three fingers per panel
|
||||
|
||||
typedef struct {
|
||||
int id; // -1: no touch
|
||||
int timeLastDown;
|
||||
float lastDownX;
|
||||
float lastDownY;
|
||||
} Touch;
|
||||
|
||||
static Touch _finger[SCE_TOUCH_PORT_MAX_NUM][MAX_NUM_FINGERS]; // keep track of finger status
|
||||
|
||||
typedef enum DraggingType {
|
||||
DRAG_NONE = 0,
|
||||
DRAG_TWO_FINGER,
|
||||
DRAG_THREE_FINGER,
|
||||
} DraggingType;
|
||||
|
||||
static DraggingType _multiFingerDragging[SCE_TOUCH_PORT_MAX_NUM]; // keep track whether we are currently drag-and-dropping
|
||||
|
||||
static int _simulatedClickStartTime[SCE_TOUCH_PORT_MAX_NUM][2]; // initiation time of last simulated left or right click (zero if no click)
|
||||
|
||||
static void psp2ProcessTouchEvent(TouchEvent *event);
|
||||
static void psp2ProcessFingerDown(TouchEvent *event);
|
||||
static void psp2ProcessFingerUp(TouchEvent *event);
|
||||
static void psp2ProcessFingerMotion(TouchEvent *event);
|
||||
static void psp2ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port);
|
||||
static void psp2ConvertTouchXYToGameXY(float touchX, float touchY, int *gameX, int *gameY);
|
||||
static void psp2FinishSimulatedMouseClicks(int port, SceUInt64 currentTime);
|
||||
|
||||
void ImGui_ImplVitaGL_InitTouch() {
|
||||
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
|
||||
sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START);
|
||||
sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT);
|
||||
sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK);
|
||||
|
||||
SceTouchPanelInfo panelinfo[SCE_TOUCH_PORT_MAX_NUM];
|
||||
for(int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
|
||||
sceTouchGetPanelInfo(port, &panelinfo[port]);
|
||||
aAWidth[port] = (float)(panelinfo[port].maxAaX - panelinfo[port].minAaX);
|
||||
aAHeight[port] = (float)(panelinfo[port].maxAaY - panelinfo[port].minAaY);
|
||||
dispWidth[port] = (float)(panelinfo[port].maxDispX - panelinfo[port].minDispX);
|
||||
dispHeight[port] = (float)(panelinfo[port].maxDispY - panelinfo[port].minDispY);
|
||||
forcerange[port] = (float)(panelinfo[port].maxForce - panelinfo[port].minForce);
|
||||
}
|
||||
|
||||
for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
_finger[port][i].id = -1;
|
||||
}
|
||||
_multiFingerDragging[port] = DRAG_NONE;
|
||||
}
|
||||
|
||||
for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
_simulatedClickStartTime[port][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_PollTouch(double x0, double y0, double sx, double sy, int *mx, int *my, bool *mbuttons) {
|
||||
offset_x = x0;
|
||||
offset_y = y0;
|
||||
scale_x = sx;
|
||||
scale_y = sy;
|
||||
|
||||
touchmouse_x = mx;
|
||||
touchmouse_y = my;
|
||||
touchmouse_button = mbuttons;
|
||||
|
||||
int finger_id = 0;
|
||||
memcpy(touch_old, touch, sizeof(touch_old));
|
||||
|
||||
for(int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
|
||||
if ((port == SCE_TOUCH_PORT_FRONT) || (rear_touch && port == SCE_TOUCH_PORT_BACK)) {
|
||||
sceTouchPeek(port, &touch[port], 1);
|
||||
psp2FinishSimulatedMouseClicks(port, touch[port].timeStamp / 1000);
|
||||
if (touch[port].reportNum > 0) {
|
||||
for (int i = 0; i < touch[port].reportNum; i++) {
|
||||
// adjust coordinates and forces to return normalized values
|
||||
// for the front, screen area is used as a reference (for direct touch)
|
||||
// e.g. touch_x = 1.0 corresponds to screen_x = 960
|
||||
// for the back panel, the active touch area is used as reference
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
psp2ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port);
|
||||
finger_id = touch[port].report[i].id;
|
||||
|
||||
// Send an initial touch if finger hasn't been down
|
||||
bool hasBeenDown = false;
|
||||
int j = 0;
|
||||
if (touch_old[port].reportNum > 0) {
|
||||
for (j = 0; j < touch_old[port].reportNum; j++) {
|
||||
if (touch_old[port].report[j].id == touch[port].report[i].id ) {
|
||||
hasBeenDown = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasBeenDown) {
|
||||
TouchEvent ev;
|
||||
ev.type = FINGERDOWN;
|
||||
ev.tfinger.timestamp = touch[port].timeStamp / 1000;
|
||||
ev.tfinger.touchId = port;
|
||||
ev.tfinger.fingerId = finger_id;
|
||||
ev.tfinger.x = x;
|
||||
ev.tfinger.y = y;
|
||||
psp2ProcessTouchEvent(&ev);
|
||||
} else {
|
||||
// If finger moved, send motion event instead
|
||||
if (touch_old[port].report[j].x != touch[port].report[i].x ||
|
||||
touch_old[port].report[j].y != touch[port].report[i].y) {
|
||||
float oldx = 0;
|
||||
float oldy = 0;
|
||||
psp2ConvertTouchXYToSDLXY(&oldx, &oldy, touch_old[port].report[j].x, touch_old[port].report[j].y, port);
|
||||
TouchEvent ev;
|
||||
ev.type = FINGERMOTION;
|
||||
ev.tfinger.timestamp = touch[port].timeStamp / 1000;
|
||||
ev.tfinger.touchId = port;
|
||||
ev.tfinger.fingerId = finger_id;
|
||||
ev.tfinger.x = x;
|
||||
ev.tfinger.y = y;
|
||||
ev.tfinger.dx = x - oldx;
|
||||
ev.tfinger.dy = y - oldy;
|
||||
psp2ProcessTouchEvent(&ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// some fingers might have been let go
|
||||
if (touch_old[port].reportNum > 0) {
|
||||
for (int i = 0; i < touch_old[port].reportNum; i++) {
|
||||
int finger_up = 1;
|
||||
if (touch[port].reportNum > 0) {
|
||||
for (int j = 0; j < touch[port].reportNum; j++) {
|
||||
if (touch[port].report[j].id == touch_old[port].report[i].id ) {
|
||||
finger_up = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (finger_up == 1) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
psp2ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port);
|
||||
finger_id = touch_old[port].report[i].id;
|
||||
// Finger released from screen
|
||||
TouchEvent ev;
|
||||
ev.type = FINGERUP;
|
||||
ev.tfinger.timestamp = touch[port].timeStamp / 1000;
|
||||
ev.tfinger.touchId = port;
|
||||
ev.tfinger.fingerId = finger_id;
|
||||
ev.tfinger.x = x;
|
||||
ev.tfinger.y = y;
|
||||
psp2ProcessTouchEvent(&ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psp2ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
if (port == SCE_TOUCH_PORT_FRONT) {
|
||||
x = (vita_x - panelinfo[port].minDispX) / dispWidth[port];
|
||||
y = (vita_y - panelinfo[port].minDispY) / dispHeight[port];
|
||||
} else {
|
||||
x = (vita_x - panelinfo[port].minAaX) / aAWidth[port];
|
||||
y = (vita_y - panelinfo[port].minAaY) / aAHeight[port];
|
||||
}
|
||||
if (x < 0.0) {
|
||||
x = 0.0;
|
||||
} else if (x > 1.0) {
|
||||
x = 1.0;
|
||||
}
|
||||
if (y < 0.0) {
|
||||
y = 0.0;
|
||||
} else if (y > 1.0) {
|
||||
y = 1.0;
|
||||
}
|
||||
*sdl_x = x;
|
||||
*sdl_y = y;
|
||||
}
|
||||
|
||||
static void psp2ProcessTouchEvent(TouchEvent *event) {
|
||||
// Supported touch gestures:
|
||||
// left mouse click: single finger short tap
|
||||
// right mouse click: second finger short tap while first finger is still down
|
||||
// pointer motion: single finger drag
|
||||
// drag and drop: dual finger drag
|
||||
if (event->type == FINGERDOWN || event->type == FINGERUP || event->type == FINGERMOTION) {
|
||||
// front (0) or back (1) panel
|
||||
int port = event->tfinger.touchId;
|
||||
if (port >= 0 && port < SCE_TOUCH_PORT_MAX_NUM) {
|
||||
switch (event->type) {
|
||||
case FINGERDOWN:
|
||||
psp2ProcessFingerDown(event);
|
||||
break;
|
||||
case FINGERUP:
|
||||
psp2ProcessFingerUp(event);
|
||||
break;
|
||||
case FINGERMOTION:
|
||||
psp2ProcessFingerMotion(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psp2ProcessFingerDown(TouchEvent *event) {
|
||||
// front (0) or back (1) panel
|
||||
int port = event->tfinger.touchId;
|
||||
// id (for multitouch)
|
||||
int id = event->tfinger.fingerId;
|
||||
|
||||
// make sure each finger is not reported down multiple times
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id == id) {
|
||||
_finger[port][i].id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// we need the timestamps to decide later if the user performed a short tap (click)
|
||||
// or a long tap (drag)
|
||||
// we also need the last coordinates for each finger to keep track of dragging
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id == -1) {
|
||||
_finger[port][i].id = id;
|
||||
_finger[port][i].timeLastDown = event->tfinger.timestamp;
|
||||
_finger[port][i].lastDownX = event->tfinger.x;
|
||||
_finger[port][i].lastDownY = event->tfinger.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psp2ProcessFingerUp(TouchEvent *event) {
|
||||
// front (0) or back (1) panel
|
||||
int port = event->tfinger.touchId;
|
||||
// id (for multitouch)
|
||||
int id = event->tfinger.fingerId;
|
||||
|
||||
// find out how many fingers were down before this event
|
||||
int numFingersDown = 0;
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id >= 0) {
|
||||
numFingersDown++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id == id) {
|
||||
_finger[port][i].id = -1;
|
||||
if (!_multiFingerDragging[port]) {
|
||||
if ((event->tfinger.timestamp - _finger[port][i].timeLastDown) <= MAX_TAP_TIME) {
|
||||
// short (<MAX_TAP_TIME ms) tap is interpreted as right/left mouse click depending on # fingers already down
|
||||
// but only if the finger hasn't moved since it was pressed down by more than MAX_TAP_MOTION_DISTANCE pixels
|
||||
float xrel = ((event->tfinger.x * 960.0) - (_finger[port][i].lastDownX * 960.0));
|
||||
float yrel = ((event->tfinger.y * 544.0) - (_finger[port][i].lastDownY * 544.0));
|
||||
float maxRSquared = (float) (MAX_TAP_MOTION_DISTANCE * MAX_TAP_MOTION_DISTANCE);
|
||||
if ((xrel * xrel + yrel * yrel) < maxRSquared) {
|
||||
if (numFingersDown == 2 || numFingersDown == 1) {
|
||||
Uint8 simulatedButton = 0;
|
||||
if (numFingersDown == 2) {
|
||||
simulatedButton = SDL_BUTTON_RIGHT;
|
||||
// need to raise the button later
|
||||
_simulatedClickStartTime[port][1] = event->tfinger.timestamp;
|
||||
} else if (numFingersDown == 1) {
|
||||
if (port == 0 && !indirect_front_touch) {
|
||||
int x, y;
|
||||
psp2ConvertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
|
||||
*touchmouse_x = x;
|
||||
*touchmouse_y = y;
|
||||
}
|
||||
simulatedButton = SDL_BUTTON_LEFT;
|
||||
// need to raise the button later
|
||||
_simulatedClickStartTime[port][0] = event->tfinger.timestamp;
|
||||
}
|
||||
touchmouse_button[simulatedButton] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (numFingersDown == 1) {
|
||||
// when dragging, and the last finger is lifted, the drag is over
|
||||
Uint8 simulatedButton = 0;
|
||||
if (_multiFingerDragging[port] == DRAG_THREE_FINGER) {
|
||||
simulatedButton = SDL_BUTTON_RIGHT;
|
||||
}
|
||||
else {
|
||||
simulatedButton = SDL_BUTTON_LEFT;
|
||||
}
|
||||
touchmouse_button[simulatedButton] = 0;
|
||||
_multiFingerDragging[port] = DRAG_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psp2ProcessFingerMotion(TouchEvent *event) {
|
||||
// front (0) or back (1) panel
|
||||
int port = event->tfinger.touchId;
|
||||
// id (for multitouch)
|
||||
int id = event->tfinger.fingerId;
|
||||
|
||||
// find out how many fingers were down before this event
|
||||
int numFingersDown = 0;
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id >= 0) {
|
||||
numFingersDown++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numFingersDown >= 1) {
|
||||
// If we are starting a multi-finger drag, start holding down the mouse button
|
||||
if (numFingersDown >= 2) {
|
||||
if (!_multiFingerDragging[port]) {
|
||||
// only start a multi-finger drag if at least two fingers have been down long enough
|
||||
int numFingersDownLong = 0;
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id >= 0) {
|
||||
if (event->tfinger.timestamp - _finger[port][i].timeLastDown > MAX_TAP_TIME) {
|
||||
numFingersDownLong++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numFingersDownLong >= 2) {
|
||||
Uint8 simulatedButton = 0;
|
||||
if (numFingersDownLong == 2) {
|
||||
simulatedButton = SDL_BUTTON_LEFT;
|
||||
_multiFingerDragging[port] = DRAG_TWO_FINGER;
|
||||
} else {
|
||||
simulatedButton = SDL_BUTTON_RIGHT;
|
||||
_multiFingerDragging[port] = DRAG_THREE_FINGER;
|
||||
}
|
||||
|
||||
touchmouse_button[simulatedButton] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check if this is the "oldest" finger down (or the only finger down), otherwise it will not affect mouse motion
|
||||
bool updatePointer = true;
|
||||
if (numFingersDown > 1) {
|
||||
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
|
||||
if (_finger[port][i].id == id) {
|
||||
for (int j = 0; j < MAX_NUM_FINGERS; j++) {
|
||||
if (_finger[port][j].id >= 0 && (i != j) ) {
|
||||
if (_finger[port][j].timeLastDown < _finger[port][i].timeLastDown) {
|
||||
updatePointer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updatePointer) {
|
||||
if (port == 0 && !indirect_front_touch) {
|
||||
int x, y;
|
||||
psp2ConvertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
|
||||
*touchmouse_x = x;
|
||||
*touchmouse_y = y;
|
||||
} else {
|
||||
// for relative mode, use the pointer speed setting
|
||||
int dx = event->tfinger.dx * 960.0 * 256 * pointer_speed_factor / scale_x;
|
||||
int dy = event->tfinger.dy * 544.0 * 256 * pointer_speed_factor / scale_y;
|
||||
hires_dx += dx;
|
||||
hires_dy += dy;
|
||||
*touchmouse_x += hires_dx / 256;
|
||||
*touchmouse_y += hires_dy / 256;
|
||||
hires_dx %= 256;
|
||||
hires_dy %= 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void psp2ConvertTouchXYToGameXY(float touchX, float touchY, int *gameX, int *gameY) {
|
||||
//map to display
|
||||
float x = touchX * 960.0;
|
||||
float y = touchY * 544.0;
|
||||
*gameX = (x - offset_x) / scale_x;
|
||||
*gameY = (y - offset_y) / scale_y;
|
||||
}
|
||||
|
||||
static void psp2FinishSimulatedMouseClicks(int port, SceUInt64 currentTime) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (_simulatedClickStartTime[port][i] != 0) {
|
||||
if (currentTime - _simulatedClickStartTime[port][i] >= SIMULATED_CLICK_DURATION) {
|
||||
int simulatedButton;
|
||||
if (i == 0) {
|
||||
simulatedButton = SDL_BUTTON_LEFT;
|
||||
} else {
|
||||
simulatedButton = SDL_BUTTON_RIGHT;
|
||||
}
|
||||
touchmouse_button[simulatedButton] = 0;
|
||||
|
||||
_simulatedClickStartTime[port][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_PrivateSetIndirectFrontTouch(bool enable) {
|
||||
indirect_front_touch = enable;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_PrivateSetRearTouch(bool enable) {
|
||||
rear_touch = enable;
|
||||
}
|
||||
|
15
libs/imgui/imgui_vita_touch.h
Normal file
15
libs/imgui/imgui_vita_touch.h
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by rsn8887 on 02/05/18.
|
||||
|
||||
#ifndef IMGUI_VITA_TOUCH_H
|
||||
#define IMGUI_VITA_TOUCH_H
|
||||
|
||||
#include <psp2/touch.h>
|
||||
|
||||
/* Touch functions */
|
||||
void ImGui_ImplVitaGL_InitTouch(void);
|
||||
void ImGui_ImplVitaGL_PollTouch(double x0, double y0, double sx, double sy, int *mx, int *my, bool *mbuttons);
|
||||
void ImGui_ImplVitaGL_PrivateSetIndirectFrontTouch(bool enable);
|
||||
void ImGui_ImplVitaGL_PrivateSetRearTouch(bool enable);
|
||||
|
||||
#endif
|
7853
libs/imgui/imgui_widgets.cpp
Normal file
7853
libs/imgui/imgui_widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
639
libs/imgui/imstb_rectpack.h
Normal file
639
libs/imgui/imstb_rectpack.h
Normal file
@ -0,0 +1,639 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.00.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Added STBRP__CDECL
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
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.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
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 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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
1417
libs/imgui/imstb_textedit.h
Normal file
1417
libs/imgui/imstb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
4903
libs/imgui/imstb_truetype.h
Normal file
4903
libs/imgui/imstb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
623
libs/imgui/stb_rect_pack.h
Normal file
623
libs/imgui/stb_rect_pack.h
Normal file
@ -0,0 +1,623 @@
|
||||
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height < c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
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.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
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 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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
1321
libs/imgui/stb_textedit.h
Normal file
1321
libs/imgui/stb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
4854
libs/imgui/stb_truetype.h
Normal file
4854
libs/imgui/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
libs/lib/libtiff.a
Normal file
BIN
libs/lib/libtiff.a
Normal file
Binary file not shown.
BIN
libs/lib/libwebp.a
Normal file
BIN
libs/lib/libwebp.a
Normal file
Binary file not shown.
20
libs/libnsbmp/COPYING
Normal file
20
libs/libnsbmp/COPYING
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (C) 2006 Richard Wilson
|
||||
Copyright (C) 2008 Sean Fox
|
||||
|
||||
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.
|
1388
libs/libnsbmp/libnsbmp.c
Normal file
1388
libs/libnsbmp/libnsbmp.c
Normal file
File diff suppressed because it is too large
Load Diff
258
libs/libnsbmp/libnsbmp.h
Normal file
258
libs/libnsbmp/libnsbmp.h
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2006 Richard Wilson <richard.wilson@netsurf-browser.org>
|
||||
* Copyright 2008 Sean Fox <dyntryx@gmail.com>
|
||||
*
|
||||
* This file is part of NetSurf's libnsbmp, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Bitmap file decoding interface.
|
||||
*/
|
||||
|
||||
#ifndef libnsbmp_h_
|
||||
#define libnsbmp_h_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* bmp flags */
|
||||
#define BMP_NEW 0
|
||||
/** image is opaque (as opposed to having an alpha mask) */
|
||||
#define BMP_OPAQUE (1 << 0)
|
||||
/** memory should be wiped */
|
||||
#define BMP_CLEAR_MEMORY (1 << 1)
|
||||
|
||||
/**
|
||||
* error return values
|
||||
*/
|
||||
typedef enum {
|
||||
BMP_OK = 0,
|
||||
BMP_INSUFFICIENT_MEMORY = 1,
|
||||
BMP_INSUFFICIENT_DATA = 2,
|
||||
BMP_DATA_ERROR = 3
|
||||
} bmp_result;
|
||||
|
||||
/**
|
||||
* encoding types
|
||||
*/
|
||||
typedef enum {
|
||||
BMP_ENCODING_RGB = 0,
|
||||
BMP_ENCODING_RLE8 = 1,
|
||||
BMP_ENCODING_RLE4 = 2,
|
||||
BMP_ENCODING_BITFIELDS = 3
|
||||
} bmp_encoding;
|
||||
|
||||
/* API for Bitmap callbacks */
|
||||
typedef void* (*bmp_bitmap_cb_create)(int width, int height, unsigned int state);
|
||||
typedef void (*bmp_bitmap_cb_destroy)(void *bitmap);
|
||||
typedef unsigned char* (*bmp_bitmap_cb_get_buffer)(void *bitmap);
|
||||
typedef size_t (*bmp_bitmap_cb_get_bpp)(void *bitmap);
|
||||
|
||||
/**
|
||||
* The Bitmap callbacks function table
|
||||
*/
|
||||
typedef struct bmp_bitmap_callback_vt_s {
|
||||
/** Callback to allocate bitmap storage. */
|
||||
bmp_bitmap_cb_create bitmap_create;
|
||||
/** Called to free bitmap storage. */
|
||||
bmp_bitmap_cb_destroy bitmap_destroy;
|
||||
/** Return a pointer to the pixel data in a bitmap. */
|
||||
bmp_bitmap_cb_get_buffer bitmap_get_buffer;
|
||||
/** Find the width of a pixel row in bytes. */
|
||||
bmp_bitmap_cb_get_bpp bitmap_get_bpp;
|
||||
} bmp_bitmap_callback_vt;
|
||||
|
||||
/**
|
||||
* bitmap image
|
||||
*/
|
||||
typedef struct bmp_image {
|
||||
/** callbacks for bitmap functions */
|
||||
bmp_bitmap_callback_vt bitmap_callbacks;
|
||||
/** pointer to BMP data */
|
||||
uint8_t *bmp_data;
|
||||
/** width of BMP (valid after _analyse) */
|
||||
uint32_t width;
|
||||
/** heigth of BMP (valid after _analyse) */
|
||||
uint32_t height;
|
||||
/** whether the image has been decoded */
|
||||
bool decoded;
|
||||
/** decoded image */
|
||||
void *bitmap;
|
||||
|
||||
/* Internal members are listed below */
|
||||
/** total number of bytes of BMP data available */
|
||||
uint32_t buffer_size;
|
||||
/** pixel encoding type */
|
||||
bmp_encoding encoding;
|
||||
/** offset of bitmap data */
|
||||
uint32_t bitmap_offset;
|
||||
/** bits per pixel */
|
||||
uint16_t bpp;
|
||||
/** number of colours */
|
||||
uint32_t colours;
|
||||
/** colour table */
|
||||
uint32_t *colour_table;
|
||||
/** whether to use bmp's limited transparency */
|
||||
bool limited_trans;
|
||||
/** colour to display for "transparent" pixels when using limited
|
||||
* transparency
|
||||
*/
|
||||
uint32_t trans_colour;
|
||||
/** scanlines are top to bottom */
|
||||
bool reversed;
|
||||
/** image is part of an ICO, mask follows */
|
||||
bool ico;
|
||||
/** true if the bitmap does not contain an alpha channel */
|
||||
bool opaque;
|
||||
/** four bitwise mask */
|
||||
uint32_t mask[4];
|
||||
/** four bitwise shifts */
|
||||
int32_t shift[4];
|
||||
/** colour representing "transparency" in the bitmap */
|
||||
uint32_t transparent_index;
|
||||
} bmp_image;
|
||||
|
||||
typedef struct ico_image {
|
||||
bmp_image bmp;
|
||||
struct ico_image *next;
|
||||
} ico_image;
|
||||
|
||||
/**
|
||||
* icon image collection
|
||||
*/
|
||||
typedef struct ico_collection {
|
||||
/** callbacks for bitmap functions */
|
||||
bmp_bitmap_callback_vt bitmap_callbacks;
|
||||
/** width of largest BMP */
|
||||
uint16_t width;
|
||||
/** heigth of largest BMP */
|
||||
uint16_t height;
|
||||
|
||||
/* Internal members are listed below */
|
||||
/** pointer to ICO data */
|
||||
uint8_t *ico_data;
|
||||
/** total number of bytes of ICO data available */
|
||||
uint32_t buffer_size;
|
||||
/** root of linked list of images */
|
||||
ico_image *first;
|
||||
} ico_collection;
|
||||
|
||||
/**
|
||||
* Initialises bitmap ready for analysing the bitmap.
|
||||
*
|
||||
* \param bmp The Bitmap to initialise
|
||||
* \param callbacks The callbacks the library will call on operations.
|
||||
* \return BMP_OK on success or appropriate error code.
|
||||
*/
|
||||
bmp_result bmp_create(bmp_image *bmp, bmp_bitmap_callback_vt *callbacks);
|
||||
|
||||
/**
|
||||
* Initialises icon ready for analysing the icon
|
||||
*
|
||||
* \param bmp The Bitmap to initialise
|
||||
* \param callbacks The callbacks the library will call on operations.
|
||||
* \return BMP_OK on success or appropriate error code.
|
||||
*/
|
||||
bmp_result ico_collection_create(ico_collection *ico,
|
||||
bmp_bitmap_callback_vt *callbacks);
|
||||
|
||||
/**
|
||||
* Analyse a BMP prior to decoding.
|
||||
*
|
||||
* This will scan the data provided and perform checks to ensure the data is a
|
||||
* valid BMP and prepare the bitmap image structure ready for decode.
|
||||
*
|
||||
* This function must be called and resturn BMP_OK before bmp_decode() as it
|
||||
* prepares the bmp internal state for the decode process.
|
||||
*
|
||||
* \param bmp the BMP image to analyse.
|
||||
* \param size The size of data in cdata.
|
||||
* \param data The bitmap source data.
|
||||
* \return BMP_OK on success or error code on faliure.
|
||||
*/
|
||||
bmp_result bmp_analyse(bmp_image *bmp, size_t size, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Analyse an ICO prior to decoding.
|
||||
*
|
||||
* This function will scan the data provided and perform checks to ensure the
|
||||
* data is a valid ICO.
|
||||
*
|
||||
* This function must be called before ico_find().
|
||||
*
|
||||
* \param ico the ICO image to analyse
|
||||
* \param size The size of data in cdata.
|
||||
* \param data The bitmap source data.
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result ico_analyse(ico_collection *ico, size_t size, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Decode a BMP
|
||||
*
|
||||
* This function decodes the BMP data such that bmp->bitmap is a valid
|
||||
* image. The state of bmp->decoded is set to TRUE on exit such that it
|
||||
* can easily be identified which BMPs are in a fully decoded state.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode(bmp_image *bmp);
|
||||
|
||||
/**
|
||||
* Decode a BMP using "limited transparency"
|
||||
*
|
||||
* Bitmaps do not have native transparency support. However, there is a
|
||||
* "trick" that is used in some instances in which the first pixel of the
|
||||
* bitmap becomes the "transparency index". The decoding application can
|
||||
* replace this index with whatever background colour it chooses to
|
||||
* create the illusion of transparency.
|
||||
*
|
||||
* When to use transparency is at the discretion of the decoding
|
||||
* application.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \param colour the colour to use as "transparent"
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode_trans(bmp_image *bmp, uint32_t transparent_colour);
|
||||
|
||||
/**
|
||||
* Finds the closest BMP within an ICO collection
|
||||
*
|
||||
* This function finds the BMP with dimensions as close to a specified set
|
||||
* as possible from the images in the collection.
|
||||
*
|
||||
* \param ico the ICO collection to examine
|
||||
* \param width the preferred width (0 to use ICO header width)
|
||||
* \param height the preferred height (0 to use ICO header height)
|
||||
*/
|
||||
bmp_image *ico_find(ico_collection *ico, uint16_t width, uint16_t height);
|
||||
|
||||
/**
|
||||
* Finalise a BMP prior to destruction.
|
||||
*
|
||||
* \param bmp the BMP image to finalise.
|
||||
*/
|
||||
void bmp_finalise(bmp_image *bmp);
|
||||
|
||||
/**
|
||||
* Finalise an ICO prior to destruction.
|
||||
*
|
||||
* \param ico the ICO image to finalise,
|
||||
*/
|
||||
void ico_finalise(ico_collection *ico);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
27
libs/libnsbmp/utils/log.h
Normal file
27
libs/libnsbmp/utils/log.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _LIBNSBMP_LOG_H_
|
||||
#define _LIBNSBMP_LOG_H_
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define LOG(x) ((void) 0)
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# elif defined(__CC_NORCROFT)
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# else
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
20
libs/libnsgif/COPYING
Normal file
20
libs/libnsgif/COPYING
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (C) 2004 Richard Wilson
|
||||
Copyright (C) 2008 Sean Fox
|
||||
|
||||
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.
|
1169
libs/libnsgif/libnsgif.c
Normal file
1169
libs/libnsgif/libnsgif.c
Normal file
File diff suppressed because it is too large
Load Diff
191
libs/libnsgif/libnsgif.h
Normal file
191
libs/libnsgif/libnsgif.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org>
|
||||
* Copyright 2008 Sean Fox <dyntryx@gmail.com>
|
||||
*
|
||||
* This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Interface to progressive animated GIF file decoding.
|
||||
*/
|
||||
|
||||
#ifndef _LIBNSGIF_H_
|
||||
#define _LIBNSGIF_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Error return values */
|
||||
typedef enum {
|
||||
GIF_WORKING = 1,
|
||||
GIF_OK = 0,
|
||||
GIF_INSUFFICIENT_FRAME_DATA = -1,
|
||||
GIF_FRAME_DATA_ERROR = -2,
|
||||
GIF_INSUFFICIENT_DATA = -3,
|
||||
GIF_DATA_ERROR = -4,
|
||||
GIF_INSUFFICIENT_MEMORY = -5,
|
||||
GIF_FRAME_NO_DISPLAY = -6,
|
||||
GIF_END_OF_FRAME = -7
|
||||
} gif_result;
|
||||
|
||||
/** GIF frame data */
|
||||
typedef struct gif_frame {
|
||||
/** whether the frame should be displayed/animated */
|
||||
bool display;
|
||||
/** delay (in cs) before animating the frame */
|
||||
unsigned int frame_delay;
|
||||
|
||||
/* Internal members are listed below */
|
||||
|
||||
/** offset (in bytes) to the GIF frame data */
|
||||
unsigned int frame_pointer;
|
||||
/** whether the frame has previously been used */
|
||||
bool virgin;
|
||||
/** whether the frame is totally opaque */
|
||||
bool opaque;
|
||||
/** whether a forcable screen redraw is required */
|
||||
bool redraw_required;
|
||||
/** how the previous frame should be disposed; affects plotting */
|
||||
unsigned char disposal_method;
|
||||
/** whether we acknoledge transparency */
|
||||
bool transparency;
|
||||
/** the index designating a transparent pixel */
|
||||
unsigned char transparency_index;
|
||||
/** x co-ordinate of redraw rectangle */
|
||||
unsigned int redraw_x;
|
||||
/** y co-ordinate of redraw rectangle */
|
||||
unsigned int redraw_y;
|
||||
/** width of redraw rectangle */
|
||||
unsigned int redraw_width;
|
||||
/** height of redraw rectangle */
|
||||
unsigned int redraw_height;
|
||||
} gif_frame;
|
||||
|
||||
/* API for Bitmap callbacks */
|
||||
typedef void* (*gif_bitmap_cb_create)(int width, int height);
|
||||
typedef void (*gif_bitmap_cb_destroy)(void *bitmap);
|
||||
typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap);
|
||||
typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque);
|
||||
typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap);
|
||||
typedef void (*gif_bitmap_cb_modified)(void *bitmap);
|
||||
|
||||
/** Bitmap callbacks function table */
|
||||
typedef struct gif_bitmap_callback_vt {
|
||||
/** Create a bitmap. */
|
||||
gif_bitmap_cb_create bitmap_create;
|
||||
/** Free a bitmap. */
|
||||
gif_bitmap_cb_destroy bitmap_destroy;
|
||||
/** Return a pointer to the pixel data in a bitmap. */
|
||||
gif_bitmap_cb_get_buffer bitmap_get_buffer;
|
||||
|
||||
/* Members below are optional */
|
||||
|
||||
/** Sets whether a bitmap should be plotted opaque. */
|
||||
gif_bitmap_cb_set_opaque bitmap_set_opaque;
|
||||
/** Tests whether a bitmap has an opaque alpha channel. */
|
||||
gif_bitmap_cb_test_opaque bitmap_test_opaque;
|
||||
/** The bitmap image has changed, so flush any persistant cache. */
|
||||
gif_bitmap_cb_modified bitmap_modified;
|
||||
} gif_bitmap_callback_vt;
|
||||
|
||||
/** GIF animation data */
|
||||
typedef struct gif_animation {
|
||||
/** LZW decode context */
|
||||
void *lzw_ctx;
|
||||
/** callbacks for bitmap functions */
|
||||
gif_bitmap_callback_vt bitmap_callbacks;
|
||||
/** pointer to GIF data */
|
||||
unsigned char *gif_data;
|
||||
/** width of GIF (may increase during decoding) */
|
||||
unsigned int width;
|
||||
/** heigth of GIF (may increase during decoding) */
|
||||
unsigned int height;
|
||||
/** number of frames decoded */
|
||||
unsigned int frame_count;
|
||||
/** number of frames partially decoded */
|
||||
unsigned int frame_count_partial;
|
||||
/** decoded frames */
|
||||
gif_frame *frames;
|
||||
/** current frame decoded to bitmap */
|
||||
int decoded_frame;
|
||||
/** currently decoded image; stored as bitmap from bitmap_create callback */
|
||||
void *frame_image;
|
||||
/** number of times to loop animation */
|
||||
int loop_count;
|
||||
|
||||
/* Internal members are listed below */
|
||||
|
||||
/** current index into GIF data */
|
||||
unsigned int buffer_position;
|
||||
/** total number of bytes of GIF data available */
|
||||
unsigned int buffer_size;
|
||||
/** current number of frame holders */
|
||||
unsigned int frame_holders;
|
||||
/** index in the colour table for the background colour */
|
||||
unsigned int background_index;
|
||||
/** image aspect ratio (ignored) */
|
||||
unsigned int aspect_ratio;
|
||||
/** size of colour table (in entries) */
|
||||
unsigned int colour_table_size;
|
||||
/** whether the GIF has a global colour table */
|
||||
bool global_colours;
|
||||
/** global colour table */
|
||||
unsigned int *global_colour_table;
|
||||
/** local colour table */
|
||||
unsigned int *local_colour_table;
|
||||
} gif_animation;
|
||||
|
||||
/**
|
||||
* Initialises necessary gif_animation members.
|
||||
*/
|
||||
void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks);
|
||||
|
||||
/**
|
||||
* Initialises any workspace held by the animation and attempts to decode
|
||||
* any information that hasn't already been decoded.
|
||||
* If an error occurs, all previously decoded frames are retained.
|
||||
*
|
||||
* @return Error return value.
|
||||
* - GIF_FRAME_DATA_ERROR for GIF frame data error
|
||||
* - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process
|
||||
* any more frames
|
||||
* - GIF_INSUFFICIENT_MEMORY for memory error
|
||||
* - GIF_DATA_ERROR for GIF error
|
||||
* - GIF_INSUFFICIENT_DATA for insufficient data to do anything
|
||||
* - GIF_OK for successful decoding
|
||||
* - GIF_WORKING for successful decoding if more frames are expected
|
||||
*/
|
||||
gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data);
|
||||
|
||||
/**
|
||||
* Decodes a GIF frame.
|
||||
*
|
||||
* @return Error return value. If a frame does not contain any image data,
|
||||
* GIF_OK is returned and gif->current_error is set to
|
||||
* GIF_FRAME_NO_DISPLAY
|
||||
* - GIF_FRAME_DATA_ERROR for GIF frame data error
|
||||
* - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
|
||||
* - GIF_DATA_ERROR for GIF error (invalid frame header)
|
||||
* - GIF_INSUFFICIENT_DATA for insufficient data to do anything
|
||||
* - GIF_INSUFFICIENT_MEMORY for insufficient memory to process
|
||||
* - GIF_OK for successful decoding
|
||||
*/
|
||||
gif_result gif_decode_frame(gif_animation *gif, unsigned int frame);
|
||||
|
||||
/**
|
||||
* Releases any workspace held by a gif
|
||||
*/
|
||||
void gif_finalise(gif_animation *gif);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
377
libs/libnsgif/lzw.c
Normal file
377
libs/libnsgif/lzw.c
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
* This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/
|
||||
* Licensed under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Copyright 2017 Michael Drake <michael.drake@codethink.co.uk>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "lzw.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief LZW decompression (implementation)
|
||||
*
|
||||
* Decoder for GIF LZW data.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Context for reading LZW data.
|
||||
*
|
||||
* LZW data is split over multiple sub-blocks. Each sub-block has a
|
||||
* byte at the start, which says the sub-block size, and then the data.
|
||||
* Zero-size sub-blocks have no data, and the biggest sub-block size is
|
||||
* 255, which means there are 255 bytes of data following the sub-block
|
||||
* size entry.
|
||||
*
|
||||
* Note that an individual LZW code can be split over up to three sub-blocks.
|
||||
*/
|
||||
struct lzw_read_ctx {
|
||||
const uint8_t *data; /**< Pointer to start of input data */
|
||||
uint32_t data_len; /**< Input data length */
|
||||
uint32_t data_sb_next; /**< Offset to sub-block size */
|
||||
|
||||
const uint8_t *sb_data; /**< Pointer to current sub-block in data */
|
||||
uint32_t sb_bit; /**< Current bit offset in sub-block */
|
||||
uint32_t sb_bit_count; /**< Bit count in sub-block */
|
||||
};
|
||||
|
||||
/**
|
||||
* LZW dictionary entry.
|
||||
*
|
||||
* Records in the dictionary are composed of 1 or more entries.
|
||||
* Entries point to previous entries which can be followed to compose
|
||||
* the complete record. To compose the record in reverse order, take
|
||||
* the `last_value` from each entry, and move to the previous entry.
|
||||
* If the previous_entry's index is < the current clear_code, then it
|
||||
* is the last entry in the record.
|
||||
*/
|
||||
struct lzw_dictionary_entry {
|
||||
uint8_t last_value; /**< Last value for record ending at entry. */
|
||||
uint8_t first_value; /**< First value for entry's record. */
|
||||
uint16_t previous_entry; /**< Offset in dictionary to previous entry. */
|
||||
};
|
||||
|
||||
/**
|
||||
* LZW decompression context.
|
||||
*/
|
||||
struct lzw_ctx {
|
||||
/** Input reading context */
|
||||
struct lzw_read_ctx input;
|
||||
|
||||
uint32_t previous_code; /**< Code read from input previously. */
|
||||
uint32_t previous_code_first; /**< First value of previous code. */
|
||||
|
||||
uint32_t initial_code_size; /**< Starting LZW code size. */
|
||||
uint32_t current_code_size; /**< Current LZW code size. */
|
||||
uint32_t current_code_size_max; /**< Max code value for current size. */
|
||||
|
||||
uint32_t clear_code; /**< Special Clear code value */
|
||||
uint32_t eoi_code; /**< Special End of Information code value */
|
||||
|
||||
uint32_t current_entry; /**< Next position in table to fill. */
|
||||
|
||||
/** Output value stack. */
|
||||
uint8_t stack_base[1 << LZW_CODE_MAX];
|
||||
|
||||
/** LZW decode dictionary. Generated during decode. */
|
||||
struct lzw_dictionary_entry table[1 << LZW_CODE_MAX];
|
||||
};
|
||||
|
||||
|
||||
/* Exported function, documented in lzw.h */
|
||||
lzw_result lzw_context_create(struct lzw_ctx **ctx)
|
||||
{
|
||||
struct lzw_ctx *c = malloc(sizeof(*c));
|
||||
if (c == NULL) {
|
||||
return LZW_NO_MEM;
|
||||
}
|
||||
|
||||
*ctx = c;
|
||||
return LZW_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Exported function, documented in lzw.h */
|
||||
void lzw_context_destroy(struct lzw_ctx *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Advance the context to the next sub-block in the input data.
|
||||
*
|
||||
* \param[in] ctx LZW reading context, updated on success.
|
||||
* \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise.
|
||||
*/
|
||||
static lzw_result lzw__block_advance(struct lzw_read_ctx *ctx)
|
||||
{
|
||||
uint32_t block_size;
|
||||
uint32_t next_block_pos = ctx->data_sb_next;
|
||||
const uint8_t *data_next = ctx->data + next_block_pos;
|
||||
|
||||
if (next_block_pos >= ctx->data_len) {
|
||||
return LZW_NO_DATA;
|
||||
}
|
||||
|
||||
block_size = *data_next;
|
||||
|
||||
if ((next_block_pos + block_size) >= ctx->data_len) {
|
||||
return LZW_NO_DATA;
|
||||
}
|
||||
|
||||
ctx->sb_bit = 0;
|
||||
ctx->sb_bit_count = block_size * 8;
|
||||
|
||||
if (block_size == 0) {
|
||||
ctx->data_sb_next += 1;
|
||||
return LZW_OK_EOD;
|
||||
}
|
||||
|
||||
ctx->sb_data = data_next + 1;
|
||||
ctx->data_sb_next += block_size + 1;
|
||||
|
||||
return LZW_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the next LZW code of given size from the raw input data.
|
||||
*
|
||||
* Reads codes from the input data stream coping with GIF data sub-blocks.
|
||||
*
|
||||
* \param[in] ctx LZW reading context, updated.
|
||||
* \param[in] code_size Size of LZW code to get from data.
|
||||
* \param[out] code_out Returns an LZW code on success.
|
||||
* \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise.
|
||||
*/
|
||||
static inline lzw_result lzw__next_code(
|
||||
struct lzw_read_ctx *ctx,
|
||||
uint8_t code_size,
|
||||
uint32_t *code_out)
|
||||
{
|
||||
uint32_t code = 0;
|
||||
uint8_t current_bit = ctx->sb_bit & 0x7;
|
||||
uint8_t byte_advance = (current_bit + code_size) >> 3;
|
||||
|
||||
assert(byte_advance <= 2);
|
||||
|
||||
if (ctx->sb_bit + code_size <= ctx->sb_bit_count) {
|
||||
/* Fast path: code fully inside this sub-block */
|
||||
const uint8_t *data = ctx->sb_data + (ctx->sb_bit >> 3);
|
||||
switch (byte_advance) {
|
||||
case 2: code |= data[2] << 16; /* Fall through */
|
||||
case 1: code |= data[1] << 8; /* Fall through */
|
||||
case 0: code |= data[0] << 0;
|
||||
}
|
||||
ctx->sb_bit += code_size;
|
||||
} else {
|
||||
/* Slow path: code spans sub-blocks */
|
||||
uint8_t byte = 0;
|
||||
uint8_t bits_remaining_0 = (code_size < (8 - current_bit)) ?
|
||||
code_size : (8 - current_bit);
|
||||
uint8_t bits_remaining_1 = code_size - bits_remaining_0;
|
||||
uint8_t bits_used[3] = {
|
||||
[0] = bits_remaining_0,
|
||||
[1] = bits_remaining_1 < 8 ? bits_remaining_1 : 8,
|
||||
[2] = bits_remaining_1 - 8,
|
||||
};
|
||||
|
||||
while (true) {
|
||||
const uint8_t *data = ctx->sb_data;
|
||||
lzw_result res;
|
||||
|
||||
/* Get any data from end of this sub-block */
|
||||
while (byte <= byte_advance &&
|
||||
ctx->sb_bit < ctx->sb_bit_count) {
|
||||
code |= data[ctx->sb_bit >> 3] << (byte << 3);
|
||||
ctx->sb_bit += bits_used[byte];
|
||||
byte++;
|
||||
}
|
||||
|
||||
/* Check if we have all we need */
|
||||
if (byte > byte_advance) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to next sub-block */
|
||||
res = lzw__block_advance(ctx);
|
||||
if (res != LZW_OK) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*code_out = (code >> current_bit) & ((1 << code_size) - 1);
|
||||
return LZW_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear LZW code dictionary.
|
||||
*
|
||||
* \param[in] ctx LZW reading context, updated.
|
||||
* \param[out] stack_pos_out Returns current stack position.
|
||||
* \return LZW_OK or error code.
|
||||
*/
|
||||
static lzw_result lzw__clear_codes(
|
||||
struct lzw_ctx *ctx,
|
||||
const uint8_t ** const stack_pos_out)
|
||||
{
|
||||
uint32_t code;
|
||||
uint8_t *stack_pos;
|
||||
|
||||
/* Reset dictionary building context */
|
||||
ctx->current_code_size = ctx->initial_code_size + 1;
|
||||
ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;;
|
||||
ctx->current_entry = (1 << ctx->initial_code_size) + 2;
|
||||
|
||||
/* There might be a sequence of clear codes, so process them all */
|
||||
do {
|
||||
lzw_result res = lzw__next_code(&ctx->input,
|
||||
ctx->current_code_size, &code);
|
||||
if (res != LZW_OK) {
|
||||
return res;
|
||||
}
|
||||
} while (code == ctx->clear_code);
|
||||
|
||||
/* The initial code must be from the initial dictionary. */
|
||||
if (code > ctx->clear_code) {
|
||||
return LZW_BAD_ICODE;
|
||||
}
|
||||
|
||||
/* Record this initial code as "previous" code, needed during decode. */
|
||||
ctx->previous_code = code;
|
||||
ctx->previous_code_first = code;
|
||||
|
||||
/* Reset the stack, and add first non-clear code added as first item. */
|
||||
stack_pos = ctx->stack_base;
|
||||
*stack_pos++ = code;
|
||||
|
||||
*stack_pos_out = stack_pos;
|
||||
return LZW_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Exported function, documented in lzw.h */
|
||||
lzw_result lzw_decode_init(
|
||||
struct lzw_ctx *ctx,
|
||||
const uint8_t *compressed_data,
|
||||
uint32_t compressed_data_len,
|
||||
uint32_t compressed_data_pos,
|
||||
uint8_t code_size,
|
||||
const uint8_t ** const stack_base_out,
|
||||
const uint8_t ** const stack_pos_out)
|
||||
{
|
||||
struct lzw_dictionary_entry *table = ctx->table;
|
||||
|
||||
/* Initialise the input reading context */
|
||||
ctx->input.data = compressed_data;
|
||||
ctx->input.data_len = compressed_data_len;
|
||||
ctx->input.data_sb_next = compressed_data_pos;
|
||||
|
||||
ctx->input.sb_bit = 0;
|
||||
ctx->input.sb_bit_count = 0;
|
||||
|
||||
/* Initialise the dictionary building context */
|
||||
ctx->initial_code_size = code_size;
|
||||
|
||||
ctx->clear_code = (1 << code_size) + 0;
|
||||
ctx->eoi_code = (1 << code_size) + 1;
|
||||
|
||||
/* Initialise the standard dictionary entries */
|
||||
for (uint32_t i = 0; i < ctx->clear_code; ++i) {
|
||||
table[i].first_value = i;
|
||||
table[i].last_value = i;
|
||||
}
|
||||
|
||||
*stack_base_out = ctx->stack_base;
|
||||
return lzw__clear_codes(ctx, stack_pos_out);
|
||||
}
|
||||
|
||||
|
||||
/* Exported function, documented in lzw.h */
|
||||
lzw_result lzw_decode(struct lzw_ctx *ctx,
|
||||
const uint8_t ** const stack_pos_out)
|
||||
{
|
||||
lzw_result res;
|
||||
uint32_t code_new;
|
||||
uint32_t code_out;
|
||||
uint8_t last_value;
|
||||
uint8_t *stack_pos = ctx->stack_base;
|
||||
uint32_t clear_code = ctx->clear_code;
|
||||
uint32_t current_entry = ctx->current_entry;
|
||||
struct lzw_dictionary_entry * const table = ctx->table;
|
||||
|
||||
/* Get a new code from the input */
|
||||
res = lzw__next_code(&ctx->input, ctx->current_code_size, &code_new);
|
||||
if (res != LZW_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Handle the new code */
|
||||
if (code_new == clear_code) {
|
||||
/* Got Clear code */
|
||||
return lzw__clear_codes(ctx, stack_pos_out);
|
||||
|
||||
} else if (code_new == ctx->eoi_code) {
|
||||
/* Got End of Information code */
|
||||
return LZW_EOI_CODE;
|
||||
|
||||
} else if (code_new > current_entry) {
|
||||
/* Code is invalid */
|
||||
return LZW_BAD_CODE;
|
||||
|
||||
} else if (code_new < current_entry) {
|
||||
/* Code is in table */
|
||||
code_out = code_new;
|
||||
last_value = table[code_new].first_value;
|
||||
} else {
|
||||
/* Code not in table */
|
||||
*stack_pos++ = ctx->previous_code_first;
|
||||
code_out = ctx->previous_code;
|
||||
last_value = ctx->previous_code_first;
|
||||
}
|
||||
|
||||
/* Add to the dictionary, only if there's space */
|
||||
if (current_entry < (1 << LZW_CODE_MAX)) {
|
||||
struct lzw_dictionary_entry *entry = table + current_entry;
|
||||
entry->last_value = last_value;
|
||||
entry->first_value = ctx->previous_code_first;
|
||||
entry->previous_entry = ctx->previous_code;
|
||||
ctx->current_entry++;
|
||||
}
|
||||
|
||||
/* Ensure code size is increased, if needed. */
|
||||
if (current_entry == ctx->current_code_size_max) {
|
||||
if (ctx->current_code_size < LZW_CODE_MAX) {
|
||||
ctx->current_code_size++;
|
||||
ctx->current_code_size_max =
|
||||
(1 << ctx->current_code_size) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store details of this code as "previous code" to the context. */
|
||||
ctx->previous_code_first = table[code_new].first_value;
|
||||
ctx->previous_code = code_new;
|
||||
|
||||
/* Put rest of data for this code on output stack.
|
||||
* Note, in the case of "code not in table", the last entry of the
|
||||
* current code has already been placed on the stack above. */
|
||||
while (code_out > clear_code) {
|
||||
struct lzw_dictionary_entry *entry = table + code_out;
|
||||
*stack_pos++ = entry->last_value;
|
||||
code_out = entry->previous_entry;
|
||||
}
|
||||
*stack_pos++ = table[code_out].last_value;
|
||||
|
||||
*stack_pos_out = stack_pos;
|
||||
return LZW_OK;
|
||||
}
|
105
libs/libnsgif/lzw.h
Normal file
105
libs/libnsgif/lzw.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/
|
||||
* Licensed under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Copyright 2017 Michael Drake <michael.drake@codethink.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef LZW_H_
|
||||
#define LZW_H_
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief LZW decompression (interface)
|
||||
*
|
||||
* Decoder for GIF LZW data.
|
||||
*/
|
||||
|
||||
|
||||
/** Maximum LZW code size in bits */
|
||||
#define LZW_CODE_MAX 12
|
||||
|
||||
|
||||
/* Declare lzw internal context structure */
|
||||
struct lzw_ctx;
|
||||
|
||||
|
||||
/** LZW decoding response codes */
|
||||
typedef enum lzw_result {
|
||||
LZW_OK, /**< Success */
|
||||
LZW_OK_EOD, /**< Success; reached zero-length sub-block */
|
||||
LZW_NO_MEM, /**< Error: Out of memory */
|
||||
LZW_NO_DATA, /**< Error: Out of data */
|
||||
LZW_EOI_CODE, /**< Error: End of Information code */
|
||||
LZW_BAD_ICODE, /**< Error: Bad initial LZW code */
|
||||
LZW_BAD_CODE, /**< Error: Bad LZW code */
|
||||
} lzw_result;
|
||||
|
||||
|
||||
/**
|
||||
* Create an LZW decompression context.
|
||||
*
|
||||
* \param[out] ctx Returns an LZW decompression context. Caller owned,
|
||||
* free with lzw_context_destroy().
|
||||
* \return LZW_OK on success, or appropriate error code otherwise.
|
||||
*/
|
||||
lzw_result lzw_context_create(
|
||||
struct lzw_ctx **ctx);
|
||||
|
||||
/**
|
||||
* Destroy an LZW decompression context.
|
||||
*
|
||||
* \param[in] ctx The LZW decompression context to destroy.
|
||||
*/
|
||||
void lzw_context_destroy(
|
||||
struct lzw_ctx *ctx);
|
||||
|
||||
/**
|
||||
* Initialise an LZW decompression context for decoding.
|
||||
*
|
||||
* Caller owns neither `stack_base_out` or `stack_pos_out`.
|
||||
*
|
||||
* \param[in] ctx The LZW decompression context to initialise.
|
||||
* \param[in] compressed_data The compressed data.
|
||||
* \param[in] compressed_data_len Byte length of compressed data.
|
||||
* \param[in] compressed_data_pos Start position in data. Must be position
|
||||
* of a size byte at sub-block start.
|
||||
* \param[in] code_size The initial LZW code size to use.
|
||||
* \param[out] stack_base_out Returns base of decompressed data stack.
|
||||
* \param[out] stack_pos_out Returns current stack position.
|
||||
* There are `stack_pos_out - stack_base_out`
|
||||
* current stack entries.
|
||||
* \return LZW_OK on success, or appropriate error code otherwise.
|
||||
*/
|
||||
lzw_result lzw_decode_init(
|
||||
struct lzw_ctx *ctx,
|
||||
const uint8_t *compressed_data,
|
||||
uint32_t compressed_data_len,
|
||||
uint32_t compressed_data_pos,
|
||||
uint8_t code_size,
|
||||
const uint8_t ** const stack_base_out,
|
||||
const uint8_t ** const stack_pos_out);
|
||||
|
||||
/**
|
||||
* Fill the LZW stack with decompressed data
|
||||
*
|
||||
* Ensure anything on the stack is used before calling this, as anything
|
||||
* on the stack before this call will be trampled.
|
||||
*
|
||||
* Caller does not own `stack_pos_out`.
|
||||
*
|
||||
* \param[in] ctx LZW reading context, updated.
|
||||
* \param[out] stack_pos_out Returns current stack position.
|
||||
* Use with `stack_base_out` value from previous
|
||||
* lzw_decode_init() call.
|
||||
* There are `stack_pos_out - stack_base_out`
|
||||
* current stack entries.
|
||||
* \return LZW_OK on success, or appropriate error code otherwise.
|
||||
*/
|
||||
lzw_result lzw_decode(
|
||||
struct lzw_ctx *ctx,
|
||||
const uint8_t ** const stack_pos_out);
|
||||
|
||||
|
||||
#endif
|
21
libs/libnsgif/utils/log.h
Normal file
21
libs/libnsgif/utils/log.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _LIBNSGIF_LOG_H_
|
||||
#define _LIBNSGIF_LOG_H_
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define LOG(x) ((void) 0)
|
||||
#else
|
||||
# define LOG(x) do { fprintf(stderr, x), fputc('\n', stderr); } while (0)
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#endif /* _LIBNSGIF_LOG_H_ */
|
21
libs/libtiff/COPYRIGHT
Normal file
21
libs/libtiff/COPYRIGHT
Normal file
@ -0,0 +1,21 @@
|
||||
Copyright (c) 1988-1997 Sam Leffler
|
||||
Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and
|
||||
its documentation for any purpose is hereby granted without fee, provided
|
||||
that (i) the above copyright notices and this permission notice appear in
|
||||
all copies of the software and related documentation, and (ii) the names of
|
||||
Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
publicity relating to the software without the specific, prior written
|
||||
permission of Sam Leffler and Silicon Graphics.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
OF THIS SOFTWARE.
|
695
libs/libtiff/tiff.h
Normal file
695
libs/libtiff/tiff.h
Normal file
@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _TIFF_
|
||||
#define _TIFF_
|
||||
|
||||
#include "tiffconf.h"
|
||||
|
||||
/*
|
||||
* Tag Image File Format (TIFF)
|
||||
*
|
||||
* Based on Rev 6.0 from:
|
||||
* Developer's Desk
|
||||
* Aldus Corporation
|
||||
* 411 First Ave. South
|
||||
* Suite 200
|
||||
* Seattle, WA 98104
|
||||
* 206-622-5500
|
||||
*
|
||||
* (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
|
||||
*
|
||||
* For BigTIFF design notes see the following links
|
||||
* http://www.remotesensing.org/libtiff/bigtiffdesign.html
|
||||
* http://www.awaresystems.be/imaging/tiff/bigtiff.html
|
||||
*/
|
||||
|
||||
#define TIFF_VERSION_CLASSIC 42
|
||||
#define TIFF_VERSION_BIG 43
|
||||
|
||||
#define TIFF_BIGENDIAN 0x4d4d
|
||||
#define TIFF_LITTLEENDIAN 0x4949
|
||||
#define MDI_LITTLEENDIAN 0x5045
|
||||
#define MDI_BIGENDIAN 0x4550
|
||||
|
||||
/*
|
||||
* Intrinsic data types required by the file format:
|
||||
*
|
||||
* 8-bit quantities int8/uint8
|
||||
* 16-bit quantities int16/uint16
|
||||
* 32-bit quantities int32/uint32
|
||||
* 64-bit quantities int64/uint64
|
||||
* strings unsigned char*
|
||||
*/
|
||||
|
||||
typedef TIFF_INT8_T int8;
|
||||
typedef TIFF_UINT8_T uint8;
|
||||
|
||||
typedef TIFF_INT16_T int16;
|
||||
typedef TIFF_UINT16_T uint16;
|
||||
|
||||
typedef TIFF_INT32_T int32;
|
||||
typedef TIFF_UINT32_T uint32;
|
||||
|
||||
typedef TIFF_INT64_T int64;
|
||||
typedef TIFF_UINT64_T uint64;
|
||||
|
||||
/*
|
||||
* Some types as promoted in a variable argument list
|
||||
* We use uint16_vap rather then directly using int, because this way
|
||||
* we document the type we actually want to pass through, conceptually,
|
||||
* rather then confusing the issue by merely stating the type it gets
|
||||
* promoted to
|
||||
*/
|
||||
|
||||
typedef int uint16_vap;
|
||||
|
||||
/*
|
||||
* TIFF header.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16 tiff_magic; /* magic number (defines byte order) */
|
||||
uint16 tiff_version; /* TIFF version number */
|
||||
} TIFFHeaderCommon;
|
||||
typedef struct {
|
||||
uint16 tiff_magic; /* magic number (defines byte order) */
|
||||
uint16 tiff_version; /* TIFF version number */
|
||||
uint32 tiff_diroff; /* byte offset to first directory */
|
||||
} TIFFHeaderClassic;
|
||||
typedef struct {
|
||||
uint16 tiff_magic; /* magic number (defines byte order) */
|
||||
uint16 tiff_version; /* TIFF version number */
|
||||
uint16 tiff_offsetsize; /* size of offsets, should be 8 */
|
||||
uint16 tiff_unused; /* unused word, should be 0 */
|
||||
uint64 tiff_diroff; /* byte offset to first directory */
|
||||
} TIFFHeaderBig;
|
||||
|
||||
|
||||
/*
|
||||
* NB: In the comments below,
|
||||
* - items marked with a + are obsoleted by revision 5.0,
|
||||
* - items marked with a ! are introduced in revision 6.0.
|
||||
* - items marked with a % are introduced post revision 6.0.
|
||||
* - items marked with a $ are obsoleted by revision 6.0.
|
||||
* - items marked with a & are introduced by Adobe DNG specification.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Tag data type information.
|
||||
*
|
||||
* Note: RATIONALs are the ratio of two 32-bit integer values.
|
||||
*/
|
||||
typedef enum {
|
||||
TIFF_NOTYPE = 0, /* placeholder */
|
||||
TIFF_BYTE = 1, /* 8-bit unsigned integer */
|
||||
TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */
|
||||
TIFF_SHORT = 3, /* 16-bit unsigned integer */
|
||||
TIFF_LONG = 4, /* 32-bit unsigned integer */
|
||||
TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */
|
||||
TIFF_SBYTE = 6, /* !8-bit signed integer */
|
||||
TIFF_UNDEFINED = 7, /* !8-bit untyped data */
|
||||
TIFF_SSHORT = 8, /* !16-bit signed integer */
|
||||
TIFF_SLONG = 9, /* !32-bit signed integer */
|
||||
TIFF_SRATIONAL = 10, /* !64-bit signed fraction */
|
||||
TIFF_FLOAT = 11, /* !32-bit IEEE floating point */
|
||||
TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */
|
||||
TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */
|
||||
TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */
|
||||
TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */
|
||||
TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */
|
||||
} TIFFDataType;
|
||||
|
||||
/*
|
||||
* TIFF Tag Definitions.
|
||||
*/
|
||||
#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */
|
||||
#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */
|
||||
#define FILETYPE_PAGE 0x2 /* one page of many */
|
||||
#define FILETYPE_MASK 0x4 /* transparency mask */
|
||||
#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */
|
||||
#define OFILETYPE_IMAGE 1 /* full resolution image data */
|
||||
#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */
|
||||
#define OFILETYPE_PAGE 3 /* one page of many */
|
||||
#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */
|
||||
#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */
|
||||
#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */
|
||||
#define TIFFTAG_COMPRESSION 259 /* data compression technique */
|
||||
#define COMPRESSION_NONE 1 /* dump mode */
|
||||
#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */
|
||||
#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */
|
||||
#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */
|
||||
#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */
|
||||
#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */
|
||||
#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
|
||||
#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
|
||||
#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
|
||||
#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
|
||||
#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
|
||||
#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
|
||||
#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
|
||||
#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
|
||||
#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */
|
||||
/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
|
||||
#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */
|
||||
#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */
|
||||
#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */
|
||||
#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */
|
||||
/* compression codes 32908-32911 are reserved for Pixar */
|
||||
#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
|
||||
#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */
|
||||
#define COMPRESSION_DEFLATE 32946 /* Deflate compression */
|
||||
#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression,
|
||||
as recognized by Adobe */
|
||||
/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
|
||||
#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */
|
||||
#define COMPRESSION_JBIG 34661 /* ISO JBIG */
|
||||
#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
|
||||
#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
|
||||
#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
|
||||
#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */
|
||||
/* compression codes 34887-34889 are reserved for ESRI */
|
||||
#define COMPRESSION_LZMA 34925 /* LZMA2 */
|
||||
#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */
|
||||
#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */
|
||||
#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
|
||||
#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
|
||||
#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
|
||||
#define PHOTOMETRIC_RGB 2 /* RGB color model */
|
||||
#define PHOTOMETRIC_PALETTE 3 /* color map indexed */
|
||||
#define PHOTOMETRIC_MASK 4 /* $holdout mask */
|
||||
#define PHOTOMETRIC_SEPARATED 5 /* !color separations */
|
||||
#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */
|
||||
#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
|
||||
#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
|
||||
#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
|
||||
#define PHOTOMETRIC_CFA 32803 /* color filter array */
|
||||
#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
|
||||
#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
|
||||
#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
|
||||
#define THRESHHOLD_BILEVEL 1 /* b&w art scan */
|
||||
#define THRESHHOLD_HALFTONE 2 /* or dithered scan */
|
||||
#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */
|
||||
#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */
|
||||
#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */
|
||||
#define TIFFTAG_FILLORDER 266 /* data order within a byte */
|
||||
#define FILLORDER_MSB2LSB 1 /* most significant -> least */
|
||||
#define FILLORDER_LSB2MSB 2 /* least significant -> most */
|
||||
#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */
|
||||
#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */
|
||||
#define TIFFTAG_MAKE 271 /* scanner manufacturer name */
|
||||
#define TIFFTAG_MODEL 272 /* scanner model name/number */
|
||||
#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */
|
||||
#define TIFFTAG_ORIENTATION 274 /* +image orientation */
|
||||
#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */
|
||||
#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */
|
||||
#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */
|
||||
#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */
|
||||
#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */
|
||||
#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */
|
||||
#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */
|
||||
#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */
|
||||
#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */
|
||||
#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */
|
||||
#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */
|
||||
#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */
|
||||
#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */
|
||||
#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */
|
||||
#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */
|
||||
#define TIFFTAG_PLANARCONFIG 284 /* storage organization */
|
||||
#define PLANARCONFIG_CONTIG 1 /* single image plane */
|
||||
#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */
|
||||
#define TIFFTAG_PAGENAME 285 /* page name image is from */
|
||||
#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */
|
||||
#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */
|
||||
#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */
|
||||
#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */
|
||||
#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */
|
||||
#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */
|
||||
#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */
|
||||
#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */
|
||||
#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
|
||||
#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */
|
||||
#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */
|
||||
#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */
|
||||
#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */
|
||||
#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */
|
||||
#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */
|
||||
#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */
|
||||
#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */
|
||||
#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */
|
||||
#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */
|
||||
#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */
|
||||
#define RESUNIT_NONE 1 /* no meaningful units */
|
||||
#define RESUNIT_INCH 2 /* english */
|
||||
#define RESUNIT_CENTIMETER 3 /* metric */
|
||||
#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */
|
||||
#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */
|
||||
#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */
|
||||
#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */
|
||||
#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */
|
||||
#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
|
||||
#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */
|
||||
#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */
|
||||
#define TIFFTAG_SOFTWARE 305 /* name & release */
|
||||
#define TIFFTAG_DATETIME 306 /* creation date and time */
|
||||
#define TIFFTAG_ARTIST 315 /* creator of image */
|
||||
#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */
|
||||
#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */
|
||||
#define PREDICTOR_NONE 1 /* no prediction scheme used */
|
||||
#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */
|
||||
#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */
|
||||
#define TIFFTAG_WHITEPOINT 318 /* image white point */
|
||||
#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */
|
||||
#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */
|
||||
#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */
|
||||
#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */
|
||||
#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */
|
||||
#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */
|
||||
#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */
|
||||
#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */
|
||||
#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */
|
||||
#define CLEANFAXDATA_CLEAN 0 /* no errors detected */
|
||||
#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */
|
||||
#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */
|
||||
#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */
|
||||
#define TIFFTAG_SUBIFD 330 /* subimage descriptors */
|
||||
#define TIFFTAG_INKSET 332 /* !inks in separated image */
|
||||
#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */
|
||||
#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */
|
||||
#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */
|
||||
#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */
|
||||
#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */
|
||||
#define TIFFTAG_TARGETPRINTER 337 /* !separation target */
|
||||
#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */
|
||||
#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */
|
||||
#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */
|
||||
#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */
|
||||
#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */
|
||||
#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */
|
||||
#define SAMPLEFORMAT_INT 2 /* !signed integer data */
|
||||
#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */
|
||||
#define SAMPLEFORMAT_VOID 4 /* !untyped data */
|
||||
#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */
|
||||
#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */
|
||||
#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */
|
||||
#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */
|
||||
#define TIFFTAG_CLIPPATH 343 /* %ClipPath
|
||||
[Adobe TIFF technote 2] */
|
||||
#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits
|
||||
[Adobe TIFF technote 2] */
|
||||
#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits
|
||||
[Adobe TIFF technote 2] */
|
||||
#define TIFFTAG_INDEXED 346 /* %Indexed
|
||||
[Adobe TIFF Technote 3] */
|
||||
#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
|
||||
#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
|
||||
/* Tags 400-435 are from the TIFF/FX spec */
|
||||
#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
|
||||
#define TIFFTAG_PROFILETYPE 401 /* ! */
|
||||
#define PROFILETYPE_UNSPECIFIED 0 /* ! */
|
||||
#define PROFILETYPE_G3_FAX 1 /* ! */
|
||||
#define TIFFTAG_FAXPROFILE 402 /* ! */
|
||||
#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
|
||||
#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
|
||||
#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
|
||||
#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
|
||||
#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
|
||||
#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
|
||||
#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
|
||||
#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
|
||||
#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
|
||||
#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
|
||||
#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
|
||||
#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
|
||||
#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
|
||||
#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
|
||||
#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
|
||||
#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
|
||||
#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
|
||||
#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
|
||||
/*
|
||||
* Tags 512-521 are obsoleted by Technical Note #2 which specifies a
|
||||
* revised JPEG-in-TIFF scheme.
|
||||
*/
|
||||
#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */
|
||||
#define JPEGPROC_BASELINE 1 /* !baseline sequential */
|
||||
#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */
|
||||
#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */
|
||||
#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */
|
||||
#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */
|
||||
#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */
|
||||
#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */
|
||||
#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */
|
||||
#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */
|
||||
#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */
|
||||
#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */
|
||||
#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */
|
||||
#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */
|
||||
#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
|
||||
#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
|
||||
#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
|
||||
#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
|
||||
#define TIFFTAG_XMLPACKET 700 /* %XML packet
|
||||
[Adobe XMP Specification,
|
||||
January 2004 */
|
||||
#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID
|
||||
[Adobe TIFF technote] */
|
||||
/* tags 32952-32956 are private tags registered to Island Graphics */
|
||||
#define TIFFTAG_REFPTS 32953 /* image reference points */
|
||||
#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
|
||||
#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */
|
||||
#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */
|
||||
/* tags 32995-32999 are private tags registered to SGI */
|
||||
#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */
|
||||
#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */
|
||||
#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */
|
||||
#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */
|
||||
/* tags 33300-33309 are private tags registered to Pixar */
|
||||
/*
|
||||
* TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
|
||||
* are set when an image has been cropped out of a larger image.
|
||||
* They reflect the size of the original uncropped image.
|
||||
* The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
|
||||
* to determine the position of the smaller image in the larger one.
|
||||
*/
|
||||
#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */
|
||||
#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */
|
||||
/* Tags 33302-33306 are used to identify special image modes and data
|
||||
* used by Pixar's texture formats.
|
||||
*/
|
||||
#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */
|
||||
#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */
|
||||
#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */
|
||||
#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
|
||||
#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
|
||||
/* tag 33405 is a private tag registered to Eastman Kodak */
|
||||
#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
|
||||
#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */
|
||||
#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */
|
||||
/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
|
||||
#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
|
||||
/* IPTC TAG from RichTIFF specifications */
|
||||
#define TIFFTAG_RICHTIFFIPTC 33723
|
||||
/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
|
||||
#define TIFFTAG_IT8SITE 34016 /* site name */
|
||||
#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
|
||||
#define TIFFTAG_IT8HEADER 34018 /* DDES Header */
|
||||
#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */
|
||||
#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */
|
||||
#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */
|
||||
#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */
|
||||
#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */
|
||||
#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */
|
||||
#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */
|
||||
#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */
|
||||
#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */
|
||||
#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */
|
||||
#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */
|
||||
#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */
|
||||
#define TIFFTAG_IT8TRAPINDICATOR 34031 /* Trapping indicator
|
||||
(untrapped=0, trapped=1) */
|
||||
#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
|
||||
/* tags 34232-34236 are private tags registered to Texas Instruments */
|
||||
#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
|
||||
/* tag 34377 is private tag registered to Adobe for PhotoShop */
|
||||
#define TIFFTAG_PHOTOSHOP 34377
|
||||
/* tags 34665, 34853 and 40965 are documented in EXIF specification */
|
||||
#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
|
||||
/* tag 34750 is a private tag registered to Adobe? */
|
||||
#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
|
||||
#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
|
||||
/* tag 34750 is a private tag registered to Pixel Magic */
|
||||
#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
|
||||
#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */
|
||||
/* tags 34908-34914 are private tags registered to SGI */
|
||||
#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. parms */
|
||||
#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */
|
||||
#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */
|
||||
#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */
|
||||
/* tags 37439-37443 are registered to SGI <gregl@sgi.com> */
|
||||
#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
|
||||
/* tag 34929 is a private tag registered to FedEx */
|
||||
#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
|
||||
#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */
|
||||
/* tags 50674 to 50677 are reserved for ESRI */
|
||||
#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */
|
||||
/* Adobe Digital Negative (DNG) format tags */
|
||||
#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */
|
||||
#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */
|
||||
#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */
|
||||
#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model
|
||||
name */
|
||||
#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space
|
||||
mapping */
|
||||
#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */
|
||||
#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */
|
||||
#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for
|
||||
the BlackLevel tag */
|
||||
#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */
|
||||
#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level
|
||||
differences (columns) */
|
||||
#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level
|
||||
differences (rows) */
|
||||
#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding
|
||||
level */
|
||||
#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */
|
||||
#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image
|
||||
area */
|
||||
#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image
|
||||
area */
|
||||
#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space
|
||||
transformation matrix 1 */
|
||||
#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space
|
||||
transformation matrix 2 */
|
||||
#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */
|
||||
#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */
|
||||
#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction
|
||||
matrix 1 */
|
||||
#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction
|
||||
matrix 2 */
|
||||
#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw
|
||||
values*/
|
||||
#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in
|
||||
linear reference space */
|
||||
#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in
|
||||
x-y chromaticity
|
||||
coordinates */
|
||||
#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero
|
||||
point */
|
||||
#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */
|
||||
#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of
|
||||
sharpening */
|
||||
#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of
|
||||
the green pixels in the
|
||||
blue/green rows track the
|
||||
values of the green pixels
|
||||
in the red/green rows */
|
||||
#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */
|
||||
#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */
|
||||
#define TIFFTAG_LENSINFO 50736 /* info about the lens */
|
||||
#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */
|
||||
#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the
|
||||
camera's anti-alias filter */
|
||||
#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */
|
||||
#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */
|
||||
#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote
|
||||
tag is safe to preserve
|
||||
along with the rest of the
|
||||
EXIF data */
|
||||
#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */
|
||||
#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */
|
||||
#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */
|
||||
#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for
|
||||
the raw image data */
|
||||
#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original
|
||||
raw file */
|
||||
#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original
|
||||
raw file */
|
||||
#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels
|
||||
of the sensor */
|
||||
#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates
|
||||
of fully masked pixels */
|
||||
#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */
|
||||
#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space
|
||||
into ICC profile space */
|
||||
#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
|
||||
#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
|
||||
/* tag 65535 is an undefined tag used by Eastman Kodak */
|
||||
#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
|
||||
|
||||
/*
|
||||
* The following are ``pseudo tags'' that can be used to control
|
||||
* codec-specific functionality. These tags are not written to file.
|
||||
* Note that these values start at 0xffff+1 so that they'll never
|
||||
* collide with Aldus-assigned tags.
|
||||
*
|
||||
* If you want your private pseudo tags ``registered'' (i.e. added to
|
||||
* this file), please post a bug report via the tracking system at
|
||||
* http://www.remotesensing.org/libtiff/bugs.html with the appropriate
|
||||
* C definitions to add.
|
||||
*/
|
||||
#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */
|
||||
#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */
|
||||
#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */
|
||||
#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */
|
||||
#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */
|
||||
#define FAXMODE_WORDALIGN 0x0008 /* word align row */
|
||||
#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */
|
||||
#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */
|
||||
/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */
|
||||
#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */
|
||||
#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */
|
||||
#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */
|
||||
#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */
|
||||
#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */
|
||||
#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */
|
||||
/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
|
||||
#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */
|
||||
#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */
|
||||
#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */
|
||||
#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */
|
||||
#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */
|
||||
#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */
|
||||
#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */
|
||||
#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */
|
||||
/* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */
|
||||
#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */
|
||||
#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */
|
||||
#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */
|
||||
#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */
|
||||
#define DCSIMAGERFILTER_IR 0 /* infrared filter */
|
||||
#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */
|
||||
#define DCSIMAGERFILTER_CFA 2 /* color filter array */
|
||||
#define DCSIMAGERFILTER_OTHER 3 /* other filter */
|
||||
#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */
|
||||
#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */
|
||||
#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */
|
||||
#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */
|
||||
#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */
|
||||
#define TIFFTAG_DCSGAMMA 65554 /* gamma value */
|
||||
#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */
|
||||
#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */
|
||||
/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
|
||||
#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */
|
||||
#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */
|
||||
/* 65559 is allocated to Oceana Matrix <dev@oceana.com> */
|
||||
#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */
|
||||
#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */
|
||||
#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */
|
||||
#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */
|
||||
#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */
|
||||
#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */
|
||||
#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/
|
||||
#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/
|
||||
#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */
|
||||
#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */
|
||||
#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */
|
||||
#define PERSAMPLE_MERGED 0 /* present as a single value */
|
||||
#define PERSAMPLE_MULTI 1 /* present as multiple values */
|
||||
#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */
|
||||
#define TIFFTAG_LERC_VERSION 65565 /* LERC version */
|
||||
#define LERC_VERSION_2_4 4
|
||||
#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */
|
||||
#define LERC_ADD_COMPRESSION_NONE 0
|
||||
#define LERC_ADD_COMPRESSION_DEFLATE 1
|
||||
#define LERC_ADD_COMPRESSION_ZSTD 2
|
||||
#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */
|
||||
#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level: WARNING not registered in Adobe-maintained registry */
|
||||
#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy : WARNING not registered in Adobe-maintained registry */
|
||||
|
||||
/*
|
||||
* EXIF tags
|
||||
*/
|
||||
#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */
|
||||
#define EXIFTAG_FNUMBER 33437 /* F number */
|
||||
#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
|
||||
#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
|
||||
#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
|
||||
#define EXIFTAG_OECF 34856 /* Optoelectric conversion
|
||||
factor */
|
||||
#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
|
||||
#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original
|
||||
data generation */
|
||||
#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital
|
||||
data generation */
|
||||
#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */
|
||||
#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
|
||||
#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
|
||||
#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */
|
||||
#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */
|
||||
#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */
|
||||
#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
|
||||
#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */
|
||||
#define EXIFTAG_METERINGMODE 37383 /* Metering mode */
|
||||
#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */
|
||||
#define EXIFTAG_FLASH 37385 /* Flash */
|
||||
#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */
|
||||
#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */
|
||||
#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */
|
||||
#define EXIFTAG_USERCOMMENT 37510 /* User comments */
|
||||
#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */
|
||||
#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */
|
||||
#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */
|
||||
#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */
|
||||
#define EXIFTAG_COLORSPACE 40961 /* Color space information */
|
||||
#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */
|
||||
#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */
|
||||
#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */
|
||||
#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */
|
||||
#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */
|
||||
#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */
|
||||
#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */
|
||||
#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */
|
||||
#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */
|
||||
#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */
|
||||
#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */
|
||||
#define EXIFTAG_FILESOURCE 41728 /* File source */
|
||||
#define EXIFTAG_SCENETYPE 41729 /* Scene type */
|
||||
#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */
|
||||
#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */
|
||||
#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */
|
||||
#define EXIFTAG_WHITEBALANCE 41987 /* White balance */
|
||||
#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */
|
||||
#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */
|
||||
#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */
|
||||
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
|
||||
#define EXIFTAG_CONTRAST 41992 /* Contrast */
|
||||
#define EXIFTAG_SATURATION 41993 /* Saturation */
|
||||
#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
|
||||
#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
|
||||
#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
|
||||
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
|
||||
#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
|
||||
#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
|
||||
|
||||
#endif /* _TIFF_ */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
119
libs/libtiff/tiffconf.h
Normal file
119
libs/libtiff/tiffconf.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* libtiff/tiffconf.h. Generated from tiffconf.h.in by configure. */
|
||||
/*
|
||||
Configuration defines for installed libtiff.
|
||||
This file maintained for backward compatibility. Do not use definitions
|
||||
from this file in your programs.
|
||||
*/
|
||||
|
||||
#ifndef _TIFFCONF_
|
||||
#define _TIFFCONF_
|
||||
|
||||
/* Signed 16-bit type */
|
||||
#define TIFF_INT16_T signed short
|
||||
|
||||
/* Signed 32-bit type */
|
||||
#define TIFF_INT32_T signed int
|
||||
|
||||
/* Signed 64-bit type */
|
||||
#define TIFF_INT64_T signed long long
|
||||
|
||||
/* Signed 8-bit type */
|
||||
#define TIFF_INT8_T signed char
|
||||
|
||||
/* Unsigned 16-bit type */
|
||||
#define TIFF_UINT16_T unsigned short
|
||||
|
||||
/* Unsigned 32-bit type */
|
||||
#define TIFF_UINT32_T unsigned int
|
||||
|
||||
/* Unsigned 64-bit type */
|
||||
#define TIFF_UINT64_T unsigned long long
|
||||
|
||||
/* Unsigned 8-bit type */
|
||||
#define TIFF_UINT8_T unsigned char
|
||||
|
||||
/* Signed size type */
|
||||
#define TIFF_SSIZE_T signed int
|
||||
|
||||
/* Pointer difference type */
|
||||
#define TIFF_PTRDIFF_T ptrdiff_t
|
||||
|
||||
/* Compatibility stuff. */
|
||||
|
||||
/* Define as 0 or 1 according to the floating point format suported by the
|
||||
machine */
|
||||
#define HAVE_IEEEFP 1
|
||||
|
||||
/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
|
||||
#define HOST_FILLORDER FILLORDER_MSB2LSB
|
||||
|
||||
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
|
||||
(Intel) */
|
||||
#define HOST_BIGENDIAN 0
|
||||
|
||||
/* Support CCITT Group 3 & 4 algorithms */
|
||||
#define CCITT_SUPPORT 1
|
||||
|
||||
/* Support JPEG compression (requires IJG JPEG library) */
|
||||
#define JPEG_SUPPORT 1
|
||||
|
||||
/* Support JBIG compression (requires JBIG-KIT library) */
|
||||
/* #undef JBIG_SUPPORT */
|
||||
|
||||
/* Support LogLuv high dynamic range encoding */
|
||||
#define LOGLUV_SUPPORT 1
|
||||
|
||||
/* Support LZW algorithm */
|
||||
#define LZW_SUPPORT 1
|
||||
|
||||
/* Support NeXT 2-bit RLE algorithm */
|
||||
#define NEXT_SUPPORT 1
|
||||
|
||||
/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
|
||||
fails with unpatched IJG JPEG library) */
|
||||
#define OJPEG_SUPPORT 1
|
||||
|
||||
/* Support Macintosh PackBits algorithm */
|
||||
#define PACKBITS_SUPPORT 1
|
||||
|
||||
/* Support Pixar log-format algorithm (requires Zlib) */
|
||||
#define PIXARLOG_SUPPORT 1
|
||||
|
||||
/* Support ThunderScan 4-bit RLE algorithm */
|
||||
#define THUNDER_SUPPORT 1
|
||||
|
||||
/* Support Deflate compression */
|
||||
#define ZIP_SUPPORT 1
|
||||
|
||||
/* Support strip chopping (whether or not to convert single-strip uncompressed
|
||||
images to mutiple strips of ~8Kb to reduce memory usage) */
|
||||
#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
|
||||
|
||||
/* Enable SubIFD tag (330) support */
|
||||
#define SUBIFD_SUPPORT 1
|
||||
|
||||
/* Treat extra sample as alpha (default enabled). The RGBA interface will
|
||||
treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
|
||||
packages produce RGBA files but don't mark the alpha properly. */
|
||||
#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
|
||||
|
||||
/* Pick up YCbCr subsampling info from the JPEG data stream to support files
|
||||
lacking the tag (default enabled). */
|
||||
#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
|
||||
|
||||
/* Support MS MDI magic number files as TIFF */
|
||||
#define MDI_SUPPORT 1
|
||||
|
||||
/*
|
||||
* Feature support definitions.
|
||||
* XXX: These macros are obsoleted. Don't use them in your apps!
|
||||
* Macros stays here for backward compatibility and should be always defined.
|
||||
*/
|
||||
#define COLORIMETRY_SUPPORT
|
||||
#define YCBCR_SUPPORT
|
||||
#define CMYK_SUPPORT
|
||||
#define ICC_SUPPORT
|
||||
#define PHOTOSHOP_SUPPORT
|
||||
#define IPTC_SUPPORT
|
||||
|
||||
#endif /* _TIFFCONF_ */
|
568
libs/libtiff/tiffio.h
Normal file
568
libs/libtiff/tiffio.h
Normal file
@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _TIFFIO_
|
||||
#define _TIFFIO_
|
||||
|
||||
/*
|
||||
* TIFF I/O Library Definitions.
|
||||
*/
|
||||
#include "tiff.h"
|
||||
#include "tiffvers.h"
|
||||
|
||||
/*
|
||||
* TIFF is defined as an incomplete type to hide the
|
||||
* library's internal data structures from clients.
|
||||
*/
|
||||
typedef struct tiff TIFF;
|
||||
|
||||
/*
|
||||
* The following typedefs define the intrinsic size of
|
||||
* data types used in the *exported* interfaces. These
|
||||
* definitions depend on the proper definition of types
|
||||
* in tiff.h. Note also that the varargs interface used
|
||||
* to pass tag types and values uses the types defined in
|
||||
* tiff.h directly.
|
||||
*
|
||||
* NB: ttag_t is unsigned int and not unsigned short because
|
||||
* ANSI C requires that the type before the ellipsis be a
|
||||
* promoted type (i.e. one of int, unsigned int, pointer,
|
||||
* or double) and because we defined pseudo-tags that are
|
||||
* outside the range of legal Aldus-assigned tags.
|
||||
* NB: tsize_t is signed and not unsigned because some functions
|
||||
* return -1.
|
||||
* NB: toff_t is not off_t for many reasons; TIFFs max out at
|
||||
* 32-bit file offsets, and BigTIFF maxes out at 64-bit
|
||||
* offsets being the most important, and to ensure use of
|
||||
* a consistently unsigned type across architectures.
|
||||
* Prior to libtiff 4.0, this was an unsigned 32 bit type.
|
||||
*/
|
||||
/*
|
||||
* this is the machine addressing size type, only it's signed, so make it
|
||||
* int32 on 32bit machines, int64 on 64bit machines
|
||||
*/
|
||||
typedef TIFF_SSIZE_T tmsize_t;
|
||||
typedef uint64 toff_t; /* file offset */
|
||||
/* the following are deprecated and should be replaced by their defining
|
||||
counterparts */
|
||||
typedef uint32 ttag_t; /* directory tag */
|
||||
typedef uint16 tdir_t; /* directory index */
|
||||
typedef uint16 tsample_t; /* sample number */
|
||||
typedef uint32 tstrile_t; /* strip or tile number */
|
||||
typedef tstrile_t tstrip_t; /* strip number */
|
||||
typedef tstrile_t ttile_t; /* tile number */
|
||||
typedef tmsize_t tsize_t; /* i/o size in bytes */
|
||||
typedef void* tdata_t; /* image data ref */
|
||||
|
||||
#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
|
||||
#define __WIN32__
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
|
||||
* or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
|
||||
*
|
||||
* By default tif_unix.c is assumed.
|
||||
*/
|
||||
|
||||
#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
|
||||
# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO)
|
||||
# define AVOID_WIN32_FILEIO
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_WIN32_FILEIO)
|
||||
# define VC_EXTRALEAN
|
||||
# include <windows.h>
|
||||
# ifdef __WIN32__
|
||||
DECLARE_HANDLE(thandle_t); /* Win32 file handle */
|
||||
# else
|
||||
typedef HFILE thandle_t; /* client data handle */
|
||||
# endif /* __WIN32__ */
|
||||
#else
|
||||
typedef void* thandle_t; /* client data handle */
|
||||
#endif /* USE_WIN32_FILEIO */
|
||||
|
||||
/*
|
||||
* Flags to pass to TIFFPrintDirectory to control
|
||||
* printing of data structures that are potentially
|
||||
* very large. Bit-or these flags to enable printing
|
||||
* multiple items.
|
||||
*/
|
||||
#define TIFFPRINT_NONE 0x0 /* no extra info */
|
||||
#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */
|
||||
#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */
|
||||
#define TIFFPRINT_COLORMAP 0x4 /* colormap */
|
||||
#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */
|
||||
#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */
|
||||
#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */
|
||||
|
||||
/*
|
||||
* Colour conversion stuff
|
||||
*/
|
||||
|
||||
/* reference white */
|
||||
#define D65_X0 (95.0470F)
|
||||
#define D65_Y0 (100.0F)
|
||||
#define D65_Z0 (108.8827F)
|
||||
|
||||
#define D50_X0 (96.4250F)
|
||||
#define D50_Y0 (100.0F)
|
||||
#define D50_Z0 (82.4680F)
|
||||
|
||||
/* Structure for holding information about a display device. */
|
||||
|
||||
typedef unsigned char TIFFRGBValue; /* 8-bit samples */
|
||||
|
||||
typedef struct {
|
||||
float d_mat[3][3]; /* XYZ -> luminance matrix */
|
||||
float d_YCR; /* Light o/p for reference white */
|
||||
float d_YCG;
|
||||
float d_YCB;
|
||||
uint32 d_Vrwr; /* Pixel values for ref. white */
|
||||
uint32 d_Vrwg;
|
||||
uint32 d_Vrwb;
|
||||
float d_Y0R; /* Residual light for black pixel */
|
||||
float d_Y0G;
|
||||
float d_Y0B;
|
||||
float d_gammaR; /* Gamma values for the three guns */
|
||||
float d_gammaG;
|
||||
float d_gammaB;
|
||||
} TIFFDisplay;
|
||||
|
||||
typedef struct { /* YCbCr->RGB support */
|
||||
TIFFRGBValue* clamptab; /* range clamping table */
|
||||
int* Cr_r_tab;
|
||||
int* Cb_b_tab;
|
||||
int32* Cr_g_tab;
|
||||
int32* Cb_g_tab;
|
||||
int32* Y_tab;
|
||||
} TIFFYCbCrToRGB;
|
||||
|
||||
typedef struct { /* CIE Lab 1976->RGB support */
|
||||
int range; /* Size of conversion table */
|
||||
#define CIELABTORGB_TABLE_RANGE 1500
|
||||
float rstep, gstep, bstep;
|
||||
float X0, Y0, Z0; /* Reference white point */
|
||||
TIFFDisplay display;
|
||||
float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */
|
||||
float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */
|
||||
float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */
|
||||
} TIFFCIELabToRGB;
|
||||
|
||||
/*
|
||||
* RGBA-style image support.
|
||||
*/
|
||||
typedef struct _TIFFRGBAImage TIFFRGBAImage;
|
||||
/*
|
||||
* The image reading and conversion routines invoke
|
||||
* ``put routines'' to copy/image/whatever tiles of
|
||||
* raw image data. A default set of routines are
|
||||
* provided to convert/copy raw image data to 8-bit
|
||||
* packed ABGR format rasters. Applications can supply
|
||||
* alternate routines that unpack the data into a
|
||||
* different format or, for example, unpack the data
|
||||
* and draw the unpacked raster on the display.
|
||||
*/
|
||||
typedef void (*tileContigRoutine)
|
||||
(TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
|
||||
unsigned char*);
|
||||
typedef void (*tileSeparateRoutine)
|
||||
(TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
|
||||
unsigned char*, unsigned char*, unsigned char*, unsigned char*);
|
||||
/*
|
||||
* RGBA-reader state.
|
||||
*/
|
||||
struct _TIFFRGBAImage {
|
||||
TIFF* tif; /* image handle */
|
||||
int stoponerr; /* stop on read error */
|
||||
int isContig; /* data is packed/separate */
|
||||
int alpha; /* type of alpha data present */
|
||||
uint32 width; /* image width */
|
||||
uint32 height; /* image height */
|
||||
uint16 bitspersample; /* image bits/sample */
|
||||
uint16 samplesperpixel; /* image samples/pixel */
|
||||
uint16 orientation; /* image orientation */
|
||||
uint16 req_orientation; /* requested orientation */
|
||||
uint16 photometric; /* image photometric interp */
|
||||
uint16* redcmap; /* colormap palette */
|
||||
uint16* greencmap;
|
||||
uint16* bluecmap;
|
||||
/* get image data routine */
|
||||
int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
|
||||
/* put decoded strip/tile */
|
||||
union {
|
||||
void (*any)(TIFFRGBAImage*);
|
||||
tileContigRoutine contig;
|
||||
tileSeparateRoutine separate;
|
||||
} put;
|
||||
TIFFRGBValue* Map; /* sample mapping array */
|
||||
uint32** BWmap; /* black&white map */
|
||||
uint32** PALmap; /* palette image map */
|
||||
TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */
|
||||
TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */
|
||||
|
||||
uint8* UaToAa; /* Unassociated alpha to associated alpha conversion LUT */
|
||||
uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
|
||||
|
||||
int row_offset;
|
||||
int col_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for extracting components from the
|
||||
* packed ABGR form returned by TIFFReadRGBAImage.
|
||||
*/
|
||||
#define TIFFGetR(abgr) ((abgr) & 0xff)
|
||||
#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
|
||||
#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
|
||||
#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
|
||||
|
||||
/*
|
||||
* A CODEC is a software package that implements decoding,
|
||||
* encoding, or decoding+encoding of a compression algorithm.
|
||||
* The library provides a collection of builtin codecs.
|
||||
* More codecs may be registered through calls to the library
|
||||
* and/or the builtin implementations may be overridden.
|
||||
*/
|
||||
typedef int (*TIFFInitMethod)(TIFF*, int);
|
||||
typedef struct {
|
||||
char* name;
|
||||
uint16 scheme;
|
||||
TIFFInitMethod init;
|
||||
} TIFFCodec;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* share internal LogLuv conversion routines? */
|
||||
#ifndef LOGLUV_PUBLIC
|
||||
#define LOGLUV_PUBLIC 1
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||
# define __attribute__(x) /*nothing*/
|
||||
#endif
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef void (*TIFFErrorHandler)(const char*, const char*, va_list);
|
||||
typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list);
|
||||
typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t);
|
||||
typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
|
||||
typedef int (*TIFFCloseProc)(thandle_t);
|
||||
typedef toff_t (*TIFFSizeProc)(thandle_t);
|
||||
typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size);
|
||||
typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size);
|
||||
typedef void (*TIFFExtendProc)(TIFF*);
|
||||
|
||||
extern const char* TIFFGetVersion(void);
|
||||
|
||||
extern const TIFFCodec* TIFFFindCODEC(uint16);
|
||||
extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
|
||||
extern void TIFFUnRegisterCODEC(TIFFCodec*);
|
||||
extern int TIFFIsCODECConfigured(uint16);
|
||||
extern TIFFCodec* TIFFGetConfiguredCODECs(void);
|
||||
|
||||
/*
|
||||
* Auxiliary functions.
|
||||
*/
|
||||
|
||||
extern void* _TIFFmalloc(tmsize_t s);
|
||||
extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz);
|
||||
extern void* _TIFFrealloc(void* p, tmsize_t s);
|
||||
extern void _TIFFmemset(void* p, int v, tmsize_t c);
|
||||
extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
|
||||
extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c);
|
||||
extern void _TIFFfree(void* p);
|
||||
|
||||
/*
|
||||
** Stuff, related to tag handling and creating custom tags.
|
||||
*/
|
||||
extern int TIFFGetTagListCount( TIFF * );
|
||||
extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index );
|
||||
|
||||
#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */
|
||||
#define TIFF_VARIABLE -1 /* marker for variable length tags */
|
||||
#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */
|
||||
#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */
|
||||
|
||||
#define FIELD_CUSTOM 65
|
||||
|
||||
typedef struct _TIFFField TIFFField;
|
||||
typedef struct _TIFFFieldArray TIFFFieldArray;
|
||||
|
||||
extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
|
||||
extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
|
||||
extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
|
||||
|
||||
extern uint32 TIFFFieldTag(const TIFFField*);
|
||||
extern const char* TIFFFieldName(const TIFFField*);
|
||||
extern TIFFDataType TIFFFieldDataType(const TIFFField*);
|
||||
extern int TIFFFieldPassCount(const TIFFField*);
|
||||
extern int TIFFFieldReadCount(const TIFFField*);
|
||||
extern int TIFFFieldWriteCount(const TIFFField*);
|
||||
|
||||
typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
|
||||
typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
|
||||
typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
|
||||
|
||||
typedef struct {
|
||||
TIFFVSetMethod vsetfield; /* tag set routine */
|
||||
TIFFVGetMethod vgetfield; /* tag get routine */
|
||||
TIFFPrintMethod printdir; /* directory print routine */
|
||||
} TIFFTagMethods;
|
||||
|
||||
extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
|
||||
extern void *TIFFGetClientInfo(TIFF *, const char *);
|
||||
extern void TIFFSetClientInfo(TIFF *, void *, const char *);
|
||||
|
||||
extern void TIFFCleanup(TIFF* tif);
|
||||
extern void TIFFClose(TIFF* tif);
|
||||
extern int TIFFFlush(TIFF* tif);
|
||||
extern int TIFFFlushData(TIFF* tif);
|
||||
extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
|
||||
extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap);
|
||||
extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...);
|
||||
extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
|
||||
extern int TIFFReadDirectory(TIFF* tif);
|
||||
extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
|
||||
extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
|
||||
extern uint64 TIFFScanlineSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFScanlineSize(TIFF* tif);
|
||||
extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFRasterScanlineSize(TIFF* tif);
|
||||
extern uint64 TIFFStripSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFStripSize(TIFF* tif);
|
||||
extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip);
|
||||
extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip);
|
||||
extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows);
|
||||
extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows);
|
||||
extern uint64 TIFFTileRowSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFTileRowSize(TIFF* tif);
|
||||
extern uint64 TIFFTileSize64(TIFF* tif);
|
||||
extern tmsize_t TIFFTileSize(TIFF* tif);
|
||||
extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows);
|
||||
extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows);
|
||||
extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request);
|
||||
extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
|
||||
extern int TIFFFileno(TIFF*);
|
||||
extern int TIFFSetFileno(TIFF*, int);
|
||||
extern thandle_t TIFFClientdata(TIFF*);
|
||||
extern thandle_t TIFFSetClientdata(TIFF*, thandle_t);
|
||||
extern int TIFFGetMode(TIFF*);
|
||||
extern int TIFFSetMode(TIFF*, int);
|
||||
extern int TIFFIsTiled(TIFF*);
|
||||
extern int TIFFIsByteSwapped(TIFF*);
|
||||
extern int TIFFIsUpSampled(TIFF*);
|
||||
extern int TIFFIsMSB2LSB(TIFF*);
|
||||
extern int TIFFIsBigEndian(TIFF*);
|
||||
extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
|
||||
extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
|
||||
extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
|
||||
extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
|
||||
extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
|
||||
extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
|
||||
extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
|
||||
extern uint32 TIFFCurrentRow(TIFF*);
|
||||
extern uint16 TIFFCurrentDirectory(TIFF*);
|
||||
extern uint16 TIFFNumberOfDirectories(TIFF*);
|
||||
extern uint64 TIFFCurrentDirOffset(TIFF*);
|
||||
extern uint32 TIFFCurrentStrip(TIFF*);
|
||||
extern uint32 TIFFCurrentTile(TIFF* tif);
|
||||
extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size);
|
||||
extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size);
|
||||
extern int TIFFSetupStrips(TIFF *);
|
||||
extern int TIFFWriteCheck(TIFF*, int, const char *);
|
||||
extern void TIFFFreeDirectory(TIFF*);
|
||||
extern int TIFFCreateDirectory(TIFF*);
|
||||
extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
|
||||
extern int TIFFCreateEXIFDirectory(TIFF*);
|
||||
extern int TIFFLastDirectory(TIFF*);
|
||||
extern int TIFFSetDirectory(TIFF*, uint16);
|
||||
extern int TIFFSetSubDirectory(TIFF*, uint64);
|
||||
extern int TIFFUnlinkDirectory(TIFF*, uint16);
|
||||
extern int TIFFSetField(TIFF*, uint32, ...);
|
||||
extern int TIFFVSetField(TIFF*, uint32, va_list);
|
||||
extern int TIFFUnsetField(TIFF*, uint32);
|
||||
extern int TIFFWriteDirectory(TIFF *);
|
||||
extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
|
||||
extern int TIFFCheckpointDirectory(TIFF *);
|
||||
extern int TIFFRewriteDirectory(TIFF *);
|
||||
extern int TIFFDeferStrileArrayWriting(TIFF *);
|
||||
extern int TIFFForceStrileArrayWriting(TIFF* );
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
|
||||
extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
|
||||
extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
|
||||
extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
|
||||
extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
|
||||
int = ORIENTATION_BOTLEFT, int = 0);
|
||||
#else
|
||||
extern void TIFFPrintDirectory(TIFF*, FILE*, long);
|
||||
extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
|
||||
extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
|
||||
extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
|
||||
extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
|
||||
#endif
|
||||
|
||||
extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
|
||||
extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
|
||||
extern int TIFFReadRGBAStripExt(TIFF*, uint32, uint32 *, int stop_on_error );
|
||||
extern int TIFFReadRGBATileExt(TIFF*, uint32, uint32, uint32 *, int stop_on_error );
|
||||
extern int TIFFRGBAImageOK(TIFF*, char [1024]);
|
||||
extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
|
||||
extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
|
||||
extern void TIFFRGBAImageEnd(TIFFRGBAImage*);
|
||||
extern TIFF* TIFFOpen(const char*, const char*);
|
||||
# ifdef __WIN32__
|
||||
extern TIFF* TIFFOpenW(const wchar_t*, const char*);
|
||||
# endif /* __WIN32__ */
|
||||
extern TIFF* TIFFFdOpen(int, const char*, const char*);
|
||||
extern TIFF* TIFFClientOpen(const char*, const char*,
|
||||
thandle_t,
|
||||
TIFFReadWriteProc, TIFFReadWriteProc,
|
||||
TIFFSeekProc, TIFFCloseProc,
|
||||
TIFFSizeProc,
|
||||
TIFFMapFileProc, TIFFUnmapFileProc);
|
||||
extern const char* TIFFFileName(TIFF*);
|
||||
extern const char* TIFFSetFileName(TIFF*, const char *);
|
||||
extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
|
||||
extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
|
||||
extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
|
||||
extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
|
||||
extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
|
||||
extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
|
||||
extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
|
||||
extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
|
||||
extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
|
||||
extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern uint32 TIFFNumberOfTiles(TIFF*);
|
||||
extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
|
||||
extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16);
|
||||
extern uint32 TIFFNumberOfStrips(TIFF*);
|
||||
extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
|
||||
extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
|
||||
extern int TIFFReadFromUserBuffer(TIFF* tif, uint32 strile,
|
||||
void* inbuf, tmsize_t insize,
|
||||
void* outbuf, tmsize_t outsize);
|
||||
extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
|
||||
extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
|
||||
extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */
|
||||
extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
|
||||
extern void TIFFSwabShort(uint16*);
|
||||
extern void TIFFSwabLong(uint32*);
|
||||
extern void TIFFSwabLong8(uint64*);
|
||||
extern void TIFFSwabFloat(float*);
|
||||
extern void TIFFSwabDouble(double*);
|
||||
extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n);
|
||||
extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
|
||||
extern void TIFFReverseBits(uint8* cp, tmsize_t n);
|
||||
extern const unsigned char* TIFFGetBitRevTable(int);
|
||||
|
||||
extern uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile);
|
||||
extern uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile);
|
||||
extern uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr);
|
||||
extern uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr);
|
||||
|
||||
#ifdef LOGLUV_PUBLIC
|
||||
#define U_NEU 0.210526316
|
||||
#define V_NEU 0.473684211
|
||||
#define UVSCALE 410.
|
||||
extern double LogL16toY(int);
|
||||
extern double LogL10toY(int);
|
||||
extern void XYZtoRGB24(float*, uint8*);
|
||||
extern int uv_decode(double*, double*, int);
|
||||
extern void LogLuv24toXYZ(uint32, float*);
|
||||
extern void LogLuv32toXYZ(uint32, float*);
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
|
||||
extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
|
||||
extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
|
||||
extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
|
||||
extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
|
||||
#else
|
||||
extern int LogL16fromY(double, int);
|
||||
extern int LogL10fromY(double, int);
|
||||
extern int uv_encode(double, double, int);
|
||||
extern uint32 LogLuv24fromXYZ(float*, int);
|
||||
extern uint32 LogLuv32fromXYZ(float*, int);
|
||||
#endif
|
||||
#endif /* LOGLUV_PUBLIC */
|
||||
|
||||
extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
|
||||
extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
|
||||
float *, float *, float *);
|
||||
extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
|
||||
uint32 *, uint32 *, uint32 *);
|
||||
|
||||
extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
|
||||
extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
|
||||
uint32 *, uint32 *, uint32 *);
|
||||
|
||||
/****************************************************************************
|
||||
* O B S O L E T E D I N T E R F A C E S
|
||||
*
|
||||
* Don't use this stuff in your applications, it may be removed in the future
|
||||
* libtiff versions.
|
||||
****************************************************************************/
|
||||
typedef struct {
|
||||
ttag_t field_tag; /* field's tag */
|
||||
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
|
||||
short field_writecount; /* write count/TIFF_VARIABLE */
|
||||
TIFFDataType field_type; /* type of associated data */
|
||||
unsigned short field_bit; /* bit in fieldsset bit vector */
|
||||
unsigned char field_oktochange; /* if true, can change while writing */
|
||||
unsigned char field_passcount; /* if true, pass dir count on set */
|
||||
char *field_name; /* ASCII name */
|
||||
} TIFFFieldInfo;
|
||||
|
||||
extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TIFFIO_ */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 8
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
9
libs/libtiff/tiffvers.h
Normal file
9
libs/libtiff/tiffvers.h
Normal file
@ -0,0 +1,9 @@
|
||||
#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.1.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
|
||||
/*
|
||||
* This define can be used in code that requires
|
||||
* compilation-related definitions specific to a
|
||||
* version or versions of the library. Runtime
|
||||
* version checking should be done based on the
|
||||
* string returned by TIFFGetVersion.
|
||||
*/
|
||||
#define TIFFLIB_VERSION 20191103
|
30
libs/webp/COPYING
Normal file
30
libs/webp/COPYING
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) 2010, Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
503
libs/webp/decode.h
Normal file
503
libs/webp/decode.h
Normal file
@ -0,0 +1,503 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Main decoding functions for WebP images.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_WEBP_DECODE_H_
|
||||
#define WEBP_WEBP_DECODE_H_
|
||||
|
||||
#include "./types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_DECODER_ABI_VERSION 0x0209 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
|
||||
// the types are left here for reference.
|
||||
// typedef enum VP8StatusCode VP8StatusCode;
|
||||
// typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
|
||||
typedef struct WebPRGBABuffer WebPRGBABuffer;
|
||||
typedef struct WebPYUVABuffer WebPYUVABuffer;
|
||||
typedef struct WebPDecBuffer WebPDecBuffer;
|
||||
typedef struct WebPIDecoder WebPIDecoder;
|
||||
typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
|
||||
typedef struct WebPDecoderOptions WebPDecoderOptions;
|
||||
typedef struct WebPDecoderConfig WebPDecoderConfig;
|
||||
|
||||
// Return the decoder's version number, packed in hexadecimal using 8bits for
|
||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
WEBP_EXTERN int WebPGetDecoderVersion(void);
|
||||
|
||||
// Retrieve basic header information: width, height.
|
||||
// This function will also validate the header, returning true on success,
|
||||
// false otherwise. '*width' and '*height' are only valid on successful return.
|
||||
// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
|
||||
// Note: The following chunk sequences (before the raw VP8/VP8L data) are
|
||||
// considered valid by this function:
|
||||
// RIFF + VP8(L)
|
||||
// RIFF + VP8X + (optional chunks) + VP8(L)
|
||||
// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
|
||||
// with the dimensions in *width and *height. The ordering of samples in
|
||||
// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
|
||||
// The returned pointer should be deleted calling WebPFree().
|
||||
// Returns NULL in case of error.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
|
||||
// If the bitstream contains transparency, it is ignored.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
|
||||
// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
|
||||
// returned is the Y samples buffer. Upon return, *u and *v will point to
|
||||
// the U and V chroma data. These U and V buffers need NOT be passed to
|
||||
// WebPFree(), unlike the returned Y luma one. The dimension of the U and V
|
||||
// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
|
||||
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
|
||||
// have a common stride returned as '*uv_stride'.
|
||||
// Return NULL in case of error.
|
||||
// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
|
||||
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height,
|
||||
uint8_t** u, uint8_t** v,
|
||||
int* stride, int* uv_stride);
|
||||
|
||||
// These five functions are variants of the above ones, that decode the image
|
||||
// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
|
||||
// available in this buffer is indicated by 'output_buffer_size'. If this
|
||||
// storage is not sufficient (or an error occurred), NULL is returned.
|
||||
// Otherwise, output_buffer is returned, for convenience.
|
||||
// The parameter 'output_stride' specifies the distance (in bytes)
|
||||
// between scanlines. Hence, output_buffer_size is expected to be at least
|
||||
// output_stride x picture-height.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBAInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeARGBInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRAInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
// RGB and BGR variants. Here too the transparency information, if present,
|
||||
// will be dropped and ignored.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
|
||||
// into pre-allocated luma/chroma plane buffers. This function requires the
|
||||
// strides to be passed: one for the luma plane and one for each of the
|
||||
// chroma ones. The size of each plane buffer is passed as 'luma_size',
|
||||
// 'u_size' and 'v_size' respectively.
|
||||
// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
|
||||
// during decoding (or because some buffers were found to be too small).
|
||||
WEBP_EXTERN uint8_t* WebPDecodeYUVInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
uint8_t* v, size_t v_size, int v_stride);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Output colorspaces and buffer
|
||||
|
||||
// Colorspaces
|
||||
// Note: the naming describes the byte-ordering of packed samples in memory.
|
||||
// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
|
||||
// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
|
||||
// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
|
||||
// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
|
||||
// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
|
||||
// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
|
||||
// these two modes:
|
||||
// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
|
||||
// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
|
||||
|
||||
typedef enum WEBP_CSP_MODE {
|
||||
MODE_RGB = 0, MODE_RGBA = 1,
|
||||
MODE_BGR = 2, MODE_BGRA = 3,
|
||||
MODE_ARGB = 4, MODE_RGBA_4444 = 5,
|
||||
MODE_RGB_565 = 6,
|
||||
// RGB-premultiplied transparent modes (alpha value is preserved)
|
||||
MODE_rgbA = 7,
|
||||
MODE_bgrA = 8,
|
||||
MODE_Argb = 9,
|
||||
MODE_rgbA_4444 = 10,
|
||||
// YUV modes must come after RGB ones.
|
||||
MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0
|
||||
MODE_LAST = 13
|
||||
} WEBP_CSP_MODE;
|
||||
|
||||
// Some useful macros:
|
||||
static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
|
||||
return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
|
||||
mode == MODE_rgbA_4444);
|
||||
}
|
||||
|
||||
static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
|
||||
return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
|
||||
mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
|
||||
WebPIsPremultipliedMode(mode));
|
||||
}
|
||||
|
||||
static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
|
||||
return (mode < MODE_YUV);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecBuffer: Generic structure for describing the output sample buffer.
|
||||
|
||||
struct WebPRGBABuffer { // view as RGBA
|
||||
uint8_t* rgba; // pointer to RGBA samples
|
||||
int stride; // stride in bytes from one scanline to the next.
|
||||
size_t size; // total size of the *rgba buffer.
|
||||
};
|
||||
|
||||
struct WebPYUVABuffer { // view as YUVA
|
||||
uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples
|
||||
int y_stride; // luma stride
|
||||
int u_stride, v_stride; // chroma strides
|
||||
int a_stride; // alpha stride
|
||||
size_t y_size; // luma plane size
|
||||
size_t u_size, v_size; // chroma planes size
|
||||
size_t a_size; // alpha-plane size
|
||||
};
|
||||
|
||||
// Output buffer
|
||||
struct WebPDecBuffer {
|
||||
WEBP_CSP_MODE colorspace; // Colorspace.
|
||||
int width, height; // Dimensions.
|
||||
int is_external_memory; // If non-zero, 'internal_memory' pointer is not
|
||||
// used. If value is '2' or more, the external
|
||||
// memory is considered 'slow' and multiple
|
||||
// read/write will be avoided.
|
||||
union {
|
||||
WebPRGBABuffer RGBA;
|
||||
WebPYUVABuffer YUVA;
|
||||
} u; // Nameless union of buffer parameters.
|
||||
uint32_t pad[4]; // padding for later use
|
||||
|
||||
uint8_t* private_memory; // Internally allocated memory (only when
|
||||
// is_external_memory is 0). Should not be used
|
||||
// externally, but accessed via the buffer union.
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int);
|
||||
|
||||
// Initialize the structure as empty. Must be called before any other use.
|
||||
// Returns false in case of version mismatch
|
||||
static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
|
||||
return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Free any memory associated with the buffer. Must always be called last.
|
||||
// Note: doesn't free the 'buffer' structure itself.
|
||||
WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Enumeration of the status codes
|
||||
|
||||
typedef enum VP8StatusCode {
|
||||
VP8_STATUS_OK = 0,
|
||||
VP8_STATUS_OUT_OF_MEMORY,
|
||||
VP8_STATUS_INVALID_PARAM,
|
||||
VP8_STATUS_BITSTREAM_ERROR,
|
||||
VP8_STATUS_UNSUPPORTED_FEATURE,
|
||||
VP8_STATUS_SUSPENDED,
|
||||
VP8_STATUS_USER_ABORT,
|
||||
VP8_STATUS_NOT_ENOUGH_DATA
|
||||
} VP8StatusCode;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Incremental decoding
|
||||
//
|
||||
// This API allows streamlined decoding of partial data.
|
||||
// Picture can be incrementally decoded as data become available thanks to the
|
||||
// WebPIDecoder object. This object can be left in a SUSPENDED state if the
|
||||
// picture is only partially decoded, pending additional input.
|
||||
// Code example:
|
||||
//
|
||||
// WebPInitDecBuffer(&output_buffer);
|
||||
// output_buffer.colorspace = mode;
|
||||
// ...
|
||||
// WebPIDecoder* idec = WebPINewDecoder(&output_buffer);
|
||||
// while (additional_data_is_available) {
|
||||
// // ... (get additional data in some new_data[] buffer)
|
||||
// status = WebPIAppend(idec, new_data, new_data_size);
|
||||
// if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
|
||||
// break; // an error occurred.
|
||||
// }
|
||||
//
|
||||
// // The above call decodes the current available buffer.
|
||||
// // Part of the image can now be refreshed by calling
|
||||
// // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
|
||||
// }
|
||||
// WebPIDelete(idec);
|
||||
|
||||
// Creates a new incremental decoder with the supplied buffer parameter.
|
||||
// This output_buffer can be passed NULL, in which case a default output buffer
|
||||
// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
|
||||
// is kept, which means that the lifespan of 'output_buffer' must be larger than
|
||||
// that of the returned WebPIDecoder object.
|
||||
// The supplied 'output_buffer' content MUST NOT be changed between calls to
|
||||
// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
|
||||
// not set to 0. In such a case, it is allowed to modify the pointers, size and
|
||||
// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
|
||||
// within valid bounds.
|
||||
// All other fields of WebPDecBuffer MUST remain constant between calls.
|
||||
// Returns NULL if the allocation failed.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer);
|
||||
|
||||
// This function allocates and initializes an incremental-decoder object, which
|
||||
// will output the RGB/A samples specified by 'csp' into a preallocated
|
||||
// buffer 'output_buffer'. The size of this buffer is at least
|
||||
// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
|
||||
// is specified by 'output_stride'.
|
||||
// Additionally, output_buffer can be passed NULL in which case the output
|
||||
// buffer will be allocated automatically when the decoding starts. The
|
||||
// colorspace 'csp' is taken into account for allocating this buffer. All other
|
||||
// parameters are ignored.
|
||||
// Returns NULL if the allocation failed, or if some parameters are invalid.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewRGB(
|
||||
WEBP_CSP_MODE csp,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
// This function allocates and initializes an incremental-decoder object, which
|
||||
// will output the raw luma/chroma samples into a preallocated planes if
|
||||
// supplied. The luma plane is specified by its pointer 'luma', its size
|
||||
// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
|
||||
// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
|
||||
// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
|
||||
// can be pass NULL in case one is not interested in the transparency plane.
|
||||
// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
|
||||
// In this case, the output buffer will be automatically allocated (using
|
||||
// MODE_YUVA) when decoding starts. All parameters are then ignored.
|
||||
// Returns NULL if the allocation failed or if a parameter is invalid.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
uint8_t* v, size_t v_size, int v_stride,
|
||||
uint8_t* a, size_t a_size, int a_stride);
|
||||
|
||||
// Deprecated version of the above, without the alpha plane.
|
||||
// Kept for backward compatibility.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewYUV(
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
uint8_t* v, size_t v_size, int v_stride);
|
||||
|
||||
// Deletes the WebPIDecoder object and associated memory. Must always be called
|
||||
// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
|
||||
WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec);
|
||||
|
||||
// Copies and decodes the next available data. Returns VP8_STATUS_OK when
|
||||
// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
|
||||
// data is expected. Returns error in other cases.
|
||||
WEBP_EXTERN VP8StatusCode WebPIAppend(
|
||||
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
|
||||
|
||||
// A variant of the above function to be used when data buffer contains
|
||||
// partial data from the beginning. In this case data buffer is not copied
|
||||
// to the internal memory.
|
||||
// Note that the value of the 'data' pointer can change between calls to
|
||||
// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
|
||||
WEBP_EXTERN VP8StatusCode WebPIUpdate(
|
||||
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
|
||||
|
||||
// Returns the RGB/A image decoded so far. Returns NULL if output params
|
||||
// are not initialized yet. The RGB/A output type corresponds to the colorspace
|
||||
// specified during call to WebPINewDecoder() or WebPINewRGB().
|
||||
// *last_y is the index of last decoded row in raster scan order. Some pointers
|
||||
// (*last_y, *width etc.) can be NULL if corresponding information is not
|
||||
// needed. The values in these pointers are only valid on successful (non-NULL)
|
||||
// return.
|
||||
WEBP_EXTERN uint8_t* WebPIDecGetRGB(
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride);
|
||||
|
||||
// Same as above function to get a YUVA image. Returns pointer to the luma
|
||||
// plane or NULL in case of error. If there is no alpha information
|
||||
// the alpha pointer '*a' will be returned NULL.
|
||||
WEBP_EXTERN uint8_t* WebPIDecGetYUVA(
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v, uint8_t** a,
|
||||
int* width, int* height, int* stride, int* uv_stride, int* a_stride);
|
||||
|
||||
// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
|
||||
// alpha information (if present). Kept for backward compatibility.
|
||||
static WEBP_INLINE uint8_t* WebPIDecGetYUV(
|
||||
const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
|
||||
int* width, int* height, int* stride, int* uv_stride) {
|
||||
return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
|
||||
stride, uv_stride, NULL);
|
||||
}
|
||||
|
||||
// Generic call to retrieve information about the displayable area.
|
||||
// If non NULL, the left/right/width/height pointers are filled with the visible
|
||||
// rectangular area so far.
|
||||
// Returns NULL in case the incremental decoder object is in an invalid state.
|
||||
// Otherwise returns the pointer to the internal representation. This structure
|
||||
// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
|
||||
WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea(
|
||||
const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Advanced decoding parametrization
|
||||
//
|
||||
// Code sample for using the advanced decoding API
|
||||
/*
|
||||
// A) Init a configuration object
|
||||
WebPDecoderConfig config;
|
||||
CHECK(WebPInitDecoderConfig(&config));
|
||||
|
||||
// B) optional: retrieve the bitstream's features.
|
||||
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
|
||||
|
||||
// C) Adjust 'config', if needed
|
||||
config.no_fancy_upsampling = 1;
|
||||
config.output.colorspace = MODE_BGRA;
|
||||
// etc.
|
||||
|
||||
// Note that you can also make config.output point to an externally
|
||||
// supplied memory buffer, provided it's big enough to store the decoded
|
||||
// picture. Otherwise, config.output will just be used to allocate memory
|
||||
// and store the decoded picture.
|
||||
|
||||
// D) Decode!
|
||||
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
|
||||
|
||||
// E) Decoded image is now in config.output (and config.output.u.RGBA)
|
||||
|
||||
// F) Reclaim memory allocated in config's object. It's safe to call
|
||||
// this function even if the memory is external and wasn't allocated
|
||||
// by WebPDecode().
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
*/
|
||||
|
||||
// Features gathered from the bitstream
|
||||
struct WebPBitstreamFeatures {
|
||||
int width; // Width in pixels, as read from the bitstream.
|
||||
int height; // Height in pixels, as read from the bitstream.
|
||||
int has_alpha; // True if the bitstream contains an alpha channel.
|
||||
int has_animation; // True if the bitstream is an animation.
|
||||
int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
|
||||
|
||||
uint32_t pad[5]; // padding for later use
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal(
|
||||
const uint8_t*, size_t, WebPBitstreamFeatures*, int);
|
||||
|
||||
// Retrieve features from the bitstream. The *features structure is filled
|
||||
// with information gathered from the bitstream.
|
||||
// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
|
||||
// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
|
||||
// features from headers. Returns error in other cases.
|
||||
// Note: The following chunk sequences (before the raw VP8/VP8L data) are
|
||||
// considered valid by this function:
|
||||
// RIFF + VP8(L)
|
||||
// RIFF + VP8X + (optional chunks) + VP8(L)
|
||||
// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
static WEBP_INLINE VP8StatusCode WebPGetFeatures(
|
||||
const uint8_t* data, size_t data_size,
|
||||
WebPBitstreamFeatures* features) {
|
||||
return WebPGetFeaturesInternal(data, data_size, features,
|
||||
WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Decoding options
|
||||
struct WebPDecoderOptions {
|
||||
int bypass_filtering; // if true, skip the in-loop filtering
|
||||
int no_fancy_upsampling; // if true, use faster pointwise upsampler
|
||||
int use_cropping; // if true, cropping is applied _first_
|
||||
int crop_left, crop_top; // top-left position for cropping.
|
||||
// Will be snapped to even values.
|
||||
int crop_width, crop_height; // dimension of the cropping area
|
||||
int use_scaling; // if true, scaling is applied _afterward_
|
||||
int scaled_width, scaled_height; // final resolution
|
||||
int use_threads; // if true, use multi-threaded decoding
|
||||
int dithering_strength; // dithering strength (0=Off, 100=full)
|
||||
int flip; // flip output vertically
|
||||
int alpha_dithering_strength; // alpha dithering strength in [0..100]
|
||||
|
||||
uint32_t pad[5]; // padding for later use
|
||||
};
|
||||
|
||||
// Main object storing the configuration for advanced decoding.
|
||||
struct WebPDecoderConfig {
|
||||
WebPBitstreamFeatures input; // Immutable bitstream features (optional)
|
||||
WebPDecBuffer output; // Output buffer (can point to external mem)
|
||||
WebPDecoderOptions options; // Decoding options
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
|
||||
|
||||
// Initialize the configuration as empty. This function must always be
|
||||
// called first, unless WebPGetFeatures() is to be called.
|
||||
// Returns false in case of mismatched version.
|
||||
static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
|
||||
return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Instantiate a new incremental decoder object with the requested
|
||||
// configuration. The bitstream can be passed using 'data' and 'data_size'
|
||||
// parameter, in which case the features will be parsed and stored into
|
||||
// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
|
||||
// Note that 'config' can be NULL too, in which case a default configuration
|
||||
// is used. If 'config' is not NULL, it must outlive the WebPIDecoder object
|
||||
// as some references to its fields will be used. No internal copy of 'config'
|
||||
// is made.
|
||||
// The return WebPIDecoder object must always be deleted calling WebPIDelete().
|
||||
// Returns NULL in case of error (and config->status will then reflect
|
||||
// the error condition, if available).
|
||||
WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* config);
|
||||
|
||||
// Non-incremental version. This version decodes the full data at once, taking
|
||||
// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
|
||||
// if the decoding was successful). Note that 'config' cannot be NULL.
|
||||
WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_WEBP_DECODE_H_
|
546
libs/webp/encode.h
Normal file
546
libs/webp/encode.h
Normal file
@ -0,0 +1,546 @@
|
||||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// WebP encoder: main interface
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_WEBP_ENCODE_H_
|
||||
#define WEBP_WEBP_ENCODE_H_
|
||||
|
||||
#include "./types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
|
||||
// the types are left here for reference.
|
||||
// typedef enum WebPImageHint WebPImageHint;
|
||||
// typedef enum WebPEncCSP WebPEncCSP;
|
||||
// typedef enum WebPPreset WebPPreset;
|
||||
// typedef enum WebPEncodingError WebPEncodingError;
|
||||
typedef struct WebPConfig WebPConfig;
|
||||
typedef struct WebPPicture WebPPicture; // main structure for I/O
|
||||
typedef struct WebPAuxStats WebPAuxStats;
|
||||
typedef struct WebPMemoryWriter WebPMemoryWriter;
|
||||
|
||||
// Return the encoder's version number, packed in hexadecimal using 8bits for
|
||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
WEBP_EXTERN int WebPGetEncoderVersion(void);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// One-stop-shop call! No questions asked:
|
||||
|
||||
// Returns the size of the compressed data (pointed to by *output), or 0 if
|
||||
// an error occurred. The compressed data must be released by the caller
|
||||
// using the call 'WebPFree(*output)'.
|
||||
// These functions compress using the lossy format, and the quality_factor
|
||||
// can go from 0 (smaller output, lower quality) to 100 (best quality,
|
||||
// larger output).
|
||||
WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
|
||||
// These functions are the equivalent of the above, but compressing in a
|
||||
// lossless manner. Files are usually larger than lossy format, but will
|
||||
// not suffer any compression loss.
|
||||
// Note these functions, like the lossy versions, use the library's default
|
||||
// settings. For lossless this means 'exact' is disabled. RGB values in
|
||||
// transparent areas will be modified to improve compression. To avoid this,
|
||||
// use WebPEncode() and set WebPConfig::exact to 1.
|
||||
WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Coding parameters
|
||||
|
||||
// Image characteristics hint for the underlying encoder.
|
||||
typedef enum WebPImageHint {
|
||||
WEBP_HINT_DEFAULT = 0, // default preset.
|
||||
WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot
|
||||
WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting
|
||||
WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc).
|
||||
WEBP_HINT_LAST
|
||||
} WebPImageHint;
|
||||
|
||||
// Compression parameters.
|
||||
struct WebPConfig {
|
||||
int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
|
||||
float quality; // between 0 and 100. For lossy, 0 gives the smallest
|
||||
// size and 100 the largest. For lossless, this
|
||||
// parameter is the amount of effort put into the
|
||||
// compression: 0 is the fastest but gives larger
|
||||
// files compared to the slowest, but best, 100.
|
||||
int method; // quality/speed trade-off (0=fast, 6=slower-better)
|
||||
|
||||
WebPImageHint image_hint; // Hint for image type (lossless only for now).
|
||||
|
||||
int target_size; // if non-zero, set the desired target size in bytes.
|
||||
// Takes precedence over the 'compression' parameter.
|
||||
float target_PSNR; // if non-zero, specifies the minimal distortion to
|
||||
// try to achieve. Takes precedence over target_size.
|
||||
int segments; // maximum number of segments to use, in [1..4]
|
||||
int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
|
||||
int filter_strength; // range: [0 = off .. 100 = strongest]
|
||||
int filter_sharpness; // range: [0 = off .. 7 = least sharp]
|
||||
int filter_type; // filtering type: 0 = simple, 1 = strong (only used
|
||||
// if filter_strength > 0 or autofilter > 0)
|
||||
int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
|
||||
int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
|
||||
// 1 = compressed with WebP lossless). Default is 1.
|
||||
int alpha_filtering; // Predictive filtering method for alpha plane.
|
||||
// 0: none, 1: fast, 2: best. Default if 1.
|
||||
int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
|
||||
// Default is 100.
|
||||
int pass; // number of entropy-analysis passes (in [1..10]).
|
||||
|
||||
int show_compressed; // if true, export the compressed picture back.
|
||||
// In-loop filtering is not applied.
|
||||
int preprocessing; // preprocessing filter:
|
||||
// 0=none, 1=segment-smooth, 2=pseudo-random dithering
|
||||
int partitions; // log2(number of token partitions) in [0..3]. Default
|
||||
// is set to 0 for easier progressive decoding.
|
||||
int partition_limit; // quality degradation allowed to fit the 512k limit
|
||||
// on prediction modes coding (0: no degradation,
|
||||
// 100: maximum possible degradation).
|
||||
int emulate_jpeg_size; // If true, compression parameters will be remapped
|
||||
// to better match the expected output size from
|
||||
// JPEG compression. Generally, the output size will
|
||||
// be similar but the degradation will be lower.
|
||||
int thread_level; // If non-zero, try and use multi-threaded encoding.
|
||||
int low_memory; // If set, reduce memory usage (but increase CPU use).
|
||||
|
||||
int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off
|
||||
// (default)].
|
||||
int exact; // if non-zero, preserve the exact RGB values under
|
||||
// transparent area. Otherwise, discard this invisible
|
||||
// RGB information for better compression. The default
|
||||
// value is 0.
|
||||
|
||||
int use_delta_palette; // reserved for future lossless feature
|
||||
int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
|
||||
|
||||
uint32_t pad[2]; // padding for later use
|
||||
};
|
||||
|
||||
// Enumerate some predefined settings for WebPConfig, depending on the type
|
||||
// of source picture. These presets are used when calling WebPConfigPreset().
|
||||
typedef enum WebPPreset {
|
||||
WEBP_PRESET_DEFAULT = 0, // default preset.
|
||||
WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot
|
||||
WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting
|
||||
WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details
|
||||
WEBP_PRESET_ICON, // small-sized colorful images
|
||||
WEBP_PRESET_TEXT // text-like
|
||||
} WebPPreset;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
|
||||
|
||||
// Should always be called, to initialize a fresh WebPConfig structure before
|
||||
// modification. Returns false in case of version mismatch. WebPConfigInit()
|
||||
// must have succeeded before using the 'config' object.
|
||||
// Note that the default values are lossless=0 and quality=75.
|
||||
static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
|
||||
return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// This function will initialize the configuration according to a predefined
|
||||
// set of parameters (referred to by 'preset') and a given quality factor.
|
||||
// This function can be called as a replacement to WebPConfigInit(). Will
|
||||
// return false in case of error.
|
||||
static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
|
||||
WebPPreset preset, float quality) {
|
||||
return WebPConfigInitInternal(config, preset, quality,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Activate the lossless compression mode with the desired efficiency level
|
||||
// between 0 (fastest, lowest compression) and 9 (slower, best compression).
|
||||
// A good default level is '6', providing a fair tradeoff between compression
|
||||
// speed and final compressed size.
|
||||
// This function will overwrite several fields from config: 'method', 'quality'
|
||||
// and 'lossless'. Returns false in case of parameter error.
|
||||
WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level);
|
||||
|
||||
// Returns true if 'config' is non-NULL and all configuration parameters are
|
||||
// within their valid ranges.
|
||||
WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Input / Output
|
||||
// Structure for storing auxiliary statistics.
|
||||
|
||||
struct WebPAuxStats {
|
||||
int coded_size; // final size
|
||||
|
||||
float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha
|
||||
int block_count[3]; // number of intra4/intra16/skipped macroblocks
|
||||
int header_bytes[2]; // approximate number of bytes spent for header
|
||||
// and mode-partition #0
|
||||
int residual_bytes[3][4]; // approximate number of bytes spent for
|
||||
// DC/AC/uv coefficients for each (0..3) segments.
|
||||
int segment_size[4]; // number of macroblocks in each segments
|
||||
int segment_quant[4]; // quantizer values for each segments
|
||||
int segment_level[4]; // filtering strength for each segments [0..63]
|
||||
|
||||
int alpha_data_size; // size of the transparency data
|
||||
int layer_data_size; // size of the enhancement layer data
|
||||
|
||||
// lossless encoder statistics
|
||||
uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
|
||||
// bit2:subtract-green bit3:color indexing
|
||||
int histogram_bits; // number of precision bits of histogram
|
||||
int transform_bits; // precision bits for transform
|
||||
int cache_bits; // number of bits for color cache lookup
|
||||
int palette_size; // number of color in palette, if used
|
||||
int lossless_size; // final lossless size
|
||||
int lossless_hdr_size; // lossless header (transform, huffman etc) size
|
||||
int lossless_data_size; // lossless image data size
|
||||
|
||||
uint32_t pad[2]; // padding for later use
|
||||
};
|
||||
|
||||
// Signature for output function. Should return true if writing was successful.
|
||||
// data/data_size is the segment of data to write, and 'picture' is for
|
||||
// reference (and so one can make use of picture->custom_ptr).
|
||||
typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* picture);
|
||||
|
||||
// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
|
||||
// the following WebPMemoryWriter object (to be set as a custom_ptr).
|
||||
struct WebPMemoryWriter {
|
||||
uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
|
||||
size_t size; // final size
|
||||
size_t max_size; // total capacity
|
||||
uint32_t pad[1]; // padding for later use
|
||||
};
|
||||
|
||||
// The following must be called first before any use.
|
||||
WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer);
|
||||
|
||||
// The following must be called to deallocate writer->mem memory. The 'writer'
|
||||
// object itself is not deallocated.
|
||||
WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer);
|
||||
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
|
||||
// completion, writer.mem and writer.size will hold the coded data.
|
||||
// writer.mem must be freed by calling WebPMemoryWriterClear.
|
||||
WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* picture);
|
||||
|
||||
// Progress hook, called from time to time to report progress. It can return
|
||||
// false to request an abort of the encoding process, or true otherwise if
|
||||
// everything is OK.
|
||||
typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
|
||||
|
||||
// Color spaces.
|
||||
typedef enum WebPEncCSP {
|
||||
// chroma sampling
|
||||
WEBP_YUV420 = 0, // 4:2:0
|
||||
WEBP_YUV420A = 4, // alpha channel variant
|
||||
WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors
|
||||
WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present
|
||||
} WebPEncCSP;
|
||||
|
||||
// Encoding error conditions.
|
||||
typedef enum WebPEncodingError {
|
||||
VP8_ENC_OK = 0,
|
||||
VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects
|
||||
VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits
|
||||
VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL
|
||||
VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid
|
||||
VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height
|
||||
VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k
|
||||
VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M
|
||||
VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes
|
||||
VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G
|
||||
VP8_ENC_ERROR_USER_ABORT, // abort request by user
|
||||
VP8_ENC_ERROR_LAST // list terminator. always last.
|
||||
} WebPEncodingError;
|
||||
|
||||
// maximum width/height allowed (inclusive), in pixels
|
||||
#define WEBP_MAX_DIMENSION 16383
|
||||
|
||||
// Main exchange structure (input samples, output bytes, statistics)
|
||||
struct WebPPicture {
|
||||
// INPUT
|
||||
//////////////
|
||||
// Main flag for encoder selecting between ARGB or YUV input.
|
||||
// It is recommended to use ARGB input (*argb, argb_stride) for lossless
|
||||
// compression, and YUV input (*y, *u, *v, etc.) for lossy compression
|
||||
// since these are the respective native colorspace for these formats.
|
||||
int use_argb;
|
||||
|
||||
// YUV input (mostly used for input to lossy compression)
|
||||
WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
|
||||
int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
|
||||
uint8_t* y, *u, *v; // pointers to luma/chroma planes.
|
||||
int y_stride, uv_stride; // luma/chroma strides.
|
||||
uint8_t* a; // pointer to the alpha plane
|
||||
int a_stride; // stride of the alpha plane
|
||||
uint32_t pad1[2]; // padding for later use
|
||||
|
||||
// ARGB input (mostly used for input to lossless compression)
|
||||
uint32_t* argb; // Pointer to argb (32 bit) plane.
|
||||
int argb_stride; // This is stride in pixels units, not bytes.
|
||||
uint32_t pad2[3]; // padding for later use
|
||||
|
||||
// OUTPUT
|
||||
///////////////
|
||||
// Byte-emission hook, to store compressed bytes as they are ready.
|
||||
WebPWriterFunction writer; // can be NULL
|
||||
void* custom_ptr; // can be used by the writer.
|
||||
|
||||
// map for extra information (only for lossy compression mode)
|
||||
int extra_info_type; // 1: intra type, 2: segment, 3: quant
|
||||
// 4: intra-16 prediction mode,
|
||||
// 5: chroma prediction mode,
|
||||
// 6: bit cost, 7: distortion
|
||||
uint8_t* extra_info; // if not NULL, points to an array of size
|
||||
// ((width + 15) / 16) * ((height + 15) / 16) that
|
||||
// will be filled with a macroblock map, depending
|
||||
// on extra_info_type.
|
||||
|
||||
// STATS AND REPORTS
|
||||
///////////////////////////
|
||||
// Pointer to side statistics (updated only if not NULL)
|
||||
WebPAuxStats* stats;
|
||||
|
||||
// Error code for the latest error encountered during encoding
|
||||
WebPEncodingError error_code;
|
||||
|
||||
// If not NULL, report progress during encoding.
|
||||
WebPProgressHook progress_hook;
|
||||
|
||||
void* user_data; // this field is free to be set to any value and
|
||||
// used during callbacks (like progress-report e.g.).
|
||||
|
||||
uint32_t pad3[3]; // padding for later use
|
||||
|
||||
// Unused for now
|
||||
uint8_t* pad4, *pad5;
|
||||
uint32_t pad6[8]; // padding for later use
|
||||
|
||||
// PRIVATE FIELDS
|
||||
////////////////////
|
||||
void* memory_; // row chunk of memory for yuva planes
|
||||
void* memory_argb_; // and for argb too.
|
||||
void* pad7[2]; // padding for later use
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int);
|
||||
|
||||
// Should always be called, to initialize the structure. Returns false in case
|
||||
// of version mismatch. WebPPictureInit() must have succeeded before using the
|
||||
// 'picture' object.
|
||||
// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
|
||||
static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
|
||||
return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPPicture utils
|
||||
|
||||
// Convenience allocation / deallocation based on picture->width/height:
|
||||
// Allocate y/u/v buffers as per colorspace/width/height specification.
|
||||
// Note! This function will free the previous buffer if needed.
|
||||
// Returns false in case of memory error.
|
||||
WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture);
|
||||
|
||||
// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
|
||||
// Note that this function does _not_ free the memory used by the 'picture'
|
||||
// object itself.
|
||||
// Besides memory (which is reclaimed) all other fields of 'picture' are
|
||||
// preserved.
|
||||
WEBP_EXTERN void WebPPictureFree(WebPPicture* picture);
|
||||
|
||||
// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
|
||||
// will fully own the copied pixels (this is not a view). The 'dst' picture need
|
||||
// not be initialized as its content is overwritten.
|
||||
// Returns false in case of memory allocation error.
|
||||
WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
|
||||
|
||||
// Compute the single distortion for packed planes of samples.
|
||||
// 'src' will be compared to 'ref', and the raw distortion stored into
|
||||
// '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be
|
||||
// stored in '*result'.
|
||||
// 'x_step' is the horizontal stride (in bytes) between samples.
|
||||
// 'src/ref_stride' is the byte distance between rows.
|
||||
// Returns false in case of error (bad parameter, memory allocation error, ...).
|
||||
WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride,
|
||||
const uint8_t* ref, size_t ref_stride,
|
||||
int width, int height,
|
||||
size_t x_step,
|
||||
int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
|
||||
float* distortion, float* result);
|
||||
|
||||
// Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results
|
||||
// are in dB, stored in result[] in the B/G/R/A/All order. The distortion is
|
||||
// always performed using ARGB samples. Hence if the input is YUV(A), the
|
||||
// picture will be internally converted to ARGB (just for the measurement).
|
||||
// Warning: this function is rather CPU-intensive.
|
||||
WEBP_EXTERN int WebPPictureDistortion(
|
||||
const WebPPicture* src, const WebPPicture* ref,
|
||||
int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
|
||||
float result[5]);
|
||||
|
||||
// self-crops a picture to the rectangle defined by top/left/width/height.
|
||||
// Returns false in case of memory allocation error, or if the rectangle is
|
||||
// outside of the source picture.
|
||||
// The rectangle for the view is defined by the top-left corner pixel
|
||||
// coordinates (left, top) as well as its width and height. This rectangle
|
||||
// must be fully be comprised inside the 'src' source picture. If the source
|
||||
// picture uses the YUV420 colorspace, the top and left coordinates will be
|
||||
// snapped to even values.
|
||||
WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
|
||||
int left, int top, int width, int height);
|
||||
|
||||
// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
|
||||
// is defined by the top-left corner pixel coordinates (left, top) as well
|
||||
// as its width and height. This rectangle must be fully be comprised inside
|
||||
// the 'src' source picture. If the source picture uses the YUV420 colorspace,
|
||||
// the top and left coordinates will be snapped to even values.
|
||||
// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
|
||||
// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
|
||||
// the original dimension will be lost). Picture 'dst' need not be initialized
|
||||
// with WebPPictureInit() if it is different from 'src', since its content will
|
||||
// be overwritten.
|
||||
// Returns false in case of memory allocation error or invalid parameters.
|
||||
WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
|
||||
int left, int top, int width, int height,
|
||||
WebPPicture* dst);
|
||||
|
||||
// Returns true if the 'picture' is actually a view and therefore does
|
||||
// not own the memory for pixels.
|
||||
WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture);
|
||||
|
||||
// Rescale a picture to new dimension width x height.
|
||||
// If either 'width' or 'height' (but not both) is 0 the corresponding
|
||||
// dimension will be calculated preserving the aspect ratio.
|
||||
// No gamma correction is applied.
|
||||
// Returns false in case of error (invalid parameter or insufficient memory).
|
||||
WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height);
|
||||
|
||||
// Colorspace conversion function to import RGB samples.
|
||||
// Previous buffer will be free'd, if any.
|
||||
// *rgb buffer should have a size of at least height * rgb_stride.
|
||||
// Returns false in case of memory error.
|
||||
WEBP_EXTERN int WebPPictureImportRGB(
|
||||
WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
|
||||
// Same, but for RGBA buffer.
|
||||
WEBP_EXTERN int WebPPictureImportRGBA(
|
||||
WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
|
||||
// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
|
||||
// input buffer ignoring the alpha channel. Avoids needing to copy the data
|
||||
// to a temporary 24-bit RGB buffer to import the RGB only.
|
||||
WEBP_EXTERN int WebPPictureImportRGBX(
|
||||
WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
|
||||
|
||||
// Variants of the above, but taking BGR(A|X) input.
|
||||
WEBP_EXTERN int WebPPictureImportBGR(
|
||||
WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
|
||||
WEBP_EXTERN int WebPPictureImportBGRA(
|
||||
WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
|
||||
WEBP_EXTERN int WebPPictureImportBGRX(
|
||||
WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
|
||||
|
||||
// Converts picture->argb data to the YUV420A format. The 'colorspace'
|
||||
// parameter is deprecated and should be equal to WEBP_YUV420.
|
||||
// Upon return, picture->use_argb is set to false. The presence of real
|
||||
// non-opaque transparent values is detected, and 'colorspace' will be
|
||||
// adjusted accordingly. Note that this method is lossy.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture,
|
||||
WebPEncCSP /*colorspace = WEBP_YUV420*/);
|
||||
|
||||
// Same as WebPPictureARGBToYUVA(), but the conversion is done using
|
||||
// pseudo-random dithering with a strength 'dithering' between
|
||||
// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
|
||||
// for photographic picture.
|
||||
WEBP_EXTERN int WebPPictureARGBToYUVADithered(
|
||||
WebPPicture* picture, WebPEncCSP colorspace, float dithering);
|
||||
|
||||
// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
|
||||
// Downsampling is handled with extra care in case of color clipping. This
|
||||
// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
|
||||
// and sharper YUV representation.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture);
|
||||
// kept for backward compatibility:
|
||||
WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
|
||||
|
||||
// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
|
||||
// The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to
|
||||
// ARGB incurs a small loss too.
|
||||
// Note that the use of this colorspace is discouraged if one has access to the
|
||||
// raw ARGB samples, since using YUV420 is comparatively lossy.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture);
|
||||
|
||||
// Helper function: given a width x height plane of RGBA or YUV(A) samples
|
||||
// clean-up or smoothen the YUV or RGB samples under fully transparent area,
|
||||
// to help compressibility (no guarantee, though).
|
||||
WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture);
|
||||
|
||||
// Scan the picture 'picture' for the presence of non fully opaque alpha values.
|
||||
// Returns true in such case. Otherwise returns false (indicating that the
|
||||
// alpha plane can be ignored altogether e.g.).
|
||||
WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture);
|
||||
|
||||
// Remove the transparency information (if present) by blending the color with
|
||||
// the background color 'background_rgb' (specified as 24bit RGB triplet).
|
||||
// After this call, all alpha values are reset to 0xff.
|
||||
WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main call
|
||||
|
||||
// Main encoding call, after config and picture have been initialized.
|
||||
// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
|
||||
// and the 'config' object must be a valid one.
|
||||
// Returns false in case of error, true otherwise.
|
||||
// In case of error, picture->error_code is updated accordingly.
|
||||
// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
|
||||
// on the value of 'picture->use_argb'. It is highly recommended to use
|
||||
// the former for lossy encoding, and the latter for lossless encoding
|
||||
// (when config.lossless is true). Automatic conversion from one format to
|
||||
// another is provided but they both incur some loss.
|
||||
WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_WEBP_ENCODE_H_
|
68
libs/webp/types.h
Normal file
68
libs/webp/types.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Common types + memory wrappers
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_WEBP_TYPES_H_
|
||||
#define WEBP_WEBP_TYPES_H_
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <inttypes.h>
|
||||
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
#define WEBP_INLINE inline
|
||||
#else
|
||||
#define WEBP_INLINE
|
||||
#endif
|
||||
#else
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
typedef long long int int64_t;
|
||||
#define WEBP_INLINE __forceinline
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifndef WEBP_EXTERN
|
||||
// This explicitly marks library functions and allows for changing the
|
||||
// signature for e.g., Windows DLL builds.
|
||||
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define WEBP_EXTERN extern
|
||||
# endif /* __GNUC__ >= 4 */
|
||||
#endif /* WEBP_EXTERN */
|
||||
|
||||
// Macro to check ABI compatibility (same major revision number)
|
||||
#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Allocates 'size' bytes of memory. Returns NULL upon error. Memory
|
||||
// must be deallocated by calling WebPFree(). This function is made available
|
||||
// by the core 'libwebp' library.
|
||||
WEBP_EXTERN void* WebPMalloc(size_t size);
|
||||
|
||||
// Releases memory returned by the WebPDecode*() functions (from decode.h).
|
||||
WEBP_EXTERN void WebPFree(void* ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_WEBP_TYPES_H_
|
BIN
res/file.png
Normal file
BIN
res/file.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
res/folder.png
Normal file
BIN
res/folder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
res/image.png
Normal file
BIN
res/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
sce_sys/icon0.png
Normal file
BIN
sce_sys/icon0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 263 B |
BIN
sce_sys/livearea/contents/bg.png
Normal file
BIN
sce_sys/livearea/contents/bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
sce_sys/livearea/contents/startup.png
Normal file
BIN
sce_sys/livearea/contents/startup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 789 B |
11
sce_sys/livearea/contents/template.xml
Normal file
11
sce_sys/livearea/contents/template.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<livearea style="a1" format-ver="01.00" content-rev="1">
|
||||
<livearea-background>
|
||||
<image>bg.png</image>
|
||||
</livearea-background>
|
||||
|
||||
<gate>
|
||||
<startup-image>startup.png</startup-image>
|
||||
</gate>
|
||||
</livearea>
|
175
source/fs.cpp
Normal file
175
source/fs.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include <psp2/io/fcntl.h>
|
||||
#include <psp2/io/stat.h>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
#include "fs.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace FS {
|
||||
std::string CWD;
|
||||
|
||||
int GetFileSize(const std::string &path, SceOff *size) {
|
||||
int ret = 0;
|
||||
SceIoStat stat;
|
||||
|
||||
if (R_FAILED(ret = sceIoGetstat(path.c_str(), &stat)))
|
||||
return ret;
|
||||
|
||||
*size = stat.st_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetFileExt(const std::string &filename) {
|
||||
std::string ext = std::filesystem::path(filename).extension();
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::toupper);
|
||||
return ext;
|
||||
}
|
||||
|
||||
static SceOff CountFiles(const std::string &path) {
|
||||
int ret = 0;
|
||||
SceOff entry_count = 0;
|
||||
SceUID dir = sceIoDopen(path.c_str());
|
||||
|
||||
do {
|
||||
SceIoDirent entries;
|
||||
std::memset(&entries, 0, sizeof(SceIoDirent));
|
||||
|
||||
ret = sceIoDread(dir, &entries);
|
||||
if (ret > 0)
|
||||
entry_count++;
|
||||
} while (ret > 0);
|
||||
|
||||
sceIoDclose(dir);
|
||||
return entry_count;
|
||||
}
|
||||
|
||||
static int sort(const void *p1, const void *p2) {
|
||||
SceIoDirent *entryA = (SceIoDirent *)p1;
|
||||
SceIoDirent *entryB = (SceIoDirent *)p2;
|
||||
|
||||
if ((SCE_S_ISDIR(entryA->d_stat.st_mode)) && !(SCE_S_ISDIR(entryB->d_stat.st_mode)))
|
||||
return -1;
|
||||
else if (!(SCE_S_ISDIR(entryA->d_stat.st_mode)) && (SCE_S_ISDIR(entryB->d_stat.st_mode)))
|
||||
return 1;
|
||||
|
||||
return strcasecmp(entryA->d_name, entryB->d_name);
|
||||
}
|
||||
|
||||
SceOff GetDirList(const std::string &path, SceIoDirent **entriesp) {
|
||||
int ret = 0, i = ((path == "ux0:")? 0 : 1);
|
||||
SceOff entry_count = 0;
|
||||
SceUID dir = 0;
|
||||
|
||||
entry_count = CountFiles(path) + ((path == "ux0:")? 0 : 1);
|
||||
|
||||
if (R_FAILED(dir = sceIoDopen(path.c_str())))
|
||||
return dir;
|
||||
|
||||
SceIoDirent *entries = new SceIoDirent[entry_count * sizeof(*entries)];
|
||||
|
||||
// Add parent directory entry if not on root path
|
||||
if (path != "ux0:") {
|
||||
std::strcpy(entries[0].d_name, "..");
|
||||
entries[0].d_stat.st_mode = SCE_S_IFDIR;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = sceIoDread(dir, &entries[i]);
|
||||
i++;
|
||||
} while (ret > 0);
|
||||
|
||||
std::qsort(entries, entry_count, sizeof(SceIoDirent), sort);
|
||||
|
||||
if (R_FAILED(ret = sceIoDclose(dir))) {
|
||||
delete entries;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*entriesp = entries;
|
||||
return entry_count;
|
||||
}
|
||||
|
||||
//TODO: Clean up change directory impl.
|
||||
static SceOff ChangeDir(const std::string &path, SceIoDirent **entries) {
|
||||
SceIoDirent *new_entries;
|
||||
|
||||
SceOff num_entries = GetDirList(path, &new_entries);
|
||||
if (num_entries < 0)
|
||||
return -1;
|
||||
|
||||
// Free entries and change the current working directory.
|
||||
delete *entries;
|
||||
CWD = path;
|
||||
*entries = new_entries;
|
||||
return num_entries;
|
||||
}
|
||||
|
||||
static int ChangeDirUp(char path[256]) {
|
||||
if (CWD.length() <= 1 && CWD.c_str()[0] == '/')
|
||||
return -1;
|
||||
|
||||
// Remove upmost directory
|
||||
bool copy = false;
|
||||
int len = 0;
|
||||
for (ssize_t i = CWD.length(); i >= 0; i--) {
|
||||
if (CWD.c_str()[i] == '/')
|
||||
copy = true;
|
||||
if (copy) {
|
||||
path[i] = CWD.c_str()[i];
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
// remove trailing slash
|
||||
if (len > 1 && path[len - 1] == '/')
|
||||
len--;
|
||||
|
||||
path[len] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
SceOff ChangeDirNext(const std::string &path, SceIoDirent **entries) {
|
||||
std::string new_path = CWD;
|
||||
new_path.append("/");
|
||||
new_path.append(path);
|
||||
return ChangeDir(new_path, entries);
|
||||
}
|
||||
|
||||
SceOff ChangeDirPrev(SceIoDirent **entries) {
|
||||
char new_path[256];
|
||||
if (ChangeDirUp(new_path) < 0)
|
||||
return -1;
|
||||
|
||||
return ChangeDir(std::string(new_path), entries);
|
||||
}
|
||||
|
||||
const std::string BuildPath(SceIoDirent *entry) {
|
||||
std::string path = CWD;
|
||||
path.append("/");
|
||||
path.append(entry->d_name);
|
||||
return path;
|
||||
}
|
||||
|
||||
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size) {
|
||||
SceUID file = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_RDONLY, 0)))
|
||||
return ret;
|
||||
|
||||
*size = sceIoLseek(file, 0, SEEK_END);
|
||||
*buffer = (unsigned char *)std::malloc(*size);
|
||||
|
||||
if (R_FAILED(ret = sceIoPread(file, *buffer, *size, SCE_SEEK_SET)))
|
||||
return ret;
|
||||
|
||||
if (R_FAILED(ret = sceIoClose(file)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
265
source/gui.cpp
Normal file
265
source/gui.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
#include <imgui_vita.h>
|
||||
#include <vitaGL.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Renderer {
|
||||
static void Start(void) {
|
||||
vglStartRendering();
|
||||
ImGui_ImplVitaGL_NewFrame();
|
||||
}
|
||||
|
||||
static void End(ImVec4 clear_color) {
|
||||
glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y);
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui::Render();
|
||||
ImGui_ImplVitaGL_RenderDrawData(ImGui::GetDrawData());
|
||||
vglStopRendering();
|
||||
}
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
enum GUI_STATES {
|
||||
GUI_STATE_HOME,
|
||||
GUI_STATE_IMAGE_PREVIEW,
|
||||
GUI_STATE_GIF_PREVIEW
|
||||
};
|
||||
|
||||
static int gui_state = GUI_STATE_HOME;
|
||||
|
||||
static void ImageWindow(SceIoDirent *entry, Tex *texture) {
|
||||
ImGui::SetNextWindowPos({0.0f, 0.0f}, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowSize({960.0f, 544.0f}, ImGuiCond_Once);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
|
||||
if (ImGui::Begin(entry->d_name, nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse))
|
||||
ImGui::Image((void *)(intptr_t)texture->id, ImVec2(texture->width, texture->height));
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
static void GifWindow(SceIoDirent *entry, Tex **texture, unsigned int *frames) {
|
||||
ImGui::SetNextWindowPos({0.0f, 0.0f}, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowSize({960.0f, 544.0f}, ImGuiCond_Once);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
if (ImGui::Begin(entry->d_name, nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
|
||||
// for (unsigned int i = 0; i < *frames; i++) {
|
||||
// ImGui::Image((void *)(intptr_t)texture[i]->id, ImVec2(texture[i]->width, texture[i]->height));
|
||||
// }
|
||||
ImGui::Image((void *)(intptr_t)texture[0]->id, ImVec2(texture[0]->width, texture[0]->height));
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
static void PropertiesWindow(bool *window, const std::string &cwd, SceIoDirent *entry, Tex *texture) {
|
||||
ImGui::OpenPopup("Properties");
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
|
||||
if (ImGui::BeginPopupModal("Properties", window, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
std::string parent_text = "Parent: ";
|
||||
parent_text.append(cwd);
|
||||
ImGui::Text(parent_text.c_str());
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
std::string name_text = "Name: ";
|
||||
name_text.append(entry->d_name);
|
||||
ImGui::Text(name_text.c_str());
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (!SCE_S_ISDIR(entry->d_stat.st_mode)) {
|
||||
char size[16];
|
||||
Utils::GetSizeString(size, (double)entry->d_stat.st_size);
|
||||
std::string size_text = "Size: ";
|
||||
size_text.append(size);
|
||||
ImGui::Text(size_text.c_str());
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
std::string width_text = "Width: ";
|
||||
width_text.append(std::to_string(texture->width));
|
||||
width_text.append("px");
|
||||
ImGui::Text(width_text.c_str());
|
||||
ImGui::SameLine(0.0f, 10.0f);
|
||||
ImGui::Button("Edit width");
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
std::string height_text = "Height: ";
|
||||
height_text.append(std::to_string(texture->height));
|
||||
height_text.append("px");
|
||||
ImGui::Text(height_text.c_str());
|
||||
ImGui::SameLine(0.0f, 10.0f);
|
||||
ImGui::Button("Edit height");
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::Button("OK", ImVec2(120, 0))) {
|
||||
*window = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void MainMenu(void) {
|
||||
bool window = true, properties_window = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
FS::CWD = "ux0:";
|
||||
SceIoDirent *entries;
|
||||
SceOff entry_count = FS::GetDirList(FS::CWD, &entries);
|
||||
SceOff selected = 0;
|
||||
|
||||
Tex texture; // Common image formats
|
||||
Tex *textures; // GIFs
|
||||
unsigned int frames = 0; // GIFs
|
||||
|
||||
while (window) {
|
||||
Renderer::Start();
|
||||
|
||||
ImGui::SetNextWindowPos({0.0f, 0.0f}, ImGuiCond_Once);
|
||||
ImGui::SetNextWindowSize({960.0f, 544.0f}, ImGuiCond_Once);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
|
||||
if (ImGui::Begin("VITAlbum", &window, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
|
||||
ImGui::TextColored(ImVec4(1.00f, 1.00f, 1.00f, 1.00f), FS::CWD.c_str());
|
||||
|
||||
ImGui::BeginChild("##FS::GetDirList");
|
||||
for (SceOff i = 0; i < entry_count; i++) {
|
||||
if (SCE_S_ISDIR(entries[i].d_stat.st_mode))
|
||||
ImGui::Image((void *)(intptr_t)folder_texture.id, ImVec2(folder_texture.width, folder_texture.height));
|
||||
else {
|
||||
std::string filename = entries[i].d_name;
|
||||
std::string ext = FS::GetFileExt(filename);
|
||||
|
||||
if ((ext == ".BMP") || (ext == ".GIF") || (ext == ".ICO") || (ext == ".JPG") || (ext == ".JPEG") || (ext == ".PCX")
|
||||
|| (ext == ".PNG") || (ext == ".PGM") || (ext == ".PPM") || (ext == ".TGA") || (ext == ".TIFF") || (ext == ".WEBP"))
|
||||
ImGui::Image((void *)(intptr_t)image_texture.id, ImVec2(image_texture.width, image_texture.height));
|
||||
else
|
||||
ImGui::Image((void *)(intptr_t)file_texture.id, ImVec2(file_texture.width, file_texture.height));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Selectable(entries[i].d_name)) {
|
||||
if (SCE_S_ISDIR(entries[i].d_stat.st_mode)) {
|
||||
std::string filename = entries[i].d_name;
|
||||
if (filename == "..")
|
||||
entry_count = FS::ChangeDirPrev(&entries);
|
||||
else
|
||||
entry_count = FS::ChangeDirNext(filename, &entries);
|
||||
GImGui->NavId = 0;
|
||||
}
|
||||
else {
|
||||
std::string path = FS::BuildPath(&entries[i]);
|
||||
std::string ext = FS::GetFileExt(path);
|
||||
|
||||
if (ext == ".BMP") {
|
||||
SceBool image_ret = Textures::LoadImageBMP(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if ((ext == ".JPG") || (ext == ".JPEG") || (ext == ".PNG") || (ext == ".PGM") || (ext == ".PPM")
|
||||
|| (ext == ".TGA")) {
|
||||
SceBool image_ret = Textures::LoadImageFile(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if (ext == ".GIF") {
|
||||
//SceBool image_ret = Textures::LoadImageGIF(path, &textures, &frames);
|
||||
//IM_ASSERT(image_ret);
|
||||
//gui_state = GUI_STATE_GIF_PREVIEW;
|
||||
SceBool image_ret = Textures::LoadImageGIF(path, &texture, &frames);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if (ext == ".ICO") {
|
||||
SceBool image_ret = Textures::LoadImageICO(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if (ext == ".PCX") {
|
||||
SceBool image_ret = Textures::LoadImagePCX(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if (ext == ".TIFF") {
|
||||
SceBool image_ret = Textures::LoadImageTIFF(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
else if (ext == ".WEBP") {
|
||||
SceBool image_ret = Textures::LoadImageWEBP(path, &texture);
|
||||
IM_ASSERT(image_ret);
|
||||
gui_state = GUI_STATE_IMAGE_PREVIEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
selected = i;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
switch (gui_state) {
|
||||
case GUI_STATE_IMAGE_PREVIEW:
|
||||
ImageWindow(&entries[selected], &texture);
|
||||
if (properties_window)
|
||||
PropertiesWindow(&properties_window, FS::CWD, &entries[selected], &texture);
|
||||
break;
|
||||
|
||||
case GUI_STATE_GIF_PREVIEW:
|
||||
GifWindow(&entries[selected], &textures, &frames);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
Renderer::End(clear_color);
|
||||
|
||||
Utils::ReadControls();
|
||||
|
||||
switch (gui_state) {
|
||||
case GUI_STATE_IMAGE_PREVIEW:
|
||||
if (pressed & SCE_CTRL_TRIANGLE)
|
||||
properties_window = !properties_window;
|
||||
|
||||
if (!properties_window) {
|
||||
if (pressed & SCE_CTRL_CANCEL) {
|
||||
Textures::Free(&texture);
|
||||
gui_state = GUI_STATE_HOME;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pressed & SCE_CTRL_CANCEL)
|
||||
properties_window = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GUI_STATE_GIF_PREVIEW:
|
||||
if (pressed & SCE_CTRL_CANCEL) {
|
||||
for (int i = 0; i < frames; i++) {
|
||||
Textures::Free(&textures[i]);
|
||||
}
|
||||
gui_state = GUI_STATE_HOME;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
42
source/log.cpp
Normal file
42
source/log.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <psp2/io/fcntl.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace Log {
|
||||
SceUID log_handle = 0;
|
||||
|
||||
int OpenHande(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = log_handle = sceIoOpen("ux0:/vpk/debug.log", SCE_O_WRONLY | SCE_O_CREAT | SCE_O_APPEND, 0777)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CloseHandle(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceIoClose(log_handle)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Debug(const char *format, ...) {
|
||||
va_list list;
|
||||
char string[1024] = {0};
|
||||
|
||||
va_start(list, format);
|
||||
int length = std::vsprintf(string, format, list);
|
||||
va_end(list);
|
||||
|
||||
int ret = 0;
|
||||
if (R_FAILED(ret = sceIoWrite(log_handle, string, length)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
109
source/main.cpp
Normal file
109
source/main.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include <imgui_vita.h>
|
||||
#include <vitaGL.h>
|
||||
|
||||
#include "gui.h"
|
||||
#include "log.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Services {
|
||||
void SetDefaultTheme(void) {
|
||||
ImGui::GetStyle().FrameRounding = 4.0f;
|
||||
ImGui::GetStyle().GrabRounding = 4.0f;
|
||||
|
||||
ImVec4 *colors = ImGui::GetStyle().Colors;
|
||||
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.00f, 0.50f, 0.50f, 1.0f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.FontGlobalScale = 1.5f;
|
||||
}
|
||||
|
||||
void Init(void) {
|
||||
// Initalize vitaGL and imGui contexts
|
||||
vglInit(0x100000);
|
||||
ImGui::CreateContext();
|
||||
ImGui_ImplVitaGL_Init();
|
||||
|
||||
// Setup style
|
||||
ImGui::StyleColorsDark();
|
||||
ImGui_ImplVitaGL_GamepadUsage(true);
|
||||
|
||||
Textures::Init();
|
||||
Log::OpenHande();
|
||||
Utils::InitAppUtil();
|
||||
SCE_CTRL_ENTER = Utils::GetEnterButton();
|
||||
SCE_CTRL_CANCEL = Utils::GetCancelButton();
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
// Clean up
|
||||
Log::Debug("Before Utils::EndAppUtil();\n");
|
||||
Utils::EndAppUtil();
|
||||
Log::Debug("Before Textures::Exit();\n");
|
||||
//Log::CloseHandle();
|
||||
Textures::Exit();
|
||||
Log::Debug("Before ImGui_ImplVitaGL_Shutdown();\n");
|
||||
ImGui_ImplVitaGL_Shutdown();
|
||||
Log::Debug("Before ImGui::DestroyContext();\n");
|
||||
ImGui::DestroyContext();
|
||||
Log::Debug("Before vglEnd();\n");
|
||||
vglEnd();
|
||||
Log::Debug("Before Log::CloseHandle();\n");
|
||||
Log::CloseHandle();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Services::Init();
|
||||
Services::SetDefaultTheme();
|
||||
GUI::MainMenu();
|
||||
Services::Exit();
|
||||
return 0;
|
||||
}
|
390
source/textures.cpp
Normal file
390
source/textures.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
// PCX
|
||||
#define DR_PCX_IMPLEMENTATION
|
||||
#define DR_PCX_NO_STDIO
|
||||
#include "dr_pcx.h"
|
||||
|
||||
// BMP
|
||||
#include "libnsbmp.h"
|
||||
|
||||
// GIF
|
||||
#include "libnsgif.h"
|
||||
|
||||
// STB
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STBI_NO_STDIO
|
||||
#define STBI_NO_BMP
|
||||
#define STBI_NO_GIF
|
||||
#define STBI_NO_HDR
|
||||
#define STBI_NO_PIC
|
||||
#define STBI_NO_PSD
|
||||
#define STBI_ONLY_JPEG
|
||||
#define STBI_ONLY_PNG
|
||||
#define STBI_ONLY_PNM
|
||||
#define STBI_ONLY_TGA
|
||||
#include "stb_image.h"
|
||||
|
||||
// TIFF
|
||||
#include "tiffio.h"
|
||||
|
||||
// WEBP
|
||||
#include "webp/decode.h"
|
||||
|
||||
#include "fs.h"
|
||||
#include "imgui.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define BYTES_PER_PIXEL 4
|
||||
#define MAX_IMAGE_BYTES (48 * 1024 * 1024)
|
||||
|
||||
Tex folder_texture, file_texture, image_texture;
|
||||
|
||||
namespace BMP {
|
||||
static void *bitmap_create(int width, int height, unsigned int state) {
|
||||
(void) state; /* unused */
|
||||
/* ensure a stupidly large (>50Megs or so) bitmap is not created */
|
||||
if (((long long)width * (long long)height) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL))
|
||||
return nullptr;
|
||||
|
||||
return calloc(width * height, BYTES_PER_PIXEL);
|
||||
}
|
||||
|
||||
static unsigned char *bitmap_get_buffer(void *bitmap) {
|
||||
assert(bitmap);
|
||||
return (unsigned char *)bitmap;
|
||||
}
|
||||
|
||||
static size_t bitmap_get_bpp(void *bitmap) {
|
||||
(void) bitmap; /* unused */
|
||||
return BYTES_PER_PIXEL;
|
||||
}
|
||||
|
||||
static void bitmap_destroy(void *bitmap) {
|
||||
assert(bitmap);
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
namespace GIF {
|
||||
static void *bitmap_create(int width, int height) {
|
||||
/* ensure a stupidly large bitmap is not created */
|
||||
if (((long long)width * (long long)height) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL))
|
||||
return nullptr;
|
||||
|
||||
return calloc(width * height, BYTES_PER_PIXEL);
|
||||
}
|
||||
|
||||
static void bitmap_set_opaque(void *bitmap, bool opaque) {
|
||||
(void) opaque; /* unused */
|
||||
(void) bitmap; /* unused */
|
||||
assert(bitmap);
|
||||
}
|
||||
|
||||
static bool bitmap_test_opaque(void *bitmap) {
|
||||
(void) bitmap; /* unused */
|
||||
assert(bitmap);
|
||||
return false;
|
||||
}
|
||||
|
||||
static unsigned char *bitmap_get_buffer(void *bitmap) {
|
||||
assert(bitmap);
|
||||
return (unsigned char *)bitmap;
|
||||
}
|
||||
|
||||
static void bitmap_destroy(void *bitmap) {
|
||||
assert(bitmap);
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
static void bitmap_modified(void *bitmap) {
|
||||
(void) bitmap; /* unused */
|
||||
assert(bitmap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ICO {
|
||||
static void *bitmap_create(int width, int height, unsigned int state) {
|
||||
(void) state; /* unused */
|
||||
return calloc(width * height, BYTES_PER_PIXEL);
|
||||
}
|
||||
|
||||
static unsigned char *bitmap_get_buffer(void *bitmap) {
|
||||
assert(bitmap);
|
||||
return (unsigned char *)bitmap;
|
||||
}
|
||||
|
||||
static size_t bitmap_get_bpp(void *bitmap) {
|
||||
(void) bitmap; /* unused */
|
||||
return BYTES_PER_PIXEL;
|
||||
}
|
||||
|
||||
static void bitmap_destroy(void *bitmap) {
|
||||
assert(bitmap);
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Textures {
|
||||
bool LoadImage(unsigned char *data, int *width, int *height, Tex *texture, void (*free_func)(void *)) {
|
||||
// Create a OpenGL texture identifier
|
||||
GLuint image;
|
||||
glGenTextures(1, &image);
|
||||
glBindTexture(GL_TEXTURE_2D, image);
|
||||
|
||||
// Setup filtering parameters for display
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Upload pixels into texture
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, *width, *height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
if (*free_func)
|
||||
free_func(data);
|
||||
|
||||
texture->id = image;
|
||||
texture->width = *width;
|
||||
texture->height = *height;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadImageFile(const std::string &path, Tex *texture) {
|
||||
unsigned char *data = nullptr;
|
||||
SceOff size = 0;
|
||||
|
||||
if (R_FAILED(FS::ReadFile(path, &data, &size)))
|
||||
return false;
|
||||
|
||||
int width = 0, height = 0;
|
||||
data = stbi_load_from_memory(data, size, &width, &height, nullptr, BYTES_PER_PIXEL);
|
||||
return LoadImage(data, &width, &height, texture, drpcx_free);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadImageBMP(const std::string &path, Tex *texture) {
|
||||
bmp_bitmap_callback_vt bitmap_callbacks = {
|
||||
BMP::bitmap_create,
|
||||
BMP::bitmap_destroy,
|
||||
BMP::bitmap_get_buffer,
|
||||
BMP::bitmap_get_bpp
|
||||
};
|
||||
|
||||
bmp_result code = BMP_OK;
|
||||
bmp_image bmp;
|
||||
unsigned char *data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
bmp_create(&bmp, &bitmap_callbacks);
|
||||
if (R_FAILED(FS::ReadFile(path, &data, (SceOff *)&size)))
|
||||
return false;
|
||||
|
||||
code = bmp_analyse(&bmp, size, data);
|
||||
if (code != BMP_OK) {
|
||||
bmp_finalise(&bmp);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
code = bmp_decode(&bmp);
|
||||
if (code != BMP_OK) {
|
||||
if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) {
|
||||
bmp_finalise(&bmp);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* skip if the decoded image would be ridiculously large */
|
||||
if ((bmp.width * bmp.height) > 200000) {
|
||||
bmp_finalise(&bmp);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LoadImage((unsigned char *)bmp.bitmap, (int *)&bmp.width, (int *)&bmp.height, texture, nullptr);
|
||||
bmp_finalise(&bmp);
|
||||
free(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadImageGIF(const std::string &path, Tex *texture, unsigned int *frames) {
|
||||
gif_bitmap_callback_vt bitmap_callbacks = {
|
||||
GIF::bitmap_create,
|
||||
GIF::bitmap_destroy,
|
||||
GIF::bitmap_get_buffer,
|
||||
GIF::bitmap_set_opaque,
|
||||
GIF::bitmap_test_opaque,
|
||||
GIF::bitmap_modified
|
||||
};
|
||||
|
||||
gif_animation gif;
|
||||
SceOff size = 0;
|
||||
gif_result code = GIF_OK;
|
||||
unsigned char *data = nullptr;
|
||||
|
||||
gif_create(&gif, &bitmap_callbacks);
|
||||
if (R_FAILED(FS::ReadFile(path, &data, &size)))
|
||||
return false;
|
||||
|
||||
do {
|
||||
code = gif_initialise(&gif, size, data);
|
||||
if (code != GIF_OK && code != GIF_WORKING) {
|
||||
gif_finalise(&gif);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
} while (code != GIF_OK);
|
||||
|
||||
//bool gif_is_animated = gif.frame_count > 1;
|
||||
bool gif_is_animated = false;
|
||||
|
||||
if (gif_is_animated) {
|
||||
*frames = gif.frame_count;
|
||||
|
||||
for (unsigned int i = 0; i < gif.frame_count; i++) {
|
||||
code = gif_decode_frame(&gif, i);
|
||||
if (code != GIF_OK) {
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
//LoadImage((unsigned char *)gif.frame_image, (int *)&gif.width, (int *)&gif.height, texture[i], nullptr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = gif_decode_frame(&gif, 0);
|
||||
if (code != GIF_OK) {
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadImage((unsigned char *)gif.frame_image, (int *)&gif.width, (int *)&gif.height, texture, nullptr);
|
||||
}
|
||||
|
||||
gif_finalise(&gif);
|
||||
free(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadImageICO(const std::string &path, Tex *texture) {
|
||||
bmp_bitmap_callback_vt bitmap_callbacks = {
|
||||
ICO::bitmap_create,
|
||||
ICO::bitmap_destroy,
|
||||
ICO::bitmap_get_buffer,
|
||||
ICO::bitmap_get_bpp
|
||||
};
|
||||
|
||||
uint16_t width = 0, height = 0;
|
||||
ico_collection ico;
|
||||
bmp_result code = BMP_OK;
|
||||
bmp_image *bmp;
|
||||
unsigned char *data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
ico_collection_create(&ico, &bitmap_callbacks);
|
||||
if (R_FAILED(FS::ReadFile(path, &data, (SceOff *)&size)))
|
||||
return false;
|
||||
|
||||
code = ico_analyse(&ico, size, data);
|
||||
if (code != BMP_OK) {
|
||||
ico_finalise(&ico);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bmp = ico_find(&ico, width, height);
|
||||
assert(bmp);
|
||||
|
||||
code = bmp_decode(bmp);
|
||||
if (code != BMP_OK) {
|
||||
if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) {
|
||||
ico_finalise(&ico);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* skip if the decoded image would be ridiculously large */
|
||||
if ((bmp->width * bmp->height) > 200000) {
|
||||
ico_finalise(&ico);
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LoadImage((unsigned char *)bmp->bitmap, (int *)&bmp->width, (int *)&bmp->height, texture, nullptr);
|
||||
ico_finalise(&ico);
|
||||
free(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadImagePCX(const std::string &path, Tex *texture) {
|
||||
unsigned char *data = nullptr;
|
||||
SceOff size = 0;
|
||||
|
||||
if (R_FAILED(FS::ReadFile(path, &data, &size)))
|
||||
return false;
|
||||
|
||||
int width = 0, height = 0;
|
||||
data = drpcx_load_memory(data, size, DRPCX_FALSE, &width, &height, nullptr, BYTES_PER_PIXEL);
|
||||
return LoadImage(data, &width, &height, texture, drpcx_free);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadImageTIFF(const std::string &path, Tex *texture) {
|
||||
TIFF *tif = TIFFOpen(path.c_str(), "r");
|
||||
if (tif) {
|
||||
uint32 width = 0, height = 0;
|
||||
size_t num_pixels = 0;
|
||||
uint32 *raster = nullptr;
|
||||
|
||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
num_pixels = width * height;
|
||||
|
||||
raster = (uint32*) _TIFFmalloc(num_pixels * sizeof (uint32));
|
||||
if (raster != nullptr) {
|
||||
if (TIFFReadRGBAImage(tif, width, height, raster, 0))
|
||||
LoadImage((unsigned char *)raster, (int *)&width, (int *)&height, texture, _TIFFfree);
|
||||
}
|
||||
|
||||
TIFFClose(tif);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadImageWEBP(const std::string &path, Tex *texture) {
|
||||
unsigned char *data = nullptr;
|
||||
SceOff size = 0;
|
||||
|
||||
if (R_FAILED(FS::ReadFile(path, &data, &size)))
|
||||
return false;
|
||||
|
||||
int width = 0, height = 0;
|
||||
data = WebPDecodeRGBA(data, size, &width, &height);
|
||||
return LoadImage(data, &width, &height, texture, free);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Free(Tex *texture) {
|
||||
glDeleteTextures(1, &texture->id);
|
||||
}
|
||||
|
||||
void Init(void) {
|
||||
bool image_ret = LoadImageFile("app0:res/file.png", &file_texture);
|
||||
IM_ASSERT(image_ret);
|
||||
|
||||
image_ret = LoadImageFile("app0:res/folder.png", &folder_texture);
|
||||
IM_ASSERT(image_ret);
|
||||
|
||||
image_ret = LoadImageFile("app0:res/image.png", &image_texture);
|
||||
IM_ASSERT(image_ret);
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
Free(&image_texture);
|
||||
Free(&folder_texture);
|
||||
Free(&file_texture);
|
||||
}
|
||||
}
|
81
source/utils.cpp
Normal file
81
source/utils.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <psp2/apputil.h>
|
||||
#include <psp2/system_param.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
int SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
|
||||
unsigned int pressed;
|
||||
|
||||
namespace Utils {
|
||||
static SceCtrlData pad, old_pad;
|
||||
|
||||
int InitAppUtil(void) {
|
||||
SceAppUtilInitParam init;
|
||||
SceAppUtilBootParam boot;
|
||||
std::memset(&init, 0, sizeof(SceAppUtilInitParam));
|
||||
std::memset(&boot, 0, sizeof(SceAppUtilBootParam));
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceAppUtilInit(&init, &boot)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EndAppUtil(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceAppUtilShutdown()))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ReadControls(void) {
|
||||
std::memset(&pad, 0, sizeof(SceCtrlData));
|
||||
sceCtrlPeekBufferPositive(0, &pad, 1);
|
||||
pressed = pad.buttons & ~old_pad.buttons;
|
||||
old_pad = pad;
|
||||
}
|
||||
|
||||
int GetEnterButton(void) {
|
||||
int button = 0, ret = 0;
|
||||
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button)))
|
||||
return ret;
|
||||
|
||||
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
|
||||
return SCE_CTRL_CIRCLE;
|
||||
else
|
||||
return SCE_CTRL_CROSS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetCancelButton(void) {
|
||||
int button = 0, ret = 0;
|
||||
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button)))
|
||||
return ret;
|
||||
|
||||
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
|
||||
return SCE_CTRL_CROSS;
|
||||
else
|
||||
return SCE_CTRL_CIRCLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetSizeString(char *string, double size) {
|
||||
int i = 0;
|
||||
const char *units[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
|
||||
|
||||
while (size >= 1024.0f) {
|
||||
size /= 1024.0f;
|
||||
i++;
|
||||
}
|
||||
|
||||
sprintf(string, "%.*f %s", (i == 0) ? 0 : 2, size, units[i]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user